Skip to content
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

mypy doesn't infer **kwargs types from superclass #10079

Open
rectalogic opened this issue Feb 11, 2021 · 5 comments
Open

mypy doesn't infer **kwargs types from superclass #10079

rectalogic opened this issue Feb 11, 2021 · 5 comments
Labels
feature topic-inference When to infer types or require explicit annotations topic-inheritance Inheritance and incompatible overrides

Comments

@rectalogic
Copy link

Bug Report
If a subclass __init__ passes **kwargs to it's superclass, the superclasses parameter types should be used to validate the subclass arguments.

To Reproduce

Run mypy on this file:

import datetime


class Bar:
    def __init__(self, a: int, b: str, c: datetime.datetime):
        pass


class Baz(Bar):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)


Baz(b=3)

Expected Behavior

Something like
error: Argument "b" to "Baz" has incompatible type "int"; expected "str"

Actual Behavior

mypy found no errors

Your Environment

  • Mypy version used: mypy 0.800
  • Mypy command-line flags: python filename
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.8.6
  • Operating system and version: macOS 10.15.7
@rectalogic rectalogic added the bug mypy got something wrong label Feb 11, 2021
@ShadowLNC
Copy link

Currently I think this is officially not supported, but I do agree it would be a nice feature to have (type checking any kwargs passthrough, not just for super() calls but anywhere they're used)

@AlexWaygood AlexWaygood added topic-inheritance Inheritance and incompatible overrides topic-inference When to infer types or require explicit annotations feature and removed bug mypy got something wrong labels Apr 4, 2022
@ikonst
Copy link
Contributor

ikonst commented Nov 11, 2022

Curious, has there been a principled decision on whether (and when) mypy should infer types?

cc @hauntsaninja

@hauntsaninja
Copy link
Collaborator

I think the principle has been to never infer types for callables. This is the boundary used to achieve gradual typing and also this helps keep performance good.

@ikonst
Copy link
Contributor

ikonst commented Nov 11, 2022

re: gradual typing, I assume the interest here would not be in inferring an untyped function, but rather when given a fat hint, e.g.

-def spam(**kwargs):
+def spam(**kwargs: Any) -> None:
    ham(**kwargs)

or something that doesn't exist a'la

-def spam(**kwargs):
+def spam(**kwargs: typing.InferMe) -> None:
    ham(**kwargs)

Would performance (needing to analyze function's body?) be the deterrent then?

@hauntsaninja
Copy link
Collaborator

I wouldn't add inference if a user explicitly provides a hint, but something like the second would be interesting, or giving mypy a mode where it doesn't care about gradual typing and does its best to infer anything it can. But yeah, for the general case performance and implementation complexity are the deterrents.

For OP's specific case, some type checkers do use a limited amount of inference on subclasses based on superclass types, e.g. I think if your signature is exactly the same, just missing types, pyright will use superclass types. Another thing that could be useful is a "typeof" kind of operator, so you could also imagine @typeof(ham)\ndef spam being a thing (ideally such a thing would be able to be composed with concatenate and unpack and all of those).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature topic-inference When to infer types or require explicit annotations topic-inheritance Inheritance and incompatible overrides
Projects
None yet
Development

No branches or pull requests

5 participants