From f0f9575406b305110a665b801414a00a6be394d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20F=C3=A4hrmann?= Date: Tue, 3 Feb 2026 19:00:45 +0100 Subject: [PATCH] [job] fix 'AttributeError' when enabling 'init' for non-DownloadJob fixes bug in 56dcd00391ba6bb344d99d9474835319fbbd48b8 --- gallery_dl/job.py | 5 +++- test/test_job.py | 65 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/gallery_dl/job.py b/gallery_dl/job.py index 186e79e9..19255f89 100644 --- a/gallery_dl/job.py +++ b/gallery_dl/job.py @@ -268,6 +268,9 @@ class Job(): for key, valuegen in self.kwdict_eval: kwdict[key] = valuegen(kwdict) + def initialize(self): + pass + def _init(self): self.extractor.initialize() self.pred_url = self._prepare_predicates( @@ -596,7 +599,7 @@ class DownloadJob(Job): return instance def initialize(self, kwdict=None): - """Delayed initialization of PathFormat, etc.""" + """initialize PathFormat, postprocessors, archive, options, etc""" extr = self.extractor cfg = extr.config diff --git a/test/test_job.py b/test/test_job.py index c59519c0..a33738e7 100644 --- a/test/test_job.py +++ b/test/test_job.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# Copyright 2021-2025 Mike Fährmann +# Copyright 2021-2026 Mike Fährmann # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as @@ -51,19 +51,45 @@ class TestDownloadJob(TestJob): func = tjob._build_extractor_filter() self.assertEqual(func(TestExtractor) , False) self.assertEqual(func(TestExtractorParent), False) - self.assertEqual(func(TestExtractorAlt) , True) + self.assertEqual(func(TestExtractorNoop) , True) config.set((), "blacklist", ":test_subcategory") func = tjob._build_extractor_filter() self.assertEqual(func(TestExtractor) , False) self.assertEqual(func(TestExtractorParent), True) - self.assertEqual(func(TestExtractorAlt) , False) + self.assertEqual(func(TestExtractorNoop) , False) config.set((), "whitelist", "test_category:test_subcategory") func = tjob._build_extractor_filter() self.assertEqual(func(TestExtractor) , True) self.assertEqual(func(TestExtractorParent), False) - self.assertEqual(func(TestExtractorAlt) , False) + self.assertEqual(func(TestExtractorNoop) , False) + + def test_opt_init(self): + config.set((), "init", True) + config.set((), "archive", ":memory:") + config.set((), "postprocessors", "directory") + + extr = TestExtractorNoop.from_url("test:noop") + tjob = self.jobclass(extr) + tjob._init() + + self.assertTrue(tjob.pathfmt) + self.assertTrue(tjob.archive) + self.assertTrue(tjob.hooks) + + def test_opt_init_false(self): + config.set((), "init", False) + config.set((), "archive", ":memory:") + config.set((), "postprocessors", "directory") + + extr = TestExtractorNoop.from_url("test:noop") + tjob = self.jobclass(extr) + tjob._init() + + self.assertFalse(tjob.pathfmt) + self.assertFalse(tjob.archive) + self.assertFalse(tjob.hooks) class TestKeywordJob(TestJob): @@ -122,6 +148,13 @@ user['self'] """) + def test_opt_init(self): + config.set((), "init", True) + + extr = TestExtractorNoop.from_url("test:noop") + tjob = self.jobclass(extr) + tjob._init() + class TestUrlJob(TestJob): jobclass = job.UrlJob @@ -165,6 +198,13 @@ https://example.org/2.jpg https://example.org/3.jpg """) + def test_opt_init(self): + config.set((), "init", True) + + extr = TestExtractorNoop.from_url("test:noop") + tjob = self.jobclass(extr) + tjob._init() + class TestInfoJob(TestJob): jobclass = job.InfoJob @@ -228,6 +268,13 @@ Directory format (default): """) + def test_opt_init(self): + config.set((), "init", True) + + extr = TestExtractorNoop.from_url("test:noop") + tjob = self.jobclass(extr) + tjob._init() + class TestDataJob(TestJob): jobclass = job.DataJob @@ -378,6 +425,13 @@ class TestDataJob(TestJob): for line in file.getvalue().split(): self.assertRegex(line, r"""^\[[23],("http[^"]+",)?\{.+\}\]$""") + def test_opt_init(self): + config.set((), "init", True) + + extr = TestExtractorNoop.from_url("test:noop") + tjob = self.jobclass(extr) + tjob._init() + class TestExtractor(Extractor): category = "test_category" @@ -437,9 +491,10 @@ class TestExtractorException(Extractor): return 1/0 -class TestExtractorAlt(Extractor): +class TestExtractorNoop(Extractor): category = "test_category_alt" subcategory = "test_subcategory" + pattern = r"test:noop" if __name__ == "__main__":