| Conditions | 11 |
| Total Lines | 54 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like get_validator_by_name() 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 timeout_decorator |
||
| 14 | def get_validator_by_name(name): |
||
| 15 | """ |
||
| 16 | For given validator name, returns associated functions array: |
||
| 17 | validator = { validate_fields: vf, validate_input: vi } |
||
| 18 | Where: |
||
| 19 | - vf(fields) |
||
| 20 | Raises a ValidationError if given fields are not valid for this validator |
||
| 21 | - vi(fields, user_input) |
||
| 22 | Throws a ValidationError if given input is not valid for this validator |
||
| 23 | |||
| 24 | Returns None if there is no validator matching that name. |
||
| 25 | """ |
||
| 26 | |||
| 27 | # Validators functions |
||
| 28 | def text_validate_fields(fields): |
||
| 29 | # TODO: Is it safe to call re.compile with user input ? Possible infinite loops ... ? |
||
| 30 | try: |
||
| 31 | re.compile(fields['regex']) |
||
| 32 | except re.error: |
||
|
|
|||
| 33 | raise ValidationError(fields['message'] + " (invalid Regex syntax)") |
||
| 34 | |||
| 35 | # Protection against Evil Regex. Only 50ms to evaluate regex - should be enough. |
||
| 36 | @timeout_decorator.timeout(0.05, use_signals=False) |
||
| 37 | def regex_check_timeout(regex, error_message, input): |
||
| 38 | try: |
||
| 39 | RegexValidator(regex, error_message)(input) |
||
| 40 | except re.error: # Should not happen ... |
||
| 41 | raise ValidationError("Invalid validator for this field.") |
||
| 42 | |||
| 43 | def text_validate_input(fields, input): |
||
| 44 | if (fields['regex']): |
||
| 45 | try: |
||
| 46 | regex_check_timeout(fields['regex'], fields['message'], input) |
||
| 47 | except timeout_decorator.TimeoutError: |
||
| 48 | raise ValidationError(fields['message']) |
||
| 49 | |||
| 50 | # Validators map |
||
| 51 | validators_map = { |
||
| 52 | Validator.VALIDATOR_NONE: { |
||
| 53 | 'validate_fields': lambda f: True, |
||
| 54 | 'validate_input': lambda f,i: True, |
||
| 55 | }, |
||
| 56 | Validator.VALIDATOR_TEXT: { |
||
| 57 | 'validate_fields': text_validate_fields, |
||
| 58 | 'validate_input': text_validate_input |
||
| 59 | }, |
||
| 60 | # TODO: Register validators here |
||
| 61 | } |
||
| 62 | |||
| 63 | # Find matching validator |
||
| 64 | try: |
||
| 65 | return validators_map[name] |
||
| 66 | except KeyError: |
||
| 67 | return None |
||
| 68 | |||
| 121 |