Uh oh!
There was an error while loading. Please reload this page.
Allow .attrs to support any dict-likes - #5667
Conversation
Hello @Illviljan! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found: There are currently no PEP 8 issues detected in this Pull Request. Cheers! 🍻 Comment last updated at 2021-10-31 09:57:53 UTC |
| return {} | ||
| elif combine_attrs == "override": | ||
| return dict(variable_attrs[0]) | ||
| return variable_attrs[0].copy() |
There was a problem hiding this comment.
Both dict(x) and x.copy() are shallow copies.
Is it a good idea for it to be shallow though? Seems a little scary to me if the attrs happens to include mutable objects.
There was a problem hiding this comment.
Yeah, I hear that, but IIUC that's what python generally does (I don't have a personally confident view though)
There was a problem hiding this comment.
Merge had a nice test that was relevant to this:
xarray/xarray/tests/test_merge.py
Line 203 in 8f5b4a1
This seems to imply that you would want to be able to tweak the attrs without worrying about other attrs changing. But the test is only made with immutable objects however. Lets do a test with:
ds1=xr.Dataset(attrs={"x": [0, 1]})
ds2=xr.Dataset(attrs={"x": 1})
ds3=xr.merge([ds1, ds2], combine_attrs="override")
ds3.attrs["x"][0] =2# assert ds1.x == [0, 1]print(ds1.x) # [2, 1]That seems like surprising behaviour to me, but it's indeed also how python does this.
There was a problem hiding this comment.
Yes, I agree. Copy-on-Write would be ideal but that's not python's strength...
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Some fun performance comparisons related to copying and initializing dicts: a=dict(a=2, b=3)
%timeitdict(a)
207ns ± 3.41nsperloop (mean ± std. dev. of7runs, 1000000loopseach)
%timeita.copy()
82.6ns ± 0.425nsperloop (mean ± std. dev. of7runs, 10000000loopseach)
importcopy%timeitcopy.copy(a)
313ns ± 3.59nsperloop (mean ± std. dev. of7runs, 1000000loopseach)
fromcopyimportcopy%timeitcopy(a)
290ns ± 3.63nsperloop (mean ± std. dev. of7runs, 1000000loopseach)
fromcopyimportdeepcopy%timeitdeepcopy(a)
3.39µs ± 55.6nsperloop (mean ± std. dev. of7runs, 100000loopseach)Using |
max-sixty
commented
Aug 6, 2021
That is an interesting result (even aside from the main result here, I'm not sure what python is doing such that But python is slow, and nanos are short — unless there's a noticeable impact on the overall performance, then prioritizing flexibility and compatibility are more consistent with the goals of the library. Does that make sense? |
Illviljan
commented
Aug 6, 2021
I'm surprised about the deepcopy being so slow too, I thought it would be similar in speed in this case and just increase if dealing with mutable objects. But using .copy is 100% compatible with how I'm starting to lean towards mutablemapping because subclassing dict has been rather difficult compared to mutablemapping. And if we go with mutablemapping then we should use copy.copy. |
max-sixty
commented
Aug 19, 2021
Is python/mypy#3004 still an issue? pre-commit suggests it's here: https://github.com/pydata/xarray/pull/5667/files#diff-3c0ce7941684cbac55c00ab890684f86acc1de1908ee2afa915dbcb7c944105aR100 — but I guess there's some reason we can't only accept a |
Illviljan
commented
Aug 20, 2021
Yes, it is still an issue. I've cheated though and used
Does |
Here's further tests to check how fast different class checkers are: fromtypingimportMutableMappingclassTest2(MutableMapping):
def__init__(self, *args, **kwargs):
self.data=dict(*args, **kwargs)
def__getitem__(self, key):
passdef__setitem__(self, key, value):
passdef__delitem__(self, key):
passdef__iter__(self):
passdef__len__(self):
passb=Test2()
%timeitissubclass(type(b), MutableMapping)
711ns ± 5.33nsperloop (mean ± std. dev. of7runs, 1000000loopseach)
%timeitisinstance(b, MutableMapping)
853ns ± 6.29nsperloop (mean ± std. dev. of7runs, 1000000loopseach)
# If you want to get really fast you can check for one of the required attributes MutableMapping has %timeithasattr(b, "update")
82.6ns ± 0.181nsperloop (mean ± std. dev. of7runs, 10000000loopseach)
|
for more information, see https://pre-commit.ci
headtr1ck
commented
Oct 12, 2022
If that is still an open issue we could merge current main, try to fix the resulting typing problems. |
pre-commit run --all-fileswhats-new.rstapi.rst