diff --git a/gallery_dl/util.py b/gallery_dl/util.py index 80c53cb86e1..6cdd994690d 100644 --- a/gallery_dl/util.py +++ b/gallery_dl/util.py @@ -532,6 +532,24 @@ def __call__(self, request): return request +class ModuleProxy(): + __slots__ = () + + def __getitem__(self, key, modules=sys.modules): + try: + return modules[key] + except KeyError: + pass + try: + __import__(key) + except ImportError: + modules[key] = NONE + return NONE + return modules[key] + + __getattr__ = __getitem__ + + class LazyPrompt(): __slots__ = () @@ -540,6 +558,7 @@ def __str__(self): class NullContext(): + __slots__ = () def __enter__(self): return None @@ -646,6 +665,7 @@ def __str__(): "restart" : raises(exception.RestartExtraction), "hash_sha1": sha1, "hash_md5" : md5, + "std" : ModuleProxy(), "re" : re, } diff --git a/test/test_util.py b/test/test_util.py index b630ffbc1a7..888a70a0644 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -830,6 +830,34 @@ def test_universal_none(self): i += 1 self.assertEqual(i, 0) + def test_module_proxy(self): + proxy = util.ModuleProxy() + + self.assertIs(proxy.os, os) + self.assertIs(proxy.os.path, os.path) + self.assertIs(proxy["os"], os) + self.assertIs(proxy["os.path"], os.path) + self.assertIs(proxy["os"].path, os.path) + + self.assertIs(proxy.abcdefghi, util.NONE) + self.assertIs(proxy["abcdefghi"], util.NONE) + self.assertIs(proxy["abc.def.ghi"], util.NONE) + self.assertIs(proxy["os.path2"], util.NONE) + + def test_null_context(self): + with util.NullContext(): + pass + + with util.NullContext() as ctx: + self.assertIs(ctx, None) + + try: + with util.NullContext() as ctx: + exc_orig = ValueError() + raise exc_orig + except ValueError as exc: + self.assertIs(exc, exc_orig) + class TestExtractor(): category = "test_category"