Skip to content

Instantly share code, notes, and snippets.

@FFY00
Created August 5, 2021 23:17
Show Gist options
  • Save FFY00/34ffe3ca1a7775d8f9c08310f64d0dc6 to your computer and use it in GitHub Desktop.
Save FFY00/34ffe3ca1a7775d8f9c08310f64d0dc6 to your computer and use it in GitHub Desktop.
import importlib
import types
from typing import Any, Callable
class _staticproperty():
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
if doc is None and fget is not None:
doc = fget.__doc__
self.__doc__ = doc
def __get__(self, instance, owner=None):
return self.fget()
def __set__(self, instance, value):
return self.fset(value)
def __delete__(self, instance):
return self.fdel()
def getter(self, fget):
self.gset = fget
return self
def setter(self, fset):
self.fset = fset
return self
def deleter(self, fdel):
self.fdel = fdel
return self
def module_property(func: Callable[..., Any]) -> _staticproperty:
'''Similar to the ``property`` built-in, but works on modules.
Cannot be acess directly, only available as a module attribute
(eg. module.some_property).'''
prop = _staticproperty(func)
module = importlib.import_module(func.__module__)
# we need to override the module type, so lets disallow this on custom module types
if module.__class__ is not types.ModuleType: # noqa: E721
raise TypeError(
'Can only set module properties on types.ModuleType modules '
f'(expecting `{types.ModuleType}`, got `{module.__class__}`)'
)
class _CustomPropertyHolderModule(types.ModuleType):
pass
# replace module class and set a static property on the module
module.__class__ = _CustomPropertyHolderModule
setattr(module.__class__, func.__name__, prop)
return prop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment