home · contact · privacy
Re-structure reportlab import to easen type-checking over it.
authorPlom Heller <plom@plomlompom.com>
Sun, 5 Apr 2026 23:05:41 +0000 (01:05 +0200)
committerPlom Heller <plom@plomlompom.com>
Sun, 5 Apr 2026 23:05:41 +0000 (01:05 +0200)
bookmaker.py
requirements.txt

index 66cc6b3f3bbdfa67556e0892dd817463c61df07c..27313edb4ff287a9c64476f137467e33290b2ef7 100755 (executable)
@@ -12,7 +12,7 @@ from argparse import (
 from io import BufferedReader, BytesIO
 from os.path import isfile
 from sys import exit as sys_exit
-from typing import Any, Optional
+from typing import Optional
 
 
 def handled_error_exit(
@@ -27,6 +27,11 @@ try:
     import pypdf
 except ImportError:
     handled_error_exit('Can\'t run at all without pypdf installed.')
+try:
+    from reportlab.pdfgen.canvas import Canvas
+    GOT_CANVAS = True
+except ImportError:
+    GOT_CANVAS = False
 
 # some general paper geometry constants
 POINTS_PER_CM = 10 * 72 / 25.4
@@ -480,7 +485,6 @@ def build_nup4_output(
         page_croppings: list[PageCrop],
         args_print_margin: int,
         args_analyze: str,
-        canvas_class: Any
         ) -> None:
     'Build nup4 pages from inputs.'
     print('-n: building 4-input-pages-per-output-page book')
@@ -508,8 +512,7 @@ def build_nup4_output(
             ornate_nup4(args_analyze,
                         is_front_page,
                         new_page,
-                        nup4_geometry,
-                        canvas_class)
+                        nup4_geometry)
             writer.add_page(new_page)
             nup4_i = 0
             is_front_page = not is_front_page
@@ -599,13 +602,12 @@ def ornate_nup4(
         is_front_page: bool,
         new_page: pypdf.PageObject,
         nup4_geometry: Nup4Geometry,
-        canvas_class
         ) -> None:
     'Apply nup4 line guides onto new_page.'
     if args_analyze:
         # borders
         packet = BytesIO()
-        c = canvas_class(packet, pagesize=A4)
+        c = Canvas(packet, pagesize=A4)
         c.setLineWidth(0.1)
         c.line(0, A4_HEIGHT, A4_WIDTH, A4_HEIGHT)
         c.line(0, A4_HALF_HEIGHT, A4_WIDTH, A4_HALF_HEIGHT)
@@ -626,7 +628,7 @@ def ornate_nup4(
     x_right_spine_limit = A4_WIDTH - x_left_spine_limit
     if args_analyze or is_front_page:
         packet = BytesIO()
-        c = canvas_class(packet, pagesize=A4)
+        c = Canvas(packet, pagesize=A4)
     if args_analyze:
         # spine lines
         c.setLineWidth(0.1)
@@ -643,7 +645,7 @@ def ornate_nup4(
 
 
 def draw_cut(
-        canvas: Any,
+        canvas: 'Canvas',
         x_spine_limit: float,
         direction: int
         ) -> None:
@@ -662,12 +664,8 @@ def main(
     'Full program run to be wrapped into ArgFail catcher.'
     args = parse_args()
     validate_args_syntax(args)
-    if args.nup4:
-        try:
-            from reportlab.pdfgen.canvas import Canvas
-        except ImportError:
-            raise ArgFail('n',
-                          'need reportlab.pdfgen.canvas installed for --nup4')
+    if args.nup4 and not GOT_CANVAS:
+        raise ArgFail('n', 'need reportlab.pdfgen.canvas installed for --nup4')
     pages_to_add, opened_files = args_to_pagelist(args.input_file,
                                                   args.page_range)
     validate_ranges(args, pages_to_add)
@@ -686,8 +684,7 @@ def main(
                           pages_to_add,
                           page_croppings,
                           args.print_margin,
-                          args.analyze,
-                          Canvas)
+                          args.analyze)
     else:
         build_single_pages_output(writer, pages_to_add, page_croppings)
     for file in opened_files:
index 0338f1e4899bf26c824895b858249be6cedfadf8..8f71fb93f158f7747470423c06cc0846ef2ba5bd 100644 (file)
@@ -1,3 +1,5 @@
 pillow==12.2.0
 pypdf==6.9.2
 reportlab==4.4.10
+# for mypy only
+types-reportlab==4.4.10.20260402