Skip to content

Enable the ruff check for unused imports#4566

Draft
psss wants to merge 2 commits intomainfrom
psss-ruff-unused-imports
Draft

Enable the ruff check for unused imports#4566
psss wants to merge 2 commits intomainfrom
psss-ruff-unused-imports

Conversation

@psss
Copy link
Contributor

@psss psss commented Feb 10, 2026

Would be nice to prevent importing irrelevant stuff.

Pull Request Checklist

  • implement the feature
  • write the documentation
  • extend the test coverage
  • update the specification
  • adjust plugin docstring
  • modify the json schema
  • mention the version
  • include a release note

Would be nice to prevent importing irrelevant stuff.
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @psss, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the project's code quality by activating the Ruff linter's unused import detection and subsequently cleaning up all identified redundant imports. This effort streamlines the codebase, making it more readable and reducing potential for dead code or confusion, thereby improving overall maintainability.

Highlights

  • Linter Configuration Update: The F401 rule, which checks for unused imports, has been re-enabled in the pyproject.toml configuration for the Ruff linter. This ensures that the codebase adheres to stricter import hygiene.
  • Unused Import Cleanup: Numerous unused import statements have been removed across a wide range of Python files, including documentation extensions, test files, and core tmt modules, to comply with the newly enforced linter rule.
  • Import Refactoring: Some tmt.utils imports were refactored to explicitly alias specific components (e.g., ShellScript as ShellScript) to prevent them from being flagged as unused by the linter, even when they were intended for re-export or specific usage patterns.
Changelog
  • docs/ext/generate_plugins.py
    • Removed unused import of tmt.utils.
  • docs/ext/generate_test_runner_guest_matrix.py
    • Removed unused import of tmt.steps.provision.
  • docs/ext/tmt_setup.py
    • Removed unused imports of subprocess and pathlib.Path.
  • pyproject.toml
    • Removed F401 (unused imports check) from the ruff.ignore list, enabling the check.
  • tests/core/web-link/test.py
    • Removed unused import of tmt.utils.
  • tests/unit/artifact/conftest.py
    • Removed unused import of CoprRepositoryProvider.
  • tests/unit/artifact/test_brew.py
    • Removed unused import of GeneralError from tmt.utils.
  • tests/unit/artifact/test_file.py
    • Removed unused imports of tmt.log, PackageAsFileArtifactInfo, and PackageAsFileArtifactProvider.
  • tests/unit/artifact/test_repository.py
    • Removed unused import of RepositoryFileProvider and PrepareError, RunError from tmt.utils.
  • tests/unit/test_beakerlib.py
    • Removed unused import of tmt.
  • tests/unit/test_config.py
    • Removed unused import of unittest.
  • tests/unit/test_data_size_validation.py
    • Removed unused imports of tmt.log and pint.Quantity.
  • tests/unit/test_exception_rendering.py
    • Removed unused import of pytest.
  • tests/unit/test_file_require.py
    • Removed unused import of tmt.
  • tests/unit/test_guest.py
    • Removed unused imports of tmt and GeneralError from tmt.utils.
  • tests/unit/test_hardware.py
    • Removed unused import of tmt.steps.
  • tests/unit/test_template.py
    • Removed multiple unused tmt related imports.
  • tests/unit/test_utils.py
    • Removed unused import of tmt.config.
  • tmt/main.py
    • Removed unused import of tmt.cli._root.
  • tmt/base.py
    • Removed unused imports of operator and tmt.plugins.
  • tmt/cli/_root.py
    • Removed unused import of tmt.plugins.
  • tmt/convert.py
    • Removed unused import of tmt.export.
  • tmt/export/init.py
    • Refactored import tmt to import tmt as tmt.
  • tmt/export/_dict.py
    • Removed unused import of tmt.utils.
  • tmt/export/_json.py
    • Removed unused import of tmt.utils.
  • tmt/export/nitrate.py
    • Removed unused imports of tmt.identifier and tmt.utils.git.
  • tmt/export/polarion.py
    • Removed unused imports of tmt.convert and tmt.utils.
  • tmt/export/rst.py
    • Removed unused import of tmt.utils.
  • tmt/libraries/init.py
    • Refactored import tmt to import tmt as tmt.
  • tmt/libraries/beakerlib.py
    • Removed unused import of tmt.
  • tmt/libraries/file.py
    • Removed unused imports of fmf and tmt.
  • tmt/lint.py
    • Updated type-checking import for tmt.base to pass.
  • tmt/package_managers/init.py
    • Refactored import tmt to import tmt as tmt.
  • tmt/result.py
    • Removed unused import of fmf.
  • tmt/steps/cleanup/init.py
    • Refactored import tmt to import tmt as tmt.
  • tmt/steps/cleanup/internal.py
    • Removed unused import of tmt.
  • tmt/steps/discover/fmf.py
    • Removed unused imports of contextlib and tmt.utils.url.
  • tmt/steps/execute/internal.py
    • Removed numerous unused imports including os, textwrap, jinja2, tmt, tmt.options, tmt.steps.scripts, safe_filename, EnvVarValue, Path, and TransferOptions.
  • tmt/steps/execute/upgrade.py
    • Removed unused imports of tmt.result, tmt.steps.discover.fmf, and tmt.steps.execute.
  • tmt/steps/finish/shell.py
    • Removed unused import of tmt.
  • tmt/steps/prepare/init.py
    • Refactored import tmt to import tmt as tmt.
  • tmt/steps/prepare/ansible.py
    • Removed unused import of tmt.
  • tmt/steps/prepare/artifact/providers/init.py
    • Refactored tmt.utils imports to explicitly alias ShellScript and retry.
  • tmt/steps/prepare/artifact/providers/brew.py
    • Removed unused imports of Sequence, Any, and ClassVar from typing.
  • tmt/steps/prepare/artifact/providers/copr_build.py
    • Removed unused import of requests.
  • tmt/steps/prepare/artifact/providers/koji.py
    • Removed unused imports of ClassVar, Union from typing and ArtifactInfo from tmt.steps.prepare.artifact.providers.
  • tmt/steps/prepare/artifact/providers/repository.py
    • Removed unused import of GeneralError from tmt.utils.
  • tmt/steps/prepare/distgit.py
    • Removed unused import of tmt.
  • tmt/steps/prepare/feature/init.py
    • Refactored import tmt to import tmt as tmt.
  • tmt/steps/prepare/install.py
    • Removed unused imports of fmf, tmt, tmt.options, and tmt.package_managers.
  • tmt/steps/prepare/shell.py
    • Removed unused imports of fmf and tmt.
  • tmt/steps/provision/init.py
    • Refactored tmt.utils imports to explicitly alias OUTPUT_WIDTH and format_timestamp.
  • tmt/steps/provision/artemis.py
    • Removed unused imports of tmt.hardware, tmt.options, and Path from tmt.utils.
  • tmt/steps/provision/bootc.py
    • Removed unused imports of tmt and tmt.base.
  • tmt/steps/provision/local.py
    • Removed unused import of tmt.base.
  • tmt/steps/provision/mock.py
    • Removed unused import of tmt.base.
  • tmt/steps/provision/mrack.py
    • Removed unused imports of tmt, tmt.options, GuestLogError, and UpdatableMessage from tmt.utils.
  • tmt/steps/provision/podman.py
    • Removed unused import of tmt.base.
  • tmt/steps/provision/testcloud.py
    • Removed unused imports of shlex, pint, and GuestLogError from tmt.utils.
  • tmt/steps/report/display.py
    • Removed unused import of tmt.
  • tmt/steps/report/html.py
    • Removed unused import of tmt.
  • tmt/steps/scripts.py
    • Removed numerous unused imports including tmt, tmt.base, tmt.steps, tmt.utils.signals, and tmt.utils.wait.
  • tmt/templates/init.py
    • Refactored import tmt to import tmt as tmt.
  • tmt/trying.py
    • Removed unused import of tmt.steps.prepare.
  • tmt/utils/templates.py
    • Removed unused import of fmf.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enables the ruff check for unused imports (F401) and removes a large number of unused imports across the codebase. This is a great cleanup that improves code quality and maintainability. My review includes a couple of suggestions to improve the readability of how some imports are handled, but overall the changes are excellent.

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
from tmt.utils import GeneralError, Path
from tmt.utils import ShellScript as ShellScript
from tmt.utils import retry as retry
from tmt.utils import GeneralError, Path, ShellScript, retry # noqa: F401
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, what was going on here?

from typing import Any, Optional, Union

import tmt
import tmt as tmt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wanted to look into why it was recommending this. My only assumption is that it is

If an import statement is used to re-export a symbol as part of a module's public interface, consider using a "redundant" import alias, which instructs Ruff (and other tools) to respect the re-export, and avoid marking it as unused, as in:

from module import member as member

But that doesn't seem right in these cases.

Incidentally it does suggest a workaround of

Alternatively, you can use all to declare a symbol as part of the module's interface, as in:

# __init__.py
import some_module

__all__ = ["some_module"]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although would like it if we used

from tmt import utils

as ways to make the namespaces a bit shorter when we otherwise use tmt.utils.GeneralError -> utils.GeneralError

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer dropping those unused imports, even if they serve as "reimports", which does not seem to be very common in our code. Shortened version - utils.GeneralError - does not look appealing to me, it seems like it can be very puzzling among the rest tmt.foo imports.

GeneralError itself would be acceptable without the namespace entirely, like other common and frequently used names - Command, Plan, etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer dropping those unused imports, even if they serve as "reimports", which does not seem to be very common in our code.

Yes, and the key issue is to find why did ruff consider this as a re-import. If we are genuinely re-importing (which I doubt because it would mean we are calling import tmt.utils.tmt, but there are genuine leftover cases like from tmt.utils import Path) then I think patching the usage would make it work.

Shortened version - utils.GeneralError - does not look appealing to me, it seems like it can be very puzzling among the rest tmt.foo imports.

GeneralError itself would be acceptable without the namespace entirely, like other common and frequently used names - Command, Plan, etc.

We will easily get too swamped with all of the from ... import. I would rather call from tmt.utils import error and error.GeneralError wherever we have clearly defined namespaced packages where we can do that. base.Command, base.Plan do not feel like a bad compromise.

@psss psss self-assigned this Feb 12, 2026
@psss psss added this to the 1.68 milestone Feb 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: backlog

Development

Successfully merging this pull request may close these issues.

3 participants