Source code for webargs.multidictproxy

from import Mapping

import marshmallow as ma

from webargs.core import missing, is_multiple

[docs]class MultiDictProxy(Mapping): """ A proxy object which wraps multidict types along with a matching schema Whenever a value is looked up, it is checked against the schema to see if there is a matching field where `is_multiple` is True. If there is, then the data should be loaded as a list or tuple. In all other cases, __getitem__ proxies directly to the input multidict. """ def __init__(self, multidict, schema: ma.Schema): = multidict self.multiple_keys = self._collect_multiple_keys(schema) @staticmethod def _collect_multiple_keys(schema: ma.Schema): result = set() for name, field in schema.fields.items(): if not is_multiple(field): continue result.add(field.data_key if field.data_key is not None else name) return result def __getitem__(self, key): val =, missing) if val is missing or key not in self.multiple_keys: return val if hasattr(, "getlist"): return if hasattr(, "getall"): return if isinstance(val, (list, tuple)): return val if val is None: return None return [val] def __str__(self): # str(proxy) proxies to str( return str( def __repr__(self): return "MultiDictProxy(data={!r}, multiple_keys={!r})".format(, self.multiple_keys ) def __delitem__(self, key): del[key] def __setitem__(self, key, value):[key] = value def __getattr__(self, name): return getattr(, name) def __iter__(self): for x in iter( # special case for header dicts which produce an iterator of tuples # instead of an iterator of strings if isinstance(x, tuple): yield x[0] else: yield x def __contains__(self, x): return x in def __len__(self): return len( def __eq__(self, other): return == other def __ne__(self, other): return != other