Repository navigation
Protocols in typing extensions #464
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
Changes from 1 commit
1ebd3f5
37b6a7b
bb3a8a9
d8ae30e
a4e68ff
c8076ee
80e8014
a6a631a
5913fe6
faf4ff0
c7f6b68
8151355
76a7ecd
95faebe
04f1c51
ce4e04f
a7cf2fb
8b50c60
1dc1971
e25077f
1c1d9fe
9b22594
458b232
dbc6def
31cbe0d
171b1e5
fc0ec94
f1f478a
8652ced
8f0a778
23e80da
dc01948
733016d
8f12689
a4d397e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,7 @@ | |
| from typing import GenericMeta, TypingMeta, Generic, Callable, TypeVar, Tuple | ||
| NO_PROTOCOL = False | ||
| try: | ||
| from typing import _type_vars, _next_in_mro, _type_check, _check_generic | ||
| from typing import _type_vars, _next_in_mro, _type_check | ||
| except ImportError: | ||
| NO_PROTOCOL = True | ||
| try: | ||
|
|
@@ -36,6 +36,17 @@ class _TypingEmpty: pass | |
| from typing import _make_subclasshook | ||
| except ImportError: | ||
| _make_subclasshook = None | ||
| try: | ||
| from typing import _check_generic | ||
| except ImportError: | ||
| def _check_generic(cls, parameters): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just always define this locally? What do you get by importing it from typing (apart from the risk that a future version of typing changes this internal function in a way that breaks us)? Same for
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may be just an artefact from initial attempts to allow this on 3.5.1 with minimal changes, I will check now. |
||
| if not cls.__parameters__: | ||
| raise TypeError("%s is not a generic class" % repr(cls)) | ||
| alen = len(parameters) | ||
| elen = len(cls.__parameters__) | ||
| if alen != elen: | ||
| raise TypeError("Too %s parameters for %s; actual %s, expected %s" % | ||
| ("many" if alen > elen else "few", repr(cls), alen, elen)) | ||
|
|
||
| if hasattr(typing, '_generic_new'): | ||
| _generic_new = typing._generic_new | ||
|
|
@@ -865,39 +876,41 @@ def __getitem__(self, params): | |
| extra=self.__extra__, | ||
| orig_bases=self.__orig_bases__) | ||
|
|
||
| if NO_PROTOCOL: | ||
| del ProtocolMeta | ||
| else: | ||
| class Protocol(metaclass=ProtocolMeta): | ||
| """Base class for protocol classes. Protocol classes are defined as:: | ||
|
|
||
| class Protocol(metaclass=ProtocolMeta): | ||
| """Base class for protocol classes. Protocol classes are defined as:: | ||
|
|
||
| class Proto(Protocol[T]): | ||
| def meth(self) -> T: | ||
| ... | ||
| class Proto(Protocol[T]): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See my comments about the corresponding docstring in the Python 2 implementation. They are also relevant here. |
||
| def meth(self) -> T: | ||
| ... | ||
|
|
||
| Such classes are primarily used with static type checkers that recognize | ||
| structural subtyping (static duck-typing), for example:: | ||
| Such classes are primarily used with static type checkers that recognize | ||
| structural subtyping (static duck-typing), for example:: | ||
|
|
||
| class C: | ||
| def meth(self) -> int: | ||
| return 0 | ||
| class C: | ||
| def meth(self) -> int: | ||
| return 0 | ||
|
|
||
| def func(x: Proto[int]) -> int: | ||
| return x.meth() | ||
| def func(x: Proto[int]) -> int: | ||
| return x.meth() | ||
|
|
||
| func(C()) # Passes static type check | ||
| func(C()) # Passes static type check | ||
|
|
||
| See PEP 544 for details. Protocol classes decorated with @typing_extensions.runtime | ||
| act as simple-minded runtime protocols that checks only the presence of | ||
| given attributes, ignoring their type signatures. | ||
| """ | ||
| See PEP 544 for details. Protocol classes decorated with @typing_extensions.runtime | ||
| act as simple-minded runtime protocols that checks only the presence of | ||
| given attributes, ignoring their type signatures. | ||
| """ | ||
|
|
||
| __slots__ = () | ||
| _is_protocol = True | ||
| __slots__ = () | ||
| _is_protocol = True | ||
|
|
||
| def __new__(cls, *args, **kwds): | ||
| if cls._gorg is Protocol: | ||
| raise TypeError("Type Protocol cannot be instantiated; " | ||
| "it can be used only as a base class") | ||
| return _generic_new(cls.__next_in_mro__, cls, *args, **kwds) | ||
| def __new__(cls, *args, **kwds): | ||
| if cls._gorg is Protocol: | ||
| raise TypeError("Type Protocol cannot be instantiated; " | ||
| "it can be used only as a base class") | ||
| return _generic_new(cls.__next_in_mro__, cls, *args, **kwds) | ||
|
|
||
|
|
||
| def runtime(cls): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still don't like the |
||
|
|
@@ -916,4 +929,4 @@ def runtime(cls): | |
|
|
||
|
|
||
| if NO_PROTOCOL: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again it seems weird to define it and then delete it. (Also maybe the flag could be reverted and be named |
||
| del Protocol, runtime | ||
| del runtime | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comment discussing when this happens and what it means.