Skip to content

[CHORE] Modernize Python syntax with pyupgrade (ruff UP rules) #1841

@oberstet

Description

@oberstet

Summary

Run ruff check --fix --select UP across the codebase to modernize Python syntax automatically. This is a low-risk, high-value cleanup that improves code consistency and readability.

Suggested by @bblommers in #1838:

"Speaking of: running ruff check --select UP seems to be mostly f-strings violations, which could be fixed automatically using ruff check --fix. I would be happy to add that as part of this PR - but I would recommend running that against the entire codebase in a separate PR for that. It makes reviewing a lot easier!"

What pyupgrade (UP) Does

The UP rule set modernizes Python syntax to use newer, cleaner constructs. Key transformations include:

String Formatting → f-strings

# Before (UP031, UP032)
"Hello, %s" % name
"Hello, {}".format(name)

# After
f"Hello, {name}"

Type Annotations → Modern Syntax

# Before (UP006, UP007)
from typing import Dict, List, Optional, Union
x: Optional[str]
y: Union[int, str]
z: Dict[str, List[int]]

# After
x: str | None
y: int | str
z: dict[str, list[int]]

Other Modernizations

Rule Before After
UP005 assertEquals() assertEqual()
UP008 super(Foo, self) super()
UP009 # -*- coding: utf-8 -*- (removed, UTF-8 is default)
UP010 from __future__ import print_function (removed)
UP015 open("f", "r") open("f")
UP018 str("literal") "literal"
UP025 "unicode" encoding (simplified)
UP028 yield in for loop yield from
UP034 (x,) extraneous parens x,
UP035 typing.Dict dict
UP036 Version checks for old Python (removed)
UP038 isinstance(x, (A, B)) isinstance(x, A | B)

Implementation

Step 1: Preview Changes

# See what would change (dry run)
ruff check --select UP src/autobahn/

Step 2: Auto-fix

# Apply fixes automatically
ruff check --fix --select UP src/autobahn/

Step 3: Manual Review

Some changes may need manual attention:

  • Complex string formatting with many arguments
  • Edge cases in type annotations
  • Any changes that affect runtime behavior (rare but possible)

Step 4: Run Tests

just test cpy314

Scope

In scope:

  • All .py files in src/autobahn/
  • Automatic fixes via ruff --fix
  • Manual fixes for any remaining violations

Out of scope:

  • Test files (can be done in follow-up)
  • Changes that would affect public API signatures
  • Any behavioral changes (this is purely syntactic)

Why a Separate PR?

As @bblommers noted, keeping this separate from typing work makes review much easier:

  1. Single concern — only modernization, no new types
  2. Mechanical changes — easy to verify correctness
  3. Clean diff — reviewers can focus on unexpected changes
  4. Bisectable — if issues arise, easy to identify source

Acceptance Criteria

  • ruff check --select UP src/autobahn/ reports zero violations
  • All tests pass (just test cpy314)
  • CI passes
  • No changes to public API behavior

Assignee

@bblommers has hinted at / offered to take this on — thank you, should you decide to invest time & work!

Related

References

Checklist

  • I have searched existing issues to avoid duplicates
  • I have described the problem clearly
  • I have provided use cases
  • I have considered alternatives
  • I have assessed impact and breaking changes

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions