diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8096a0d1a4cf85..b530176a21d951 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -911,9 +911,5 @@ There are three ways in which an import can be categorized as "first-party": the `src` setting and, for each directory, check for the existence of a subdirectory `foo` or a file `foo.py`. -By default, `src` is set to the project root. In the above example, we'd want to set -`src = ["./src"]` to ensure that we locate `./my_project/src/foo` and thus categorize `import foo` -as first-party in `baz.py`. In practice, for this limited example, setting `src = ["./src"]` is -unnecessary, as all imports within `./my_project/src/foo` would be categorized as first-party via -the same-package heuristic; but if your project contains multiple packages, you'll want to set `src` -explicitly. +By default, `src` is set to the project root, along with `"src"` subdirectory in the project root. +This ensures that Ruff supports both flat and "src" layouts out of the box diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index 6e94612b03083b..ded96edf7d1678 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -271,7 +271,6 @@ impl Configuration { .chain(lint.extend_per_file_ignores) .collect(), )?, - fix_safety: FixSafetyTable::from_rule_selectors( &lint.extend_safe_fixes, &lint.extend_unsafe_fixes, @@ -280,8 +279,9 @@ impl Configuration { require_explicit: false, }, ), - - src: self.src.unwrap_or_else(|| vec![project_root.to_path_buf()]), + src: self + .src + .unwrap_or_else(|| vec![project_root.to_path_buf(), project_root.join("src")]), explicit_preview_rules: lint.explicit_preview_rules.unwrap_or_default(), task_tags: lint diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index db52812c013271..431dce58a1fbb0 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -323,7 +323,7 @@ pub struct Options { /// The directories to consider when resolving first- vs. third-party /// imports. /// - /// As an example: given a Python package structure like: + /// As an example, given a Python package structure like: /// /// ```text /// my_project @@ -341,15 +341,17 @@ pub struct Options { /// /// When omitted, the `src` directory will typically default to the /// directory containing the nearest `pyproject.toml`, `ruff.toml`, or - /// `.ruff.toml` file (the "project root"), unless a configuration file - /// is explicitly provided (e.g., via the `--config` command-line flag). + /// `.ruff.toml` file (the "project root") along with a `"src"` subdirectory, + /// unless a configuration file is explicitly provided (e.g., via the + /// `--config` command-line flag). These defaults ensure that uv supports both + /// flat layouts and `src` layouts (as seen above) out of the box. /// /// This field supports globs. For example, if you have a series of Python /// packages in a `python_modules` directory, `src = ["python_modules/*"]` - /// would expand to incorporate all of the packages in that directory. User - /// home directory and environment variables will also be expanded. + /// would expand to incorporate all packages in that directory. User home + /// directory and environment variables will also be expanded. #[option( - default = r#"["."]"#, + default = r#"[".", "src"]"#, value_type = "list[str]", example = r#" # Allow imports relative to the "src" and "test" directories. diff --git a/ruff.schema.json b/ruff.schema.json index 83b27a24f71cf2..c0373933f42a96 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -671,7 +671,7 @@ ] }, "src": { - "description": "The directories to consider when resolving first- vs. third-party imports.\n\nAs an example: given a Python package structure like:\n\n```text my_project ├── pyproject.toml └── src └── my_package ├── __init__.py ├── foo.py └── bar.py ```\n\nThe `./src` directory should be included in the `src` option (e.g., `src = [\"src\"]`), such that when resolving imports, `my_package.foo` is considered a first-party import.\n\nWhen omitted, the `src` directory will typically default to the directory containing the nearest `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file (the \"project root\"), unless a configuration file is explicitly provided (e.g., via the `--config` command-line flag).\n\nThis field supports globs. For example, if you have a series of Python packages in a `python_modules` directory, `src = [\"python_modules/*\"]` would expand to incorporate all of the packages in that directory. User home directory and environment variables will also be expanded.", + "description": "The directories to consider when resolving first- vs. third-party imports.\n\nAs an example, given a Python package structure like:\n\n```text my_project ├── pyproject.toml └── src └── my_package ├── __init__.py ├── foo.py └── bar.py ```\n\nThe `./src` directory should be included in the `src` option (e.g., `src = [\"src\"]`), such that when resolving imports, `my_package.foo` is considered a first-party import.\n\nWhen omitted, the `src` directory will typically default to the directory containing the nearest `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file (the \"project root\") along with a `\"src\"` subdirectory, unless a configuration file is explicitly provided (e.g., via the `--config` command-line flag). These defaults ensure that uv supports both flat layouts and `src` layouts (as seen above) out of the box.\n\nThis field supports globs. For example, if you have a series of Python packages in a `python_modules` directory, `src = [\"python_modules/*\"]` would expand to incorporate all packages in that directory. User home directory and environment variables will also be expanded.", "type": [ "array", "null"