<commit_before># -*- coding: utf-8 -*-
"""Asynchronous request parser. Compatible with Python>=3.4."""
import asyncio
import sys
import inspect

import marshmallow as ma
from marshmallow.compat import iteritems
from marshmallow.utils import missing

from webargs import core

PY_34 = sys.version_info < (3, 5)

if PY_34:
    from webargs.async_decorators34 import _use_args
else:
    from webargs.async_decorators import _use_args

class AsyncParser(core.Parser):
    """Asynchronous variant of `webargs.core.Parser`, where parsing methods may be
    either coroutines or regular methods.
    """

    @asyncio.coroutine
    def _parse_request(self, schema, req, locations):
        if schema.many:
            assert 'json' in locations, 'schema.many=True is only supported for JSON location'
            # The ad hoc Nested field is more like a workaround or a helper, and it servers its
            # purpose fine. However, if somebody has a desire to re-design the support of
            # bulk-type arguments, go ahead.
            parsed = yield from self.parse_arg(
                name='json',
                field=ma.fields.Nested(schema, many=True),
                req=req,
                locations=locations
            )
            if parsed is missing:
                parsed = []
        else:
            argdict = schema.fields
            parsed = {}
            for argname, field_obj in iteritems(argdict):
                parsed_value = yield from self.parse_arg(argname, field_obj, req, locations)
                # If load_from is specified on the field, try to parse from that key
                if parsed_value is missing and field_obj.load_from:
                    parsed_value = yield from self.parse_arg(field_obj.load_from,
                                                             field_obj, req, locations)
                    argname = field_obj.load_from
                if parsed_value is not missing:
                    parsed[argname] = parsed_value
        return parsed

    # TODO: Lots of duplication from core.Parser here. Rethink.
    @asyncio.coroutine
    def parse(self, argmap, req=None, locations=None, validate=None, force_all=False):
        """Coroutine variant of `webargs.core.Parser`.

        Receives the same arguments as `webargs.core.Parser.parse`.
        """
        req = req if req is not None else self.get_default_request()
        assert req is not None, 'Must pass req object'
        ret = None
        validators = core._ensure_list_of_callables(validate)
        schema = self._get_schema(argmap, req)
        try:
            parsed = yield from self._parse_request(schema=schema, req=req, locations=locations)
            result = self.load(parsed, schema)
            data = result.data if core.MARSHMALLOW_VERSION_INFO[0] < 3 else result
            self._validate_arguments(data, validators)
        except ma.exceptions.ValidationError as error:
            self._on_validation_error(error)
        else:
            data = result.data if core.MARSHMALLOW_VERSION_INFO[0] < 3 else result
            ret = data
        finally:
            self.clear_cache()
        if force_all:
            core.fill_in_missing_args(ret, schema)
        return ret

    use_args = _use_args

    def use_kwargs(self, *args, **kwargs):
        """Decorator that injects parsed arguments into a view function or method.

        Receives the same arguments as `webargs.core.Parser.use_kwargs`.
<commit_msg>Minor rework of AsyncParser.parse<commit_after># -*- coding: utf-8 -*-
"""Asynchronous request parser. Compatible with Python>=3.4."""
import asyncio
import sys
import inspect

import marshmallow as ma
from marshmallow.compat import iteritems
from marshmallow.utils import missing

from webargs import core

PY_34 = sys.version_info < (3, 5)

if PY_34:
    from webargs.async_decorators34 import _use_args
else:
    from webargs.async_decorators import _use_args

class AsyncParser(core.Parser):
    """Asynchronous variant of `webargs.core.Parser`, where parsing methods may be
    either coroutines or regular methods.
    """

    @asyncio.coroutine
    def _parse_request(self, schema, req, locations):
        if schema.many:
            assert 'json' in locations, 'schema.many=True is only supported for JSON location'
            # The ad hoc Nested field is more like a workaround or a helper, and it servers its
            # purpose fine. However, if somebody has a desire to re-design the support of
            # bulk-type arguments, go ahead.
            parsed = yield from self.parse_arg(
                name='json',
                field=ma.fields.Nested(schema, many=True),
                req=req,
                locations=locations
            )
            if parsed is missing:
                parsed = []
        else:
            argdict = schema.fields
            parsed = {}
            for argname, field_obj in iteritems(argdict):
                parsed_value = yield from self.parse_arg(argname, field_obj, req, locations)
                # If load_from is specified on the field, try to parse from that key
                if parsed_value is missing and field_obj.load_from:
                    parsed_value = yield from self.parse_arg(field_obj.load_from,
                                                             field_obj, req, locations)
                    argname = field_obj.load_from
                if parsed_value is not missing:
                    parsed[argname] = parsed_value
        return parsed

    # TODO: Lots of duplication from core.Parser here. Rethink.
    @asyncio.coroutine
    def parse(self, argmap, req=None, locations=None, validate=None, force_all=False):
        """Coroutine variant of `webargs.core.Parser`.

        Receives the same arguments as `webargs.core.Parser.parse`.
        """
        req = req if req is not None else self.get_default_request()
        assert req is not None, 'Must pass req object'
        data = None
        validators = core._ensure_list_of_callables(validate)
        schema = self._get_schema(argmap, req)
        try:
            parsed = yield from self._parse_request(schema=schema, req=req, locations=locations)
            result = self.load(parsed, schema)
            data = result.data if core.MARSHMALLOW_VERSION_INFO[0] < 3 else result
            self._validate_arguments(data, validators)
        except ma.exceptions.ValidationError as error:
            self._on_validation_error(error)
        finally:
            self.clear_cache()
        if force_all:
            core.fill_in_missing_args(data, schema)
        return data

    use_args = _use_args

    def use_kwargs(self, *args, **kwargs):
        """Decorator that injects parsed arguments into a view function or method.

        Receives the same arguments as `webargs.core.Parser.use_kwargs`.

{'fraction_non_alphanumeric': 0.07371186688074734, 'fraction_numerical': 0.004086994599328565, 'mean_word_length': 2.17516218721038, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5127997', 'n_tokens_mistral': 1874, 'n_tokens_neox': 1825, 'n_words': 589}