Skip to content

Commit e292a0d

Browse files
committed
Basic updates to use standard protocols
1 parent 761ee6a commit e292a0d

File tree

2 files changed

+84
-40
lines changed

2 files changed

+84
-40
lines changed

stdlib/2/typing.pyi

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Type = object()
1616
_promote = object()
1717
no_type_check = object()
1818
ClassVar = object()
19+
Protocol = object()
1920

2021
class GenericMeta(type): ...
2122

@@ -52,46 +53,56 @@ _KT_co = TypeVar('_KT_co', covariant=True) # Key type covariant containers.
5253
_VT_co = TypeVar('_VT_co', covariant=True) # Value type covariant containers.
5354
_T_contra = TypeVar('_T_contra', contravariant=True) # Ditto contravariant.
5455

55-
class SupportsInt(metaclass=ABCMeta):
56+
@runtime
57+
class SupportsInt(Protocol, metaclass=ABCMeta):
5658
@abstractmethod
5759
def __int__(self) -> int: ...
5860

59-
class SupportsFloat(metaclass=ABCMeta):
61+
@runtime
62+
class SupportsFloat(Protocol, metaclass=ABCMeta):
6063
@abstractmethod
6164
def __float__(self) -> float: ...
6265

63-
class SupportsComplex(metaclass=ABCMeta):
66+
@runtime
67+
class SupportsComplex(Protocol, metaclass=ABCMeta):
6468
@abstractmethod
6569
def __complex__(self) -> complex: ...
6670

67-
class SupportsAbs(Generic[_T]):
71+
@runtime
72+
class SupportsAbs(Protocol[_T]):
6873
@abstractmethod
6974
def __abs__(self) -> _T: ...
7075

71-
class SupportsRound(Generic[_T]):
76+
@runtime
77+
class SupportsRound(Protocol[_T]):
7278
@abstractmethod
7379
def __round__(self, ndigits: int = ...) -> _T: ...
7480

75-
class Reversible(Generic[_T_co]):
81+
@runtime
82+
class Reversible(Protocol[_T_co]):
7683
@abstractmethod
7784
def __reversed__(self) -> Iterator[_T_co]: ...
7885

79-
class Sized(metaclass=ABCMeta):
86+
@runtime
87+
class Sized(Protocol, metaclass=ABCMeta):
8088
@abstractmethod
8189
def __len__(self) -> int: ...
8290

83-
class Hashable(metaclass=ABCMeta):
91+
@runtime
92+
class Hashable(Protocol, metaclass=ABCMeta):
8493
# TODO: This is special, in that a subclass of a hashable class may not be hashable
8594
# (for example, list vs. object). It's not obvious how to represent this. This class
8695
# is currently mostly useless for static checking.
8796
@abstractmethod
8897
def __hash__(self) -> int: ...
8998

90-
class Iterable(Generic[_T_co]):
99+
@runtime
100+
class Iterable(Protocol[_T_co]):
91101
@abstractmethod
92102
def __iter__(self) -> Iterator[_T_co]: ...
93103

94-
class Iterator(Iterable[_T_co], Generic[_T_co]):
104+
@runtime
105+
class Iterator(Iterable[_T_co], Protocol[_T_co]):
95106
@abstractmethod
96107
def next(self) -> _T_co: ...
97108

@@ -114,11 +125,13 @@ class Generator(Iterator[_T_co], Generic[_T_co, _T_contra, _V_co]):
114125
gi_frame = ... # type: FrameType
115126
gi_running = ... # type: bool
116127

117-
class Container(Generic[_T_co]):
128+
@runtime
129+
class Container(Protocol[_T_co]):
118130
@abstractmethod
119131
def __contains__(self, x: object) -> bool: ...
120132

121-
class Sequence(Iterable[_T_co], Container[_T_co], Sized, Reversible[_T_co], Generic[_T_co]):
133+
@runtime
134+
class Sequence(Iterable[_T_co], Container[_T_co], Sized, Reversible[_T_co], Protocol[_T_co]):
122135
@overload
123136
@abstractmethod
124137
def __getitem__(self, i: int) -> _T_co: ...
@@ -132,7 +145,8 @@ class Sequence(Iterable[_T_co], Container[_T_co], Sized, Reversible[_T_co], Gene
132145
def __iter__(self) -> Iterator[_T_co]: ...
133146
def __reversed__(self) -> Iterator[_T_co]: ...
134147

135-
class MutableSequence(Sequence[_T], Generic[_T]):
148+
@runtime
149+
class MutableSequence(Sequence[_T], Protocol[_T]):
136150
@abstractmethod
137151
def insert(self, index: int, object: _T) -> None: ...
138152
@overload
@@ -155,7 +169,8 @@ class MutableSequence(Sequence[_T], Generic[_T]):
155169
def remove(self, object: _T) -> None: ...
156170
def __iadd__(self, x: Iterable[_T]) -> MutableSequence[_T]: ...
157171

158-
class AbstractSet(Sized, Iterable[_T_co], Container[_T_co], Generic[_T_co]):
172+
@runtime
173+
class AbstractSet(Sized, Iterable[_T_co], Container[_T_co], Protocol[_T_co]):
159174
@abstractmethod
160175
def __contains__(self, x: object) -> bool: ...
161176
# Mixin methods
@@ -170,7 +185,8 @@ class AbstractSet(Sized, Iterable[_T_co], Container[_T_co], Generic[_T_co]):
170185
# TODO: argument can be any container?
171186
def isdisjoint(self, s: AbstractSet[Any]) -> bool: ...
172187

173-
class MutableSet(AbstractSet[_T], Generic[_T]):
188+
@runtime
189+
class MutableSet(AbstractSet[_T], Protocol[_T]):
174190
@abstractmethod
175191
def add(self, x: _T) -> None: ...
176192
@abstractmethod
@@ -199,7 +215,8 @@ class ValuesView(MappingView, Iterable[_VT_co], Generic[_VT_co]):
199215
def __contains__(self, o: object) -> bool: ...
200216
def __iter__(self) -> Iterator[_VT_co]: ...
201217

202-
class Mapping(Iterable[_KT], Container[_KT], Sized, Generic[_KT, _VT_co]):
218+
@runtime
219+
class Mapping(Iterable[_KT], Container[_KT], Sized, Protocol[_KT, _VT_co]):
203220
# TODO: We wish the key type could also be covariant, but that doesn't work,
204221
# see discussion in https: //github.com/python/typing/pull/273.
205222
@abstractmethod
@@ -218,7 +235,8 @@ class Mapping(Iterable[_KT], Container[_KT], Sized, Generic[_KT, _VT_co]):
218235
def iteritems(self) -> Iterator[Tuple[_KT, _VT_co]]: ...
219236
def __contains__(self, o: object) -> bool: ...
220237

221-
class MutableMapping(Mapping[_KT, _VT], Generic[_KT, _VT]):
238+
@runtime
239+
class MutableMapping(Mapping[_KT, _VT], Protocol[_KT, _VT]):
222240
@abstractmethod
223241
def __setitem__(self, k: _KT, v: _VT) -> None: ...
224242
@abstractmethod
@@ -399,3 +417,4 @@ class NamedTuple(tuple):
399417
def _replace(self, **kwargs: Any) -> NamedTuple: ...
400418

401419
def NewType(name: str, tp: Type[_T]) -> Type[_T]: ...
420+
def runtime(cls: _T) -> _T: ...

stdlib/3/typing.pyi

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Type = object()
1717
_promote = object()
1818
no_type_check = object()
1919
ClassVar = object()
20+
Protocol = object()
2021

2122
class GenericMeta(type): ...
2223

@@ -55,50 +56,61 @@ _KT_co = TypeVar('_KT_co', covariant=True) # Key type covariant containers.
5556
_VT_co = TypeVar('_VT_co', covariant=True) # Value type covariant containers.
5657
_T_contra = TypeVar('_T_contra', contravariant=True) # Ditto contravariant.
5758

58-
class SupportsInt(metaclass=ABCMeta):
59+
@runtime
60+
class SupportsInt(Protocol, metaclass=ABCMeta):
5961
@abstractmethod
6062
def __int__(self) -> int: ...
6163

62-
class SupportsFloat(metaclass=ABCMeta):
64+
@runtime
65+
class SupportsFloat(Protocol, metaclass=ABCMeta):
6366
@abstractmethod
6467
def __float__(self) -> float: ...
6568

66-
class SupportsComplex(metaclass=ABCMeta):
69+
@runtime
70+
class SupportsComplex(Protocol, metaclass=ABCMeta):
6771
@abstractmethod
6872
def __complex__(self) -> complex: ...
6973

70-
class SupportsBytes(metaclass=ABCMeta):
74+
@runtime
75+
class SupportsBytes(Protocol, metaclass=ABCMeta):
7176
@abstractmethod
7277
def __bytes__(self) -> bytes: ...
7378

74-
class SupportsAbs(Generic[_T]):
79+
@runtime
80+
class SupportsAbs(Protocol[_T]):
7581
@abstractmethod
7682
def __abs__(self) -> _T: ...
7783

78-
class SupportsRound(Generic[_T]):
84+
@runtime
85+
class SupportsRound(Protocol[_T]):
7986
@abstractmethod
8087
def __round__(self, ndigits: int = ...) -> _T: ...
8188

82-
class Reversible(Generic[_T_co]):
89+
@runtime
90+
class Reversible(Protocol[_T_co]):
8391
@abstractmethod
8492
def __reversed__(self) -> Iterator[_T_co]: ...
8593

86-
class Sized(metaclass=ABCMeta):
94+
@runtime
95+
class Sized(Protocol, metaclass=ABCMeta):
8796
@abstractmethod
8897
def __len__(self) -> int: ...
8998

90-
class Hashable(metaclass=ABCMeta):
99+
@runtime
100+
class Hashable(Protocol, metaclass=ABCMeta):
91101
# TODO: This is special, in that a subclass of a hashable class may not be hashable
92102
# (for example, list vs. object). It's not obvious how to represent this. This class
93103
# is currently mostly useless for static checking.
94104
@abstractmethod
95105
def __hash__(self) -> int: ...
96106

97-
class Iterable(Generic[_T_co]):
107+
@runtime
108+
class Iterable(Protocol[_T_co]):
98109
@abstractmethod
99110
def __iter__(self) -> Iterator[_T_co]: ...
100111

101-
class Iterator(Iterable[_T_co], Generic[_T_co]):
112+
@runtime
113+
class Iterator(Iterable[_T_co], Protocol[_T_co]):
102114
@abstractmethod
103115
def __next__(self) -> _T_co: ...
104116
def __iter__(self) -> 'Iterator[_T_co]': ...
@@ -130,7 +142,8 @@ class Generator(Iterator[_T_co], Generic[_T_co, _T_contra, _V_co]):
130142
# Awaitable, AsyncIterator, AsyncIterable, Coroutine, Collection, ContextManager.
131143
# See https: //github.com/python/typeshed/issues/655 for why this is not easy.
132144

133-
class Awaitable(Generic[_T_co]):
145+
@runtime
146+
class Awaitable(Protocol[_T_co]):
134147
@abstractmethod
135148
def __await__(self) -> Generator[Any, None, _T_co]: ...
136149

@@ -153,12 +166,14 @@ class AwaitableGenerator(Generator[_T_co, _T_contra, _V_co], Awaitable[_V_co],
153166
Generic[_T_co, _T_contra, _V_co, _S]):
154167
pass
155168

156-
class AsyncIterable(Generic[_T_co]):
169+
@runtime
170+
class AsyncIterable(Protocol[_T_co]):
157171
@abstractmethod
158172
def __anext__(self) -> Awaitable[_T_co]: ...
159173

174+
@runtime
160175
class AsyncIterator(AsyncIterable[_T_co],
161-
Generic[_T_co]):
176+
Protocol[_T_co]):
162177
@abstractmethod
163178
def __anext__(self) -> Awaitable[_T_co]: ...
164179
def __aiter__(self) -> 'AsyncIterator[_T_co]': ...
@@ -186,18 +201,22 @@ if sys.version_info >= (3, 6):
186201
ag_frame = ... # type: FrameType
187202
ag_running = ... # type: bool
188203

189-
class Container(Generic[_T_co]):
204+
@runtime
205+
class Container(Protocol[_T_co]):
190206
@abstractmethod
191207
def __contains__(self, x: object) -> bool: ...
192208

193209

194210
if sys.version_info >= (3, 6):
195-
class Collection(Sized, Iterable[_T_co], Container[_T_co], Generic[_T_co]): ...
211+
@runtime
212+
class Collection(Sized, Iterable[_T_co], Container[_T_co], Protocol[_T_co]): ...
196213
_Collection = Collection
197214
else:
198-
class _Collection(Sized, Iterable[_T_co], Container[_T_co], Generic[_T_co]): ...
215+
@runtime
216+
class _Collection(Sized, Iterable[_T_co], Container[_T_co], Protocol[_T_co]): ...
199217

200-
class Sequence(_Collection[_T_co], Reversible[_T_co], Generic[_T_co]):
218+
@runtime
219+
class Sequence(_Collection[_T_co], Reversible[_T_co], Protocol[_T_co]):
201220
@overload
202221
@abstractmethod
203222
def __getitem__(self, i: int) -> _T_co: ...
@@ -214,7 +233,8 @@ class Sequence(_Collection[_T_co], Reversible[_T_co], Generic[_T_co]):
214233
def __iter__(self) -> Iterator[_T_co]: ...
215234
def __reversed__(self) -> Iterator[_T_co]: ...
216235

217-
class MutableSequence(Sequence[_T], Generic[_T]):
236+
@runtime
237+
class MutableSequence(Sequence[_T], Protocol[_T]):
218238
@abstractmethod
219239
def insert(self, index: int, object: _T) -> None: ...
220240
@overload
@@ -237,7 +257,8 @@ class MutableSequence(Sequence[_T], Generic[_T]):
237257
def remove(self, object: _T) -> None: ...
238258
def __iadd__(self, x: Iterable[_T]) -> MutableSequence[_T]: ...
239259

240-
class AbstractSet(_Collection[_T_co], Generic[_T_co]):
260+
@runtime
261+
class AbstractSet(_Collection[_T_co], Protocol[_T_co]):
241262
@abstractmethod
242263
def __contains__(self, x: object) -> bool: ...
243264
# Mixin methods
@@ -252,7 +273,8 @@ class AbstractSet(_Collection[_T_co], Generic[_T_co]):
252273
# TODO: Argument can be a more general ABC?
253274
def isdisjoint(self, s: AbstractSet[Any]) -> bool: ...
254275

255-
class MutableSet(AbstractSet[_T], Generic[_T]):
276+
@runtime
277+
class MutableSet(AbstractSet[_T], Protocol[_T]):
256278
@abstractmethod
257279
def add(self, x: _T) -> None: ...
258280
@abstractmethod
@@ -283,7 +305,8 @@ class ValuesView(MappingView, Iterable[_VT_co], Generic[_VT_co]):
283305

284306
# TODO: ContextManager (only if contextlib.AbstractContextManager exists)
285307

286-
class Mapping(_Collection[_KT], Generic[_KT, _VT_co]):
308+
@runtime
309+
class Mapping(_Collection[_KT], Protocol[_KT, _VT_co]):
287310
# TODO: We wish the key type could also be covariant, but that doesn't work,
288311
# see discussion in https: //github.com/python/typing/pull/273.
289312
@abstractmethod
@@ -299,7 +322,8 @@ class Mapping(_Collection[_KT], Generic[_KT, _VT_co]):
299322
def values(self) -> ValuesView[_VT_co]: ...
300323
def __contains__(self, o: object) -> bool: ...
301324

302-
class MutableMapping(Mapping[_KT, _VT], Generic[_KT, _VT]):
325+
@runtime
326+
class MutableMapping(Mapping[_KT, _VT], Protocol[_KT, _VT]):
303327
@abstractmethod
304328
def __setitem__(self, k: _KT, v: _VT) -> None: ...
305329
@abstractmethod
@@ -502,3 +526,4 @@ class NamedTuple(tuple):
502526
def _replace(self, **kwargs: Any) -> NamedTuple: ...
503527

504528
def NewType(name: str, tp: Type[_T]) -> Type[_T]: ...
529+
def runtime(cls: _T) -> _T: ...

0 commit comments

Comments
 (0)