def response_dict(self, request, D,
                      is_batch=False,
                      version_hint='1.0',
                      json_encoder=None):
        json_encoder = json_encoder or self.json_encoder
        version = version_hint
        response = self.empty_response(version=version)
        apply_version = {
            '2.0':
            lambda f, r, p: f(r, **encode_kw(p)) if type(p) is dict else f(r, *p),
            '1.1':
            lambda f, r, p: f(r, *encode_arg11(p), **encode_kw(encode_kw11(p))),
            '1.0': lambda f, r, p: f(r, *p)
        }

        try:
            # params: An Array or Object, that holds the actual parameter values
            # for the invocation of the procedure. Can be omitted if empty.
            if 'params' not in D:
                D['params'] = []
            if 'method' not in D or 'params' not in D:
                raise InvalidParamsError(
                    'Request requires str:"method" and list:"params"')
            if D['method'] not in self.urls:
                raise MethodNotFoundError(
                    'Method not found. Available methods: %s' % (
                        '\n'.join(self.urls.keys())))

            if 'jsonrpc' in D:
                if str(D['jsonrpc']) not in apply_version:
                    raise InvalidRequestError(
                        'JSON-RPC version %s not supported.' % D['jsonrpc'])
                version = request.jsonrpc_version = response['jsonrpc'] = str(
                    D['jsonrpc'])
            elif 'version' in D:
                if str(D['version']) not in apply_version:
                    raise InvalidRequestError(
                        'JSON-RPC version %s not supported.' % D['version'])
                version = request.jsonrpc_version = response['version'] = str(
                    D['version'])
            else:
                request.jsonrpc_version = '1.0'

            method = self.urls[str(D['method'])]
            if getattr(method, 'json_validate', False):
                validate_params(method, D)

            if 'id' in D and D['id'] is not None:  # regular request
                response['id'] = D['id']
                if version in ('1.1', '2.0') and 'error' in response:
                    response.pop('error')
            elif is_batch:  # notification, not ok in a batch format, but happened anyway
                raise InvalidRequestError

            R = apply_version[version](method, request, D['params'])

            if 'id' not in D or ('id' in D and D['id'] is None):  # notification
                return None, 204

            if isinstance(R, tuple):
                R = list(R)

            encoder = json_encoder()
            builtin_types = (dict, list, set, NoneType, bool, six.text_type
                       ) + six.integer_types + six.string_types
            if all(not isinstance(R, e) for e in builtin_types):
                try:
                    rs = encoder.default(R)  # ...or something this thing supports
                except TypeError as exc:
                    raise TypeError("Return type not supported, for %r" % R)

            response['result'] = R

            status = 200

        except Error as e:
            response['error'] = e.json_rpc_format
            if version in ('1.1', '2.0') and 'result' in response:
                response.pop('result')
            status = e.status
        except Exception as e:
            # exception missed by others
            signals.got_request_exception.send(sender=self.__class__,
                                               request=request)

            # Put stacktrace into the OtherError only if DEBUG is enabled
            if settings.DEBUG:
                other_error = OtherError(e)
            else:
                other_error = OtherError("Internal Server Error")

            response['error'] = other_error.json_rpc_format
            status = other_error.status
            if version in ('1.1', '2.0') and 'result' in response:
                response.pop('result')

        # Exactly one of result or error MUST be specified. It's not
        # allowed to specify both or none.
        if version in ('1.1', '2.0'
                   ) and 'error' in response and not response['error']:
            response.pop('error')

        return response, status
dataset/ETHPy150Open samuraisam/django-json-rpc/jsonrpc/site.py/JSONRPCSite.response_dict/original