Class that acts as mapping for **unpacking
Without subclassing dict, what would a class need to be considered a mapping so that it can be passed to a method with **
.
from abc import ABCMeta
class uobj:
__metaclass__ = ABCMeta
uobj.register(dict)
def f(**k): return k
o = uobj()
f(**o)
# outputs: f() argument after ** must be a mapping, not uobj
At least to the point where it throws errors of missing functionality of mapping, so I can begin implementing.
I reviewed emulating container types but simply defining magic methods has no effect, and using ABCMeta
to override and register it as a dict validates assertions as subclass, but fails isinstance(o, dict)
. Ideally, I dont even want to use ABCMeta
.
The __getitem__()
and keys()
methods will suffice:
>>> class D:
def keys(self):
return ['a', 'b']
def __getitem__(self, key):
return key.upper()
>>> def f(**kwds):
print kwds
>>> f(**D())
{'a': 'A', 'b': 'B'}
If you're trying to create a Mapping — not just satisfy the requirements for passing to a function — then you really should inherit from collections.abc.Mapping
. As described in the documentation, you need to implement just:
__getitem__
__len__
__iter__
The Mixin will implement everything else for you: __contains__
, keys
, items
, values
, get
, __eq__
, and __ne__
.