| | import six |
| |
|
| | from .utils import typename |
| |
|
| | __all__ = ["VariadicSignatureType", "isvariadic", "VariadicSignatureMeta", "Variadic"] |
| |
|
| | class VariadicSignatureType(type): |
| | |
| | def __subclasscheck__(cls, subclass): |
| | other_type = (subclass.variadic_type if isvariadic(subclass) |
| | else (subclass,)) |
| | return subclass is cls or all( |
| | issubclass(other, cls.variadic_type) for other in other_type |
| | ) |
| |
|
| | def __eq__(cls, other): |
| | """ |
| | Return True if other has the same variadic type |
| | Parameters |
| | ---------- |
| | other : object (type) |
| | The object (type) to check |
| | Returns |
| | ------- |
| | bool |
| | Whether or not `other` is equal to `self` |
| | """ |
| | return (isvariadic(other) and |
| | set(cls.variadic_type) == set(other.variadic_type)) |
| |
|
| | def __hash__(cls): |
| | return hash((type(cls), frozenset(cls.variadic_type))) |
| |
|
| |
|
| | def isvariadic(obj): |
| | """Check whether the type `obj` is variadic. |
| | Parameters |
| | ---------- |
| | obj : type |
| | The type to check |
| | Returns |
| | ------- |
| | bool |
| | Whether or not `obj` is variadic |
| | Examples |
| | -------- |
| | >>> isvariadic(int) |
| | False |
| | >>> isvariadic(Variadic[int]) |
| | True |
| | """ |
| | return isinstance(obj, VariadicSignatureType) |
| |
|
| |
|
| | class VariadicSignatureMeta(type): |
| | """A metaclass that overrides ``__getitem__`` on the class. This is used to |
| | generate a new type for Variadic signatures. See the Variadic class for |
| | examples of how this behaves. |
| | """ |
| | def __getitem__(cls, variadic_type): |
| | if not (isinstance(variadic_type, (type, tuple)) or type(variadic_type)): |
| | raise ValueError("Variadic types must be type or tuple of types" |
| | " (Variadic[int] or Variadic[(int, float)]") |
| |
|
| | if not isinstance(variadic_type, tuple): |
| | variadic_type = variadic_type, |
| | return VariadicSignatureType( |
| | 'Variadic[%s]' % typename(variadic_type), |
| | (), |
| | dict(variadic_type=variadic_type, __slots__=()) |
| | ) |
| |
|
| |
|
| | class Variadic(six.with_metaclass(VariadicSignatureMeta)): |
| | """A class whose getitem method can be used to generate a new type |
| | representing a specific variadic signature. |
| | Examples |
| | -------- |
| | >>> Variadic[int] # any number of int arguments |
| | >>> # xdoctest: +SKIP |
| | <class 'multipledispatch.variadic.Variadic[int]'> |
| | >>> Variadic[(int, str)] # any number of one of int or str arguments |
| | <class 'multipledispatch.variadic.Variadic[(int, str)]'> |
| | >>> issubclass(int, Variadic[int]) |
| | True |
| | >>> issubclass(int, Variadic[(int, str)]) |
| | True |
| | >>> issubclass(str, Variadic[(int, str)]) |
| | True |
| | >>> issubclass(float, Variadic[(int, str)]) |
| | False |
| | """ |
| |
|