FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Inline staticmethod assignment on subclass fails with `Incompatible types in assignment` · Issue #4574 · python/mypy · GitHub

Repository navigation

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

Closed as not planned

Description

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.

Activity

  1. gvanrossum commented on Feb 14, 2018

    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"
    
  2. momandine commented on Feb 14, 2018

    Author

    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)
  3. momandine commented on Feb 14, 2018

    Author

    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)
  4. momandine commented on Feb 14, 2018

    Author

    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)
  5. gvanrossum commented on Feb 14, 2018

    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?

  6. momandine commented on Feb 15, 2018

    Author

    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.

  7. AlexWaygood commented on Mar 28, 2022

    Member

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

  8. youtux commented on 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

  9. AlexWaygood commented on May 4, 2022

    Member

    @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.

  10. AlexWaygood commented on May 4, 2022

    Member

    Thanks @youtux :)

  11. added a commit that references this issue on May 9, 2024
  12. emmatyping commented on Dec 27, 2024

    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.

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 wrongtopic-descriptorsProperties, class vs. instance attributes

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL