Created
July 16, 2021 17:32
-
-
Save kristoffer-paulsson/5280fe9f63afcf68b544b6a9f82a1a55 to your computer and use it in GitHub Desktop.
A way of checking and collecting policies on objects so that they can be easily reported.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright (c) 2021 by Kristoffer Paulsson. <[email protected]> | |
"""The checker.py example is expected to fail with 2 exceptions one ValueError and one RuntimeWarning. | |
The RuntimeWarning should tell the last executed policy that was started.""" | |
from contextlib import ContextDecorator | |
from contextvars import ContextVar | |
check_ctx = ContextVar("check", default=None) | |
class report(ContextDecorator): | |
"""Collects reports last time a @check with a set policy was done.""" | |
def __init__(self): | |
self._token = check_ctx.set(list()) | |
def __enter__(self): | |
return check_ctx.get() | |
def __exit__(self, *exc): | |
checks = check_ctx.get() | |
check_ctx.reset(self._token) | |
if exc: | |
raise RuntimeWarning("Checks failed while applying rules in validation.", checks) | |
return False | |
def check(policy: str): | |
"""Check policy decorator.""" | |
if not policy: | |
raise ValueError("Check policy not set!") | |
def decorator(func): | |
"""Method decorator.""" | |
def checker(self, *args, **kwargs): | |
"""Policy checker.""" | |
checks = check_ctx.get() | |
if type(checks) is list: | |
checks.append(policy) | |
return func(self, *args, **kwargs) | |
return checker | |
return decorator | |
class ReportBase: | |
"""Base class for validation enabled policies.""" | |
def apply_rules(self) -> bool: | |
return any([getattr(self, m)() for m in filter(lambda name: name.startswith("_check_"), dir(self))]) | |
def validate(self): | |
self.apply_rules() | |
class Evaluation(ReportBase): | |
"""Evaluating certain policies.""" | |
@check("policy_1") | |
def _check_number1(self) -> bool: | |
return False | |
@check("policy_2") | |
def _check_number2(self) -> bool: | |
return True | |
@check("policy_3") | |
def _check_number3(self) -> bool: | |
raise ValueError("No value") | |
@check("policy_4") | |
def _check_number4(self) -> bool: | |
return True | |
def main(): | |
evaluatee = Evaluation() | |
with report(): | |
evaluatee.validate() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment