typeshed icon indicating copy to clipboard operation
typeshed copied to clipboard

`dict` vs `MutableMapping` in `stdlib` annotations

Open sobolevn opened this issue 3 years ago • 3 comments
trafficstars

Today I've noticed that copy.deepcopy requires dict type as memo= argument: https://github.com/python/cpython/blob/main/Lib/copy.py

But, this is actually not quite true, MutableMapping works just fine, because only these methods are used in the implementation:

  • __setitem__
  • .get

But, I have some mixed feelings about it:

  1. It is more like an implementation details, no one promises that it will continue to work, some dict only magic can be used in any method at almost any time
  2. It is more correct, because custom types do work:
import typing

class My(typing.MutableMapping):
    def __init__(self):
        self._data = {}
    def __getitem__(self, k):
        return self._data[k]
    def __setitem__(self, k, v):
        self._data[k] = v
    def __delitem__(self, k):
        del self._data[k]
    def __len__(self):
        return len(self._data)
    def __iter__(self):
        return iter(self._data)

import copy
print(copy.deepcopy(1, memo=My()))  # 1

So, should we allow MutableMapping / Mapping where dict is too specific? Or should we keep things more reliable?

sobolevn avatar Aug 28 '22 09:08 sobolevn

only these methods are used

Not necessarily true:

            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
                y = copier(memo)

An advantage of dict is that when you define a __deepcopy__ method, you can type it as taking a dict, and then you can do anything you would usually do with a dict. Presumably defining custom __deepcopy__ logic is more common than passing in a memo argument explicitly, so IMO convenience and simplicity there is more important.

Akuli avatar Aug 28 '22 09:08 Akuli

What about other similar cases? How should we make a decision: dict or (Mutable)Mapping?

sobolevn avatar Aug 28 '22 09:08 sobolevn

What about other similar cases? How should we make a decision: dict or (Mutable)Mapping?

In general, we should be as permissive as possible in argument annotations if the implementation doesn't explicitly check for a dictionary as opposed to any other mutable mapping.

AlexWaygood avatar Aug 28 '22 10:08 AlexWaygood

Closing, as I think the question has been answered :)

AlexWaygood avatar Sep 28 '22 09:09 AlexWaygood