refactor: clarify module bootstrap and G'MIC output handling

Import all built-in modules explicitly, remove dead ImageMagick branch,
and call finalize_gmic_output in gmic_grayscale for resume parity with gmic.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Frank Schwenk
2026-07-18 17:34:18 +02:00
parent a60a18a253
commit fd4658434a
3 changed files with 8 additions and 19 deletions
+5 -12
View File
@@ -4,14 +4,13 @@ from collections import defaultdict
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
# Register all built-in modules (side effect of submodule imports).
import imagepipeline.modules # noqa: F401
from imagepipeline.core.exceptions import ValidationError from imagepipeline.core.exceptions import ValidationError
from imagepipeline.core.runner import PipelineRunner from imagepipeline.core.runner import PipelineRunner
from imagepipeline.core.step import INPUT_SOURCE, StepDefinition, StepRef from imagepipeline.core.step import INPUT_SOURCE, StepDefinition, StepRef
from imagepipeline.modules.registry import get_module from imagepipeline.modules.registry import get_module
# Import built-in modules so they register on package load.
import imagepipeline.modules.imagemagick_grayscale # noqa: F401
class Pipeline: class Pipeline:
"""Define and run an image processing pipeline.""" """Define and run an image processing pipeline."""
@@ -61,9 +60,7 @@ class Pipeline:
input_refs = self._normalize_inputs(inputs) input_refs = self._normalize_inputs(inputs)
reserved = {"inputs", "input"} reserved = {"inputs", "input"}
if reserved & set(params): if reserved & set(params):
raise ValidationError( raise ValidationError("Do not pass 'inputs' or 'input' as module parameters")
"Do not pass 'inputs' or 'input' as module parameters"
)
definition = StepDefinition( definition = StepDefinition(
step_id=step_id, step_id=step_id,
@@ -97,9 +94,7 @@ class Pipeline:
def output_root(self) -> Path | None: def output_root(self) -> Path | None:
return self._output_root return self._output_root
def _normalize_inputs( def _normalize_inputs(self, inputs: StepRef | str | list[StepRef | str]) -> list[str]:
self, inputs: StepRef | str | list[StepRef | str]
) -> list[str]:
if isinstance(inputs, list): if isinstance(inputs, list):
if not inputs: if not inputs:
raise ValidationError("inputs must not be an empty list") raise ValidationError("inputs must not be an empty list")
@@ -110,9 +105,7 @@ class Pipeline:
if not step_id: if not step_id:
raise ValidationError("step_id must not be empty") raise ValidationError("step_id must not be empty")
if "/" in step_id or "\\" in step_id: if "/" in step_id or "\\" in step_id:
raise ValidationError( raise ValidationError(f"step_id must not contain path separators: {step_id!r}")
f"step_id must not contain path separators: {step_id!r}"
)
if any(step.step_id == step_id for step in self._steps): if any(step.step_id == step_id for step in self._steps):
raise ValidationError(f"Duplicate step_id: {step_id!r}") raise ValidationError(f"Duplicate step_id: {step_id!r}")
+2 -1
View File
@@ -4,7 +4,7 @@ from imagepipeline.core.context import ModuleContext
from imagepipeline.core.params import Param from imagepipeline.core.params import Param
from imagepipeline.modules.base import SubprocessModule from imagepipeline.modules.base import SubprocessModule
from imagepipeline.modules.registry import register from imagepipeline.modules.registry import register
from imagepipeline.utils.gmic import split_gmic_command from imagepipeline.utils.gmic import finalize_gmic_output, split_gmic_command
from imagepipeline.utils.subprocess import run_command from imagepipeline.utils.subprocess import run_command
@@ -35,3 +35,4 @@ class GmicGrayscale(SubprocessModule):
dst = ctx.output_dir / src.name dst = ctx.output_dir / src.name
cmd = ["gmic", str(src), *split_gmic_command(gmic_command), "-output", str(dst)] cmd = ["gmic", str(src), *split_gmic_command(gmic_command), "-output", str(dst)]
run_command(cmd, timeout=self.default_timeout) run_command(cmd, timeout=self.default_timeout)
finalize_gmic_output(ctx.output_dir, dst)
@@ -1,7 +1,5 @@
from __future__ import annotations from __future__ import annotations
from pathlib import Path
from imagepipeline.core.context import ModuleContext from imagepipeline.core.context import ModuleContext
from imagepipeline.core.params import Param from imagepipeline.core.params import Param
from imagepipeline.modules.base import SubprocessModule from imagepipeline.modules.base import SubprocessModule
@@ -34,8 +32,5 @@ class ImageMagickGrayscale(SubprocessModule):
for index, src in enumerate(ctx.input_paths, start=1): for index, src in enumerate(ctx.input_paths, start=1):
self.log_image(ctx, index, total, src) self.log_image(ctx, index, total, src)
dst = ctx.output_dir / src.name dst = ctx.output_dir / src.name
if command == "magick": cmd = [command, str(src), "-colorspace", colorspace, str(dst)]
cmd = [command, str(src), "-colorspace", colorspace, str(dst)]
else:
cmd = [command, str(src), "-colorspace", colorspace, str(dst)]
run_command(cmd) run_command(cmd)