Skip to content

False negative when using the power (**) operator #7765

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
nikola-benes opened this issue Oct 21, 2019 · 5 comments
Closed

False negative when using the power (**) operator #7765

nikola-benes opened this issue Oct 21, 2019 · 5 comments

Comments

@nikola-benes
Copy link

When checking the following function with mypy 0.730 (Python version 3.7.4):

def foo(x: int) -> str:
   return 2 ** x

mypy reports no errors:

Success: no issues found in 1 source file

With the --strict option turned on, mypy reports:

foo.py:2: error: Returning Any from function declared to return "str"

The expected output would be something like

foo.py:2: error: Incompatible return value type (got "int", expected "str")
@srittau
Copy link
Contributor

srittau commented Oct 21, 2019

This is an issue with typeshed due to a limitation in the type system. foo can return either an int or a float, depending on whether x is a positive or negative number. While we could change typeshed in a way that 2 ** x will always return float (which is correct, since for typing purposes int is a subtype if float), this would be rather annoying for users that know that it will return an int, for example because they know that x is always non-negative. Therefore we return Any, because there is no way to properly express this.

We would need a range type to be able to express this.

@nikola-benes
Copy link
Author

nikola-benes commented Oct 21, 2019

Wouldn't Union[int, float] be a better option instead of Any? The users can then assert that the result is an int if they are sure that x is non-negative.

@nikola-benes
Copy link
Author

Also, a related problem is that

def foo(x: int) -> float:
    return 2 ** x

fails with mypy --strict. What is the recomended way to deal with this? Explicit type conversion (float(2 ** x))?

@msullivan
Copy link
Collaborator

Wouldn't Union[int, float] be a better option instead of Any? The users can then assert that the result is an int if they are sure that x is non-negative.

We try to avoid that sort of union return in typeshed stubs because they produce a pretty bad user experience.

@msullivan
Copy link
Collaborator

Also, a related problem is that

def foo(x: int) -> float:
    return 2 ** x

fails with mypy --strict. What is the recomended way to deal with this? Explicit type conversion (float(2 ** x))?

Yeah, probably. --disallow-return-any maybe shouldn't be in --strict? See #7767 which I just opened

Kyle-Verhoog added a commit to Kyle-Verhoog/sketches-py that referenced this issue May 4, 2022
For some reason (python/mypy#7765) `**` has a
return type of `Any` so just use `math.pow()` instead.
Kyle-Verhoog added a commit to DataDog/sketches-py that referenced this issue May 4, 2022
For some reason (python/mypy#7765) `**` has a
return type of `Any` so just use `math.pow()` instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants