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

Regression since 0.620: Argument 1 to "__div__" of "int" has incompatible type "float"; expected "int" #5557

Closed
gvanrossum opened this issue Sep 1, 2018 · 8 comments
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-0-high

Comments

@gvanrossum
Copy link
Member

Consider:

def f(a):
    # type: (Union[int, float]) -> None
    a /= 1.1  # <-- Line 10

This looks fine to me, and gives no errors in 0.620 in either Python 2 or Python 3 mode. In the current master it gives this error in Python 2 mode:

_.py:10: error: Argument 1 to "__div__" of "int" has incompatible type "float"; expected "int"
_.py:10: note: __rdiv__ will not be called when evaluating 'float / float': must define __div__

In Python 3 it gives this error:

_.py:10: error: Unsupported operand types for / (likely involving Union)
_.py:10: note: __rtruediv__ will not be called when evaluating 'float / float': must define __truediv__

@Michael0x2a IIRC you did something with operators recently?

@gvanrossum gvanrossum mentioned this issue Sep 1, 2018
12 tasks
@ilevkivskyi
Copy link
Member

@Michael0x2a Another point about this is that ideally a user should not see any __X__ in error messages unless this will give some insight, for example this

Argument 1 to "__div__" of "int" has incompatible type "float"; expected "int"

Should be formulated as Unsupported operand types for / "int" and "float"

Also I am not sure we should show the note about some subtleties of Python internals unless these methods are defined in user code (not in typeshed stubs).

@ilevkivskyi
Copy link
Member

(The comment above is in addition to the fact that it would be great to fix the false positive.)

@ilevkivskyi ilevkivskyi added bug mypy got something wrong priority-0-high false-positive mypy gave an error on correct code labels Sep 1, 2018
@ilevkivskyi
Copy link
Member

Btw the problem looks specific to unions so there is a chance PR #5545 will also fix this.

@ilevkivskyi
Copy link
Member

@Michael0x2a If this is the case, could you please add few tests of this kind to #5545? (In both Python 2 and Python 3 mode.)

@gvanrossum
Copy link
Member Author

Confirmed that #5545 fixes this.

@Michael0x2a
Copy link
Collaborator

Ah, whoops -- I probably should have been more vocal about what I was planning on doing here. But yes, this is fixed by #5545 -- I'll make sure to add some tests.

I also agree that we should get rid of the __rdiv__ will not be called when evaluating 'float / float': must define __div__ note -- I was actually planning on submitting a PR for that sometime this weekend. It's a useful error message if you're creating a library with custom numeric types + are trying to debug some code using said numeric types, but as I discovered earlier while debugging, isn't very useful for anybody else.

(Fun story: I ran into that error message while I was debugging some code the other day, and was severely confused for a good half-minute, even though I was originally the one who added that error message...)

Another point about this is that ideally a user should not see any X in error messages unless this will give some insight

I also agree -- I think the fact that we do is an unfortunate consequence of how mypy doesn't cleanly handle division in Python 2 in general. Mypy ought to have detected that __div__ is an operator method in Python 2, but doesn't. Basically, this is the comment I left here.

@mvaled
Copy link

mvaled commented Sep 4, 2018

I was thinking to add a bug, but I believe this takes cares of it. The PR #5545 also solves the case below.

The problematic code was having an 'Undefined' number that returns itself in most arithmetic operations:

import numbers
from typing import Any, Union


class _Undefined(numbers.Number):
    def idem(self, other: Any) -> 'Result':
        return self

    def selfy(self) -> 'Result':
        return self

    __add__ = __radd__ = __iadd__ = idem
    __sub__ = __rsub__ = __isub__ = idem
    __mul__ = __rmul__ = __imul__ = idem
    __div__ = __rdiv__ = __idiv__ = idem
    __truediv__ = __rtruediv__ = __itruediv__ = idem
    __floordiv__ = __rfloordiv__ = __ifloordiv__ = idem
    __mod__ = __rmod__ = __imod__ = idem
    __pow__ = __rpow__ = __ipow__ = idem
    __trunc__ = selfy
    __float__ = lambda s: 0.0
    __int__ = lambda s: 0
    __abs__ = selfy
    __neg__ = selfy
    __invert__ = selfy

    def __bool__(self):
        return False

    def __str__(self):
        return 'Undefined'
    __repr__ = __str__

    def __hash__(self):
        return id(self)

    def __eq__(self, other):
        return other is self

    def __ne__(self, other):
        return self is not other

    def nope(self, other):
        if isinstance(other, numbers.Number):
            return False
        else:
            return NotImplemented

    __lt__ = __le__ = __gt__ = __ge__ = nope

    del idem, selfy, nope


Undefined = _Undefined()
Result = Union[float, int, _Undefined]
BuiltinNumber = Union[float, int]


def divide(n: Result, d: Result) -> Result:
    return n / d


def divide2(n: BuiltinNumber, d: BuiltinNumber) -> BuiltinNumber:
    return n / d

However, mypy 0.600+ do complained in both 'divide' and 'divide2'.

@ilevkivskyi
Copy link
Member

This is fixed by #5545

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-0-high
Projects
None yet
Development

No branches or pull requests

4 participants