-
Notifications
You must be signed in to change notification settings - Fork 8
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
Readonly settings #169
Readonly settings #169
Conversation
f07790f
to
3c74d7c
Compare
This seems to be a terrible idea... I'm getting weird errors where other Settings objects now think they're readonly when they're not. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #169 +/- ##
==========================================
+ Coverage 99.21% 99.22% +0.01%
==========================================
Files 36 36
Lines 1911 1938 +27
==========================================
+ Hits 1896 1923 +27
Misses 15 15 ☔ View full report in Codecov by Sentry. |
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.
I think we should use the pydantic functionality to make settings immutable. That way we raise an error if a user mutates something.
I think that
>>> protocol.settings.mysetting
'foo'
>>> protocol.settings.mysetting = "bar"
>>> protocol.settings.mysetting
'foo'
is much riskier for users than
>>> protocol.settings.mysetting
'foo'
>>> protocol.settings.mysetting = "bar"
TypeError: 'Settings' is immutable and does not support type assignment
@dwhswenson I tried that originally. I had this in place: But you ended up with very strange behaviour, where "brand new" Settings objects were readonly, see here: https://github.com/OpenFreeEnergy/gufe/actions/runs/4628556994/jobs/8187777193#step:7:886 I never quite figured it out, but it felt like the readonly was applying to all instances of the class, rather than a given instance of the class |
6f81b96
to
2b610dd
Compare
@dwhswenson thanks for the improvement. I'm waiting on merging this as it causes a few headaches downstream in openfe. In |
todo: add unfreeze |
2b610dd
to
38e3e90
Compare
Hello @richardjgowers! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:
Comment last updated at 2024-01-25 10:42:08 UTC |
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.
Mostly LGTM -- requesting small additional tests that aren't testing nested behavior, mainly so that no future refactors accidentally break things.
@@ -13,8 +13,8 @@ | |||
class TestAlchemicalNetwork(GufeTokenizableTestsMixin): | |||
|
|||
cls = AlchemicalNetwork | |||
key = "AlchemicalNetwork-8c6df17d7ecf5902e2e338984cc11140" | |||
repr = "<AlchemicalNetwork-8c6df17d7ecf5902e2e338984cc11140>" | |||
key = "AlchemicalNetwork-d1035e11493ca60ff7bac5171eddfee3" |
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.
Just checking: is this changing the gufe key because you've changed the fixture to use non-None
settings? (Otherwise, nothing in this PR should affect gufe keys, right?)
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.
yep it's this
@@ -53,3 +53,45 @@ def test_invalid_constraint(value, good): | |||
else: | |||
with pytest.raises(ValueError): | |||
_ = OpenMMSystemGeneratorFFSettings(constraints=value) | |||
|
|||
|
|||
class TestFreezing: |
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.
Current tests check that it works we do settings.subsettings.item = ...
. Could you add a test that does settings.subsettings = ...
? (example: you attempt to replace the entire thermo_settings
in one go).
gufe/protocols/protocol.py
Outdated
"""The full settings for this ``Protocol`` instance.""" | ||
return self._settings | ||
"""A copy of the full settings for this ``Protocol`` instance. This is read only""" | ||
return self._settings.frozen_copy() |
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.
this is probably overzealous and causes a copy on each access right?
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.
With the extra test added, LGTM!
type[A] is the correct way to indicate A or a subclass thereof
must use Settings now
setting __config__.allow_mutation was giving bizarre behaviour temporarily retreat from that madness and instead `Protocol.settings` returns a deepcopy it ain't perfect but it'll stop some things
tests for freezing behaviour
avoids copy on each access, probably saves some time in a `Protocol.settings` heavy access pattern
d771889
to
8f1476d
Compare
Adds
Settings.frozen_copy
andSettings.unfrozen_copy
to create immutable/mutable versions of Settings object. These freezes are recursive and apply to all contained Settings too.Protocols now freeze their Settings on creation. This should stop mistakes around modifying a Protocol's Settings in place.