regex_validation_sealer()   F
last analyzed

Complexity

Conditions 11

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 11
c 6
b 0
f 0
dl 0
loc 36
rs 3.1764

1 Method

Rating   Name   Duplication   Size   Complexity  
B __init__() 0 14 6

How to fix   Complexity   

Complexity

Complex classes like regex_validation_sealer() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import re
2
3
from fields import __base__
4
from fields import _Factory
5
from fields import _SealerWrapper
6
7
8
class ValidationError(Exception):
9
    pass
10
11
12
def regex_validation_sealer(fields, defaults, RegexType=type(re.compile(""))):
13
    """
14
    Example sealer that just does regex-based validation.
15
    """
16
    required = set(fields) - set(defaults)
17
    if required:
18
        raise TypeError(
19
            "regex_validation_sealer doesn't support required arguments. Fields that need fixing: %s" % required)
20
21
    klass = None
22
    kwarg_validators = dict(
23
        (key, val if isinstance(val, RegexType) else re.compile(val)) for key, val in defaults.items()
24
    )
25
    arg_validators = list(
26
        kwarg_validators[key] for key in fields
27
    )
28
29
    def __init__(self, *args, **kwargs):
30
        for pos, (value, validator) in enumerate(zip(args, arg_validators)):
31
            if not validator.match(value):
32
                raise ValidationError("Positional argument %s failed validation. %r doesn't match regex %r" % (
33
                    pos, value, validator.pattern
34
                ))
35
        for key, value in kwargs.items():
36
            if key in kwarg_validators:
37
                validator = kwarg_validators[key]
38
                if not validator.match(value):
39
                    raise ValidationError("Keyword argument %r failed validation. %r doesn't match regex %r" % (
40
                        key, value, validator.pattern
41
                    ))
42
        super(klass, self).__init__(*args, **kwargs)
43
44
    klass = type("RegexValidateBase", (__base__,), dict(
45
        __init__=__init__,
46
    ))
47
    return klass
48
49
50
RegexValidate = _Factory(sealer=_SealerWrapper(regex_validation_sealer))
51