mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Allow TypeVarTuple arguments to subclasses of generic TypedDict

Open erikkemperman opened this issue 7 months ago • 6 comments

Fixes #16975 Supersedes #16977

Allows TypeVarTuples as type argument for subclasses of generic TypedDicts.

Since (1) TypedDict became generic and (2) TypeVarTuple was introduced, mypy now supports creating generic typed dictionaries with variadic type arguments. However, things went wrong when deriving a subclass from such a generic typeddict.

Full disclosure: I submitted an earlier PR for this issue, but it's been a while. Earlier I wasn't 100% sure about one minor aspect of the changes I made, but in the mean time the context has changed to the point that that aspect is no longer relevant.

For tests, I started with a copy of an existing one from test-data/unit/check-typevar-tuple.test, and added two subclasses: one which just passes a TypeVarTuple generic type parameter up to the base class, and another which passes a TypeVarTuple and adds a regular TypeVar argument.

I did this all of this twice: once using the Unpack[Ts] syntax and once using the *Ts syntax.

erikkemperman avatar Jun 04 '25 13:06 erikkemperman

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

github-actions[bot] avatar Jun 04 '25 14:06 github-actions[bot]

Apologies, I removed the *Ts syntax unit test for now, obviously that doesn't work for older Python versions... Should perhaps live in check-python311.test? I'm still not entirely clear on the logic behind which test goes where, to be honest.

erikkemperman avatar Jun 04 '25 14:06 erikkemperman

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

github-actions[bot] avatar Jun 04 '25 15:06 github-actions[bot]

Should perhaps live in check-python311.test

Yes, every test that depends on python version higher than minimal supported version (3.9 now) should live in check-python*.test files (matching the minimal version where such syntax is supported)

sterliakov avatar Jun 04 '25 23:06 sterliakov

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

github-actions[bot] avatar Jun 05 '25 10:06 github-actions[bot]

@sterliakov Thanks for taking a look, and for the suggestion. I've moved the tests using *Ts syntax into check-python311.test.

erikkemperman avatar Jun 05 '25 11:06 erikkemperman

@sterliakov Sorry to ping you again, but perhaps you could review this PR or maybe suggest a member who could? For what it's worth, the code change is pretty minimal and the test coverage should be sufficient, IMHO. Thanks in advance!

erikkemperman avatar Aug 05 '25 11:08 erikkemperman

Thanks @sterliakov!

About the NamedTuple analogy, there is a similar test for it being Generic with TypeVarTuple argument here but only directly, not propagated via inheritance. Which makes sense, I think, as NamedTuples don't behave the same way as TypedDicts do when subclassed (which isn't actually what happens, but you probably get what I mean):

class MyDict(TypedDict):
    foo: int

class MySubDict(MyDict):
    bar: int


msd = MySubDict(foo=1, bar=2)  # Fine



class MyTuple(NamedTuple):
    foo: int

class MySubTuple(MyTuple):
    bar: int


mst = MySubTuple(foo=1, bar=2)  # Error: unexpected keyword "bar"

I sometimes think it would be nice to be able to extend NamedTuples this way, but think I understand why it doesn't currently work that way.

erikkemperman avatar Aug 05 '25 13:08 erikkemperman

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

github-actions[bot] avatar Oct 24 '25 14:10 github-actions[bot]

@hauntsaninja I hope you don't mind my pinging you directly; your name was suggested by @sterliakov above. If you have a little time, I would greatly appreciate if you could take a look at this!

I understand that (apparently) this isn't an issue that many folks run into, but I think you'll agree that it actually is a bug that may as well be fixed. I've rebased the branch to latest master just now.

erikkemperman avatar Oct 24 '25 15:10 erikkemperman