This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author tinchester
Recipients tinchester
Date 2022-01-16.22:48:06
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1642373286.75.0.870897334257.issue46404@roundup.psfhosted.org>
In-reply-to
Content
We've received a report over at the attrs issue tracker about our test suite failing on Python 3.11. Here's the link: https://github.com/python-attrs/attrs/issues/907

It turns out to be an issue with the no-arg `super()` calls in slotted classes. Here's a minimal reproducer example:

```
from attrs import define


@define
class A:
    pass


@define
class B(A):
    def test(self):
        super()


B().test()
```

```
Traceback (most recent call last):
  File "/Users/tintvrtkovic/pg/attrs/a01.py", line 15, in <module>
    B().test()
    ^^^^^^^^^^
  File "/Users/tintvrtkovic/pg/attrs/a01.py", line 12, in test
    super()
    ^^^^^^^
TypeError: super(type, obj): obj must be an instance or subtype of type
```
This is a known issue for which we have implemented workarounds. The workarounds aren't effective for 3.11 though. I have implemented a fix in attrs (https://github.com/python-attrs/attrs/pull/910), but I still thought I'd post this here to maybe get the core devs opinion.

Dataclasses exhibit the exact same issue when used with `slots=True`, both in 3.10 when `slots` was added and in 3.11. I guess no one reported it or tried fixing it.

A comprehensive description of the issue follows: since it's impossible to add *slotness* (i.e. set `__slots__`) to a class after it has been created, when creating a slotted class the class decorators in attrs and dataclasses actually replace the class they are applied to with a copy of it, with slots added. This works, except in the case of the no-arg `super()` being used in any of the class methods (and maybe another edge case that I can't remember). When the compiler encounters the no-arg `super()` form, it adds some state to the function `__closure__` cells. This state causes the exception shown above, since it's incorrect when the class gets replaced.

So these closure cells need to be rewritten when the class is replaced. In Python versions prior to 3.11, the closure cells were immutable so extra effort was needed to rewrite them. The functions are here: https://github.com/python-attrs/attrs/blob/9727008fd1e40bc55cdc6aee71e0f61553f33127/src/attr/_compat.py#L145.

In 3.11, our old closure cell rewriting doesn't work any more, but closure cells don't appear to be immutable either, so the fix in my attr PR linked above is simple. Still, it's another branch in the code to support a specific version.

I don't know if there's anything actionable here for Python, apart from confirming or denying if this behavior is expected.
History
Date User Action Args
2022-01-16 22:48:06tinchestersetrecipients: + tinchester
2022-01-16 22:48:06tinchestersetmessageid: <1642373286.75.0.870897334257.issue46404@roundup.psfhosted.org>
2022-01-16 22:48:06tinchesterlinkissue46404 messages
2022-01-16 22:48:06tinchestercreate