[ruff] Respect lint.pydocstyle.property-decorators in RUF066 (#22515)

Resolves #22216.

This diff makes `RUF066` (`property-without-return`) respect the
`lint.pydocstyle.property-decorators` setting. `RUF066` is now
consistent with other rules that check for property methods like
`PLR0206`, `D401`, `PLR6301`, and `DOC201`
This commit is contained in:
liam
2026-01-14 16:02:24 -05:00
committed by GitHub
parent b79e9bac14
commit 1bd5ff77d0
4 changed files with 61 additions and 1 deletions

View File

@@ -0,0 +1,15 @@
from my_library import custom_property
class Example:
@custom_property
def missing_return(self): # ERROR: No return
x = 1
@custom_property
def with_return(self): # OK: Has return
return 1
@property
def builtin_property(self): # ERROR: No return (builtin @property still works)
x = 1

View File

@@ -19,6 +19,7 @@ mod tests {
use crate::pyproject_toml::lint_pyproject_toml;
use crate::registry::Rule;
use crate::rules::pydocstyle::settings::Settings as PydocstyleSettings;
use crate::settings::LinterSettings;
use crate::settings::types::{CompiledPerFileIgnoreList, PerFileIgnore, PreviewMode};
use crate::test::{test_path, test_resource_path};
@@ -235,6 +236,24 @@ mod tests {
Ok(())
}
#[test]
fn property_without_return_custom_decorator() -> Result<()> {
let diagnostics = test_path(
Path::new("ruff/RUF066_custom_property_decorator.py"),
&LinterSettings {
pydocstyle: PydocstyleSettings {
property_decorators: ["my_library.custom_property".to_string()]
.into_iter()
.collect(),
..PydocstyleSettings::default()
},
..LinterSettings::for_rule(Rule::PropertyWithoutReturn)
},
)?;
assert_diagnostics!(diagnostics);
Ok(())
}
#[test]
fn confusables() -> Result<()> {
let diagnostics = test_path(

View File

@@ -29,6 +29,10 @@ use crate::{FixAvailability, Violation};
/// return f"{self.first_name} {self.last_name}"
/// ```
///
/// ## Options
///
/// - `lint.pydocstyle.property-decorators`
///
/// ## References
/// - [Python documentation: The property class](https://docs.python.org/3/library/functions.html#property)
#[derive(ViolationMetadata)]
@@ -62,7 +66,8 @@ pub(crate) fn property_without_return(checker: &Checker, function_def: &StmtFunc
..
} = function_def;
if !visibility::is_property(decorator_list, [], semantic)
let extra_property_decorators = checker.settings().pydocstyle.property_decorators();
if !visibility::is_property(decorator_list, extra_property_decorators, semantic)
|| visibility::is_overload(decorator_list, semantic)
|| function_type::is_stub(function_def, semantic)
{

View File

@@ -0,0 +1,21 @@
---
source: crates/ruff_linter/src/rules/ruff/mod.rs
---
RUF066 `missing_return` is a property without a `return` statement
--> RUF066_custom_property_decorator.py:6:9
|
4 | class Example:
5 | @custom_property
6 | def missing_return(self): # ERROR: No return
| ^^^^^^^^^^^^^^
7 | x = 1
|
RUF066 `builtin_property` is a property without a `return` statement
--> RUF066_custom_property_decorator.py:14:9
|
13 | @property
14 | def builtin_property(self): # ERROR: No return (builtin @property still works)
| ^^^^^^^^^^^^^^^^
15 | x = 1
|