Note that this would cause errors for 'valid' code, when finally referenced a variable created only in try: which *may* have been bound before the exception. The coder may know 99% that the variable created in the try block will never fail (except maybe out of memory errors, I suppose). e.g. something like
----
try:
bar = foo.x
baz = bar.y
finally:
if bar is not None:
bar.z
----
Anyway, it is extremely prone to bugs, so IMO it is acceptable to error in that scenario.
I suspect this is quite easy to solve moderately well.
Instead of simply processing all TRY children nodes sequentially
process `finally:` children first, and then the `try:`, `except:` and `else:` children.
The better approach would be to save a copy of the contents of the scope before processing the `try:` children nodes, and use that saved copy of the scope while processing the `finally:` children. That way it is possible to check whether the referenced names were created during the `try:` branch.
Note that this would cause errors for 'valid' code, when finally referenced a variable created only in try: which *may* have been bound before the exception. The coder may know 99% that the variable created in the try block will never fail (except maybe out of memory errors, I suppose). e.g. something like
----
try:
bar = foo.x
baz = bar.y
finally:
if bar is not None:
bar.z
----
Anyway, it is extremely prone to bugs, so IMO it is acceptable to error in that scenario.
I suspect this is quite easy to solve moderately well.
Instead of simply processing all TRY children nodes sequentially
https:/ /github. com/pyflakes/ pyflakes/ blob/master/ pyflakes/ checker. py#L1092
process `finally:` children first, and then the `try:`, `except:` and `else:` children.
The better approach would be to save a copy of the contents of the scope before processing the `try:` children nodes, and use that saved copy of the scope while processing the `finally:` children. That way it is possible to check whether the referenced names were created during the `try:` branch.