Adrian Garcia Badaracco <adr...@adriangb.com> added the comment:

While this is figured out, would it be possible to remove the silent 
overriding? This seems like something type checkers should be doing, not silent 
runtime modification of classes. Pyright already (correctly) checks this, so I 
think it would just need to be added to MyPy.

>>> class C(Protocol):
...   def __init__(self) -> None:
...     print('init!')
...
>>> c = C()  # Pyright error, MyPy says it's okay

I came across this while trying to create a class that requires concrete 
subclasses to define a specific field, and it seems like Protocol is the only 
thing that can pull this off because of how type checkers special case it: 
https://gist.github.com/adriangb/6c1a001ee7035bad5bd56df70e0cf5e6

I don't particularly like this use of Protocol, but it works (aside from the 
overriding issue).

I don't know if this usage of implementing `__init__` on a protocol class 
should be valid or not, but I do think it's interesting that `__init__` is 
never called on the protocol class itself, even if the protocol class is the 
one defining it. It is only called on `MyAPIKey`, which is a concrete class 
that happens to inherit the implementation from a protocol class. So maybe that 
should be valid? I'm not sure.

But I do know that making type checkers enforce this instead runtime would 
allow this use case to work while still prohibiting the (in my opinion invalid) 
use case of calling `__init__` on the protocol class itself.

----------
nosy: +adriangb
status: pending -> open

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue44807>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to