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

Remove sorting on attrdict key nesting #578

Merged
merged 4 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ Both the index and the values of the timeseries (both being date strings) should

|changed| `inbuilt` math -> `pre-defined` math and `custom` math -> `pre-defined` math in the documentation.

|changed| Calliope attribute dictionaries (AttrDicts) no longer sort dictionary keys on `union`. Key order is now: original dictionary key order + any new keys being added in the order they appear in the new dictionary.

### Internal changes

|new| `py.typed` file so that mypy recognises Calliope as a typed library when it is imported as a dependency.

|changed| GitHub action versions updated: `codecov/codecov-action` -> v4, `actions/checkout` -> v4, `dawidd6/action-download-artifact` -> v3.
Copy link
Member

Choose a reason for hiding this comment

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

Do we want CI changes in the changelog? We didn't in the past, but I realise some CI-related changes have been there since 0.7.0.dev2

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe we don't, you're right


|fixed| Spelling of Black config option `skip-magic-trailing-comma`.

## 0.7.0.dev2 (2024-01-26)

v0.7 includes a major change to how Calliope internally operates.
Expand Down
4 changes: 2 additions & 2 deletions src/calliope/attrdict.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ def to_yaml(self, path=None):

def keys_nested(self, subkeys_as="list"):
"""
Returns all keys in the AttrDict, sorted, including the keys of
Returns all keys in the AttrDict, including the keys of
nested subdicts (which may be either regular dicts or AttrDicts).

If ``subkeys_as='list'`` (default), then a list of
Expand All @@ -366,7 +366,7 @@ def keys_nested(self, subkeys_as="list"):

"""
keys = []
for k, v in sorted(self.items()):
for k, v in self.items():
# Check if dict instance (which AttrDict is too),
# and for non-emptyness of the dict
if isinstance(v, dict) and v:
Expand Down
18 changes: 15 additions & 3 deletions tests/test_core_attrdict.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def regular_dict(self):
d = {
"a": 1,
"b": 2,
"c": {"x": "foo", "y": "bar", "z": {"I": 1, "II": 2}},
"d": None,
"c": {"x": "foo", "y": "bar", "z": {"I": 1, "II": 2}},
}
return d

Expand Down Expand Up @@ -238,12 +238,12 @@ def test_as_dict_flat(self, attr_dict):
def test_keys_nested_as_list(self, attr_dict):
d = attr_dict
dd = d.keys_nested()
assert dd == ["a", "b", "c.x", "c.y", "c.z.I", "c.z.II", "d"]
assert dd == ["a", "b", "d", "c.x", "c.y", "c.z.I", "c.z.II"]

def test_keys_nested_as_dict(self, attr_dict):
d = attr_dict
dd = d.keys_nested(subkeys_as="dict")
assert dd == ["a", "b", {"c": ["x", "y", {"z": ["I", "II"]}]}, "d"]
assert dd == ["a", "b", "d", {"c": ["x", "y", {"z": ["I", "II"]}]}]

def test_union(self, attr_dict):
d = attr_dict
Expand Down Expand Up @@ -279,6 +279,18 @@ def test_union_empty_dicts(self, attr_dict):
d.union(d_new)
assert len(d.baz.bar.keys()) == 0

def test_union_order_retained(self, attr_dict):
d_new = AttrDict({"a": 10, "e": {"b": 1, "a": 2}, "A": -1, "c.z.II": 20})
attr_dict.union(d_new, allow_override=True)
assert attr_dict == {
"a": 10,
"b": 2,
"d": None,
"c": {"x": "foo", "y": "bar", "z": {"I": 1, "II": 20}},
"e": {"b": 1, "a": 2},
"A": -1,
}

def test_del_key_single(self, attr_dict):
attr_dict.del_key("c")
assert "c" not in attr_dict
Expand Down