8000 Inline staticmethod assignment on subclass fails with `Incompatible types in assignment` · Issue #4574 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Inline staticmethod assignment on subclass fails with Incompatible types in assignment #4574

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

Closed
momandine opened this issue Feb 14, 2018 · 11 comments
Labels
bug mypy got something wrong topic-descriptors Properties, class vs. instance attributes

Comments

@momandine
Copy link

A simplification of some old code I am trying to add mypy to:

class Base(object):
    def foo(self):
         # type: () -> None
         a = self.static_foo()

class SubClass(Base):
    static_foo = staticmethod(lambda: 5)

Results in the error:
error: Incompatible types in assignment (expression has type "staticmethod", base class "Job" defined the type as "Callable[[], int]")

Oddly, as far as I can tell, static_foo is not actually defined on the base class.

This is using Dropbox's mypy setup, with --strict-optional. I am actually not sure which version we're on, but can look it up and edit this issue.

@gvanrossum
Copy link
Member

There must be a little more going on than you show, since if I type that example into mypy:

class Base:
    def foo(self) -> None:
        a = self.static_foo()
class Sub(Base):
    static_foo = staticmethod(lambda: 5)

I get a much simpler error:

_.py:3: error: "Base" has no attribute "static_foo"

@momandine
Copy link
Author
momandine commented Feb 14, 2018

Well, this example doesn't error at all, which is closer:

  1 from typing import Any, Dict
  2
  3 class Base(object):
  4     def __init__(self, dikt):
  5         # type: (Dict[Any, Any]) -> None
  6         object.__setattr__(self, '_dict', dikt)
  7
  8     def __getattr__(self, name):
  9         # type: (str) -> Any
 10         return self._dict[name]
 11
 12     def __setattr__(self, name, val):
 13         # type: (str, Any) -> None
 14         if name in self._dict:
 15             self._dict[name] = val
 16         else:
 17             object.__setattr__(self, name, val)
 18
 19     def foo(self):
 20          # type: () -> None
 21          a = self.static_foo()
 22
 23
 24
 25 class SubClass(Base):
 26     static_foo = staticmethod(lambda: 5)

@momandine
Copy link
Author
momandine commented Feb 14, 2018

This does repro (though in my actual example, there is no staticmethod declared on the base class (???).

  1 from typing import Any, Dict
  2
  3 class Base(object):
  4     def __init__(self, dikt):
  5         # type: (Dict[Any, Any]) -> None
  6         object.__setattr__(self, '_dict', dikt)
  7
  8     def __getattr__(self, name):
  9         # type: (str) -> Any
 10         return self._dict[name]
 11
 12     def __setattr__(self, name, val):
 13         # type: (str, Any) -> None
 14         if name in self._dict:
 15             self._dict[name] = val
 16         else:
 17             object.__setattr__(self, name, val)
 18
 19     def foo(self):
 20          # type: () -> None
 21          a = self.static_foo()
 22
 23     @staticmethod
 24     def static_foo():
 25         # type: () -> int
 26         return 0
 27
 28
 29 class SubClass(Base):
 30     static_foo = staticmethod(lambda: 5)
 31
 32     def __init__(self, *args, **kwargs):
 33         # type: (*Any, **Any) -> None
 34         super(SubClass, self).__init__(*args, **kwargs)

@momandine
Copy link
Author
momandine commented Feb 14, 2018

More minimal repro:

class Base(object):
    def foo(self) -> None:
        a = self.static_foo()

    @staticmethod
    def static_foo() -> int:
        return 0

class SubClass(Base):
    static_foo = staticmethod(lambda: 5)

@gvanrossum
Copy link
Member

And to clarify, this gives the following error:

_.py:16: error: Incompatible types in assignment (expression has type "staticmethod", base class "Base" defined the type as "Callable[[], int]")

Now it's very clear that the error is caused by mypy's lack of understanding of how staticmethod() relates to @staticmethod.

As to why it gave this same error for you with the real version of the original code, even though there was no definition of static_foo in the base class there, I'm still not sure. But maybe you don't care and you would just like mypy's understanding of staticmethod() to be improved?

@momandine
Copy link
Author
momandine commented Feb 15, 2018

Improving mypy's understanding of inline usage of staticmethod seems tractable/higher priority. Given how clever this code is, someone may have monkey patched something somewhere to the same effect of the minimal example.

@AlexWaygood AlexWaygood added bug mypy got something wrong topic-descriptors Properties, class vs. instance attributes labels Mar 28, 2022
@AlexWaygood
Copy link
Member

The false-positive error is no longer emitted on mypy 0.930+.

@youtux
Copy link
youtux commented May 4, 2022

@AlexWaygood this is error is back, at least with mypy 0.950 and 3.7 <= python <= 3.9:
https://mypy-play.net/?mypy=0.950&python=3.8&gist=1e25a16047bae31555e210da7797f640

@AlexWaygood
Copy link
Member
AlexWaygood commented May 4, 2022

@AlexWaygood this is error is back, at least with mypy 0.950 and 3.7 <= python <= 3.9:
https://mypy-play.net/?mypy=0.950&python=3.8&gist=1e25a16047bae31555e210da7797f640

Hah! This bug was never fixed. The reason I thought it was is because I was testing on 3.10, and the typeshed stub (correctly) states that staticmethod.__call__ was added in 3.10. This means that there's no false positive error on 3.10, but it's not because the mypy bug is fixed, it's because the typeshed stub is different if you're running on 3.10.

@AlexWaygood AlexWaygood reopened this May 4, 2022
@AlexWaygood
Copy link
Member

Thanks @youtux :)

ymilki added a commit to ymilki/yelp_encodings that referenced this issue Sep 21, 2022
* Changed inline staticmethod assignment in subclasses
    * In <py310, the staticmethod typeshed stub doesn't correcetly
    define the `__call__`. See python/mypy#4574
* Removed py2-only exception block
* Inlined `_Encoder` protocol from typeshed for typecasting.
ymilki added a commit to ymilki/yelp_encodings that referenced this issue Sep 26, 2022
* Changed inline staticmethod assignment in subclasses
    * In <py310, the staticmethod typeshed stub doesn't correcetly
    define the `__call__`. See python/mypy#4574
    * Add tests to cover these methods
* Removed py2-only exception block
* Inlined `_Encoder` protocol from typeshed for typecasting.

squash! R   Add type annotations
PierreGtch added a commit to PierreGtch/braindecode that referenced this issue May 9, 2024
bruAristimunha pushed a commit to braindecode/braindecode that referenced this issue May 9, 2024
* Add mypy dependency

* Update pre-commit

* Test pre-commit

* Test pre-commit

* Set files to check

* Only check mypy at push

* Fix type

* Fix type

* Fix type

* Fix type

* Fix missing methods from EEGModuleMixin, not nice...

* Fix types

* Remove staticmethod(..)  from IdentityTransform

* Fix type

* Undo IdentityTransform not staticmethod

* Ignore check for staticmethods in transforms because of python/mypy#4574

* Ignore BaseConcatDataset.split for now

* Fix type

* Fix type

* Fix type

* Fix types

* Fix types

* Fix types

* Fix types

* Add future import

* Fix type

* Fix types

* Fix types

* Ignore type staticmethod

* Ignore type staticmethod

* Fix type

* Ignore import error for preprocessors

* Update whats_new.rst
@emmatyping
Copy link
Member

3.9, the last version affected by this bug, has 8 more months before it hits EOL. I don't think it is worth fixing this.

@emmatyping emmatyping closed this as not planned Won't fix, can't repro, duplicate, stale Dec 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-descriptors Properties, class vs. instance attributes
Projects
None yet
Development

No branches or pull requests

5 participants
0