Class decorator that scans a class definition for Validators and builds a _fields variable that captures their definition order.
(cls)
| 52 | validate_attributes(cls) |
| 53 | |
| 54 | def validate_attributes(cls): |
| 55 | ''' |
| 56 | Class decorator that scans a class definition for Validators |
| 57 | and builds a _fields variable that captures their definition order. |
| 58 | ''' |
| 59 | validators = [] |
| 60 | for name, val in vars(cls).items(): |
| 61 | if isinstance(val, Validator): |
| 62 | validators.append(val) |
| 63 | |
| 64 | # Apply validated decorator to any callable with annotations |
| 65 | elif callable(val) and val.__annotations__: |
| 66 | setattr(cls, name, validated(val)) |
| 67 | |
| 68 | # Collect all of the field names |
| 69 | cls._fields = tuple([v.name for v in validators]) |
| 70 | |
| 71 | # Collect type conversions. The lambda x:x is an identity |
| 72 | # function that's used in case no expected_type is found. |
| 73 | cls._types = tuple([ getattr(v, 'expected_type', lambda x: x) |
| 74 | for v in validators ]) |
| 75 | |
| 76 | # Create the __init__ method |
| 77 | if cls._fields: |
| 78 | cls.create_init() |
| 79 | |
| 80 | |
| 81 | return cls |
| 82 | |
| 83 | def typed_structure(clsname, **validators): |
| 84 | cls = type(clsname, (Structure,), validators) |
no test coverage detected