Skip to content

DatasetView class breaks Liskov's rule. #8855

Open
@owenlittlejohns

Description

@owenlittlejohns

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 using getattr. This does not catch the __setitem__ method, as it is a Magic Method, and those aren't affected by getattr.
  • 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

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    To do

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions