Skip to content

Commit b22d424

Browse files
yangdanny97meta-codesync[bot]
authored andcommitted
skip dunder for missing override decorator check
Summary: fixes #3413 Reviewed By: grievejia Differential Revision: D105349466 fbshipit-source-id: e53d0ee75ba73de07f90b59990e0d98895b4b822
1 parent 9b38ee1 commit b22d424

3 files changed

Lines changed: 34 additions & 3 deletions

File tree

pyrefly/lib/alt/class/class_field.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3600,6 +3600,7 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> {
36003600
if !is_explicit_override
36013601
&& parent_attr_found
36023602
&& !parent_has_any
3603+
&& !is_dunder(field_name.as_str())
36033604
&& class_field.can_have_override_decorator()
36043605
{
36053606
self.error(

pyrefly/lib/test/class_overrides.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,10 +1182,10 @@ testcase!(
11821182
TestEnv::new().enable_missing_override_decorator_error(),
11831183
r#"
11841184
class Base:
1185-
def __str__(self) -> str: ... # E: overrides a member in a parent class but is missing an `@override` decorator
1185+
def __str__(self) -> str: ... # OK
11861186
11871187
class Derived(Base):
1188-
def __str__(self) -> str: ... # E: overrides a member in a parent class but is missing an `@override` decorator
1188+
def __str__(self) -> str: ... # OK
11891189
"#,
11901190
);
11911191

@@ -1235,6 +1235,36 @@ class B(A):
12351235
"#,
12361236
);
12371237

1238+
testcase!(
1239+
test_missing_override_decorator_dunder_from_object,
1240+
TestEnv::new().enable_missing_override_decorator_error(),
1241+
r#"
1242+
class A:
1243+
def __repr__(self) -> str:
1244+
return "A"
1245+
1246+
def __eq__(self, other: object) -> bool:
1247+
return True
1248+
1249+
def __str__(self) -> str:
1250+
return "A"
1251+
"#,
1252+
);
1253+
1254+
testcase!(
1255+
test_missing_override_decorator_dunder_from_non_object,
1256+
TestEnv::new().enable_missing_override_decorator_error(),
1257+
r#"
1258+
class Base:
1259+
def __len__(self) -> int:
1260+
return 0
1261+
1262+
class Child(Base):
1263+
def __len__(self) -> int:
1264+
return 1
1265+
"#,
1266+
);
1267+
12381268
testcase!(
12391269
test_missing_override_decorator_classvar,
12401270
TestEnv::new().enable_missing_override_decorator_error(),

website/docs/error-kinds.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ In this example, `os.bacarat` is treated as a module name, so failing to find it
10251025

10261026
## missing-override-decorator
10271027

1028-
A method overrides a parent class method but does not have the `@override` decorator.
1028+
A method overrides a parent class method but does not have the `@override` decorator. We do not emit this error for dunder methods.
10291029

10301030
This error supports strict override enforcement as specified in the [typing spec](https://typing.python.org/en/latest/spec/class-compat.html#strict-enforcement-per-project). When enabled, it requires all overriding methods to be explicitly marked with `@typing.override`.
10311031

0 commit comments

Comments
 (0)