Open
Description
parameters = _remove_dups_flatten(parameters) # type: ignore[no-any-expr]
if len(parameters) == 1: # type: ignore[no-any-expr]
return parameters[0] # type: ignore[no-any-expr]
return _IntersectionGenericAlias(self, parameters) # type: ignore[arg-type, no-any-expr]
basedtyping/basedtyping/__init__.py
Line 468 in 4a459f2
),
)
class _IntersectionGenericAlias(_BasedGenericAlias, _root=True):
def copy_with(self, args: object) -> Self: # type: ignore[override] # TODO: put in the overloads
return cast(Self, Intersection[args])
def __eq__(self, other: object) -> bool:
if not isinstance(other, _IntersectionGenericAlias):
return NotImplemented
return set(self.__args__) == set(other.__args__)
def __hash__(self) -> int:
return hash(frozenset(self.__args__))
def __instancecheck__(self, obj: object) -> bool:
return self.__subclasscheck__(type(obj))
def __subclasscheck__(self, cls: type[object]) -> bool:
return all(issubclass(cls, arg) for arg in self.__args__)
def __reduce__(self) -> (object, object):
func, (_, args) = super().__reduce__() # type: ignore[no-any-expr, misc]
return func, (Intersection, args)
if sys.version_info > (3, 9):
@_BasedSpecialForm
def Intersection(self: _BasedSpecialForm, parameters: object) -> object:
"""Intersection type; Intersection[X, Y] means both X and Y.
To define an intersection:
- If using __future__.annotations, shortform can be used e.g. A & B
- otherwise the fullform must be used e.g. Intersection[A, B].
Details:
- The arguments must be types and there must be at least one.
- None as an argument is a special case and is replaced by
type(None).
- Intersections of intersections are flattened, e.g.::
Intersection[Intersection[int, str], float] == Intersection[int, str, float]
- Intersections of a single argument vanish, e.g.::
Intersection[int] == int # The constructor actually returns int
- Redundant arguments are skipped, e.g.::
Intersection[int, str, int] == Intersection[int, str]
- When comparing intersections, the argument order is ignored, e.g.::
Intersection[int, str] == Intersection[str, int]
- You cannot subclass or instantiate an intersection.
"""
if parameters == ():
raise TypeError("Cannot take an Intersection of no types.")
if not isinstance(parameters, tuple):
parameters = (parameters,)
msg = "Intersection[arg, ...]: each arg must be a type."
parameters = tuple(_type_check(p, msg) for p in parameters) # type: ignore[no-any-expr]
parameters = _remove_dups_flatten(parameters) # type: ignore[no-any-expr]
if len(parameters) == 1: # type: ignore[no-any-expr]
return parameters[0] # type: ignore[no-any-expr]
return _IntersectionGenericAlias(self, parameters) # type: ignore[arg-type, no-any-expr]
else:
Intersection = _BasedSpecialForm(
"Intersection", doc="", alias=_IntersectionGenericAlias
)
class _TypeFormForm(_BasedSpecialForm, _root=True): # type: ignore[misc]
def __init__(self, doc: str):
self._name = "TypeForm"
self._doc = self.__doc__ = doc
def __getitem__(self, parameters: object | tuple[object]) -> _BasedGenericAlias:
if not isinstance(parameters, tuple):
parameters = (parameters,)
return _BasedGenericAlias(self, parameters) # type: ignore[arg-type]
TypeForm = _TypeFormForm(doc="""\
A type that can be used to represent a ``builtins.type`` or a ``SpecialForm``.
For example:
def f[T](t: TypeForm[T]) -> T: ...
reveal_type(f(int | str)) # int | str
""")