diff --git a/CHANGELOG b/CHANGELOG index ace91c9..9fabc6d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,7 +4,8 @@ v0.2 (unreleased): - Fixed API behavior when blocked, when using AssertEdit, and under other circumstances. - Added copyvio detector functionality: specifying a max time for checks; - improved exclusion support. Fixed assorted bugs. + improved exclusion support. URL loading and parsing is parallelized to speed + up check times. Fixed assorted bugs. - Added support for Wikimedia Labs when creating a config file. - Added and improved lazy importing for various dependencies. - Fixed a bug in job scheduling. diff --git a/earwigbot/lazy.py b/earwigbot/lazy.py index c58f8c0..f66fafe 100644 --- a/earwigbot/lazy.py +++ b/earwigbot/lazy.py @@ -29,22 +29,21 @@ until they are used (i.e. their attributes are read or modified). from imp import acquire_lock, release_lock import sys +from threading import RLock from types import ModuleType __all__ = ["LazyImporter"] -def _getattribute(self, attr): - _load(self) - return self.__getattribute__(attr) +_real_get = ModuleType.__getattribute__ -def _setattr(self, attr, value): - _load(self) - self.__setattr__(attr, value) - -def _load(self): - type(self).__getattribute__ = ModuleType.__getattribute__ - type(self).__setattr__ = ModuleType.__setattr__ - reload(self) +def _mock_get(self, attr): + with _real_get(self, "_lock"): + if _real_get(self, "_unloaded"): + type(self)._unloaded = False + reload(self) + type(self).__getattribute__ = _real_get + del type(self)._lock + return _real_get(self, attr) class _LazyModule(type): @@ -54,8 +53,9 @@ class _LazyModule(type): if name not in sys.modules: attributes = { "__name__": name, - "__getattribute__": _getattribute, - "__setattr__": _setattr + "__getattribute__": _mock_get, + "_unloaded": True, + "_lock": RLock() } parents = (ModuleType,) klass = type.__new__(cls, "module", parents, attributes)