Repository navigation
mypy rejects subclassing Any typed **kwargs entries within a function #22309
Description
(No AI or LLMs were used in finding or writing up this issue.)
This bug is analogous to #21998 but for **kwargs instead of *args .
Summary
In Python and passing other type checkers (e.g. pyright 1.1.414 commandline and the pyright playground ) it is ok to subclass an entry passed within the **kwargs which is typed as Any, but mypy 2.4.0 and recent master seem to reject this, inconsistent with the apparent intention of #5865 and #14135 .
To Reproduce
For example, consider the following MyPy playground example modified off of
mypy/test-data/unit/check-varargs.test
Line 763 in 93b5e51
| [case testUnpackKwargsReveal] |
Any typed field to the **kwargs and try to subclass it:https://mypy-play.net/?gist=58c6c0424361c088e769d22bc04383f6&mypy=2.4.0&python=3.12
from typing import Unpack, TypedDict, Any
class Person(TypedDict):
name: str
age: int
some_any_field: Any
def foo(arg: bool, **kwargs: Unpack[Person]) -> None:
reveal_type(kwargs)
reveal_type(kwargs['name'])
reveal_type(kwargs['some_any_field'])
# mypy says cannot subclass an explicit `Any` type here, inconsistent with https://github.com/python/mypy/issues/5865 and https://github.com/python/mypy/pull/14135
# pyright allows it (it is a valid thing to do), see https://pyright-play.net/?code=GYJw9gtgBALgngBwJYDsDmUkQWEMoCqKCAhgMYDWANFACqICmAJgCJJkw0CCKcAUHzIAbEgGdRUAAoMQosCgAU9BMzYcAlAC4%2BUXVBQkIDTVFEwQOvSTTHMKGJd1yjAfRK8XwJAyFMTPfj4mBmAoYDAwBRIQNBMAIwihGgAqZIoAd2i0URMiUkoAbWlZeQBddSgAWgA%2BKAA5eWNHKBAGADcGEiEXeBUFDKzRdWbWjq6exn7MmNECgHIDIznykfbO7t6GKcH55wY3Dy8fJmXhvShhMQkAZQBXOO2Z3ch99zhPb19Tk1JxKABiKBtLpIJiwMCme6XP4MAAeCCE7CQ%2BACNAgiDgphIcAkKDADj4o3WEz64TA6iAA
class Sub(kwargs['some_any_field']): pass
reveal_type(foo)
Note that the same is recognized as valid in Pyright, e.g. https://pyright-play.net/?code=GYJw9gtgBALgngBwJYDsDmUkQWEMoCqKCAhgMYDWANFACqICmAJgCJJkw0CCKcAUHzIAbEgGdRUAAoMQosCgAU9BMzYcAlAC4%2BUXVBQkIDTVFEwQOvSTTHMKGJd1yjAfRK8XwJAyFMTPfj4mBmAoYDAwBRIQNBMAIwihGgAqZIoAd2i0URMiUkoAbWlZeQBddSgAWgA%2BKAA5eWNHKBAGADcGEiEXeBUFDKzRdWbWjq6exn7MmNECgHIDIznykfbO7t6GKcH55wY3Dy8fJmXhvShhMQkAZQBXOO2Z3ch99zhPb19Tk1JxKABiKBtLpIJiwMCme6XP4MAAeCCE7CQ%2BACNAgiDgphIcAkKDADj4o3WEz64TA6iAA
Expected Behavior
MyPy, like Pyright (see link above), should recognize it is valid for explicitly Any typed kwargs entries to be subclassed, like MyPy already recognizes for explicitly Any typed parameters that are not *args, **kwargs or accessed by index.
Actual Behavior
MyPy treats explicit Any typed function arguments as valid bases if they are not in **kwargs (or *args) or accessed by index, but treats them as invalid inheritance bases if they are from **kwargs (or *args) .
Your Environment
- Mypy version used: 2.4.0 and recent master
- Mypy command-line flags: see sandbox/playground link ( https://mypy-play.net/?gist=58c6c0424361c088e769d22bc04383f6&mypy=2.4.0&python=3.12 )
- Mypy configuration options from
mypy.ini(and other config files): https://mypy-play.net/?gist=58c6c0424361c088e769d22bc04383f6&mypy=2.4.0&python=3.12 - Python version used: 3.12
Activity
Support string subscripts on deferred base classes