diff --git a/docs/configuration.rst b/docs/configuration.rst index b62ad33f..055e4e29 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -6085,6 +6085,18 @@ Description this cache. +filters-environment +------------------- +Type + ``bool`` +Default + ``true`` +Description + Evaluate filter expressions raising an exception as ``false`` + instead of aborting the current extractor run + by wrapping them in a `try`/`except` block. + + format-separator ---------------- Type diff --git a/gallery_dl/__init__.py b/gallery_dl/__init__.py index b4db17d6..8a23127f 100644 --- a/gallery_dl/__init__.py +++ b/gallery_dl/__init__.py @@ -105,6 +105,11 @@ def main(): output.ANSI = True + # filter environment + filterenv = config.get((), "filters-environment", True) + if not filterenv: + util.compile_expression = util.compile_expression_raw + # format string separator separator = config.get((), "format-separator") if separator: diff --git a/gallery_dl/util.py b/gallery_dl/util.py index e76ddf36..2f17dc21 100644 --- a/gallery_dl/util.py +++ b/gallery_dl/util.py @@ -616,11 +616,28 @@ else: Popen = subprocess.Popen -def compile_expression(expr, name="", globals=None): +def compile_expression_raw(expr, name="", globals=None): code_object = compile(expr, name, "eval") return functools.partial(eval, code_object, globals or GLOBALS) +def compile_expression_tryexcept(expr, name="", globals=None): + code_object = compile(expr, name, "eval") + + def _eval(locals=None, globals=(globals or GLOBALS), co=code_object): + try: + return eval(co, globals, locals) + except exception.GalleryDLException: + raise + except Exception: + return False + + return _eval + + +compile_expression = compile_expression_tryexcept + + def import_file(path): """Import a Python module from a filesystem path""" path, name = os.path.split(path) diff --git a/test/test_util.py b/test/test_util.py index 35e72473..dba54bba 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -134,19 +134,18 @@ class TestPredicate(unittest.TestCase): with self.assertRaises(SyntaxError): util.FilterPredicate("(") - with self.assertRaises(exception.FilterError): - util.FilterPredicate("a > 1")(url, {"a": None}) - - with self.assertRaises(exception.FilterError): - util.FilterPredicate("b > 1")(url, {"a": 2}) + self.assertFalse( + util.FilterPredicate("a > 1")(url, {"a": None})) + self.assertFalse( + util.FilterPredicate("b > 1")(url, {"a": 2})) pred = util.FilterPredicate(["a < 3", "b < 4", "c < 5"]) self.assertTrue(pred(url, {"a": 2, "b": 3, "c": 4})) self.assertFalse(pred(url, {"a": 3, "b": 3, "c": 4})) self.assertFalse(pred(url, {"a": 2, "b": 4, "c": 4})) self.assertFalse(pred(url, {"a": 2, "b": 3, "c": 5})) - with self.assertRaises(exception.FilterError): - pred(url, {"a": 2}) + + self.assertFalse(pred(url, {"a": 2})) def test_build_predicate(self): pred = util.build_predicate([]) @@ -445,6 +444,7 @@ class TestOther(unittest.TestCase): self.assertEqual(expr({"a": 1, "b": 2, "c": 3}), 7) self.assertEqual(expr({"a": 9, "b": 9, "c": 9}), 90) + expr = util.compile_expression_raw("a + b * c") with self.assertRaises(NameError): expr() with self.assertRaises(NameError):