Skip to content

Instance variables typed as Callable on the class body don't get assignment warnings when missing in __slots__ #19187

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

Open
bzoracler opened this issue May 31, 2025 · 3 comments
Labels
bug mypy got something wrong

Comments

@bzoracler
Copy link
Contributor

Bug Report, To Reproduce, & Actual Behaviour

See mypy Playground:

from collections.abc import Callable

class A:
    __slots__ = ()
    a: int
    b: Callable[[int], str]
    
    def __init__(self, /) -> None:
        self.a = 1  # E: Trying to assign name "a" that is not in "__slots__" of type "__main__.A"  [misc]
        self.b = lambda _: str(_)  # No warning

Expected Behavior

from collections.abc import Callable

class A:
    __slots__ = ()
    a: int
    b: Callable[[int], str]
    
    def __init__(self, /) -> None:
        self.a = 1  # E: Trying to assign name "a" that is not in "__slots__" of type "__main__.A"  [misc]
        self.b = lambda _: str(_)  # E: Trying to assign name "b" that is not in "__slots__" of type "__main__.A"  [misc]

Your Environment

  • Mypy version used: (Occurs as far back as 1.0.0)
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.9, 3.12
@bzoracler bzoracler added the bug mypy got something wrong label May 31, 2025
@sterliakov
Copy link
Collaborator

mypy/mypy/checker.py

Lines 3756 to 3757 in 68233f6

if isinstance(typ, FunctionLike):
return True # Can be a property, or some other magic

We allow assignments to any callable-typed attribute not in slots. Probably using FunctionLike was an oversight. AFAIC something function-ish can only be assigned if it's a property-like inline definition that has a setter, so only a Decorator (which isn't even a FunctionLike!) should be relevant?

@bzoracler
Copy link
Contributor Author

Decorator is on the mypy.nodes.Node AST while FunctionLike is on the mypy.types.Type AST, so I don't think they preclude each other (d.type can be a FunctionLike where d: Decorator). Also, I believe that properties with setters are normally OverloadedFuncDefs rather than Decorators.

But anyway, the only kind of item which should be allowed here is something that's a class variable with __set__. IIRC @property is not represented as a descriptor in mypy, so that's a special casing needed to be accounted for.

@sterliakov
Copy link
Collaborator

Whoops, sorry, my bad, I was looking at the parent node, not at the type, because with our property representation it's usually easier.

Properties with setters are settable, so we really don't want this warning for them, and that can only be OverloadedFuncDef with is_property=True. Properties without setters can't be set, and current implementation should already produce an error similar to "can't assign to a property without setter", so we want to allow Decorator nodes too.

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