-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[ty] synthesize __setattr__ for frozen dataclasses #19307
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
[ty] synthesize __setattr__ for frozen dataclasses #19307
Conversation
ebc8af1
to
dd1a59e
Compare
|
@sharkdp i could use some help understanding your comment here
did you mean to say raises instead returns? and if so, can you maybe expand a bit on your idea for differentiating based on the function body (which doesn't exist in the ast since it's synthesized), since as far as i understand it from this code a also as an aside, it looks like at runtime a from dataclasses import dataclass
@dataclass(frozen=True)
class Test:
b: int
test = Test(1)
test.a = 2 Traceback (most recent call last):
File "/Users/justinchapman/src/ruff/../test.py", line 8, in <module>
test.a = 2 # This will raise an error because the dataclass is frozen
^^^^^^
File "<string>", line 4, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'a' |
Yes
My idea was that we could distinguish between calling a user-defined Another way to do this would be to look up All of this would only be a way to provide a nicer error message. Something that mentions "frozen dataclass" instead of "custom
Ah, interesting. I think I probably just tried accessing an unknown member, not setting it. I think it would also be fine to emit the invalid-assignment diagnostic here instead of unresolved-attribute. What's more important is the thing above. |
3d9404a
to
e171a27
Compare
d0e8f67
to
c6fda6f
Compare
9c3c18b
to
f5bb268
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for this. Look, this found a new true positive!
attrs (https://github.com/python-attrs/attrs)
+ error[invalid-assignment] tests/test_next_gen.py:267:13: Property `c` defined in `C` is read-only
I made a few minor updates to bring this into a mergeable state. Most importantly, we can not skip the whole check for the frozen
flag, and can rely on __setattr__
alone. This leads to a big code improvement.
@sharkdp ah, awesome - thanks! i had planned to work on it a bit more, but if its good with you its good with me :) i appreciate you getting it merged is there anything else in astral-sh/ty#111 that you think would be good to work on next? one thing this is still missing i believe is emitting the same error for |
I noticed that it was still in draft, but it seemed like a good and consistent contribution. You're certainly welcome to add something on top of this!
Adding that would be great. I noticed that you already added a test for it.
Adding support for more of the synthesized methods/arguments would certainly be a good next step. I haven't looked closely at this, and maybe some of these might not require any special casing at all. The next thing I'd do would probably be to write a few more tests for these, even if they are initially still failing. That should give us an idea what to focus on next. Support for dataclass fields is another interesting area, but we're already working on this. |
Summary
Synthesize a
__setattr__
method with a return type ofNever
for frozen dataclasses.https://docs.python.org/3/library/dataclasses.html#frozen-instances
https://docs.python.org/3/library/dataclasses.html#dataclasses.FrozenInstanceError
Related
astral-sh/ty#111
#17974 (comment)
#18347 (comment)
WIP
Test Plan
New Markdown tests