ruff/crates/ruff_linter/resources/test/fixtures/pyupgrade
Igor Drokin 54df73c9f7
[`pyupgrade`] Apply `UP008` only when the `__class__` cell exists (#19424)
## Summary

Resolves #19357 

Skip UP008 diagnostic for `builtins.super(P, self)` calls when
`__class__` is not referenced locally, preventing incorrect fixes.

**Note:** I haven't found concrete information about which cases
`__class__` will be loaded into the scope. Let me know if anyone has
references, it would be useful to enhance the implementation. I did a
lot of tests to determine when `__class__` is loaded. Considered
sources:
1. [Python doc
super](https://docs.python.org/3/library/functions.html#super)
2. [Python doc classes](https://docs.python.org/3/tutorial/classes.html)
3. [pep-3135](https://peps.python.org/pep-3135/#specification)

As I understand it, Python will inject at runtime into local scope a
`__class__` variable if it detects references to `super` or `__class__`.
This allows calling `super()` and passing appropriate parameters.
However, the compiler doesn't do the same for `builtins.super`, so we
need to somehow introduce `__class__` into the local scope.

I figured out `__class__` will be in scope with valid value when two
conditions are met:
1. `super` or `__class__` names have been loaded within function scope
4. `__class__` is not overridden.

I think my solution isn't elegant, so I would be appreciate a detailed
review.

## Test Plan

Added 19 test cases, updated snapshots.

---------

Co-authored-by: Igor Drokin <drokinii1017@gmail.com>
2025-09-09 14:59:23 -04:00
..
.editorconfig [`pyupgrade`] Preserve parenthesis when fixing native literals containing newlines (`UP018`) (#17220) 2025-04-24 08:48:02 +02:00
UP001.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP003.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP004.py Improve handling of builtin symbols in linter rules (#10919) 2024-04-16 11:37:31 +01:00
UP005.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP006_0.py Revert "Add all PEP-585 names to UP006 rule" (#15250) 2025-01-04 12:23:53 +01:00
UP006_1.py Revert "Add all PEP-585 names to UP006 rule" (#15250) 2025-01-04 12:23:53 +01:00
UP006_2.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP006_3.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP007.py [`pyupgrade`] Avoid PEP-604 unions with `typing.NamedTuple` (`UP007`, `UP045`) (#18682) 2025-06-30 17:22:23 -04:00
UP008.py [`pyupgrade`] Apply `UP008` only when the `__class__` cell exists (#19424) 2025-09-09 14:59:23 -04:00
UP009_0.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_1.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_2.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_3.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_4.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_5.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_6.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_7.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_8.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_9.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_10.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP009_code_utf8_utf8.py [`pyupgrade`] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (`UP009`) (#14728) 2024-12-11 10:30:41 +00:00
UP009_hashbang_utf8_other.py [`pyupgrade`] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (`UP009`) (#14728) 2024-12-11 10:30:41 +00:00
UP009_many_empty_lines.py [`pyupgrade`] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (`UP009`) (#14728) 2024-12-11 10:30:41 +00:00
UP009_other_other.py [`pyupgrade`] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (`UP009`) (#14728) 2024-12-11 10:30:41 +00:00
UP009_other_utf8.py [`pyupgrade`] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (`UP009`) (#14728) 2024-12-11 10:30:41 +00:00
UP009_utf8_code_other.py [`pyupgrade`] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (`UP009`) (#14728) 2024-12-11 10:30:41 +00:00
UP009_utf8_other.py [`pyupgrade`] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (`UP009`) (#14728) 2024-12-11 10:30:41 +00:00
UP009_utf8_utf8.py [`pyupgrade`] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (`UP009`) (#14728) 2024-12-11 10:30:41 +00:00
UP009_utf8_utf8_other.py [`pyupgrade`] Do not report when a UTF-8 comment is followed by a non-UTF-8 one (`UP009`) (#14728) 2024-12-11 10:30:41 +00:00
UP010_0.py [`pyupgrade`] Avoid reporting `__future__` features as unnecessary when they are used (`UP010`) (#19769) 2025-08-20 15:22:03 -04:00
UP010_1.py [`pyupgrade`] Avoid reporting `__future__` features as unnecessary when they are used (`UP010`) (#19769) 2025-08-20 15:22:03 -04:00
UP011.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP012.py Add t-string fixtures for rules that do not need to be modified (#19146) 2025-07-14 09:46:31 -05:00
UP013.py [`pyupgrade`] Do not upgrade functional TypedDicts with private field names to the class-based syntax (`UP013`) (#16219) 2025-02-18 13:03:27 +00:00
UP014.py [`pyupgrade`] Mark fixes for `convert-typed-dict-functional-to-class` and `convert-named-tuple-functional-to-class` as unsafe if they will remove comments (`UP013`, `UP014`) (#14842) 2024-12-08 18:51:37 +00:00
UP015.py Detect permutations in redundant open modes (#14255) 2024-11-10 22:48:30 -05:00
UP015_1.py Use `Tokens` from parsed type annotation or parsed source (#11740) 2024-06-05 07:50:33 +00:00
UP017.py Avoid failures due to non-deterministic binding ordering (#10478) 2024-03-19 18:01:33 +00:00
UP018.py Add t-string fixtures for rules that do not need to be modified (#19146) 2025-07-14 09:46:31 -05:00
UP018_CR.py [`pyupgrade`] Preserve parenthesis when fixing native literals containing newlines (`UP018`) (#17220) 2025-04-24 08:48:02 +02:00
UP018_LF.py [`pyupgrade`] Preserve parenthesis when fixing native literals containing newlines (`UP018`) (#17220) 2025-04-24 08:48:02 +02:00
UP019.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP020.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP021.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP022.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP023.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP024_0.py Treat `os.error` as an `OSError` alias (#7582) 2023-09-21 21:18:14 +00:00
UP024_1.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP024_2.py [`pyupgrade`] Add `resource.error` as deprecated alias of `OSError` (`UP024`) (#17933) 2025-05-14 10:37:25 -04:00
UP024_3.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP024_4.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP025.py [`ruff`] Fix syntax error introduced for an empty string followed by a u-prefixed string (`UP025`) (#18899) 2025-07-01 09:34:08 -04:00
UP026.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP028_0.py [`pyupgrade`] Do not offer fix when at least one target is `global`/`nonlocal` (`UP028`) (#16451) 2025-03-04 11:28:01 +01:00
UP028_1.py [`pyupgrade`] Do not offer fix when at least one target is `global`/`nonlocal` (`UP028`) (#16451) 2025-03-04 11:28:01 +01:00
UP029.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP030_0.py [`pyupgrade`] Fix `UP030` to avoid modifying double curly braces in format strings (#19378) 2025-07-29 18:35:54 +00:00
UP030_1.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP031_0.py [`pyupgrade`] Show violations without auto-fix for `UP031` (#11229) 2024-08-14 11:59:40 +00:00
UP031_1.py [`pyupgrade`] Show violations without auto-fix for `UP031` (#11229) 2024-08-14 11:59:40 +00:00
UP032_0.py Use `Tokens` from parsed type annotation or parsed source (#11740) 2024-06-05 07:50:33 +00:00
UP032_1.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP032_2.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP032_3.py Avoid converting f-strings within Django `gettext` calls (#7898) 2023-10-10 16:31:09 +00:00
UP033_0.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP033_1.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP034.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP035.py [`pyupgrade`] Apply `UP035` only on py313+ for `get_type_hints()` (#18476) 2025-06-05 17:16:29 +01:00
UP036_0.py Mark `sys.version_info[0] < 3` and similar comparisons as outdated (#13175) 2024-08-30 19:38:46 -04:00
UP036_1.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP036_2.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP036_3.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP036_4.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP036_5.py [`pyupgrade`] Extend version detection to include `sys.version_info.major` (`UP036`) (#18633) 2025-06-23 20:01:55 +00:00
UP037_0.py [`pyupgrade`] Handle end-of-line comments for `quoted-annotation` (`UP037`) (#15824) 2025-01-30 00:03:05 -06:00
UP037_1.py Mark quotes as unnecessary for non-evaluated annotations (#11485) 2024-05-22 15:44:31 -04:00
UP037_2.pyi Parse triple quoted string annotations as if parenthesized (#15387) 2025-01-16 11:38:15 +05:30
UP038.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP039.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00
UP040.py [`pyupgrade`] Don't introduce invalid syntax when upgrading old-style type aliases with parenthesized multiline values (`UP040`) (#16026) 2025-02-07 17:05:17 +00:00
UP040.pyi [`pyupgrade`] Comments within parenthesized value ranges should not affect applicability (`UP040`) (#16027) 2025-02-07 14:44:33 -06:00
UP041.py Add pyupgrade `UP041` to replace `TimeoutError` aliases (#8476) 2023-11-03 17:24:47 +00:00
UP042.py [`pyupgrade`] Replace `str, Enum` with `StrEnum` (`UP042`) (#10713) 2024-04-06 01:56:28 +00:00
UP043.py Mark UP043 fix unsafe when the type annotation contains any comments (#14458) 2024-11-19 15:24:02 +01:00
UP043.pyi [`pyupgrade`] Enable rule triggering for stub files (`UP043`) (#20027) 2025-09-09 12:57:26 +00:00
UP044.py Avoid applying PEP 646 rewrites in invalid contexts (#14234) 2024-11-09 15:47:28 -05:00
UP045.py [`pyupgrade`] Handle nested `Optional`s (`UP045`) (#19770) 2025-08-19 18:12:15 -04:00
UP046_0.py [`pyupgrade`] Handle multiple base classes for PEP 695 generics (`UP046`) (#15659) 2025-01-22 20:19:13 -05:00
UP046_1.py [`pyupgrade`] Add rules to use PEP 695 generics in classes and functions (`UP046`, `UP047`) (#15565) 2025-01-22 11:35:21 -05:00
UP047.py [`pyupgrade`] Add rules to use PEP 695 generics in classes and functions (`UP046`, `UP047`) (#15565) 2025-01-22 11:35:21 -05:00
UP049_0.py [`pyupgrade`] Rename private type parameters in PEP 695 generics (`UP049`) (#15862) 2025-02-04 13:22:57 -05:00
UP049_1.py [`pyupgrade`] [`ruff`] Don't apply renamings if the new name is shadowed in a scope of one of the references to the binding (`UP049`, `RUF052`) (#16032) 2025-02-08 11:25:23 +00:00
UP050.py [`pyupgrade`]: new rule UP050 (`useless-class-metaclass-type`) (#18334) 2025-05-28 09:22:44 +02:00
future_annotations.py Rename `ruff` crate to `ruff_linter` (#7529) 2023-09-20 08:38:27 +02:00