Skip to content

Commit

Permalink
Use Iterable as the container component type, so that any iterable of…
Browse files Browse the repository at this point in the history
… hashable objects can be passed, but still convert to frozenset underneath.
  • Loading branch information
tonyandrewmeyer committed Jul 22, 2024
1 parent 4209071 commit 405e5b5
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
venv/
build/
docs/build/
docs/_build/
*.charm
.tox/
.coverage
Expand Down
1 change: 1 addition & 0 deletions docs/custom_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,4 +310,5 @@ def _compute_navigation_tree(context):
('py:class', '_CharmSpec'),
('py:class', 'scenario.state._DCBase'),
('py:class', 'scenario.state._EntityStatus'),
('py:class', 'scenario.state._max_posargs.<locals>._MaxPositionalArgs'),
]
22 changes: 11 additions & 11 deletions scenario/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
Final,
FrozenSet,
Generic,
Iterable,
List,
Literal,
Optional,
Expand Down Expand Up @@ -1210,34 +1211,34 @@ class State(_max_posargs(0)):
default_factory=dict,
)
"""The present configuration of this charm."""
relations: FrozenSet["AnyRelation"] = dataclasses.field(default_factory=frozenset)
relations: Iterable["AnyRelation"] = dataclasses.field(default_factory=frozenset)
"""All relations that currently exist for this charm."""
networks: FrozenSet[Network] = dataclasses.field(default_factory=frozenset)
networks: Iterable[Network] = dataclasses.field(default_factory=frozenset)
"""Manual overrides for any relation and extra bindings currently provisioned for this charm.
If a metadata-defined relation endpoint is not explicitly mapped to a Network in this field,
it will be defaulted.
[CAVEAT: `extra-bindings` is a deprecated, regretful feature in juju/ops. For completeness we
support it, but use at your own risk.] If a metadata-defined extra-binding is left empty,
it will be defaulted.
"""
containers: FrozenSet[Container] = dataclasses.field(default_factory=frozenset)
containers: Iterable[Container] = dataclasses.field(default_factory=frozenset)
"""All containers (whether they can connect or not) that this charm is aware of."""
storages: FrozenSet[Storage] = dataclasses.field(default_factory=frozenset)
storages: Iterable[Storage] = dataclasses.field(default_factory=frozenset)
"""All ATTACHED storage instances for this charm.
If a storage is not attached, omit it from this listing."""

# we don't use sets to make json serialization easier
opened_ports: FrozenSet[_Port] = dataclasses.field(default_factory=frozenset)
opened_ports: Iterable[_Port] = dataclasses.field(default_factory=frozenset)
"""Ports opened by juju on this charm."""
leader: bool = False
"""Whether this charm has leadership."""
model: Model = Model()
"""The model this charm lives in."""
secrets: FrozenSet[Secret] = dataclasses.field(default_factory=frozenset)
secrets: Iterable[Secret] = dataclasses.field(default_factory=frozenset)
"""The secrets this charm has access to (as an owner, or as a grantee).
The presence of a secret in this list entails that the charm can read it.
Whether it can manage it or not depends on the individual secret's `owner` flag."""
resources: FrozenSet[Resource] = dataclasses.field(default_factory=frozenset)
resources: Iterable[Resource] = dataclasses.field(default_factory=frozenset)
"""All resources that this charm can access."""
planned_units: int = 1
"""Number of non-dying planned units that are expected to be running this application.
Expand All @@ -1249,7 +1250,7 @@ class State(_max_posargs(0)):
# to this list.
deferred: List["DeferredEvent"] = dataclasses.field(default_factory=list)
"""Events that have been deferred on this charm by some previous execution."""
stored_states: FrozenSet["StoredState"] = dataclasses.field(
stored_states: Iterable["StoredState"] = dataclasses.field(
default_factory=frozenset,
)
"""Contents of a charm's stored state."""
Expand Down Expand Up @@ -1306,9 +1307,8 @@ def __post_init__(self):
"stored_states",
]:
val = getattr(self, name)
# We check for "not frozenset" rather than "is set" so that you can
# actually pass a tuple or list or really any iterable of hashable
# objects, and it will end up as a frozenset.
# It's ok to pass any iterable (of hashable objects), but you'll get
# a frozenset as the actual attribute.
if not isinstance(val, frozenset):
object.__setattr__(self, name, frozenset(val))

Expand Down

0 comments on commit 405e5b5

Please sign in to comment.