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

Incompatible override with **kwargs TypedDict and Any #13491

Closed
cdce8p opened this issue Aug 23, 2022 · 3 comments
Closed

Incompatible override with **kwargs TypedDict and Any #13491

cdce8p opened this issue Aug 23, 2022 · 3 comments
Labels
bug mypy got something wrong

Comments

@cdce8p
Copy link
Collaborator

cdce8p commented Aug 23, 2022

Bug Report
Came across this override error while testing **kwargs unpack from #13471.
/CC: @ilevkivskyi

To Reproduce

from typing import Any, TypedDict
from typing_extensions import Unpack


class Details(TypedDict, total=False):
    arg: str
    value: int

class Parent:
    def turn_on(self, **kwargs: Any) -> None: ...

class Child(Parent):
    def turn_on(self, **kwargs: Unpack[Details]) -> None: ...  # <-- error

Expected Behavior

The parent methods uses Any as annotation for **kwargs. Any override with Upack[_TypedDict_] should be compatible.

Actual Behavior

test.py:13: error: Signature of "turn_on" incompatible with supertype "Parent"  [override]
test.py:13: note:      Superclass:
test.py:13: note:          def turn_on(self, **kwargs: Any) -> None
test.py:13: note:      Subclass:
test.py:13: note:          def turn_on(*, arg: str = ..., value: int = ...) -> None

Your Environment

  • Mypy version used: mypy 0.980+dev.0c0f071ef5d41c24182a5a94a5db882f9e917802 (compiled: no)
  • Mypy command-line flags: --enable-incomplete-features
  • Python version used: 3.10
@cdce8p cdce8p added the bug mypy got something wrong label Aug 23, 2022
@ilevkivskyi
Copy link
Member

ilevkivskyi commented Aug 23, 2022

This is not a bug. This actually violates Liskov. The suppertype can accept arbitrary keywords, while subtype only some.

If you really want to express "I don't care about arguments", use *args: Any, **kwargs: Any. Mypy special-cases this as "whatever works".

@cdce8p
Copy link
Collaborator Author

cdce8p commented Aug 23, 2022

This is not a bug. This actually violates Liskov. The suppertype can accept arbitrary keywords, while subtype only some.

Doesn't that depend on the definition of completeness? I.e. the TypedDict defines the keyword arguments which must be present, but just technically you can still pass any other arguments to it, as well. The code wouldn't break.

I also checked pyright, which does not emit an error, at the moment.

If you really want to express "I don't care about arguments", use *args: Any, **kwargs: Any. Mypy special-cases this as "whatever works".

Adding *args isn't an option in this case, unfortunately.

@ilevkivskyi
Copy link
Member

Allowing arbitrary keywords will significantly reduce safety. Imagine:

class Spec(TypedDict, total=False):
    one: int
    other: str

def foo(**kwargs: Spec) -> None: ...
foo(ohter=42)  # Oops, a typo, makes the type error unnoticed

I also checked pyright, which does not emit an error, at the moment.

Well, use pyright then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

2 participants