For example:
class A(object):
def float(self):
# type: () -> float
return 1.0
gives:
mypy -v .
LOG: Mypy version 0.521
LOG: Metadata not found for test
LOG: Parsing ./test.py (test)
LOG: Processing SCC singleton (test) as inherently stale with stale deps (builtins)
LOG: No fresh SCCs left in queue
LOG: Build finished in 0.862 seconds with 10 modules, 2071 types, and 1 errors
test.py:3: error: Invalid type "test.A.float"
Unfortunately, this is not an easy (and in fact old) problem. Mypy doesn't record the order of assignments (and other name bindings), so that while you are inside a class, then it finds float in the class namespace first. There is a simpler repro of this:
y = x # no error here
x = 1
I am not sure whether we should keep this open or mark it as a duplicate of https://github.com/python/mypy/issues/2788
As a workaround, you can write builtins.float in the annotation, and add import builtins at the start (on Python 2 this import needs to be under if typing.TYPE_CHECKING: ...).
Mypy could perhaps detect the issue and give a more informative error message, such as suggesting the import builtins trick.
@JukkaL I'm not sure if this is the same issue, but I'm seeing something similar for this example:
import foo
class Bar:
def foo(f: foo.Foo) -> None:
pass
If this is related, then the error message might need to be more elaborate.
@ns-cweber This is closely related. The problem is that mypy does not follow Python name resolution rules exactly one to one. There is no simple solution for this, but maybe indeed we could make the error message more clear. Anyway, I am raising priority to normal.
the workaround suggested by @ilevkivskyi works for now well, with only the downside that people unfamiliar with the problem initially may wonder why we used the builtins.float; which can be solved by adding a comment to point it out to this issue.
Raising priority to high since this keeps coming. We can at least try to follow Python rules in most cases. General solution may be hard.
Most helpful comment
Raising priority to high since this keeps coming. We can at least try to follow Python rules in most cases. General solution may be hard.