facebook / pyre-check

Performant type-checking for python.
https://pyre-check.org/
MIT License
6.8k stars 433 forks source link

Pyre does not reason about `if` statements with logical operators #903

Open bigfootjon opened 1 month ago

bigfootjon commented 1 month ago

Pyre Bug

Pyre does not reason about complex if statements. This is used in e.g. aiohttp:

https://github.com/aio-libs/aiohttp/blob/master/aiohttp/client.py#L1034

[Reproduction steps](https://pyre-check.org/play?input=from%20typing%20import%20TYPE_CHECKING%0Aimport%20sys%0A%0Aif%20TYPE_CHECKING%20and%20True%3A%0A%23if%20TYPE_CHECKING%3A%0A%23if%20sys.version_info%20%3E%20(2%2C%209)%20and%20True%3A%0A%23if%20sys.version_info%20%3E%20(2%2C%209)%3A%0A%20%20%20%20def%20get()%20-%3E%20None%3A%0A%20%20%20%20%20%20%20%20pass%0Aelse%3A%0A%20%20%20%20def%20get(i%3A%20int)%20-%3E%20None%3A%0A%20%20%20%20%20%20%20%20pass%0A%20%20%20%20%0Aget(1))

(try commenting and uncommenting the various options to see the various results)

Expected behavior All of the above if statements should report a type error

Logs See playground link

bigfootjon commented 1 month ago

Per discussion with @stroxler this code would need to be updated:

https://github.com/facebook/pyre-check/blob/main/source/analysis/preprocessing.ml#L4773-L4774

The likely solution is to switch to a replace-special-values-with-constant-true phase followed by a merge-logical-expressions-phase