id,node_id,number,title,user,state,locked,assignee,milestone,comments,created_at,updated_at,closed_at,author_association,active_lock_reason,draft,pull_request,body,reactions,performed_via_github_app,state_reason,repo,type 2195718932,I_kwDOAMm_X86C4AMU,8855,DatasetView class breaks Liskov's rule.,7788154,open,0,,,2,2024-03-19T18:38:30Z,2024-03-19T19:13:17Z,,CONTRIBUTOR,,,,"### What is your issue? Working on [migrating the datatree.py module](https://github.com/pydata/xarray/pull/8789) into `xarray/core` revealed that the `DatasetView` class, which implements `Dataset` while disabling methods to mutate the object, breaks [Liskov's substitution principle](https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides). 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](https://github.com/pydata/xarray/blob/main/xarray/core/dataset.py#L1529)). ``` # 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](https://stackoverflow.com/a/9059858). 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 (https://github.com/python/mypy/issues/3004). This affects the assignment of `Dataset` objects to the `DataTree.ds` property. (Separate issue, but related)","{""url"": ""https://api.github.com/repos/pydata/xarray/issues/8855/reactions"", ""total_count"": 1, ""+1"": 1, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,,13221727,issue