# 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 ```pycon >>> from dataclasses import dataclass >>> @dataclass ... class C: ... recursive: object = ... ... >>> c1 = C() >>> c1.recursive = c1 >>> c1 == c1 True ``` ### Python 3.13 ```pycon >>> from dataclasses import dataclass >>> @dataclass ... class C: ... recursive: object = ... ... >>> c1 = C() >>> c1.recursive = c1 >>> c1 == c1 Traceback (most recent call last): File "<stdin>", line 1, in <module> c1 == c1 File "<string>", line 4, in __eq__ File "<string>", line 4, in __eq__ File "<string>", line 4, in __eq__ [Previous line repeated 996 more times] RecursionError: maximum recursion depth exceeded ``` This has started happening since 18cfc1eea569f0ce72ad403840c0e6cc5f81e1c2. Previously, 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`. This 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). ``` sip-build: An internal error occurred... Traceback (most recent call last): File "/usr/bin/sip-build", line 8, in <module> sys.exit(main()) ^^^^^^ File "/usr/lib64/python3.13/site-packages/sipbuild/tools/build.py", line 37, in main handle_exception(e) File "/usr/lib64/python3.13/site-packages/sipbuild/exceptions.py", line 81, in handle_exception raise e File "/usr/lib64/python3.13/site-packages/sipbuild/tools/build.py", line 34, in main project.build() File "/usr/lib64/python3.13/site-packages/sipbuild/project.py", line 245, in build self.builder.build() File "/usr/lib64/python3.13/site-packages/sipbuild/builder.py", line 48, in build self._generate_bindings() File "/usr/lib64/python3.13/site-packages/sipbuild/builder.py", line 280, in _generate_bindings buildable = bindings.generate() ^^^^^^^^^^^^^^^^^^^ File "/builddir/build/BUILD/PyQt5-5.15.9/project.py", line 619, in generate buildable = super().generate() ^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.13/site-packages/sipbuild/bindings.py", line 214, in generate output_pyi(spec, project, pyi_path) File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py", line 53, in output_pyi _module(pf, spec, module) File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py", line 132, in _module _class(pf, spec, module, klass, defined) File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py", line 267, in _class _class(pf, spec, module, nested, defined, indent) File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py", line 289, in _class _callable(pf, spec, module, member, klass.overloads, File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py", line 485, in _callable _overload(pf, spec, module, overload, overloaded, first_overload, File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py", line 575, in _overload signature = _python_signature(spec, module, py_signature, defined, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py", line 599, in _python_signature as_str = _argument(spec, module, arg, defined, arg_nr=arg_nr) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py", line 676, in _argument s += _type(spec, module, arg, defined, out=out) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/pyi.py", line 710, in _type return ArgumentFormatter(spec, arg).as_type_hint(module, out, defined) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/formatters/argument.py", line 327, in as_type_hint s += TypeHintManager(self.spec).as_type_hint(hint, out, context, ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.13/site-packages/sipbuild/generator/outputs/type_hints.py", line 107, in __new__ manager = cls._spec_manager_map[spec] ~~~~~~~~~~~~~~~~~~~~~^^^^^^ File "/usr/lib64/python3.13/weakref.py", line 415, in __getitem__ return self.data[ref(key)] ~~~~~~~~~^^^^^^^^^^ File "<string>", line 4, in __eq__ File "<string>", line 4, in __eq__ File "<string>", line 4, in __eq__ [Previous line repeated 495 more times] RecursionError: maximum recursion depth exceeded in comparison ``` cc @rhettinger @ericvsmith Thanks to @swt2c for bisecting the problem. Thanks to @encukou who gave me a hint of what to look for when finding the smaller reproducer. ### CPython versions tested on: 3.13 ### Operating systems tested on: Linux <!-- gh-linked-prs --> ### Linked PRs * gh-116790 <!-- /gh-linked-prs -->