Minor documentation and typing fixes

This commit is contained in:
James R. Barlow
2023-09-25 00:19:48 -07:00
parent 7018e2b247
commit 47b0f28564
5 changed files with 75 additions and 11 deletions
+46 -4
View File
@@ -14,7 +14,7 @@ from contextlib import suppress
from datetime import datetime, timezone
from pathlib import Path
from shutil import copyfileobj
from typing import Any, BinaryIO, Iterable, Sequence, cast
from typing import Any, BinaryIO, Iterable, Iterator, Sequence, cast
import img2pdf
import pikepdf
@@ -771,6 +771,14 @@ def get_docinfo(base_pdf: pikepdf.Pdf, context: PdfContext) -> dict[str, str]:
def generate_postscript_stub(context: PdfContext) -> Path:
"""Generates a PostScript file stub for the given PDF context.
Args:
context: The PDF context to generate the PostScript file stub for.
Returns:
Path: The path to the generated PostScript file stub.
"""
output_file = context.get_path('pdfa.ps')
generate_pdfa_ps(output_file)
return output_file
@@ -788,7 +796,7 @@ def convert_to_pdfa(input_pdf: Path, input_ps_stub: Path, context: PdfContext) -
# pikepdf can deal with this, but we make the world a better place by
# stamping them out as soon as possible.
with pikepdf.open(input_pdf) as pdf_file:
if _repair_docinfo_nulls(pdf_file):
if _repair_docinfo_nuls(pdf_file):
pdf_file.save(fix_docinfo_file)
else:
safe_symlink(input_pdf, fix_docinfo_file)
@@ -811,7 +819,7 @@ def convert_to_pdfa(input_pdf: Path, input_ps_stub: Path, context: PdfContext) -
return output_file
def _repair_docinfo_nulls(pdf):
def _repair_docinfo_nuls(pdf):
"""If the DocumentInfo block contains NUL characters, remove them.
If the DocumentInfo block is malformed, log an error and continue.
@@ -935,6 +943,17 @@ def metadata_fixup(working_file: Path, context: PdfContext) -> Path:
def _file_size_ratio(
input_file: Path, output_file: Path
) -> tuple[float | None, float | None]:
"""Calculate ratio of input to output file sizes and percentage savings.
Args:
input_file (Path): The path to the input file.
output_file (Path): The path to the output file.
Returns:
tuple[float | None, float | None]: A tuple containing the file size
ratio and the percentage savings achieved by the output file size
compared to the input file size.
"""
input_size = input_file.stat().st_size
output_size = output_file.stat().st_size
if output_size == 0:
@@ -965,7 +984,20 @@ def optimize_pdf(
return output_pdf, messages
def enumerate_compress_ranges(iterable):
def enumerate_compress_ranges(
iterable: Iterable,
) -> Iterator[tuple[tuple[int, int], Any]]:
"""Enumerate the ranges of non-empty elements in an iterable.
Compresses consecutive ranges of length 1 into single elements.
Args:
iterable: An iterable of elements to enumerate.
Yields:
A tuple containing a range of indices and the corresponding element.
If the element is None, the range represents a skipped range of indices.
"""
skipped_from, index = None, None
for index, txt_file in enumerate(iterable):
index += 1
@@ -1009,6 +1041,16 @@ def merge_sidecars(txt_files: Iterable[Path | None], context: PdfContext) -> Pat
def copy_final(
input_file: Path, output_file: str | Path | BinaryIO, _context: PdfContext
) -> None:
"""Copy the final temporary file to the output destination.
Args:
input_file (Path): The input file to copy.
output_file (str | Path | BinaryIO): The output file to copy to.
_context (PdfContext): The PDF context.
Returns:
None
"""
log.debug('%s -> %s', input_file, output_file)
with input_file.open('rb') as input_stream:
if output_file == '-':
+3 -1
View File
@@ -100,7 +100,9 @@ class OcrmypdfPluginManager(pluggy.PluginManager):
self.register(module)
def get_plugin_manager(plugins: list[str | Path], builtins=True):
def get_plugin_manager(
plugins: list[str | Path], builtins=True
) -> pluggy.PluginManager:
return OcrmypdfPluginManager(
project_name='ocrmypdf',
plugins=plugins,
+19 -3
View File
@@ -9,12 +9,15 @@ import logging
import os
import sys
import threading
from argparse import Namespace
from enum import IntEnum
from io import IOBase
from pathlib import Path
from typing import AnyStr, BinaryIO, Iterable, Union
from warnings import warn
import pluggy
from ocrmypdf._logging import PageNumberFilter, RichTqdmProgressAdapter
from ocrmypdf._plugin_manager import get_plugin_manager
from ocrmypdf._sync import run_pipeline
@@ -43,7 +46,7 @@ def configure_logging(
*,
progress_bar_friendly: bool = True,
manage_root_logger: bool = False,
plugin_manager=None,
plugin_manager: pluggy.PluginManager | None = None,
):
"""Set up logging.
@@ -131,8 +134,21 @@ def configure_logging(
def create_options(
*, input_file: PathOrIO, output_file: PathOrIO, parser: ArgumentParser, **kwargs
):
"""Construct an options object from the input/output files and keyword arguments."""
) -> Namespace:
"""Construct an options object from the input/output files and keyword arguments.
Args:
input_file: Input file path or file object.
output_file: Output file path or file object.
parser: ArgumentParser object.
**kwargs: Keyword arguments.
Returns:
argparse.Namespace: An argparse Namespace object containing the parsed arguments.
Raises:
TypeError: If the type of a keyword argument is not supported.
"""
cmdline = []
deferred = []
+5 -1
View File
@@ -15,7 +15,11 @@ T = TypeVar('T', int, float)
def numeric(basetype: Callable[[Any], T], min_: T | None = None, max_: T | None = None):
"""Validator for numeric params."""
"""Validator for numeric command line parameters.
Stipulates that the value must be of type basetype (typically int or float), and
optionally, within the range [min_, max_].
"""
min_ = basetype(min_) if min_ is not None else None
max_ = basetype(max_) if max_ is not None else None
+2 -2
View File
@@ -158,7 +158,7 @@ def safe_symlink(input_file: os.PathLike, soft_link_name: os.PathLike) -> None:
# Guard against soft linking to oneself
if input_file == soft_link_name:
log.warning(
"No symbolic link created. You are using the original data directory "
"No symbolic link created. You are using the original data directory "
"as the working directory."
)
return
@@ -303,7 +303,7 @@ def check_pdf(input_file: Path) -> bool:
return False
def clamp(n, smallest, largest): # mypy doesn't understand types for this
def clamp(n: T, smallest: T, largest: T) -> T:
"""Clamps the value of ``n`` to between ``smallest`` and ``largest``."""
return max(smallest, min(n, largest))