Skip to content

fix(docker): stop legacy PyPDF2 3.x shadowing pypdf, breaking multi-record PDF print - #407

Open
gonzalesedwin1123 wants to merge 2 commits into
19.0from
op-1168
Open

fix(docker): stop legacy PyPDF2 3.x shadowing pypdf, breaking multi-record PDF print#407
gonzalesedwin1123 wants to merge 2 commits into
19.0from
op-1168

Conversation

@gonzalesedwin1123

Copy link
Copy Markdown
Member

Summary

  • Install Odoo with uv pip install --no-deps in docker/Dockerfile. Odoo's setup.py declares an unpinned PyPDF2, so the editable install pulled legacy PyPDF2 3.0.1 alongside the pypdf 5.4.0 that OCB's requirements.txt pins for Python 3.13 (all of Odoo's real dependencies are already installed from that requirements file two layers earlier).
  • odoo/tools/pdf probes the legacy PyPDF2 package before pypdf with no version guard, so PyPDF2 3.x won the backend selection — and its removed 1.x API (reader.numPages, getPage) raises PyPDF2.errors.DeprecationError in ir.actions.report._render_qweb_pdf_prepare_streams whenever a report is printed for more than one record (single-record printing skips the split path, which is why it still worked).
  • Add a regression test in spp_base_common (test_pdf_backend.py) that exercises the exact legacy split API against the image's selected PDF backend; it fails with the production error on any image that regresses.
  • Bump spp_base_common to 19.0.2.0.2 with a readme/HISTORY.md fragment.

OpenProject

  • Fixes OP#1168 (Unable to print PDF for multiple records)

Test plan

  • TDD red: test fails on the pre-fix image with PyPDF2.errors.DeprecationError: reader.numPages ... removed in PyPDF2 3.0.0 — identical to the OP#1168 screenshot
  • TDD green: ./spp t spp_base_common on the rebuilt image — 7 passed, 0 failed, 0 errors
  • Rebuilt image has no PyPDF2 installed; odoo.tools.pdf selects the _pypdf backend (pypdf 5.4.0)
  • End-to-end: _render_qweb_pdf('base.report_irmodulereference', res_ids=[<3 ids>]) in the running dev container returns a valid PDF through wkhtmltopdf + the multi-record split path
  • No bundled addon imports PyPDF2 directly (grepped /mnt/extra-addons and the OCA addon trees)

Notes

  • Root cause is upstream: OCB setup.py:52 unpinned PyPDF2 contradicts its own requirements.txt pin of PyPDF==5.4.0 for py3.13, and odoo/tools/pdf/_pypdf2_2.py accepts PyPDF2 3.x without a version guard. Upstream reports to follow; this PR fixes our image regardless.

…ecord PDF print

Odoo's setup.py declares an unpinned PyPDF2, so the editable install pulled
legacy PyPDF2 3.0.1 next to the pypdf 5.4.0 that OCB's requirements.txt pins
for Python 3.13. odoo.tools.pdf probes PyPDF2 first with no version guard,
and its removed 1.x API (reader.numPages) raises DeprecationError in
_render_qweb_pdf_prepare_streams whenever more than one record is printed.

Install Odoo with --no-deps (its real dependencies are already installed
from requirements.txt) and add a regression test in spp_base_common that
exercises the legacy split API against the image's selected PDF backend.

Fixes OP#1168
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.34%. Comparing base (c33d3cb) to head (fd828cd).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             19.0     #407      +/-   ##
==========================================
+ Coverage   71.49%   72.34%   +0.84%     
==========================================
  Files         243      404     +161     
  Lines       20785    29008    +8223     
==========================================
+ Hits        14860    20985    +6125     
- Misses       5925     8023    +2098     
Flag Coverage Δ
spp_analytics 93.25% <ø> (?)
spp_api_v2_change_request 66.53% <ø> (ø)
spp_api_v2_cycles 71.03% <ø> (?)
spp_api_v2_data 77.77% <ø> (?)
spp_api_v2_entitlements 70.23% <ø> (?)
spp_api_v2_gis 71.57% <ø> (?)
spp_api_v2_programs 92.22% <ø> (?)
spp_api_v2_service_points 71.03% <ø> (?)
spp_api_v2_simulation 71.19% <ø> (?)
spp_approval 50.34% <ø> (?)
spp_area 80.16% <ø> (?)
spp_area_hdx 81.60% <ø> (?)
spp_audit 72.13% <ø> (?)
spp_base_common 91.07% <ø> (ø)
spp_case_cel 89.50% <ø> (?)
spp_case_demo 94.75% <ø> (?)
spp_programs 65.27% <ø> (ø)
spp_registry 87.22% <ø> (+0.07%) ⬆️
spp_security 69.56% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 162 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gonzalesedwin1123

Copy link
Copy Markdown
Member Author

Upstream reports filed: odoo/odoo#281660 (odoo/odoo#281660) and OCA/OCB#1346 (OCA/OCB#1346). If either lands a proper fix (version guard in odoo/tools/pdf or a setup.py pin), the --no-deps here remains correct and harmless — it simply keeps requirements.txt as the single source of dependency pins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant