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

Readonly settings #169

Merged
merged 18 commits into from
Jan 25, 2024
Merged

Readonly settings #169

merged 18 commits into from
Jan 25, 2024

Conversation

richardjgowers
Copy link
Contributor

@richardjgowers richardjgowers commented Apr 6, 2023

Adds Settings.frozen_copy and Settings.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.

@richardjgowers
Copy link
Contributor Author

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.

@IAlibay IAlibay requested a review from mikemhenry April 6, 2023 11:52
@codecov
Copy link

codecov bot commented Apr 6, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (c12bba6) 99.21% compared to head (8f1476d) 99.22%.

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.
📢 Have feedback on the report? Share it here.

Copy link
Member

@dwhswenson dwhswenson left a 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

@richardjgowers
Copy link
Contributor Author

@dwhswenson I tried that originally.

I had this in place:

f07790f

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

@richardjgowers richardjgowers changed the title Readonly settings [WIP] Readonly settings Apr 11, 2023
@richardjgowers
Copy link
Contributor Author

@dwhswenson thanks for the improvement. I'm waiting on merging this as it causes a few headaches downstream in openfe. In TestResultClient I get a lot of: E TypeError: Object of type DummySpecificSettings is not JSON serializable from within self._store_gufe_tokenizable and I've not had time to dig through and see what's happening there.

@richardjgowers
Copy link
Contributor Author

todo: add unfreeze

@pep8speaks
Copy link

pep8speaks commented Dec 18, 2023

Hello @richardjgowers! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

Line 92:80: E501 line too long (106 > 79 characters)

Comment last updated at 2024-01-25 10:42:08 UTC

@richardjgowers richardjgowers changed the title [WIP] Readonly settings Readonly settings Dec 18, 2023
Copy link
Member

@dwhswenson dwhswenson left a 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"
Copy link
Member

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?)

Copy link
Contributor Author

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:
Copy link
Member

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).

"""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()
Copy link
Contributor Author

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?

Copy link
Member

@dwhswenson dwhswenson left a 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
settings are immutable once inside a Protocol
settings are immutable once inside a Protocol
must use Settings now
richardjgowers and others added 11 commits January 25, 2024 10:41
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
@richardjgowers richardjgowers enabled auto-merge (squash) January 25, 2024 10:42
@richardjgowers richardjgowers merged commit 51e6812 into main Jan 25, 2024
10 checks passed
@richardjgowers richardjgowers deleted the readonly_settings branch January 25, 2024 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants