diff --git a/src/checkers/filesystem.rs b/src/checkers/filesystem.rs index 343901261c..2c854328c4 100644 --- a/src/checkers/filesystem.rs +++ b/src/checkers/filesystem.rs @@ -13,7 +13,7 @@ pub fn check_file_path( // flake8-no-pep420 if settings.rules.enabled(&Rule::ImplicitNamespacePackage) { - if let Some(diagnostic) = implicit_namespace_package(path, package) { + if let Some(diagnostic) = implicit_namespace_package(path, package, &settings.src) { diagnostics.push(diagnostic); } } diff --git a/src/rules/flake8_no_pep420/rules.rs b/src/rules/flake8_no_pep420/rules.rs index 52ef33806d..5bff1476f1 100644 --- a/src/rules/flake8_no_pep420/rules.rs +++ b/src/rules/flake8_no_pep420/rules.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::path::{Path, PathBuf}; use ruff_macros::derive_message_formats; @@ -19,8 +19,19 @@ impl Violation for ImplicitNamespacePackage { } /// INP001 -pub fn implicit_namespace_package(path: &Path, package: Option<&Path>) -> Option { - if package.is_none() && path.extension().map_or(true, |ext| ext != "pyi") { +pub fn implicit_namespace_package( + path: &Path, + package: Option<&Path>, + src: &[PathBuf], +) -> Option { + if package.is_none() + // Ignore `.pyi` files, which don't require an `__init__.py`. + && path.extension().map_or(true, |ext| ext != "pyi") + // Ignore any files that are direct children of a source directory (e.g., `src/manage.py`). + && !path + .parent() + .map_or(false, |parent| src.iter().any(|src| src == parent)) + { #[cfg(all(test, windows))] let path = path .to_string_lossy()