Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow more immutable funcs for RUF009 #4660

Merged
merged 4 commits into from
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/ruff/resources/test/fixtures/ruff/RUF009.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class A:
fine_timedelta: datetime.timedelta = datetime.timedelta(hours=7)
fine_tuple: tuple[int] = tuple([1])
fine_regex: re.Pattern = re.compile(r".*")
fine_float: float = float('-inf')
fine_int: int = int(12)
fine_complex: complex = complex(1, 2)


DEFAULT_IMMUTABLETYPE_FOR_ALL_DATACLASSES = ImmutableType(40)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,37 +46,6 @@ B006_B008.py:119:30: B008 Do not perform function call in argument defaults
120 | ...
|

B006_B008.py:157:34: B008 Do not perform function call `float` in argument defaults
|
157 | def float_infinity_literal(value=float("1e999")):
| ^^^^^^^^^^^^^^ B008
158 | pass
|

B006_B008.py:162:30: B008 Do not perform function call `float` in argument defaults
Copy link
Member

@charliermarsh charliermarsh May 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably update these comments, they're not out-of-date, I think? (Can we also remove the special-casing code in the bugbear module, which should now be redundant?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow exactly on the comments. We settled on allowing float calls now right? So these snapshots can go.

I updated the comments in the .py fixture to reflect this. As for the Violating string it's formatted like so:

format!("Do not perform function call `{name}` in argument defaults")

So this needs no edit. Does that cover what you mean or are you referring to something else.

As for the special casing float logic, I'm removing it now!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I meant "they're out-of-date", not "they're not out-of-date". What you've done here looks correct to me.

Copy link
Contributor Author

@qdegraaf qdegraaf May 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah check, all good! Removed infinity/nan logic now as well.

|
162 | # But don't allow standard floats
163 | def float_int_is_wrong(value=float(3)):
| ^^^^^^^^ B008
164 | pass
|

B006_B008.py:166:45: B008 Do not perform function call `float` in argument defaults
|
166 | def float_str_not_inf_or_nan_is_wrong(value=float("3.14")):
| ^^^^^^^^^^^^^ B008
167 | pass
|

B006_B008.py:192:21: B008 Do not perform function call `float` in argument defaults
|
192 | # B006 and B008
193 | # We should handle arbitrary nesting of these B008.
194 | def nested_combo(a=[float(3), dt.datetime.now()]):
| ^^^^^^^^ B008
195 | pass
|

B006_B008.py:192:31: B008 Do not perform function call `dt.datetime.now` in argument defaults
|
192 | # B006 and B008
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,34 @@ RUF009.py:19:41: RUF009 Do not perform function call `default_function` in datac
23 | another_class_var: ClassVar[list[int]] = default_function()
|

RUF009.py:36:41: RUF009 Do not perform function call `default_function` in dataclass defaults
RUF009.py:39:41: RUF009 Do not perform function call `default_function` in dataclass defaults
|
36 | @dataclass
37 | class B:
38 | hidden_mutable_default: list[int] = default_function()
39 | @dataclass
40 | class B:
41 | hidden_mutable_default: list[int] = default_function()
| ^^^^^^^^^^^^^^^^^^ RUF009
39 | another_dataclass: A = A()
40 | not_optimal: ImmutableType = ImmutableType(20)
42 | another_dataclass: A = A()
43 | not_optimal: ImmutableType = ImmutableType(20)
|

RUF009.py:37:28: RUF009 Do not perform function call `A` in dataclass defaults
RUF009.py:40:28: RUF009 Do not perform function call `A` in dataclass defaults
|
37 | class B:
38 | hidden_mutable_default: list[int] = default_function()
39 | another_dataclass: A = A()
40 | class B:
41 | hidden_mutable_default: list[int] = default_function()
42 | another_dataclass: A = A()
| ^^^ RUF009
40 | not_optimal: ImmutableType = ImmutableType(20)
41 | good_variant: ImmutableType = DEFAULT_IMMUTABLETYPE_FOR_ALL_DATACLASSES
43 | not_optimal: ImmutableType = ImmutableType(20)
44 | good_variant: ImmutableType = DEFAULT_IMMUTABLETYPE_FOR_ALL_DATACLASSES
|

RUF009.py:38:34: RUF009 Do not perform function call `ImmutableType` in dataclass defaults
RUF009.py:41:34: RUF009 Do not perform function call `ImmutableType` in dataclass defaults
|
38 | hidden_mutable_default: list[int] = default_function()
39 | another_dataclass: A = A()
40 | not_optimal: ImmutableType = ImmutableType(20)
41 | hidden_mutable_default: list[int] = default_function()
42 | another_dataclass: A = A()
43 | not_optimal: ImmutableType = ImmutableType(20)
| ^^^^^^^^^^^^^^^^^ RUF009
41 | good_variant: ImmutableType = DEFAULT_IMMUTABLETYPE_FOR_ALL_DATACLASSES
42 | okay_variant: A = DEFAULT_A_FOR_ALL_DATACLASSES
44 | good_variant: ImmutableType = DEFAULT_IMMUTABLETYPE_FOR_ALL_DATACLASSES
45 | okay_variant: A = DEFAULT_A_FOR_ALL_DATACLASSES
|


3 changes: 3 additions & 0 deletions crates/ruff_python_semantic/src/analyze/typing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ pub fn is_immutable_annotation(model: &SemanticModel, expr: &Expr) -> bool {
}

const IMMUTABLE_FUNCS: &[&[&str]] = &[
&["", "float"],
&["", "int"],
&["", "complex"],
&["", "tuple"],
&["", "frozenset"],
&["datetime", "date"],
Expand Down