30
30
31
31
from abc import abstractmethod
32
32
from collections .abc import Mapping
33
+ from typing import Any , Type , Mapping as MappingType , Iterator , TypeVar , Tuple , Union
33
34
35
+ KT = TypeVar ('KT' )
36
+ VT = TypeVar ('VT' )
34
37
35
- class BidirectionalMapping (Mapping ): # pylint: disable=abstract-method,no-init
38
+
39
+ class BidirectionalMapping (MappingType [KT , VT ]): # pylint: disable=abstract-method,no-init
36
40
"""Abstract base class (ABC) for bidirectional mapping types.
37
41
38
42
Extends :class:`collections.abc.Mapping` primarily by adding the
@@ -51,7 +55,7 @@ class BidirectionalMapping(Mapping): # pylint: disable=abstract-method,no-init
51
55
52
56
@property
53
57
@abstractmethod
54
- def inverse (self ):
58
+ def inverse (self ) -> MappingType [ VT , KT ] :
55
59
"""The inverse of this bidirectional mapping instance.
56
60
57
61
*See also* :attr:`bidict.BidictBase.inverse`, :attr:`bidict.BidictBase.inv`
@@ -65,7 +69,7 @@ def inverse(self):
65
69
# clear there's no reason to call this implementation (e.g. via super() after overriding).
66
70
raise NotImplementedError
67
71
68
- def __inverted__ (self ):
72
+ def __inverted__ (self ) -> Iterator [ Tuple [ VT , KT ]] :
69
73
"""Get an iterator over the items in :attr:`inverse`.
70
74
71
75
This is functionally equivalent to iterating over the items in the
@@ -82,7 +86,7 @@ def __inverted__(self):
82
86
return iter (self .inverse .items ())
83
87
84
88
@classmethod
85
- def __subclasshook__ (cls , C ) : # noqa: N803 (argument name should be lowercase)
89
+ def __subclasshook__ (cls , C : 'Type[BidirectionalMapping[Any, Any]]' ) -> Union [ bool , 'NotImplemented' ] : # noqa: N803 (argument name should be lowercase)
86
90
"""Check if *C* is a :class:`~collections.abc.Mapping`
87
91
that also provides an ``inverse`` attribute,
88
92
thus conforming to the :class:`BidirectionalMapping` interface,
@@ -91,12 +95,9 @@ def __subclasshook__(cls, C): # noqa: N803 (argument name should be lowercase)
91
95
"""
92
96
if cls is not BidirectionalMapping : # lgtm [py/comparison-using-is]
93
97
return NotImplemented
94
- if not Mapping .__subclasshook__ (C ):
95
- return NotImplemented
96
- mro = getattr (C , '__mro__' , None )
97
- if mro is None : # Python 2 old-style class
98
+ if not Mapping .__subclasshook__ (C ): # type: ignore
98
99
return NotImplemented
99
- if not any (B .__dict__ .get ('inverse' ) for B in mro ):
100
+ if not any (B .__dict__ .get ('inverse' ) for B in C . __mro__ ):
100
101
return NotImplemented
101
102
return True
102
103
0 commit comments