-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Indexing TypeVars / need a workaround for higher-kindedness #6066
Comments
Why not 0.650? I am not sure I understand what do you actually need here. Do you really need class Root(Generic[T]):
def __init__(self, ct, cto):
# type: (ContainedCls[T], ContainedCls[T]) -> None
self.contained = ct
self.contained_other = cto
def iter_subcontained(self):
# type: () -> List[T]
return self.contained.items
class ContainedCls(Generic[T]):
def __init__(self, items):
# type: (List[T]) -> None
self.items = items
class ContainedClsPrime(ContainedCls[T]): # <- type variable was missing
pass
# List item 0 has incompatible type "str"; expected "int"
bad = Root[int](ContainedCls([1]), ContainedClsPrime(['definitely not an int']))
good = Root(ContainedCls([1]), ContainedClsPrime([2]))
reveal_type(good.iter_subcontained()) # Revealed type is 'builtins.list[builtins.int*]' |
I wanted to add a plug for adding support for higher kinds. Here's my use case: S = TypeVar('S')
T = TypeVar('T', bound='MyClass')
class MyClass(Generic[S]):
def __init__(self, obj):
# type: (S) -> None
self.obj = obj
@classmethod
def create(cls, obj):
# type: (Type[T], S) -> T[S]
return cls(obj)
def get_obj(self):
# type: () -> S
return self.obj
class Data:
def __init__(self, data_point):
self.data_point = data_point
d = Data('a data point')
x = MyClass.create(d)
print(x.obj.data_point) This fails, for a variety of reasons:
One thing I could do is this: d = Data('a data point')
x = MyClass(d)
obj = x.obj # type: Data
print(obj.data_point) However, it seems to me that having to override the type-inference system isn't ideal—I'd rather not have to do it manually and let the magic of mypy put everything in place for me :) Out of curiosity, what makes adding kind support a hard problem? @ilevkivskyi / others: if I should open a new issue for this use-case, please let me know. |
I actually think this may be what you want. Could you please post a self-consistent example that at least uses For example (not 100% perfect, but it works, just tried on master): T = TypeVar('T', bound=C[Any])
S = TypeVar('S')
class C(Generic[S]):
def __init__(self, x: S) -> None:
self.x = x
@classmethod
def create(cls: Type[T], x: S) -> T:
return cls(x)
class D(C[int]):
...
reveal_type(C.create('yes')) # Revealed type is '__main__.C[builtins.str]'
D.create('no') # Argument 1 to "create" has incompatible type "str"; expected "int"
reveal_type(D.create(42)) # Revealed type is '__main__.D' Although higher order kinds is a useful feature, I don't see that they are desperately needed in this particular example. |
Ooops. Fixed. Hmm, let me try that out. |
This may or may not be necessary for Rohan's use case, but since |
@bwo I can make class D(C[S]):
...
reveal_type(D.create('yes')) # Revealed type is '__main__.D[builtins.str]'
D[int].create('no') # Argument 1 to "create" has incompatible type "str"; expected "int" Could you please post an exact example that currently doesn't work, but you want it to work? |
oh! well, that's unexpected and nice. |
I'm using mypy 0.630.
I have a container, which can contain various types, some of which contain further types. I want the root of the container to be able to return grandchild types, or failing that to be able to return fully-specified child types. My first thought doesn't work:
Because
TypeVar
s can't be indexed.This also doesn't work, because
iter_subcontained
can't be typed:Alas, this also doesn't work:
This almost works:
But it doesn't constrain the two
ContainedCls[T]
s to be the sameContainedCls
subtype, and it doesn't (this really surprised me) even constrain them to be containing the sameT
! It also seems wrong to be able to makeRoot3
generic only in the leaf types, and not in any of the intermediate types.The text was updated successfully, but these errors were encountered: