New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dataclasses that inherit from Protocol subclasses have wrong __init__ #89244
Comments
I believe In Python ### Demonstration from dataclasses import dataclass
from typing import Protocol
class P(Protocol):
pass
@dataclass
class B(P):
value: str
print(B("test")) In Traceback (most recent call last):
File "test.py", line 11, in <module>
print(B("test"))
TypeError: B() takes no arguments In B(value='test') ### Affected Projects |
I believe this was a deeper issue that affected all classes inheriting Protocol, causing a TypeError on even the most basic case (see attached): Traceback (most recent call last):
File "/.../test.py", line 14, in <module>
MyClass()
File "/.../test.py", line 11, in __init__
super().__init__()
File "/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/typing.py", line 1083, in _no_init
raise TypeError('Protocols cannot be instantiated')
TypeError: Protocols cannot be instantiated This was a new regression in 3.9.7 and seems to be resolved by this fix. The desired behavior should be supported according to PEP-544: https://www.python.org/dev/peps/pep-0544/#explicitly-declaring-implementation |
Ian,
is calling the Simply remove This behavior was changed in #27545 (see Cheers, |
Julian, That is certainly a workaround, however the behavior you are describing is inconsistent with PEP-544 in both word and intention. From the PEP:
It further describes the semantics of inheriting as "unchanged" from a "regular base class". If the semantics are "unchanged" then it should follow that super().__init__() would pass through the protocol to the object.__init__, just like a "regular base class" would if it does not override __init__. Furthermore, the intention of inheriting a Protocol as described in the PEP:
The purpose of adding a Protocol sub-class as an explicit base class is thus only to improve static analysis, it should *not* to modify the runtime semantics. Consider the case where a package maintainer wants to enhance the flexibility of their types by transitioning from using an ABC to using structural sub-typing. That simple typing change would be a breaking change to the package consumers, who must now remove a super().__init__() call. Ian |
Remove the `_WithOp` protocol because it is not used and causes the dataclass `GraphContext` to not be able to init in some python versions. Reference to issue of dataclasses Inheriting from Protocol python/cpython#89244 Pull Request resolved: #85916 Approved by: https://github.com/BowenBao, https://github.com/abock, https://github.com/thiagocrepaldi
Remove the `_WithOp` protocol because it is not used and causes the dataclass `GraphContext` to not be able to init in some python versions. Reference to issue of dataclasses Inheriting from Protocol python/cpython#89244 Pull Request resolved: #85916 Approved by: https://github.com/BowenBao, https://github.com/abock, https://github.com/thiagocrepaldi
Remove the `_WithOp` protocol because it is not used and causes the dataclass `GraphContext` to not be able to init in some python versions. Reference to issue of dataclasses Inheriting from Protocol python/cpython#89244 Pull Request resolved: pytorch#85916 Approved by: https://github.com/BowenBao, https://github.com/abock, https://github.com/thiagocrepaldi
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: