mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
gh-104873: Add typing.get_protocol_members and typing.is_protocol (#104878)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
ba516e70c6
commit
fc8037d84c
5 changed files with 152 additions and 2 deletions
|
@ -131,7 +131,9 @@ __all__ = [
|
|||
'get_args',
|
||||
'get_origin',
|
||||
'get_overloads',
|
||||
'get_protocol_members',
|
||||
'get_type_hints',
|
||||
'is_protocol',
|
||||
'is_typeddict',
|
||||
'LiteralString',
|
||||
'Never',
|
||||
|
@ -3337,3 +3339,43 @@ def override[F: _Func](method: F, /) -> F:
|
|||
# read-only property, TypeError if it's a builtin class.
|
||||
pass
|
||||
return method
|
||||
|
||||
|
||||
def is_protocol(tp: type, /) -> bool:
|
||||
"""Return True if the given type is a Protocol.
|
||||
|
||||
Example::
|
||||
|
||||
>>> from typing import Protocol, is_protocol
|
||||
>>> class P(Protocol):
|
||||
... def a(self) -> str: ...
|
||||
... b: int
|
||||
>>> is_protocol(P)
|
||||
True
|
||||
>>> is_protocol(int)
|
||||
False
|
||||
"""
|
||||
return (
|
||||
isinstance(tp, type)
|
||||
and getattr(tp, '_is_protocol', False)
|
||||
and tp != Protocol
|
||||
)
|
||||
|
||||
|
||||
def get_protocol_members(tp: type, /) -> frozenset[str]:
|
||||
"""Return the set of members defined in a Protocol.
|
||||
|
||||
Example::
|
||||
|
||||
>>> from typing import Protocol, get_protocol_members
|
||||
>>> class P(Protocol):
|
||||
... def a(self) -> str: ...
|
||||
... b: int
|
||||
>>> get_protocol_members(P)
|
||||
frozenset({'a', 'b'})
|
||||
|
||||
Raise a TypeError for arguments that are not Protocols.
|
||||
"""
|
||||
if not is_protocol(tp):
|
||||
raise TypeError(f'{tp!r} is not a Protocol')
|
||||
return frozenset(tp.__protocol_attrs__)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue