99)
1010
1111import contextlib
12- from typing import TypeVar , final
12+ from typing import Any , TypeVar , final
1313from typing_extensions import deprecated
1414
1515import beartype .door
@@ -35,7 +35,7 @@ class ParametricTypeMeta(type):
3535 `Type[type(Arg1), type(Arg2)](Arg1, Arg2, **kw_args)`.
3636 """
3737
38- def __getitem__ (cls , p ) :
38+ def __getitem__ (cls , p : TypeHint | tuple [ TypeHint , ...]) -> type :
3939 if not cls .concrete :
4040 # Initialise the type parameters. This can perform, e.g., validation.
4141 p = p if isinstance (p , tuple ) else (p ,) # Ensure that it is a tuple.
@@ -46,7 +46,7 @@ def __getitem__(cls, p):
4646 else :
4747 raise TypeError ("Cannot specify type parameters. This type is concrete." )
4848
49- def __concrete_class__ (cls , * args , ** kw_args ) :
49+ def __concrete_class__ (cls , * args : object , ** kw_args : object ) -> type :
5050 """If `cls` is not a concrete class, infer the type parameters and return a
5151 concrete class. If `cls` is already a concrete class, simply return it.
5252
@@ -62,7 +62,7 @@ def __concrete_class__(cls, *args, **kw_args):
6262 cls = cls [type_parameter ]
6363 return cls
6464
65- def __init_type_parameter__ (cls , * ps ) :
65+ def __init_type_parameter__ (cls , * ps : TypeHint ) -> TypeHint | tuple [ TypeHint , ...] :
6666 """Function called to initialise the type parameters.
6767
6868 The default behaviour is to just return `ps`.
@@ -75,7 +75,9 @@ def __init_type_parameter__(cls, *ps):
7575 """
7676 return ps
7777
78- def __infer_type_parameter__ (cls , * args , ** kw_args ):
78+ def __infer_type_parameter__ (
79+ cls , * args : object , ** kw_args : object
80+ ) -> type | tuple [type , ...]:
7981 """Function called when the constructor of this parametric type is called
8082 before the parameters have been specified.
8183
@@ -96,29 +98,27 @@ def __infer_type_parameter__(cls, *args, **kw_args):
9698 return type_parameter
9799
98100 @property
99- def parametric (cls ):
101+ def parametric (cls ) -> bool :
100102 """bool: Check whether the type is a parametric type."""
101103 return getattr (cls , "_parametric" , False )
102104
103105 @property
104- def concrete (cls ):
106+ def concrete (cls ) -> bool :
105107 """bool: Check whether the parametric type is instantiated or not."""
106- if cls .parametric :
107- return getattr (cls , "_concrete" , False )
108- else :
108+ if not cls .parametric :
109109 raise RuntimeError (
110110 "Cannot check whether a non-parametric type is instantiated or not."
111111 )
112+ return getattr (cls , "_concrete" , False )
112113
113114 @property
114- def type_parameter (cls ):
115+ def type_parameter (cls ) -> object :
115116 """object: Get the type parameter. Parametric type must be instantiated."""
116- if cls .concrete :
117- return cls ._type_parameter
118- else :
117+ if not cls .concrete :
119118 raise RuntimeError (
120119 "Cannot get the type parameter of non-instantiated parametric type."
121120 )
121+ return cls ._type_parameter
122122
123123
124124def _default_le_type_par (p_left : TypeHint | object , p_right : TypeHint | object ) -> bool :
@@ -133,7 +133,7 @@ def _default_le_type_par(p_left: TypeHint | object, p_right: TypeHint | object)
133133class CovariantMeta (ParametricTypeMeta ):
134134 """A metaclass that implements *covariance* of parametric types."""
135135
136- def __subclasscheck__ (cls , subclass ) :
136+ def __subclasscheck__ (cls , subclass : type ) -> bool :
137137 # Check that they are instances of the same parametric type.
138138 if (
139139 is_concrete (cls )
@@ -150,7 +150,7 @@ def __subclasscheck__(cls, subclass):
150150 # Default behaviour to `type`s subclass check.
151151 return type .__subclasscheck__ (cls , subclass )
152152
153- def __instancecheck__ (cls , instance ) :
153+ def __instancecheck__ (cls , instance : object ) -> bool :
154154 # If `A` is a parametric type, then `A[T1]` and `A[T2]` are subclasses of
155155 # `A`. With the implementation of `__subclasscheck__` above, we have that
156156 # `issubclass(A[T1], A[T2])` whenever `issubclass(T1, T2)`. _However_,
@@ -162,7 +162,9 @@ def __instancecheck__(cls, instance):
162162 # since it is fast and only gives true positives.
163163 return type .__instancecheck__ (cls , instance ) or issubclass (type (instance ), cls )
164164
165- def __le_type_parameter__ (cls , p_left , p_right ):
165+ def __le_type_parameter__ (
166+ cls , p_left : tuple [object , ...], p_right : tuple [object , ...]
167+ ) -> bool :
166168 # Check that there are an equal number of parameters.
167169 if len (p_left ) != len (p_right ):
168170 return False
@@ -172,7 +174,7 @@ def __le_type_parameter__(cls, p_left, p_right):
172174 )
173175
174176
175- def parametric (original_class = None ) :
177+ def parametric (original_class : type | None = None , / ) -> type :
176178 """A decorator for parametric classes.
177179
178180 When the constructor of this parametric type is called before the type parameter
@@ -214,11 +216,11 @@ def __le_type_parameter__(cls, left, right) -> bool:
214216 bases = (CovariantMeta , original_meta )
215217 name = f"CovariantMeta[{ repr_short (original_meta )} ]"
216218
217- def __call__ (cls , * args , ** kw_args ) :
219+ def __call__ (cls : type , * args : object , ** kw_args : object ) -> object :
218220 cls = cls .__concrete_class__ (* args , ** kw_args )
219221 return original_meta .__call__ (cls , * args , ** kw_args )
220222
221- def __instancecheck__ (cls , instance ) :
223+ def __instancecheck__ (cls : type , instance : object ) -> bool :
222224 # An implementation of `__instancecheck__` is necessary to ensure that
223225 # `isinstance(A[SubType](), A[Type])`. `CovariantMeta` comes first in the MRO,
224226 # but the implementation of `__instancecheck__` should be taken from
@@ -239,13 +241,13 @@ def __instancecheck__(cls, instance):
239241 },
240242 )
241243
242- subclasses = {}
244+ subclasses : dict [ tuple [ object , ...], type ] = {}
243245
244- def __new__ (cls , * ps ) :
246+ def __new__ (cls : type , * ps : object ) -> type :
245247 # Only create a new subclass if it doesn't exist already.
246248 if ps not in subclasses :
247249
248- def __new__ (cls , * args , ** kw_args ) :
250+ def __new__ (cls : type , * args : object , ** kw_args : object ) -> object :
249251 return original_class .__new__ (cls )
250252
251253 # Create subclass.
@@ -268,20 +270,20 @@ def __new__(cls, *args, **kw_args):
268270 subclasses [ps ] = subclass
269271 return subclasses [ps ]
270272
271- def __init_subclass__ (cls , ** kw_args ) :
273+ def __init_subclass__ (cls : type , ** kw_args : object ) -> None :
272274 cls ._parametric = False
273275 # If the subclass has the same `__new__` as `ParametricClass`, then we should
274276 # replace it with the `__new__` of `Class`. If the user already defined another
275277 # `__new__`, then everything is fine.
276278 if cls .__new__ is __new__ :
277279
278- def class_new (cls , * args , ** kw_args ) :
280+ def class_new (cls : type , * args : object , ** kw_args : object ) -> object :
279281 return original_class .__new__ (cls )
280282
281283 cls .__new__ = class_new
282284 super (original_class , cls ).__init_subclass__ (** kw_args )
283285
284- def __class_nonparametric__ (cls ) :
286+ def __class_nonparametric__ (cls : type ) -> type :
285287 """Return the non-parametric type of an object.
286288
287289 :mod:`plum.parametric` produces parametric subtypes of classes. This
@@ -333,7 +335,7 @@ def __class_nonparametric__(cls):
333335 """
334336 return original_class
335337
336- def __class_unparametrized__ (cls ) :
338+ def __class_unparametrized__ (cls : type ) -> type :
337339 """Return the unparametrized type of an object.
338340
339341 :mod:`plum.parametric` produces parametric subtypes of classes. This
@@ -418,7 +420,7 @@ def __class_unparametrized__(cls):
418420 return parametric_class
419421
420422
421- def is_concrete (t ) :
423+ def is_concrete (t : object ) -> bool :
422424 """Check if a type `t` is a concrete instance of a parametric type.
423425
424426 Args:
@@ -603,25 +605,25 @@ def type_unparametrized(q: T, /) -> type[T]:
603605 parameter(s).
604606 """
605607 typ = type (q )
606- return q .__class_unparametrized__ () if isinstance (typ , ParametricTypeMeta ) else typ
608+ return q .__class_unparametrized__ () if isinstance (typ , ParametricTypeMeta ) else typ # type: ignore[redundant-expr]
607609
608610
609- def kind (SuperClass = object ) :
611+ def kind (cls : type = object , / ) -> type :
610612 """Create a parametric wrapper type for dispatch purposes.
611613
612614 Args:
613- SuperClass (type): Super class.
615+ cls (type): Super class.
614616
615617 Returns:
616618 object: New parametric type wrapper.
617619 """
618620
619621 @parametric
620- class Kind (SuperClass ):
621- def __init__ (self , * xs ) :
622+ class Kind (cls ):
623+ def __init__ (self , * xs : object ) -> None :
622624 self .xs = xs
623625
624- def get (self ):
626+ def get (self ) -> object :
625627 return self .xs [0 ] if len (self .xs ) == 1 else self .xs
626628
627629 return Kind
@@ -645,7 +647,7 @@ class Val:
645647 """
646648
647649 @classmethod
648- def __infer_type_parameter__ (cls , * arg ) :
650+ def __infer_type_parameter__ (cls , * arg : Any ) -> object :
649651 """Function called when the constructor of `Val` is called to determine the type
650652 parameters."""
651653 if len (arg ) == 0 :
@@ -654,14 +656,14 @@ def __infer_type_parameter__(cls, *arg):
654656 raise ValueError ("Too many values. `Val` accepts only one argument." )
655657 return arg [0 ]
656658
657- def __init__ (self , val = None ):
659+ def __init__ (self , val : Any = None ) -> None :
658660 """Construct a value object with type `Val(arg)` that can be used to dispatch
659661 based on values.
660662
661663 Args:
662664 val (object): The value to be moved to the type domain.
663665 """
664- if type (self ).concrete :
666+ if type (self ).concrete : # type: ignore[attr-defined]
665667 if val is not None and type_parameter (self ) != val :
666668 raise ValueError ("The value must be equal to the type parameter." )
667669 else :
@@ -670,5 +672,5 @@ def __init__(self, val=None):
670672 def __repr__ (self ) -> str :
671673 return repr_short (type (self )).replace ("._parametric" , "" ) + "()"
672674
673- def __eq__ (self , other ) :
675+ def __eq__ (self , other : object ) -> bool :
674676 return type (self ) is type (other )
0 commit comments