Passed
Push — master ( 55adfd...84b7e9 )
by Michael
03:30
created

JsonRpcRequest.__init__()   B

Complexity

Conditions 5

Size

Total Lines 22
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 22
rs 8.9833
c 0
b 0
f 0
cc 5
nop 9

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
import typing
2
from dataclasses import dataclass, field
3
4
from .. import constants, errors, utils
5
6
7
__all__ = (
8
    'JsonRpcRequest',
9
)
10
11
12
@dataclass
13
class JsonRpcRequest:
14
    method: str
15
    msg_id: typing.Any = constants.NOTHING
16
    jsonrpc: str = constants.VERSION_2_0
17
    extra_args: dict = field(default_factory=dict)
18
    context: dict = field(default_factory=dict)
19
    params: typing.Any = constants.NOTHING
20
    args: typing.Optional[typing.Union[list, tuple]] = None
21
    kwargs: typing.Optional[dict] = None
22
23
    def __post_init__(self):
24
        utils.validate_jsonrpc(self.jsonrpc)
25
26
        if self.params is constants.NOTHING:
27
            self.set_args_and_kwargs(self.args, self.kwargs)
28
        elif not self.args and not self.kwargs:
29
            self.set_params(self.params)
30
        else:
31
            raise errors.InvalidParams('Need use params or args with kwargs.')
32
33
    def set_params(self, params: typing.Any) -> None:
34
        self.params = params
35
        self.args, self.kwargs = utils.convert_params_to_args_and_kwargs(params)
36
37
    def set_args_and_kwargs(self, args: typing.Optional[list] = None, kwargs: typing.Optional[dict] = None) -> None:
38
        self.params, self.args, self.kwargs = utils.parse_args_and_kwargs(args, kwargs)
39
40
    @property
41
    def is_notification(self) -> bool:
42
        return self.msg_id is constants.NOTHING
43
44
    @classmethod
45
    def from_dict(cls, data: typing.Dict[str, typing.Any], **kwargs) -> 'JsonRpcRequest':
46
        cls._validate_json_request(data)
47
48
        return cls(
49
            msg_id=data.get('id', constants.NOTHING),
50
            method=data['method'],
51
            params=data.get('params', constants.NOTHING),
52
            jsonrpc=data['jsonrpc'],
53
            **kwargs,
54
        )
55
56
    def to_dict(self) -> dict:
57
        data = {
58
            'method': self.method,
59
            'jsonrpc': self.jsonrpc,
60
        }
61
62
        if not self.is_notification:
63
            data['id'] = self.msg_id
64
65
        if self.params is not constants.NOTHING:
66
            data['params'] = self.params
67
68
        return data
69
70
    @staticmethod
71
    def _validate_json_request(data: typing.Any) -> None:
72
        if not isinstance(data, dict):
73
            raise errors.InvalidRequest('A request must be of the dict type.')
74
75
        if not ({'method', 'jsonrpc'}) <= data.keys():
76
            raise errors.InvalidRequest('A request must contain "method" and "jsonrpc".')
77
78
        utils.validate_jsonrpc(data['jsonrpc'])
79