mafw.devtools.toolchain.tools.pyupgrade
PyUpgradeTool — concrete ProjectTool for pyupgrade.
This module implements the PyUpgradeTool class that manages the
pyupgrade syntax modernizer across two configuration files:
pyproject.toml— lower-bound>=specifier inproject.optional-dependencies.dev.pre-commit-config.yaml— therevfield of thehttps://github.com/asottile/pyupgraderepository entry
Because pyupgrade is referenced in two places, the verify() method checks
that the two declared versions are consistent. The post_update() hook
recreates the dev hatch environment, then runs pyupgrade via
pre-commit run pyupgrade --all-files at the highest supported Python
version, and reverts both files if the command fails.
The tool follows the same cross-file synchronization pattern as
RuffTool: the base class’s
_saved_content and _revert() handle pyproject.toml, while a separate
_saved_precommit attribute tracks the pre-commit config file state.
Classes
|
Manage pyupgrade across pyproject.toml and pre-commit. |
- class mafw.devtools.toolchain.tools.pyupgrade.PyUpgradeTool(project_root: Path | None = None)[source]
Bases:
ProjectToolManage pyupgrade across pyproject.toml and pre-commit.
pyupgrade is categorized as a project tool. Its version lower bound lives in
project.optional-dependencies.devand the pre-commit hook revision is declared in.pre-commit-config.yamlunder theasottile/pyupgraderepository. Both must stay in sync.The
update()method writes both files (pyproject first, then pre-commit). Onpost_update()failure, both files are reverted to their pre-update contents: pyproject.toml via the inherited_revert()helper, and.pre-commit-config.yamlvia the local_saved_precommitattribute.- Parameters:
project_root (Path | None) – Path to the project root directory containing both
pyproject.tomland.pre-commit-config.yaml. Defaults to the current working directory.
- _get_precommit_version() Version | None[source]
Read the pyupgrade version from the pre-commit config rev field.
Parses
.pre-commit-config.yaml, locates theasottile/pyupgraderepo entry, reads itsrevfield, strips thevprefix, and returns it as aVersion.- Returns:
The version from the pre-commit rev field, or
Noneif the repo or rev cannot be found.- Return type:
Version | None
- _revert_all() None[source]
Restore both config files to their saved pre-update state.
Uses the parent class
_revert()for pyproject.toml and manually restores.pre-commit-config.yamlfrom the saved content. Silently handles the case where saved content is not available.
- _revert_precommit() None[source]
Restore .pre-commit-config.yaml to its saved pre-update state.
Silently handles the case where saved content is not available.
- post_update() None[source]
Recreate the dev environment and run pyupgrade via pre-commit.
Performs the following steps after a successful version update:
Forces recreation of the
devhatch environment so that the newly specified dependency versions are resolved and installed.Determines the highest supported Python version dynamically from
tool.mafw.supported-pythonin pyproject.toml.Runs
pre-commit run pyupgrade --all-filesvia the dev environment to execute pyupgrade on all source files.
If environment recreation fails due to a dependency conflict, both pyproject.toml and .pre-commit-config.yaml are reverted. If pyupgrade fails, both files are also reverted.
- Raises:
DevtoolsError – If environment recreation fails or pyupgrade exits with a non-zero exit code.
- update() bool[source]
Update the pyupgrade version in pyproject.toml and .pre-commit-config.yaml.
Performs both updates:
Sets the
>=lower bound for pyupgrade inproject.optional-dependencies.devto the latest PyPI version (delegated to the parent class).Updates the
revfield of theasottile/pyupgraderepo entry in.pre-commit-config.yamltov{latest_version}.
Before modifying, saves both file contents so they can be reverted by
post_update()on failure. The parent class handles saving pyproject.toml via_saved_content; this method additionally saves the pre-commit config.- Returns:
Trueif either file was changed,Falseif both are already up to date.- Return type:
bool
- Raises:
DevtoolsError – If either file cannot be read or written.
- verify() list[Issue][source]
Compare pyupgrade version in pyproject.toml with the pre-commit rev.
Reads the
>=lower bound fromproject.optional-dependencies.devand therevfield (stripped ofvprefix) from theasottile/pyupgraderepo entry. Returns anIssueif they do not match.- Returns:
A list containing at most one
toolchain.Issueif the two versions differ, or an empty list if they are consistent.- Return type:
list[toolchain.Issue]
- property env_name: str
Hatch environment where pyupgrade is validated.
- Returns:
"dev"- Return type:
str
- property package_name: str
PyPI package name.
- Returns:
"pyupgrade"- Return type:
str
- property section_path: str
TOML section path where pyupgrade is declared.
- Returns:
"project.optional-dependencies.dev"- Return type:
str
- mafw.devtools.toolchain.tools.pyupgrade._PRECOMMIT_REPO_URL: Final[str] = 'https://github.com/asottile/pyupgrade'
Repository URL for the pyupgrade pre-commit hook entry.