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

Wrong type of exponentiation with integer base and power #1259

Closed
eternalphane opened this issue May 10, 2021 · 7 comments
Closed

Wrong type of exponentiation with integer base and power #1259

eternalphane opened this issue May 10, 2021 · 7 comments
Labels
enhancement New feature or request

Comments

@eternalphane
Copy link

Wrong type inference of integer raised to power of any integer other than literal 2

Environment data

  • Language Server version: 2021.5.2-pre.1
  • OS and version: Windows 10
  • Python version (and distribution if applicable, e.g. Anaconda): 3.9.5 (pipenv)
  • python.analysis.indexing: true
  • python.analysis.typeCheckingMode: off

Expected behaviour

a = 10**1
b = 10**3
c = 10**int(2)

Type of both a, b and c should be inferred as int.

Actual behaviour

image
image
image

@jakebailey
Copy link
Member

The problem is that negative exponents make the result float, so in order to avoid having a return type of __pow__ be Union[int, float], typeshed types this as Any, which is more permissive. The type system can't really distinguish negative from positive integers.

I special cased the literal 2 to help with this (as that's the most common power), but you've made a bunch of snippets that aren't that special case: python/typeshed#4473

@jakebailey
Copy link
Member

I'm not really sure there's a good way around this, besides special casing every literal integer (which has its tradeoffs).

Note that you can annotate your code if you're certain that you're correct:

x: int = 10**10

@jakebailey jakebailey added the waiting for user response Requires more information from user label May 10, 2021
@github-actions github-actions bot removed the triage label May 10, 2021
@eternalphane
Copy link
Author

The type system can't really distinguish negative from positive integers.

True for the stubs, but since pylance is not simply a collection of stubs, is there any chance for the type checker to at least distinguish negative from positive literals?

@jakebailey
Copy link
Member

Doing so would mean that we're no longer following the typing PEPs (we do what the stubs say), but it does appear as though mypy special cases this: https://mypy-play.net/?mypy=latest&python=3.9&gist=fdab7fc65290a63d922ba2b50b70f38b

reveal_type(10**2)
reveal_type(10**3)
reveal_type(10**-1)

def return_int(x: int) -> int:
    return x
    
reveal_type(10**return_int(2))
main.py:1: note: Revealed type is 'builtins.int'
main.py:2: note: Revealed type is 'builtins.int'
main.py:3: note: Revealed type is 'builtins.float'
main.py:8: note: Revealed type is 'Any'

@jakebailey
Copy link
Member

Though, not in a particularly sensible way... https://mypy-play.net/?mypy=latest&python=3.9&gist=fc3a42659210f6c87a96f56ecf965a91

from typing import Literal

def return_10() -> Literal[10]: return 10
def return_neg1() -> Literal[-1]: return -1

reveal_type(10**return_10())
reveal_type(10**return_neg1())
main.py:6: note: Revealed type is 'Any'
main.py:7: note: Revealed type is 'Any'

@erictraut
Copy link
Contributor

I don't think we should special case this in the type checker. This is not the only place where the type system cannot describe the semantics of a call exactly, and adding special cases in the type checker is a slippery slope that we should not go down. The current solution (a return type of Any) is a good compromise because it eliminates false positives in this case.

@jakebailey jakebailey added enhancement New feature or request needs decision Do we want this enhancement? and removed waiting for user response Requires more information from user labels May 11, 2021
@savannahostrowski savannahostrowski removed the needs decision Do we want this enhancement? label Jun 8, 2021
@judej
Copy link
Contributor

judej commented Apr 20, 2022

Closing old issue. If this is still a problem, please reopen with the information requested. thanks

@judej judej closed this as completed Apr 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants