refactor: centralize plugin manager setup
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This commit is contained in:
+64
-6
@@ -70,6 +70,49 @@ PathOrIO = BinaryIO | StrPath
|
||||
_api_lock = threading.Lock()
|
||||
|
||||
|
||||
def setup_plugin_infrastructure(
|
||||
plugins: Sequence[Path | str] | None = None,
|
||||
plugin_manager: pluggy.PluginManager | None = None,
|
||||
) -> pluggy.PluginManager:
|
||||
"""Set up plugin infrastructure with proper initialization.
|
||||
|
||||
This function handles:
|
||||
1. Creating or validating the plugin manager
|
||||
2. Calling plugin initialization hooks
|
||||
3. Setting up any future plugin registries (Phase 2)
|
||||
|
||||
Args:
|
||||
plugins: List of plugin paths/names to load
|
||||
plugin_manager: Existing plugin manager (if any)
|
||||
|
||||
Returns:
|
||||
Properly initialized plugin manager
|
||||
|
||||
Raises:
|
||||
ValueError: If both plugins and plugin_manager are provided
|
||||
"""
|
||||
if plugins and plugin_manager:
|
||||
raise ValueError("plugins= and plugin_manager are mutually exclusive")
|
||||
|
||||
if not plugins:
|
||||
plugins = []
|
||||
elif isinstance(plugins, (str, Path)):
|
||||
plugins = [plugins]
|
||||
else:
|
||||
plugins = list(plugins)
|
||||
|
||||
# Create plugin manager if not provided
|
||||
if not plugin_manager:
|
||||
plugin_manager = get_plugin_manager(plugins)
|
||||
|
||||
# Initialize plugins (this was missing in the API path)
|
||||
plugin_manager.hook.initialize(plugin_manager=plugin_manager) # pylint: disable=no-member
|
||||
|
||||
# Future: Initialize plugin option registry here (Phase 2)
|
||||
|
||||
return plugin_manager
|
||||
|
||||
|
||||
class Verbosity(IntEnum):
|
||||
"""Verbosity level for configure_logging."""
|
||||
|
||||
@@ -363,8 +406,14 @@ def ocr( # noqa: D417
|
||||
|
||||
parser = get_parser()
|
||||
with _api_lock:
|
||||
if not plugin_manager:
|
||||
plugin_manager = get_plugin_manager(plugins)
|
||||
# Set up plugin infrastructure with proper initialization
|
||||
plugin_manager = setup_plugin_infrastructure(
|
||||
plugins=plugins,
|
||||
plugin_manager=plugin_manager
|
||||
)
|
||||
|
||||
# Get parser and let plugins add their options
|
||||
parser = get_parser()
|
||||
plugin_manager.hook.add_options(parser=parser) # pylint: disable=no-member
|
||||
|
||||
if 'verbose' in kwargs:
|
||||
@@ -490,8 +539,12 @@ def _pdf_to_hocr( # noqa: D417
|
||||
extra_attrs[key] = options_kwargs.pop(key)
|
||||
|
||||
with _api_lock:
|
||||
if not plugin_manager:
|
||||
plugin_manager = get_plugin_manager(plugins)
|
||||
# Set up plugin infrastructure with proper initialization
|
||||
plugin_manager = setup_plugin_infrastructure(
|
||||
plugins=plugins,
|
||||
plugin_manager=plugin_manager
|
||||
)
|
||||
|
||||
plugin_manager.hook.add_options(parser=get_parser()) # pylint: disable=no-member
|
||||
|
||||
# Create OCROptions directly
|
||||
@@ -589,8 +642,12 @@ def _hocr_to_ocr_pdf( # noqa: D417
|
||||
extra_attrs[key] = options_kwargs.pop(key)
|
||||
|
||||
with _api_lock:
|
||||
if not plugin_manager:
|
||||
plugin_manager = get_plugin_manager(plugins)
|
||||
# Set up plugin infrastructure with proper initialization
|
||||
plugin_manager = setup_plugin_infrastructure(
|
||||
plugins=plugins,
|
||||
plugin_manager=plugin_manager
|
||||
)
|
||||
|
||||
plugin_manager.hook.add_options(parser=get_parser()) # pylint: disable=no-member
|
||||
|
||||
# Create OCROptions directly
|
||||
@@ -620,4 +677,5 @@ __all__ = [
|
||||
'ocr',
|
||||
'run_pipeline',
|
||||
'run_pipeline_cli',
|
||||
'setup_plugin_infrastructure',
|
||||
]
|
||||
|
||||
+6
-2
@@ -483,13 +483,17 @@ def get_options_and_plugins(
|
||||
Returns:
|
||||
Tuple of (OCROptions, PluginManager)
|
||||
"""
|
||||
# Import here to avoid circular imports
|
||||
from ocrmypdf.api import setup_plugin_infrastructure
|
||||
|
||||
# First pass: get plugins so we can register their options
|
||||
pre_options, _unused = plugins_only_parser.parse_known_args(args=args)
|
||||
plugin_manager = get_plugin_manager(pre_options.plugins)
|
||||
|
||||
# Set up plugin infrastructure with proper initialization
|
||||
plugin_manager = setup_plugin_infrastructure(plugins=pre_options.plugins)
|
||||
|
||||
# Get parser and let plugins add their options
|
||||
parser = get_parser()
|
||||
plugin_manager.hook.initialize(plugin_manager=plugin_manager) # pylint: disable=no-member
|
||||
plugin_manager.hook.add_options(parser=parser) # pylint: disable=no-member
|
||||
|
||||
# Parse all arguments
|
||||
|
||||
@@ -12,6 +12,7 @@ import pytest
|
||||
|
||||
from ocrmypdf import api, pdfinfo
|
||||
from ocrmypdf._exec import unpaper
|
||||
from ocrmypdf.api import setup_plugin_infrastructure
|
||||
from ocrmypdf.cli import get_options_and_plugins
|
||||
from ocrmypdf.exceptions import ExitCode
|
||||
|
||||
@@ -164,3 +165,8 @@ def pytest_collection_modifyitems(config, items):
|
||||
for item in items:
|
||||
if "slow" in item.keywords:
|
||||
item.add_marker(skip_slow)
|
||||
|
||||
|
||||
def get_test_plugin_manager(plugins=None):
|
||||
"""Get a properly initialized plugin manager for testing."""
|
||||
return setup_plugin_infrastructure(plugins=plugins or [])
|
||||
|
||||
@@ -16,6 +16,7 @@ from ocrmypdf._jobcontext import PdfContext
|
||||
from ocrmypdf._metadata import metadata_fixup
|
||||
from ocrmypdf._pipeline import convert_to_pdfa
|
||||
from ocrmypdf._plugin_manager import get_plugin_manager
|
||||
from ocrmypdf.api import setup_plugin_infrastructure
|
||||
from ocrmypdf.cli import get_options_and_plugins
|
||||
from ocrmypdf.exceptions import ExitCode
|
||||
from ocrmypdf.pdfa import file_claims_pdfa, generate_pdfa_ps
|
||||
@@ -330,8 +331,10 @@ def test_metadata_fixup_warning(resources, outdir, caplog):
|
||||
|
||||
copyfile(resources / 'graph.pdf', outdir / 'graph.pdf')
|
||||
|
||||
# Use the new setup function instead of get_plugin_manager directly
|
||||
plugin_manager = setup_plugin_infrastructure([])
|
||||
context = PdfContext(
|
||||
options, outdir, outdir / 'graph.pdf', None, get_plugin_manager([])
|
||||
options, outdir, outdir / 'graph.pdf', None, plugin_manager
|
||||
)
|
||||
metadata_fixup(
|
||||
working_file=outdir / 'graph.pdf', context=context, pdf_save_settings={}
|
||||
@@ -346,7 +349,7 @@ def test_metadata_fixup_warning(resources, outdir, caplog):
|
||||
graph.save(outdir / 'graph_mod.pdf')
|
||||
|
||||
context = PdfContext(
|
||||
options, outdir, outdir / 'graph_mod.pdf', None, get_plugin_manager([])
|
||||
options, outdir, outdir / 'graph_mod.pdf', None, plugin_manager
|
||||
)
|
||||
metadata_fixup(
|
||||
working_file=outdir / 'graph.pdf', context=context, pdf_save_settings={}
|
||||
@@ -379,8 +382,11 @@ def test_prevent_gs_invalid_xml(resources, outdir):
|
||||
]
|
||||
)
|
||||
pdfinfo = PdfInfo(outdir / 'layers.rendered.pdf')
|
||||
|
||||
# Use the new setup function
|
||||
plugin_manager = setup_plugin_infrastructure([])
|
||||
context = PdfContext(
|
||||
options, outdir, outdir / 'layers.rendered.pdf', pdfinfo, get_plugin_manager([])
|
||||
options, outdir, outdir / 'layers.rendered.pdf', pdfinfo, plugin_manager
|
||||
)
|
||||
|
||||
convert_to_pdfa(
|
||||
|
||||
@@ -12,6 +12,7 @@ from packaging.version import Version
|
||||
|
||||
from ocrmypdf._exec import unpaper
|
||||
from ocrmypdf._validation import check_options
|
||||
from ocrmypdf.api import setup_plugin_infrastructure
|
||||
from ocrmypdf.cli import get_options_and_plugins
|
||||
from ocrmypdf.exceptions import BadArgsError, ExitCode, MissingDependencyError
|
||||
|
||||
|
||||
Reference in New Issue
Block a user