Skip to content

Comments

fix: use immutable types for state component attributes to reflect that they are immutable#2335

Draft
tonyandrewmeyer wants to merge 2 commits intocanonical:mainfrom
tonyandrewmeyer:state-types
Draft

fix: use immutable types for state component attributes to reflect that they are immutable#2335
tonyandrewmeyer wants to merge 2 commits intocanonical:mainfrom
tonyandrewmeyer:state-types

Conversation

@tonyandrewmeyer
Copy link
Collaborator

We expect all of the state attributes to be treated as immutable, but some are typed as dict. Clean that up so that although the attribute may be a dict, it is typed as Mapping, so that a type checker will flag people wrongly mutating the state.

Also adds a custom __init__ for Secret, which cleans up the private attributes (tracking revisions) and makes sure that the remote_grants mapping has frozenset items rather than set.

Copy link
Contributor

@james-garner-canonical james-garner-canonical left a comment

Choose a reason for hiding this comment

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

Changing from dict -> Mapping in the type annotations, and from set -> frozenset both in annotation and in actual code are technically not backwards compatible, though it should only be a problem if anyone is mutating their 'frozen' state. I'm in favour of making this change, but is there any due diligence we should do first?

Comment on lines +325 to +326
object.__setattr__(self, '_tracked_revision', 1)
object.__setattr__(self, '_latest_revision', 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

These lines aren't necessary since we set the attributes directly in the class direclaration.

object.__setattr__(self, 'rotate', rotate)
object.__setattr__(self, '_tracked_revision', 1)
object.__setattr__(self, '_latest_revision', 1)
_deepcopy_mutable_fields(self)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be unnecessary (and is inefficient) since we copy remote_grants manually above.

Comment on lines +319 to +320
remote_grants = {k: frozenset(v) for k, v in remote_grants.items()}
object.__setattr__(self, 'remote_grants', remote_grants)
Copy link
Contributor

Choose a reason for hiding this comment

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

I normally prefer the style that you have here, but I think we should stick to this pattern for consistency and clearer typing of the remote_grants variable.

Suggested change
remote_grants = {k: frozenset(v) for k, v in remote_grants.items()}
object.__setattr__(self, 'remote_grants', remote_grants)
object.__setattr__(
self, 'remote_grants', {k: frozenset(v) for k, v in remote_grants.items()}
)

@benhoyt
Copy link
Collaborator

benhoyt commented Feb 20, 2026

I'm in favour of making this change, but is there any due diligence we should do first?

Can we run type checking (and unit tests) on the supertox charms?

@tonyandrewmeyer
Copy link
Collaborator Author

Can we run type checking (and unit tests) on the supertox charms?

Yeah, I've done that before for other things. We also have the published charms list that get checked, although it still needs to love to handle the dropping of Python 3.8.

The trickiest part is having to do many variants, because it might be "lint" or "static" or variants of those.

@tonyandrewmeyer tonyandrewmeyer marked this pull request as draft February 20, 2026 00:05
@tonyandrewmeyer
Copy link
Collaborator Author

Discussing with James whether to continue with this branch/PR or to revive the previous one. Maybe we want to do more than just the changes in here.

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