Title: Python 3.13 regression: Recursive dataclasses fail to ==: RecursionError: maximum recursion depth exceeded · Issue #116647 · python/cpython · GitHub
Open Graph Title: Python 3.13 regression: Recursive dataclasses fail to ==: RecursionError: maximum recursion depth exceeded · Issue #116647 · python/cpython
X Title: Python 3.13 regression: Recursive dataclasses fail to ==: RecursionError: maximum recursion depth exceeded · Issue #116647 · python/cpython
Description: Bug report Bug description: There is a regression in comparing recursive dataclasses for equality in Python 3.13.0 from the first alpha until at least a4. Python 3.12 >>> from dataclasses import dataclass >>> @dataclass ... class C: ... ...
Open Graph Description: Bug report Bug description: There is a regression in comparing recursive dataclasses for equality in Python 3.13.0 from the first alpha until at least a4. Python 3.12 >>> from dataclasses import da...
X Description: Bug report Bug description: There is a regression in comparing recursive dataclasses for equality in Python 3.13.0 from the first alpha until at least a4. Python 3.12 >>> from dataclasses ...
Opengraph URL: https://github.com/python/cpython/issues/116647
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Python 3.13 regression: Recursive dataclasses fail to ==: RecursionError: maximum recursion depth exceeded","articleBody":"# Bug report\r\n\r\n### Bug description:\r\n\r\nThere is a regression in comparing recursive dataclasses for equality in Python 3.13.0 from the first alpha until at least a4.\r\n\r\n### Python 3.12\r\n\r\n```pycon\r\n\u003e\u003e\u003e from dataclasses import dataclass\r\n\u003e\u003e\u003e @dataclass\r\n... class C:\r\n... recursive: object = ...\r\n... \r\n\u003e\u003e\u003e c1 = C()\r\n\u003e\u003e\u003e c1.recursive = c1\r\n\u003e\u003e\u003e c1 == c1\r\nTrue\r\n```\r\n\r\n\r\n### Python 3.13\r\n\r\n```pycon\r\n\u003e\u003e\u003e from dataclasses import dataclass\r\n\u003e\u003e\u003e @dataclass\r\n... class C:\r\n... recursive: object = ...\r\n... \r\n\u003e\u003e\u003e c1 = C()\r\n\u003e\u003e\u003e c1.recursive = c1\r\n\u003e\u003e\u003e c1 == c1\r\nTraceback (most recent call last):\r\n File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\r\n c1 == c1\r\n File \"\u003cstring\u003e\", line 4, in __eq__\r\n File \"\u003cstring\u003e\", line 4, in __eq__\r\n File \"\u003cstring\u003e\", line 4, in __eq__\r\n [Previous line repeated 996 more times]\r\nRecursionError: maximum recursion depth exceeded\r\n```\r\n\r\nThis has started happening since 18cfc1eea569f0ce72ad403840c0e6cc5f81e1c2.\r\n\r\nPreviously, tuples were compared via `==`, which skips calling `__eq__` for items with the same identity. Now it skips the identity check and compares items directly with `__eq__`, causing `RecursionError`.\r\n\r\nThis breaks sip-build; hence, we cannot build pyqt5 or pyqt6 in Fedora with Python 3.13 to test the entire stack. For details, see this [Fedora bugzilla](https://bugzilla.redhat.com/show_bug.cgi?id=2250649).\r\n\r\n```\r\nsip-build: An internal error occurred...\r\nTraceback (most recent call last):\r\n File \"/usr/bin/sip-build\", line 8, in \u003cmodule\u003e\r\n sys.exit(main())\r\n ^^^^^^\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/tools/build.py\", line 37, in main\r\n handle_exception(e)\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/exceptions.py\", line 81, in handle_exception\r\n raise e\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/tools/build.py\", line 34, in main\r\n project.build()\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/project.py\", line 245, in build\r\n self.builder.build()\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/builder.py\", line 48, in build\r\n self._generate_bindings()\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/builder.py\", line 280, in _generate_bindings\r\n buildable = bindings.generate()\r\n ^^^^^^^^^^^^^^^^^^^\r\n File \"/builddir/build/BUILD/PyQt5-5.15.9/project.py\", line 619, in generate\r\n buildable = super().generate()\r\n ^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/bindings.py\", line 214, in generate\r\n output_pyi(spec, project, pyi_path)\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py\", line 53, in output_pyi\r\n _module(pf, spec, module)\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py\", line 132, in _module\r\n _class(pf, spec, module, klass, defined)\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py\", line 267, in _class\r\n _class(pf, spec, module, nested, defined, indent)\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py\", line 289, in _class\r\n _callable(pf, spec, module, member, klass.overloads,\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py\", line 485, in _callable\r\n _overload(pf, spec, module, overload, overloaded, first_overload,\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py\", line 575, in _overload\r\n signature = _python_signature(spec, module, py_signature, defined,\r\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py\", line 599, in _python_signature\r\n as_str = _argument(spec, module, arg, defined, arg_nr=arg_nr)\r\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py\", line 676, in _argument\r\n s += _type(spec, module, arg, defined, out=out)\r\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py\", line 710, in _type\r\n return ArgumentFormatter(spec, arg).as_type_hint(module, out, defined)\r\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/formatters/argument.py\", line 327, in as_type_hint\r\n s += TypeHintManager(self.spec).as_type_hint(hint, out, context,\r\n ^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n File \"/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/type_hints.py\", line 107, in __new__\r\n manager = cls._spec_manager_map[spec]\r\n ~~~~~~~~~~~~~~~~~~~~~^^^^^^\r\n File \"/usr/lib64/python3.13/weakref.py\", line 415, in __getitem__\r\n return self.data[ref(key)]\r\n ~~~~~~~~~^^^^^^^^^^\r\n File \"\u003cstring\u003e\", line 4, in __eq__\r\n File \"\u003cstring\u003e\", line 4, in __eq__\r\n File \"\u003cstring\u003e\", line 4, in __eq__\r\n [Previous line repeated 495 more times]\r\nRecursionError: maximum recursion depth exceeded in comparison\r\n```\r\n\r\ncc @rhettinger @ericvsmith\r\n\r\nThanks to @swt2c for bisecting the problem. Thanks to @encukou who gave me a hint of what to look for when finding the smaller reproducer.\r\n\r\n### CPython versions tested on:\r\n\r\n3.13\r\n\r\n### Operating systems tested on:\r\n\r\nLinux\n\n\u003c!-- gh-linked-prs --\u003e\n### Linked PRs\n* gh-116790\n\u003c!-- /gh-linked-prs --\u003e\n","author":{"url":"https://github.com/hroncok","@type":"Person","name":"hroncok"},"datePublished":"2024-03-12T10:36:26.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":6},"url":"https://github.com/116647/cpython/issues/116647"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:eaa61518-791d-0b34-b414-d16525f3d5a4 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | B848:201472:CA7285:11CBB43:696A21A7 |
| html-safe-nonce | 5b91cfb1b90516d2411372dbd776d2c806ddf401aa47efc6cc85fdc19acdc48a |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCODQ4OjIwMTQ3MjpDQTcyODU6MTFDQkI0Mzo2OTZBMjFBNyIsInZpc2l0b3JfaWQiOiIzNTgyMjI0NzY3ODUxODMxNzE5IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | b4d083d45cf790158f6d10a2ac526b0feba515e457724648e4fc299172ebffc5 |
| hovercard-subject-tag | issue:2181276251 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/116647/issue_layout |
| twitter:image | https://opengraph.githubassets.com/493712826b393acab26735f9e91156f4349d5961833e2f74b4798239450129b7/python/cpython/issues/116647 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/493712826b393acab26735f9e91156f4349d5961833e2f74b4798239450129b7/python/cpython/issues/116647 |
| og:image:alt | Bug report Bug description: There is a regression in comparing recursive dataclasses for equality in Python 3.13.0 from the first alpha until at least a4. Python 3.12 >>> from dataclasses import da... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | hroncok |
| hostname | github.com |
| expected-hostname | github.com |
| None | 014f3d193f36b7d393f88ca22d06fbacd370800b40a547c1ea67291e02dc8ea3 |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | d515f6f09fa57a93bf90355cb894eb84ca4f458f |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width