Last active
June 11, 2020 08:29
-
-
Save erkandiken/8bebf633b776b4767e38ae6cf568d117 to your computer and use it in GitHub Desktop.
Decorator examples for checking register read, write, range check operations
This file contains 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
class BaseValidationError(Exception): | |
pass | |
class ValueExceedsMaximumError(BaseValidationError): | |
pass | |
class ValueUnderMinimumError(BaseValidationError): | |
pass | |
class NegativeValueError(BaseValidationError): | |
pass | |
class InvalidReadError(BaseValidationError): | |
pass | |
class InvalidWriteError(BaseValidationError): | |
pass |
This file contains 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
from decorators import check_read_access, check_write_access, check_range | |
class ExampleClass(object): | |
def __init__(self, device_comm): | |
self.device_comm = device_comm | |
@check_read_access | |
def read(self, reg): | |
return self.device_comm.read_register(reg.address) | |
@check_write_access | |
def write(self, reg, value): | |
self.device_comm.write_register(reg.address, value) | |
@check_range(1, 255) | |
def set_time_register(self, reg, value): | |
self.write(reg, value) |
This file contains 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
import logging | |
import functools | |
from custom_exceptions import BaseValidationError, ValueExceedsMaximumError, \ | |
NegativeValueError, InvalidWriteError, InvalidReadError, ValueUnderMinimumError | |
logger = logging.getLogger(__name__) | |
def check_read_access(func): | |
""" | |
Decorator to check read access of a register before attempting to read | |
:param func: method passed to decorator | |
:return: wrapper function | |
""" | |
@functools.wraps(func) | |
def wrapper_check_read_access(*args, **kwargs): | |
""" | |
Wrapper func checks for the read access | |
:param args: positional arguments (args[0]: self, args[1]: reg) | |
:param kwargs: keyword arguments | |
:return: None or wrapped func method | |
""" | |
try: | |
reg = args[1] | |
if reg.read is False: | |
raise InvalidReadError(reg.reg_name) | |
except BaseValidationError as err: | |
logger.error(repr(err)) | |
return None | |
else: | |
return func(*args, **kwargs) | |
return wrapper_check_read_access | |
def check_write_access(func): | |
""" | |
Decorator to check write access of a register before attempting to write | |
:param func: method passed to decorator | |
:return: wrapper function | |
""" | |
@functools.wraps(func) | |
def wrapper_check_write_access(*args, **kwargs): | |
""" | |
Wrapper func checks for the write access | |
:param args:positional arguments (args[0]: self, args[1]: reg) | |
:param kwargs: keyword arguments | |
:return: None or wrapped func method | |
""" | |
try: | |
reg = args[1] | |
if reg.write is False: | |
raise InvalidWriteError(reg.reg_name) | |
except BaseValidationError as err: | |
logger.error(repr(err)) | |
return None | |
else: | |
return func(*args, **kwargs) | |
return wrapper_check_write_access | |
def check_range(min_value, max_value): | |
""" | |
Decorator for checking input value against min and max values | |
:param min_value: min value required | |
:param max_value: max value required | |
:return: wrapper function | |
""" | |
def decorator_check_range(func): | |
@functools.wraps(func) | |
def wrapper_check_range(*args, **kwargs): | |
""" | |
:param args: positional arguments | |
:param kwargs: keyword arguments | |
:return: None or wrapped func | |
""" | |
try: | |
value = args[1] | |
if value > max_value: | |
raise ValueExceedsMaximumError(value) | |
elif value < min_value: | |
raise ValueUnderMinimumError(value) | |
elif value < 0.0: | |
raise NegativeValueError(value) | |
except BaseValidationError as err: | |
logger.error(repr(err)) | |
return None | |
else: | |
return func(*args, **kwargs) | |
return wrapper_check_range | |
return decorator_check_range |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment