Skip to content

typing.MutableMapping not a drop-in replacement for collections.abc.MutableMapping #203

Closed
@bdarnell

Description

@bdarnell

The only difference between typing.MutableMapping and its collections.abc counterpart is supposed to be the support for generic type parameters. However, it looks like it's also missing some other methods:

import collections.abc
import typing

def define_user_dict(base_class):
    class MyUserDict(base_class):
        def __getitem__(self, k):
            return None
        def __setitem__(self, k, v):
            pass
        def __delitem__(self, k):
            pass
        def __iter__(self):
            return iter(())
        def __len__(self):
            return 0
    return MyUserDict

UserDict1 = define_user_dict(collections.abc.MutableMapping)
UserDict2 = define_user_dict(typing.MutableMapping[str, str])

UserDict1().update() # this one works
UserDict2().update() # this one fails
$ python3.5 /tmp/mappingtest.py
Traceback (most recent call last):
  File "/tmp/mappingtest.py", line 22, in <module>
    UserDict2().update()
AttributeError: 'MyUserDict' object has no attribute 'update'

Tested on python 3.5.1, and on python 3.4 with typing 3.5.1.0 installed.

Is changing my base class from collections.abc.MutableMapping to typing.MutableMapping the right way to tell the type checker what types my user dict will work with? Should I be using both base classes together? Is there a way to tell the type checker that MyUserDict is a typing.MutableMapping[str, str] while keeping collections.abc.MutableMapping as the runtime base class?

Additionally, isinstance() checking is funky: isinstance(dict(), UserDict2) returns true, so I can't use isinstance() to distinguish my dict type from any other.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions