You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When we subclassing Protocol, we get a __init__ differing from default one but the protocol in question didn't define any __init__.
example
Previously, pure class __init__ take no arguments.
In [21]: class B:
...: pass
In [22]: B(b=1,c=2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-22-9790dbc81f4f> in <module>
----> 1 B(b=1,c=2)
TypeError: B() takes no arguments
Now with Protocol, we get different __init__ API implicitly.
In [20]: from typing_extensions import Protocol
...: from typing import *
...:
...: class A(Protocol):
...: a:int
...:
...: class B(A):
...: pass
...:
...: B(b=1,c=2)
Out[20]: <__main__.B at 0x10a866198>
It seems that it inherit __init__(self,*args,**kwargs) from Protocol.
But the document (mypy) does not say anything about it.
This is not intuitive and surprising. At least any sane programmer would assume that __init__ didn't change, in reasoning that Protocol is just pure interface thus nothing would be inherited.
ENV
➜ pip show typing_extensions
Name: typing-extensions
Version: 3.7.2
Summary: Backported and Experimental Type Hints for Python 3.5+
Home-page: https://github.com/python/typing/blob/master/typing_extensions/README.rst
Author: Guido van Rossum, Jukka Lehtosalo, Lukasz Langa, Michael Lee
Author-email: levkivskyi@gmail.com
License: PSF
Location: /Users/catch22/miniconda3/lib/python3.7/site-packages
Requires:
Required-by:
➜ ipython
Python 3.7.1 (default, Dec 14 2018, 13:28:58)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.2.0 -- An enhanced Interactive Python. Type '?' for help.
Still getting this in Python 3.12 I believe. When I define an empty init in the class inheriting from the protocol my issues are solved. And they are only caused if I inherit from a Protocol.
Maybe it's linked to the fact that I'm using a generic Protocol but I wouldn't know much about this.
...
# Generic types per repositoryModel=TypeVar("Model", bound=DbBaseModel)
TCreate=TypeVar("TCreate", bound=BaseModel, contravariant=True)
TUpdate=TypeVar("TUpdate", bound=BaseModel, contravariant=True)
# Only used as inputModelSchema=TypeVar("ModelSchema", bound=BaseModel)
Data=TypeVar("Data", bound=BaseModel)
classRepositoryProtocol(Protocol[Model, TCreate, TUpdate]):
@propertydefmodel(self) ->Type[Model]: ...
I noticed this as I was using BaseRepository as a dependency in a FastAPI route. As soon as I added the protocol, the route was expecting *args, *kwargs as required arguments.
As soon as I remove the protocol, this is fixed again.
When I kept the Protocol but defined an empty init in BaseRepository, it was also fixed.
Activity
uriyyo commentedon Aug 2, 2021
This issue is fixed by python/cpython#27545
RamiAwar commentedon Feb 24, 2024
Still getting this in Python 3.12 I believe. When I define an empty init in the class inheriting from the protocol my issues are solved. And they are only caused if I inherit from a Protocol.
Maybe it's linked to the fact that I'm using a generic Protocol but I wouldn't know much about this.
I noticed this as I was using BaseRepository as a dependency in a FastAPI route. As soon as I added the protocol, the route was expecting *args, *kwargs as required arguments.
As soon as I remove the protocol, this is fixed again.
When I kept the Protocol but defined an empty init in BaseRepository, it was also fixed.