facebook / facebook/pyrefly

Narrowing inside `try` is preserved into `finally`, ignoring type outside of `try`

Open
#2,845 1 comment 0 reactions 1 assignee Claimed by @asukaminato0721 View on GitHub
narrowing scoping-control-flow typechecking
Dominant language
Rust
Stars
7k
Forks
516
PR merge metrics
No merged PRs in 30d

Description

### Describe the Bug

```python
from typing import *

def something_that_might_throw() -> None:
raise Exception()

class Thing():
def something(self) -> None:
pass

def blah() -> None:
x = None
try:
something_that_might_throw()
if x is None:
x = Thing()
except Exception:
raise
finally:
reveal_type(x) # revealed type: Thing, but it could be `None`
x.something()
```

Python: 3.12

### Sandbox Link

https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN0AqADroRIzDDB04tGAwAWrNgH0FqBspoQ28jQuoB3ABQBKOgFoAfHQByudDEQi6LupVQQ4MOgFF8AYxhiBgh7U2dXSJF-KFQ4ODoAFUV2Uyd0SIkpGRo5FLYjLygwMytbe0cIyJdiOLgxLEk6bFj5UwtrOwd0yPw6AF5yhyrGSlIe6pccvKVVeXVNbV05w3CMyc4pPs8hyvWN1z7B5KU1yJgAoP4-QODQ9AnJ908YEch0VCgocZHIyhgAG4wT6qZgwIz4MwAYjcgOBsEwjDBiCS%2BQANM0AK78CD8fy4TFQRHYbwAAy6MFJv0OhGmClOJhAaJAZH%2BYG%2BhAYtCgFBhAAVSGzvtIMDgCHR8ehIGxMe4QvZCCIYQBlGDeXQMYhwRAAeh1rMkHN4bB1MHQOswuH8cB1kulsvU9x1dDAvDoqABHliLW8du0DvlGVwd3scEV6DICns5iBlDg9wGdCEIAAzIQAIwAJmTIgA2jBKNQ4wBdESY9BcHh8GCYcyYCD-fwhIGJgDk2nQvBgrZEnYY5n%2BAEdMQ2a%2BYANYwUjmVD%2BQLxNsGVCUdA99AgAC%2BzNnzZgADFoDAKGgsHgiGRN0A

### (Only applicable for extension issues) IDE Information

I'm not sure what the desired behavior is, but clearly we're guessing wrong in this case by taking the refined type from the `try`.

If we take the original type before the `try` then it doesn't account for the fact that the `try` could have succeeded. I thought we created a flow branch at the beginning of the try-block and merging the two branches should have handled this, but something is going wrong.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.