Fix pdf text extraction multipage - #5260
Open
codewithfourtix wants to merge 3 commits into
Open
Conversation
Restore the extracted-text read to its position after the page loop in get_text_lines. The refactoring in aboutcode-org#4606 removed one level of with-block nesting and dedented the whole function body except the final two lines, which silently moved them inside the for loop: - with the default max_pages=5, the function returned right after processing page 1, so text on pages 2-5 was never extracted and copyright/license/email/url detection silently missed it - when max_pages was reached via break, or the PDF had no pages, the function returned None, crashing the caller textcode.analysis.unicode_text_lines_from_pdf with a TypeError when it iterates the result Signed-off-by: Ali Zulfiqar <codewithfourtix@gmail.com>
Add a 7-page test PDF with distinct text on each page and tests asserting that: - text is extracted from all pages up to the default max_pages=5 - reaching max_pages returns the extracted lines and not None - max_pages=0 extracts all pages The existing PDF test files only assert content from the first page, which is why the regression was not caught. Signed-off-by: Ali Zulfiqar <codewithfourtix@gmail.com>
There was a problem hiding this comment.
Pull request overview
Fixes a regression in PDF text extraction where textcode/pdf.py:get_text_lines() returned after processing only the first page (and could return None in some paths), causing downstream text analysis to miss content beyond page 1 and potentially crash.
Changes:
- Move
extracted_text.seek(0)andreturn extracted_text.readlines()outside the per-page loop so extraction continues through all pages up tomax_pages. - Add regression tests covering multi-page extraction,
max_pages=1(noNone), andmax_pages=0(unlimited pages).
Reviewed changes
Copilot reviewed 1 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/textcode/pdf.py |
Fixes control flow so text extraction does not stop after the first processed page. |
tests/textcode/test_pdf.py |
Adds multi-page regression tests validating correct max_pages behavior and non-None returns. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
43
to
+47
| interpreter.process_page(page) | ||
| if max_pages and page_num == max_pages: | ||
| break | ||
| extracted_text.seek(0) | ||
| return extracted_text.readlines() | ||
| extracted_text.seek(0) | ||
| return extracted_text.readlines() |
Signed-off-by: Ali Zulfiqar <codewithfourtix@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fix a regression in
textcode/pdf.pywhere PDF text extraction silently stops after the first page, and can returnNoneinstead of a list of lines.The bug
The refactoring in #4606 (commit
fa63f1a7d, "Improve package scan performance") removed one level ofwith contextlib.closing(...)nesting inget_text_lines()and dedented the function body — except the final two lines, which kept their old absolute indentation and therefore silently moved inside the page loop:Consequences:
max_pages=5, the function returns right after processing page 1, so text on pages 2–5 is never extracted. Copyright, license, email and URL detection silently miss anything past the first page of every PDF.max_pagesis reached (viabreak), or the PDF yields no pages, the function returnsNone. The callertextcode.analysis.unicode_text_lines_from_pdfthen crashes withTypeError: 'NoneType' object is not iterable.Before #4606, both lines executed after the loop. This PR restores that placement.
Why existing tests did not catch it
The PDF test files in
tests/textcode/data/pdf/only assert content from the first page, so the suite passes both with and without the regression.Tests added
A 7-page test PDF (
multi_page.pdf) with distinct text on each page, plus three regression tests asserting that:max_pages=5(and not beyond);max_pagesreturns the extracted lines and notNone;max_pages=0extracts all pages.Verified against the pinned
pdfminer.six==20260107: all existing PDF tests still pass, and the new tests fail ondevelopand pass with this fix.Related issues
I checked open issues and PRs — none cover this regression. (Open issue #3794 is a different, older
TypeErrorcoming from inside pdfminer on a malformed PDF, predating #4606.)