mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
![]() Summary -- This PR extends the documentation of the `LoadBeforeGlobalDeclaration` check to specify the behavior on versions of Python before 3.13. Namely, on Python 3.12, the `else` clause of a `try` statement is visited before the `except` handlers: ```pycon Python 3.12.9 (main, Feb 12 2025, 14:50:50) [Clang 19.1.6 ] on linux Type "help", "copyright", "credits" or "license" for more information. >>> a = 10 >>> def g(): ... try: ... 1 / 0 ... except: ... a = 1 ... else: ... global a ... >>> def f(): ... try: ... pass ... except: ... global a ... else: ... print(a) ... File "<stdin>", line 5 SyntaxError: name 'a' is used prior to global declaration ``` The order is swapped on 3.13 (see [CPython#111123](https://github.com/python/cpython/issues/111123)): ```pycon Python 3.13.2 (main, Feb 5 2025, 08:05:21) [GCC 14.2.1 20250128] on linux Type "help", "copyright", "credits" or "license" for more information. >>> a = 10 ... def g(): ... try: ... 1 / 0 ... except: ... a = 1 ... else: ... global a ... File "<python-input-0>", line 8 global a ^^^^^^^^ SyntaxError: name 'a' is assigned to before global declaration >>> def f(): ... try: ... pass ... except: ... global a ... else: ... print(a) ... >>> ``` The current implementation of PLE0118 is correct for 3.13 but not 3.12: [playground](https://play.ruff.rs/d7467ea6-f546-4a76-828f-8e6b800694c9) (it flags the first case regardless of Python version). We decided to maintain this incorrect diagnostic for Python versions before 3.13 because the pre-3.13 behavior is very unintuitive and confirmed to be a bug, although the bug fix was not backported to earlier versions. This can lead to false positives and false negatives for pre-3.13 code, but we also expect that to be very rare, as demonstrated by the ecosystem check (before the version-dependent check was reverted here). Test Plan -- N/a |
||
---|---|---|
.. | ||
red_knot | ||
red_knot_ide | ||
red_knot_project | ||
red_knot_python_semantic | ||
red_knot_server | ||
red_knot_test | ||
red_knot_vendored | ||
red_knot_wasm | ||
ruff | ||
ruff_annotate_snippets | ||
ruff_benchmark | ||
ruff_cache | ||
ruff_db | ||
ruff_dev | ||
ruff_diagnostics | ||
ruff_formatter | ||
ruff_graph | ||
ruff_index | ||
ruff_linter | ||
ruff_macros | ||
ruff_notebook | ||
ruff_python_ast | ||
ruff_python_ast_integration_tests | ||
ruff_python_codegen | ||
ruff_python_formatter | ||
ruff_python_index | ||
ruff_python_literal | ||
ruff_python_parser | ||
ruff_python_resolver | ||
ruff_python_semantic | ||
ruff_python_stdlib | ||
ruff_python_trivia | ||
ruff_python_trivia_integration_tests | ||
ruff_server | ||
ruff_source_file | ||
ruff_text_size | ||
ruff_wasm | ||
ruff_workspace |