Skip to content

Relative paths in per-file-ignores not respected when running ruff outside working directory using --config with pyproject.toml #12058

Open
@mihirsamdarshi

Description

Description

I noticed this (potential) issue while debugging koxudaxi/ruff-pycharm-plugin#359 for PyCharm. It's may be expected behavior, so please close this issue if so.

When running ruff from a directory that is not the same as the one containing the pyproject.toml file and specifying the --config option, the relative paths specified in the pyproject.toml's per-file-ignores configuration are not respected.

This normally isn't a problem, since the pyproject.toml lives in the root of project files, but I have a full-stack application where the python source code does not live in the source code (see the issue above). I open this root folder in PyCharm. Unfortunately, the ruff-pycharm-plugin runs ruff from the project's root directory, and therefore needs to pass the --config parameter.

Steps to Reproduce

  1. Create a new project, and install ruff

    ❯ rye init example-project
    ❯ cd example-project
    ❯ uv venv && source .venv/bin/activate # or `rye sync`
    ❯ uv pip install ruff
    ❯ example-project/.venv/bin/ruff --version
    ruff 0.4.10
  2. In example-project/pyproject.toml, configure per-file-ignores with relative paths:

    [tool.ruff.lint]
    # The default `rye` project will error on `D103` and `D104` when select = ["ALL"] is used
    select = ["ALL"]
    
    [tool.ruff.lint.per-file-ignores]
    "./src/example_project/__init__.py" = ["D104"]
  3. Deactivate the venv, verify that the ruff check command's output is correct from the project's working directory.

    ❯ deactivate
    ❯ .venv/bin/ruff check --config pyproject.toml src/
    warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`.
    warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
    example-project/src/example_project/__init__.py:1:5: D103 Missing docstring in public function
    Found 1 error.
    
  4. Navigate up a directory, then run ruff check again

    cd ..
    ❯ example-project/.venv/bin/ruff check example-project/src/ --config example-project/pyproject.toml
    warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`.
    warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`.
    example-project/src/example_project/__init__.py:1:1: D104 Missing docstring in public package
    example-project/src/example_project/__init__.py:1:5: D103 Missing docstring in public function
    Found 2 errors.

Environment

  • Ruff version: 0.4.10
  • OS: macOS 14.5
  • Shell: fish

Possible Solution

Consider adjusting how ruff resolves relative paths in the per-file-ignores configuration. It may need to use the directory of the pyproject.toml file as the base for resolving these paths, rather than the current working directory.

Activity

MichaReiser

MichaReiser commented on Jun 27, 2024

@MichaReiser
Member

Thanks for the very detailed issue!

I had a quick look at the code and I can confirm that paths are always relative to the root directory.

extend_exclude: options
.extend_exclude
.map(|paths| {
paths
.into_iter()
.map(|pattern| {
let absolute = fs::normalize_path_to(&pattern, project_root);
FilePattern::User(pattern, absolute)
})
.collect()
})
.unwrap_or_default(),
extend_include: options
.extend_include
.map(|paths| {
paths
.into_iter()
.map(|pattern| {
let absolute = fs::normalize_path_to(&pattern, project_root);
FilePattern::User(pattern, absolute)
})
.collect()
})
.unwrap_or_default(),
include: options.include.map(|paths| {
paths
.into_iter()
.map(|pattern| {
let absolute = fs::normalize_path_to(&pattern, project_root);
FilePattern::User(pattern, absolute)
})
.collect()
}),
fix: options.fix,

I'm not entirely sure why the paths are relative to the root and not the configuration. @charliermarsh do you know more about the design decision?

mihirsamdarshi

mihirsamdarshi commented on Jul 13, 2024

@mihirsamdarshi
Author

@MichaReiser If I submitted a patch would that be helpful/accepted? Should I wait for @charliermarsh's input?

MichaReiser

MichaReiser commented on Jul 13, 2024

@MichaReiser
Member

@mihirsamdarshi, I would prefer to hear @charliermarsh's opinion first. I'm not very familiar with that part of Ruff and the configuration schema is kind of complicated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    configurationRelated to settings and configuration

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Relative paths in `per-file-ignores` not respected when running `ruff` outside working directory using `--config` with `pyproject.toml` · Issue #12058 · astral-sh/ruff