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

Unreachable after pow #3214

Closed
antonio-fr opened this issue Aug 18, 2022 · 4 comments
Closed

Unreachable after pow #3214

antonio-fr opened this issue Aug 18, 2022 · 4 comments
Assignees

Comments

@antonio-fr
Copy link

Working in cryptography, I often use the pow built-in method. I recently switched to pylance in VSCode. I investigated why it says that one of my scripts has "unreachable code", for half of the code base.

Environment data

  • Pylance extension, language server 2022.8.30
  • OS and version: Windows 10
  • Python version : Python 3.9.11 64 bits

Code Snippet

def RSAcompute(message, exponent, pubkey):
    data = pow(message, exponent, pubkey)
    # Everything under is marked as "unreachable"
    # Because the variable output from pow is assessed
    # as NoReturn type by pylance.
    toto = 42 # says here unreachable
    return data

print("OK start")
res = RSAcompute(12, 34, 56)
print("Now pylance says unreachable")

Expected behavior

Should know that the built-in function pow returns int or float. And should not trigger "unreachable code" when using the pow command.

Actual behavior

Flags anything following pow(...) as unreachable.

@debonte
Copy link
Contributor

debonte commented Aug 18, 2022

I believe that this has something to do with the first overload of pow in builtins.pyi:

@overload
def pow(base: int, exp: int, mod: Literal[0]) -> NoReturn: ...

It's NoReturn in that case because pow throws an exception if mod is zero. See
https://github.com/python/typeshed/pull/6287/files#r750494382

If you annotate your function's pubkey parameter as an int, the issue will go away.

def RSAcompute(message, exponent, pubkey: int):

I'm a little surprised by that given that pubkey could still be zero.

@erictraut should be able to explain what's going on here.

@antonio-fr
Copy link
Author

Thank you for the investigation from your side. I reported this because it was very annoying : all my code was grey underlined, that breaks the readability, makes it harder to code. And I was astonished by the cause. Sometimes, I even disabled real time language server in VScode to be able to read my code correctly.
I can confirm your hint works perfectly. Thank you for this, it was so annoying.

Of course, from a mathematical pov, the modulus can't be 0, because this is like a divisor.
Indeed int includes 0 and this shouldn't change anything. Maybe an underlying issue discovered by luck?

For the sake of curiosity, how can we specify this is a strictly positive integer ? (as it should)

@erictraut
Copy link
Contributor

@debonte, your analysis is correct. The current type definition of pow in the typeshed builtins.pyi stub is unfortunate because the first overload is declared to return a NoReturn type. That's fine if the argument types are known, but if the argument types are Any or Unknown, this overload will be selected. We may want to file a PR or a bug report in typeshed. I would recommend deleting the first overload because it does more damage than good.

@antonio-fr, the Python static type system isn't expressive enough to indicate a "strictly positive integer". It's able to express a type of int or a specific literal value like Literal[0]. In this situation, it's sufficient to indicate that it's an int.

@debonte
Copy link
Contributor

debonte commented Aug 19, 2022

The NoReturn overload has been removed in typeshed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants