Description
What is your issue?
Working on migrating the datatree.py module into xarray/core
revealed that the DatasetView
class, which implements Dataset
while disabling methods to mutate the object, breaks Liskov's substitution principle. The type for one of the overloads of DatasetView.__getitem__
is more general than the corresponding Dataset.__getitem__
signature (due to the use of Self
in the Dataset signature).
# In Dataset:
class Dataset(...):
...
@overload
def __getitem__(self, key: Iterable[Hashable]) -> Self: ...
The use of Self
means that signature inherited from the superclass has a return type of DatasetView
, but the DatasetView
signature is overridden to have a return type of Dataset
(the more generalised parent).
To avoid this, a couple of implementations were attempted:
- A class that tries to intercept the methods that mutate the
Dataset
usinggetattr
. This does not catch the__setitem__
method, as it is a Magic Method, and those aren't affected bygetattr
. - A
Metaclass
that can intercept Magic Methods, too. Implementation was inspired from here. I didn't get it to fully work, and eventually realised this was getting too complicated given the scope of the original problem. - A mix-in for the mutating methods. I couldn't get this to work in the timescale agreed upon.
- Resorting back to ignoring the
mypy
errors for now, so we can proceed with the migration (given that there isn't a significant implementation concern identified from these type issues).
Also note, there is a tangentially-related known mypy
error when a property setter accepts an argument of a different type to the property itself (python/mypy#3004). This affects the assignment of Dataset
objects to the DataTree.ds
property. (Separate issue, but related)
Metadata
Metadata
Assignees
Type
Projects
Status