Skip to content

Instantly share code, notes, and snippets.

@earonesty
Created September 12, 2019 13:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save earonesty/f286c826e69b8b4f5337bd534b757baa to your computer and use it in GitHub Desktop.
Save earonesty/f286c826e69b8b4f5337bd534b757baa to your computer and use it in GitHub Desktop.
strict decorator for python classes
#pylint: disable=protected-access
import inspect, itertools, functools
class StrictError(TypeError):
pass
def strict(cls):
cls._x_frozen = False
cls._x_setter = getattr(cls, "__setattr__", object.__setattr__)
def frozen_setattr(self, key, value):
if self._x_frozen and not hasattr(self, key):
raise StrictError("Class %s is frozen. Cannot set '%s'." % (cls.__name__, key))
cls._x_setter(self, key, value)
def init_decorator(func):
info = inspect.getfullargspec(func)
for k in itertools.chain(info.args, info.kwonlyargs):
if k != "self" and k not in func.__annotations__:
raise StrictError("%s missing type specifier in __init__" % k)
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
func(self, *args, **kwargs)
self._x_frozen = True
return wrapper
cls.__setattr__ = frozen_setattr
cls.__init__ = init_decorator(cls.__init__)
return cls
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment