webargs.multidictproxy — webargs 6.1.0 documentation
Description: Declarative parsing and validation of HTTP request objects.

# Source code for webargs.multidictproxy

    from collections.abc import Mapping

    from webargs.compat import MARSHMALLOW_VERSION_INFO
    from webargs.core import missing, is_multiple

    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):
            self.data = multidict
            self.multiple_keys = self._collect_multiple_keys(schema)

        @staticmethod
        def _collect_multiple_keys(schema):
            result = set()
            for name, field in schema.fields.items():
                if not is_multiple(field):
                    continue
                if MARSHMALLOW_VERSION_INFO[0] < 3:
                    result.add(field.load_from if field.load_from is not None else name)
                else:
                    result.add(field.data_key if field.data_key is not None else name)
            return result

        def __getitem__(self, key):
            val = self.data.get(key, missing)
            if val is missing or key not in self.multiple_keys:
                return val
            if hasattr(self.data, "getlist"):
                return self.data.getlist(key)
            if hasattr(self.data, "getall"):
                return self.data.getall(key)
            if isinstance(val, (list, tuple)):
                return val
            if val is None:
                return None
            return [val]

        def __str__(self):  # str(proxy) proxies to str(proxy.data)
            return str(self.data)

        def __repr__(self):
            return "MultiDictProxy(data={!r}, multiple_keys={!r})".format(
                self.data, self.multiple_keys
            )

        def __delitem__(self, key):
            del self.data[key]

        def __setitem__(self, key, value):
            self.data[key] = value

        def __getattr__(self, name):
            return getattr(self.data, name)

        def __iter__(self):
            return iter(self.data)

        def __contains__(self, x):
            return x in self.data

        def __len__(self):
            return len(self.data)

        def __eq__(self, other):
            return self.data == other

        def __ne__(self, other):
            return self.data != other