-
-
Notifications
You must be signed in to change notification settings - Fork 632
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
Add @frozen_after_init
decorator to make some @dataclass uses safer with V2
#8431
Merged
Eric-Arellano
merged 5 commits into
pantsbuild:master
from
Eric-Arellano:freeze-after-init
Oct 9, 2019
Merged
Add @frozen_after_init
decorator to make some @dataclass uses safer with V2
#8431
Eric-Arellano
merged 5 commits into
pantsbuild:master
from
Eric-Arellano:freeze-after-init
Oct 9, 2019
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Eric-Arellano
requested review from
stuhood,
jsirois,
benjyw,
illicitonion and
cosmicexplorer
October 9, 2019 17:47
cosmicexplorer
approved these changes
Oct 9, 2019
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 so much!!!
Co-Authored-By: Danny McClanahan <1305167+cosmicexplorer@users.noreply.github.com>
benjyw
approved these changes
Oct 9, 2019
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.
NEAT!
Eric-Arellano
changed the title
Add
Add Oct 9, 2019
@freeze_after_init
decorator to make some @dataclass uses safer with V2@frozen_after_init
decorator to make some @dataclass uses safer with V2
Eric-Arellano
force-pushed
the
freeze-after-init
branch
from
October 9, 2019 18:35
71f55b6
to
88f31cd
Compare
Eric-Arellano
added a commit
that referenced
this pull request
Oct 10, 2019
Builds off of #8362, this time tackling trickier instances. This introduces a new idiom of using `@dataclass(unsafe_hash=True)`. Certain custom `__new__` implementations could not be implemented using either the normal dataclass auto-generated `__init__()` nor through `__post_init__()`. When `frozen=True`, it is impossible to implement your own `__init__()` because you cannot set attribute values. So, we cannot use `frozen=True` but still must have a hash to work with V2. `unsafe_hash=True` does this for us. We use `@frozen_after_init` from #8431 to ensure that we don't accidentally mutate the object after.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
In #8423 (comment), we realized the need to be able to not always use
frozen=True
when using dataclasses for the V2 engine. Specifically, when we need a custom__init__()
, we cannot havefrozen=True
because__init__()
must be able to mutate the object's attributes.However, we still want to keep the benefits of
frozen=True
as much as possible. After we create the object, we do not want to allow any additional modifications. This is important because the V2 engine uses the__hash__()
of an object to determine its node ID - if the object mutates after creation, the ID will become invalid.Solution
As suggested in #8423 (comment), introduce a new decorator
@frozen_after_init
that only allows setting attributes in the__init__()
and then marks the object as frozen after.This is done by setting a flag in the
__init__()
to mark that the object should there-on-out be frozen. Then, we modify__setattr__()
to check for that flag to prohibit any mutations other than those in the__init__()
.Result
@dataclass(unsafe_hash=True)
can now be marked with@frozen_after_init
so that we can have the custom__init__()
s but not lose the benefits offrozen=True
.This also works on any arbitrary class.
We do not yet enforce that dataclasses must use this attribute (or
frozen=True
), which is left for #8181.