Open
Description
ReifiedGenericCopy._can_do_instance_and_subclass_checks_without_generics = ( # pylint:disable=protected-access
basedtyping/basedtyping/__init__.py
Line 295 in 3945f0c
is tracked [here](https://github.com/KotlinIsland/basedmypy/issues/5)
"""
__reified_generics__: tuple[type, ...]
"""Should be a generic but cant due to https://github.com/KotlinIsland/basedmypy/issues/142"""
__type_vars__: tuple[TypeVar, ...]
"""``TypeVar``\\s that have not yet been reified. so this tuple should always be empty by the time the ``ReifiedGeneric`` is instantiated"""
@_tp_cache # type: ignore[name-defined,misc]
def __class_getitem__( # type: ignore[misc]
cls, item: GenericItems
) -> type[ReifiedGeneric[T]]:
# when defining the generic (ie. `class Foo(ReifiedGeneric[T]):`) we want the normal behavior
if cls is ReifiedGeneric:
# https://github.com/KotlinIsland/basedtypeshed/issues/7
return super().__class_getitem__(item) # type: ignore[misc,no-any-return]
items = item if isinstance(item, tuple) else (item,)
# if we're subtyping a class that already has reified generics:
superclass_reified_generics = tuple(
generic
for generic in (
cls.__reified_generics__ if hasattr(cls, "__reified_generics__") else ()
)
if not isinstance(generic, TypeVar) # type: ignore[misc]
)
# normal generics use __parameters__, we use __type_vars__ because the Generic base class deletes properties
# named __parameters__ when copying to a new class
orig_type_vars = (
cls.__type_vars__
if hasattr(cls, "__type_vars__")
else cast(
tuple[TypeVar, ...], cls.__parameters__ # type: ignore[attr-defined]
)
)
# add any reified generics from the superclass if there is one
items = superclass_reified_generics + items
expected_length = len(orig_type_vars)
actual_length = len(items) - len(superclass_reified_generics)
if expected_length != len(items) - len(superclass_reified_generics):
raise NotEnoughTypeParametersError(
"Incorrect number of type parameters specified. expected length:"
f" {expected_length}, actual length {actual_length}"
)
ReifiedGenericCopy: type[ReifiedGeneric[T]] = type(
cls.__name__,
(
cls, # make the copied class extend the original so normal instance checks work
),
# TODO: proper type
dict[str, object](
__reified_generics__=tuple(
_type_convert(t) for t in items # type: ignore[name-defined,misc]
),
_orig_type_vars=orig_type_vars,
__type_vars__=_collect_type_vars( # type: ignore[name-defined,misc]
items, cast(type, TypeVar)
),
),
)
# can't set it in the dict above otherwise __init_subclass__ overwrites it
ReifiedGenericCopy._can_do_instance_and_subclass_checks_without_generics = ( # pylint:disable=protected-access
False
)
return ReifiedGenericCopy
def __init_subclass__(cls) -> None: # pylint:disable=arguments-differ
cls._can_do_instance_and_subclass_checks_without_generics = True
super().__init_subclass__()
# TODO: make this work with any "form", not just unions