Skip to content

mypy rejects subclassing Any typed **kwargs entries within a function #22309

Open

Description

@willy-b

(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

[case testUnpackKwargsReveal]
to add an 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)
Image

Note that the same is recognized as valid in Pyright, e.g. https://pyright-play.net/?code=GYJw9gtgBALgngBwJYDsDmUkQWEMoCqKCAhgMYDWANFACqICmAJgCJJkw0CCKcAUHzIAbEgGdRUAAoMQosCgAU9BMzYcAlAC4%2BUXVBQkIDTVFEwQOvSTTHMKGJd1yjAfRK8XwJAyFMTPfj4mBmAoYDAwBRIQNBMAIwihGgAqZIoAd2i0URMiUkoAbWlZeQBddSgAWgA%2BKAA5eWNHKBAGADcGEiEXeBUFDKzRdWbWjq6exn7MmNECgHIDIznykfbO7t6GKcH55wY3Dy8fJmXhvShhMQkAZQBXOO2Z3ch99zhPb19Tk1JxKABiKBtLpIJiwMCme6XP4MAAeCCE7CQ%2BACNAgiDgphIcAkKDADj4o3WEz64TA6iAA

Image

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions