Skip to content

Instantly share code, notes, and snippets.

@mauicv
Created March 6, 2021 15:28
Show Gist options
  • Save mauicv/c1166af302ae1895ab59dfdbe6a04a58 to your computer and use it in GitHub Desktop.
Save mauicv/c1166af302ae1895ab59dfdbe6a04a58 to your computer and use it in GitHub Desktop.
[class instance validator] Validates class on instance change for testing purposes #validation #testing
"""Functions that can be used as decorators to check the state of class datastructures are sound.
The class_validator function adds a validation step to each method in the decorated class if the environment is
in TESTING mode. This is used primarily for testing in order to catch cases where class instances enter states
they shouldn't.
Example:
```
def simple_validator(self, *args, **kwargs):
if self.value > 10:
raise ValueError()
@add_inst_validator(env="TESTING", validator=simple_validator)
class Test:
def __init__(self, value):
self.value = value
def set_value(self, value):
self.value = value
```
"""
import functools
def print_all(cls_inst, *args, **kwargs):
print('instance:', cls_inst)
print('args:', *args)
print('kwargs:', **kwargs)
def decorator(func, validator):
@functools.wraps(func)
def new_method(cls_inst, *args, **kwargs):
ret_val = func(cls_inst, *args, **kwargs)
validator(cls_inst, *args, **kwargs)
return ret_val
return new_method
def add_inst_validator(env='TESTING', validator=print_all):
def class_decorator(cls):
if env == 'TESTING':
for attr, val in cls.__dict__.items():
if callable(val) and not attr.startswith("__"):
setattr(cls, attr, decorator(val, validator))
return cls
return class_decorator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment