PyMuPDF 1.24.5__tar.gz → 1.24.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/PKG-INFO +1 -1
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/READMErb.md +1 -1
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/changes.txt +40 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/pipcl.py +28 -14
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/scripts/gh_release.py +28 -6
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/scripts/sysinstall.py +59 -23
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/scripts/test.py +19 -1
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/setup.py +38 -13
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/__init__.py +122 -168
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/extra.i +6 -2
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/table.py +11 -7
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/utils.py +57 -65
- PyMuPDF-1.24.7/tests/resources/dotted-gridlines.pdf +0 -0
- PyMuPDF-1.24.7/tests/resources/test-3591.pdf +0 -0
- PyMuPDF-1.24.7/tests/resources/test_3493.epub +0 -0
- PyMuPDF-1.24.7/tests/resources/test_3594.pdf +0 -0
- PyMuPDF-1.24.7/tests/resources/test_3615.epub +0 -0
- PyMuPDF-1.24.7/tests/resources/test_toc_count.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_2791.py +3 -2
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_drawings.py +11 -1
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_general.py +11 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_metadata.py +1 -1
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_pixmap.py +94 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_tables.py +17 -1
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_textbox.py +11 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_textextract.py +15 -0
- PyMuPDF-1.24.7/tests/test_toc.py +276 -0
- PyMuPDF-1.24.5/tests/test_toc.py +0 -137
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/COPYING +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/README.md +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/pyproject.toml +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/pytest.ini +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/__main__.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/_apply_pages.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/fitz___init__.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/fitz_table.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/fitz_utils.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src/pymupdf.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/__init__.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/__main__.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/_config.h +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/fitz_old.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-annot.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-convert.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-defines.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-devices.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-fields.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-fileobj.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-geo-c.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-geo-py.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-globals.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-other.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-pdfinfo.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-pixmap.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-portfolio.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-python.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-select.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-stext.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/helper-xobject.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/utils.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/src_classic/version.i +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/README.md +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/conftest.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/gentle_compare.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/001003ED.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/1.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/2.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/2201.00069.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/3.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/4.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/Bezier.epub +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/PragmaticaC.otf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/battery-file-22.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/bug1945.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/bug1971.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/chinese-tables.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/chinese-tables.pickle +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/circular-toc.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/cython.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/cython.pickle +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/full_toc.txt +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/github_sample.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/has-bad-fonts.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/image-file1.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/img-transparent.png +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/joined.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/metadata.txt +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/mupdf_explored.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/nur-ruhig.jpg +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/quad-calc-0.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/simple_toc.txt +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/small-table.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/strict-yes-no.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/symbol-list.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/symbols.txt +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test-2333.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test-2462.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test-2812.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test-3143.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test-3150.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test-3207.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test-707448.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test-707673.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test2093.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test2182.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test2238.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_1645_expected_1.22.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_1645_expected_1.24.2.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_1645_expected_1.24.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_1645_expected_1.25.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_1824.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2108.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2270.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2533.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2548.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2553-2.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2553.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2596.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2608_expected +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2634.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2635.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2645_1.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2645_2.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2645_3.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2710.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2730.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2742.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2788.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2791_content.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2791_coverpage.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2861.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2871.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2885.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2904.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2907.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2954.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2957_1.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2957_2.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2969.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_2979.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3058.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3062.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3070.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3072.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3087.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3179.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3186.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3197.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3357.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3362.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_3376.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_annot_file_info.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/test_delete_image.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/type3font.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/v110-changes.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/resources/widgettest.pdf +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/run_compound.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_2548.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_2634.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_2904.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_2907.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_annots.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_badfonts.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_balance_count.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_cluster_drawings.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_crypting.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_docs_samples.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_embeddedfiles.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_extractimage.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_flake8.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_font.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_geometry.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_imagebbox.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_import.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_insertimage.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_insertpdf.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_linequad.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_mupdf_regressions.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_named_links.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_nonpdf.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_object_manipulation.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_objectstreams.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_optional_content.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_page_links.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_pagedelete.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_pagelabels.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_pylint.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_remove-rotation.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_showpdfpage.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_story.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_tesseract.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_textsearch.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_widgets.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/tests/test_word_delimiters.py +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/valgrind.supp +0 -0
- {PyMuPDF-1.24.5 → PyMuPDF-1.24.7}/wdev.py +0 -0
|
@@ -2,6 +2,46 @@ Change Log
|
|
|
2
2
|
==========
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
**Changes in version 1.24.7 (2024-06-26)**
|
|
6
|
+
|
|
7
|
+
* Fixed issues:
|
|
8
|
+
|
|
9
|
+
* **Fixed** `3615 <https://github.com/pymupdf/PyMuPDF/issues/3615>`_: Document.pagemode or Document.pagelayout crashes for epub files
|
|
10
|
+
* **Fixed** `3616 <https://github.com/pymupdf/PyMuPDF/issues/3616>`_: not last version reported
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
**Changes in version 1.24.6 (2024-06-25)**
|
|
14
|
+
|
|
15
|
+
* Fixed issues:
|
|
16
|
+
|
|
17
|
+
* **Fixed** `3599 <https://github.com/pymupdf/PyMuPDF/issues/3599>`_: Story.fit_width() has a weird line
|
|
18
|
+
* **Fixed** `3594 <https://github.com/pymupdf/PyMuPDF/issues/3594>`_: Garbled extraction for Amazon Sustainability Report
|
|
19
|
+
* **Fixed** `3591 <https://github.com/pymupdf/PyMuPDF/issues/3591>`_: 'width' in Page.get_drawings() returns width equal as 0
|
|
20
|
+
* **Fixed** `3561 <https://github.com/pymupdf/PyMuPDF/issues/3561>`_: ZeroDivisionError: float division by zero with page.apply_redactions()
|
|
21
|
+
* **Fixed** `3559 <https://github.com/pymupdf/PyMuPDF/issues/3559>`_: SegFault 11 when empty H1 H2 H3 H4 etc element is used in insert_htmlbox
|
|
22
|
+
* **Fixed** `3539 <https://github.com/pymupdf/PyMuPDF/issues/3539>`_: Add dotted gridline detection to table recognition
|
|
23
|
+
* **Fixed** `3519 <https://github.com/pymupdf/PyMuPDF/issues/3519>`_: get_toc(simple=False) AttributeError: 'Outline' object has no attribute 'rect'
|
|
24
|
+
* **Fixed** `3510 <https://github.com/pymupdf/PyMuPDF/issues/3510>`_: page.get_label() gets wrong label on the first page of doc
|
|
25
|
+
* **Fixed** `3494 <https://github.com/pymupdf/PyMuPDF/issues/3494>`_: 1.24.2/1.24.3: spurious characters introduced when using subset_fonts and insert_pdf
|
|
26
|
+
* **Fixed** `3470 <https://github.com/pymupdf/PyMuPDF/issues/3470>`_: subset_fonts error exit without exception/warning
|
|
27
|
+
* **Fixed** `3400 <https://github.com/pymupdf/PyMuPDF/issues/3400>`_: set_toc alters link coordinates for some rotated pages on pymupdf 1.24.2
|
|
28
|
+
* **Fixed** `3347 <https://github.com/pymupdf/PyMuPDF/issues/3347>`_: Incorrect links to points on pages having different heights
|
|
29
|
+
* **Fixed** `3237 <https://github.com/pymupdf/PyMuPDF/issues/3237>`_: Set_metadata() does not work
|
|
30
|
+
* **Fixed** `3493 <https://github.com/pymupdf/PyMuPDF/discussions/3493>`_: Isolate PyMuPDF from other libraries; issues when PyMuPDF is loaded with other libraries like GdkPixbuf
|
|
31
|
+
|
|
32
|
+
* Other:
|
|
33
|
+
|
|
34
|
+
* Fixed concurrent use of PyMuPDF caused by use of constant temporary filenames.
|
|
35
|
+
|
|
36
|
+
* Add musllinux x86_64 wheels to release.
|
|
37
|
+
|
|
38
|
+
* Added clearer version information:
|
|
39
|
+
|
|
40
|
+
* `pymupdf.pymupdf_version`.
|
|
41
|
+
* `pymupdf.mupdf_version`.
|
|
42
|
+
* `pymupdf.pymupdf_date`.
|
|
43
|
+
|
|
44
|
+
|
|
5
45
|
**Changes in version 1.24.5 (2024-05-30)**
|
|
6
46
|
|
|
7
47
|
* Fixed issues:
|
|
@@ -2075,49 +2075,63 @@ def run_if( command, out, *prerequisites):
|
|
|
2075
2075
|
>>> out = 'run_if_test_out'
|
|
2076
2076
|
>>> if os.path.exists( out):
|
|
2077
2077
|
... os.remove( out)
|
|
2078
|
+
>>> if os.path.exists( f'{out}.cmd'):
|
|
2079
|
+
... os.remove( f'{out}.cmd')
|
|
2078
2080
|
>>> run_if( f'touch {out}', out)
|
|
2081
|
+
pipcl.py: run_if(): Running command because: File does not exist: 'run_if_test_out'
|
|
2082
|
+
pipcl.py: run(): Running: touch run_if_test_out
|
|
2079
2083
|
True
|
|
2080
2084
|
|
|
2081
2085
|
If we repeat, the output file will be up to date so the command is not run:
|
|
2082
2086
|
|
|
2083
2087
|
>>> run_if( f'touch {out}', out)
|
|
2088
|
+
pipcl.py: run_if(): Not running command because up to date: 'run_if_test_out'
|
|
2084
2089
|
|
|
2085
2090
|
If we change the command, the command is run:
|
|
2086
2091
|
|
|
2087
2092
|
>>> run_if( f'touch {out}', out)
|
|
2093
|
+
pipcl.py: run_if(): Running command because: Command has changed
|
|
2094
|
+
pipcl.py: run(): Running: touch run_if_test_out
|
|
2088
2095
|
True
|
|
2089
2096
|
|
|
2090
2097
|
If we add a prerequisite that is newer than the output, the command is run:
|
|
2091
2098
|
|
|
2099
|
+
>>> time.sleep(1)
|
|
2092
2100
|
>>> prerequisite = 'run_if_test_prerequisite'
|
|
2093
2101
|
>>> run( f'touch {prerequisite}')
|
|
2094
|
-
|
|
2102
|
+
pipcl.py: run(): Running: touch run_if_test_prerequisite
|
|
2103
|
+
>>> run_if( f'touch {out}', out, prerequisite)
|
|
2104
|
+
pipcl.py: run_if(): Running command because: Prerequisite is new: 'run_if_test_prerequisite'
|
|
2105
|
+
pipcl.py: run(): Running: touch run_if_test_out
|
|
2095
2106
|
True
|
|
2096
2107
|
|
|
2097
2108
|
If we repeat, the output will be newer than the prerequisite, so the
|
|
2098
2109
|
command is not run:
|
|
2099
2110
|
|
|
2100
|
-
>>> run_if( f'touch
|
|
2111
|
+
>>> run_if( f'touch {out}', out, prerequisite)
|
|
2112
|
+
pipcl.py: run_if(): Not running command because up to date: 'run_if_test_out'
|
|
2101
2113
|
'''
|
|
2102
2114
|
doit = False
|
|
2115
|
+
cmd_path = f'{out}.cmd'
|
|
2116
|
+
|
|
2103
2117
|
if not doit:
|
|
2104
2118
|
out_mtime = _fs_mtime( out)
|
|
2105
2119
|
if out_mtime == 0:
|
|
2106
2120
|
doit = f'File does not exist: {out!r}'
|
|
2107
2121
|
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
else:
|
|
2113
|
-
cmd = None
|
|
2114
|
-
if command != cmd:
|
|
2115
|
-
if cmd is None:
|
|
2116
|
-
doit = 'No previous command stored'
|
|
2122
|
+
if not doit:
|
|
2123
|
+
if os.path.isfile( cmd_path):
|
|
2124
|
+
with open( cmd_path) as f:
|
|
2125
|
+
cmd = f.read()
|
|
2117
2126
|
else:
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2127
|
+
cmd = None
|
|
2128
|
+
if command != cmd:
|
|
2129
|
+
if cmd is None:
|
|
2130
|
+
doit = 'No previous command stored'
|
|
2131
|
+
else:
|
|
2132
|
+
doit = f'Command has changed'
|
|
2133
|
+
if 0:
|
|
2134
|
+
doit += f': {cmd!r} => {command!r}'
|
|
2121
2135
|
|
|
2122
2136
|
if not doit:
|
|
2123
2137
|
# See whether any prerequisites are newer than target.
|
|
@@ -51,6 +51,8 @@ action inputs, which can't be easily translated into command-line arguments.
|
|
|
51
51
|
inputs_PYMUPDF_SETUP_MUPDF_BUILD
|
|
52
52
|
Used to directly set PYMUPDF_SETUP_MUPDF_BUILD.
|
|
53
53
|
E.g. 'git:--recursive --depth 1 --shallow-submodules --branch master https://github.com/ArtifexSoftware/mupdf.git'
|
|
54
|
+
inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE
|
|
55
|
+
Used to directly set PYMUPDF_SETUP_MUPDF_BUILD_TYPE.
|
|
54
56
|
inputs_wheels_implementations
|
|
55
57
|
Used to directly set PYMUPDF_SETUP_IMPLEMENTATIONS.
|
|
56
58
|
'a', 'b', 'ab'.
|
|
@@ -133,6 +135,12 @@ def main():
|
|
|
133
135
|
pattern = f'{prefix}-*{platform_tag()}.whl'
|
|
134
136
|
paths = glob.glob( pattern)
|
|
135
137
|
log( f'{pattern=} {paths=}')
|
|
138
|
+
# Follow pipcl.py and look at AUDITWHEEL_PLAT. This allows us to
|
|
139
|
+
# cope if building for both musl and normal linux.
|
|
140
|
+
awp = os.environ.get('AUDITWHEEL_PLAT')
|
|
141
|
+
if awp:
|
|
142
|
+
paths = [i for i in paths if awp in i]
|
|
143
|
+
log(f'After selecting AUDITWHEEL_PLAT={awp!r}, {paths=}.')
|
|
136
144
|
paths = ' '.join( paths)
|
|
137
145
|
run( f'pip install {paths}')
|
|
138
146
|
elif arg == 'venv':
|
|
@@ -180,6 +188,7 @@ def build( platform_=None, valgrind=False):
|
|
|
180
188
|
inputs_wheels_windows_auto = get_bool('inputs_wheels_windows_auto', inputs_wheels_default)
|
|
181
189
|
inputs_wheels_cps = os.environ.get('inputs_wheels_cps')
|
|
182
190
|
inputs_PYMUPDF_SETUP_MUPDF_BUILD = os.environ.get('inputs_PYMUPDF_SETUP_MUPDF_BUILD')
|
|
191
|
+
inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE = os.environ.get('inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE')
|
|
183
192
|
inputs_wheels_implementations = os.environ.get('inputs_wheels_implementations', 'b')
|
|
184
193
|
|
|
185
194
|
log( f'{inputs_flavours=}')
|
|
@@ -194,6 +203,7 @@ def build( platform_=None, valgrind=False):
|
|
|
194
203
|
log( f'{inputs_wheels_windows_auto=}')
|
|
195
204
|
log( f'{inputs_wheels_cps=}')
|
|
196
205
|
log( f'{inputs_PYMUPDF_SETUP_MUPDF_BUILD=}')
|
|
206
|
+
log( f'{inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE=}')
|
|
197
207
|
|
|
198
208
|
# Build Pyodide wheel if specified.
|
|
199
209
|
#
|
|
@@ -236,7 +246,11 @@ def build( platform_=None, valgrind=False):
|
|
|
236
246
|
else:
|
|
237
247
|
log( f'Not changing {name}={v!r} to {value!r}')
|
|
238
248
|
set_if_unset( 'CIBW_BUILD_VERBOSITY', '3')
|
|
239
|
-
|
|
249
|
+
# We exclude pp* because of `fitz_wrap.obj : error LNK2001: unresolved
|
|
250
|
+
# external symbol PyUnicode_DecodeRawUnicodeEscape`.
|
|
251
|
+
# 2024-06-05: musllinux on aarch64 fails because libclang cannot find
|
|
252
|
+
# libclang.so.
|
|
253
|
+
set_if_unset( 'CIBW_SKIP', 'pp* *i686 cp36* cp37* *musllinux*aarch64*')
|
|
240
254
|
|
|
241
255
|
def make_string(*items):
|
|
242
256
|
ret = list()
|
|
@@ -315,6 +329,10 @@ def build( platform_=None, valgrind=False):
|
|
|
315
329
|
env_set('PYMUPDF_SETUP_MUPDF_BUILD', inputs_PYMUPDF_SETUP_MUPDF_BUILD, pass_=True)
|
|
316
330
|
env_set('PYMUPDF_SETUP_MUPDF_TGZ', '', pass_=True) # Don't put mupdf in sdist.
|
|
317
331
|
|
|
332
|
+
if inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE not in ('-', None):
|
|
333
|
+
log(f'Setting PYMUPDF_SETUP_MUPDF_BUILD_TYPE to {inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE!r}.')
|
|
334
|
+
env_set('PYMUPDF_SETUP_MUPDF_BUILD_TYPE', inputs_PYMUPDF_SETUP_MUPDF_BUILD_TYPE, pass_=True)
|
|
335
|
+
|
|
318
336
|
def set_cibuild_test():
|
|
319
337
|
log( f'set_cibuild_test(): {inputs_skeleton=}')
|
|
320
338
|
valgrind_text = ''
|
|
@@ -440,7 +458,7 @@ def cpu_bits():
|
|
|
440
458
|
#
|
|
441
459
|
venv_name = f'venv-pymupdf-{platform.python_version()}-{cpu_bits()}'
|
|
442
460
|
|
|
443
|
-
def venv( command=None, packages=None, quick=False):
|
|
461
|
+
def venv( command=None, packages=None, quick=False, system_site_packages=False):
|
|
444
462
|
'''
|
|
445
463
|
Runs remaining args, or the specified command if present, in a venv.
|
|
446
464
|
|
|
@@ -454,16 +472,17 @@ def venv( command=None, packages=None, quick=False):
|
|
|
454
472
|
install Python packages in it.
|
|
455
473
|
'''
|
|
456
474
|
command2 = ''
|
|
457
|
-
ssp = ''
|
|
458
475
|
if platform.system() == 'OpenBSD':
|
|
459
476
|
# libclang not available from pypi.org, but system py3-llvm package
|
|
460
477
|
# works. `pip install` should be run with --no-build-isolation and
|
|
461
478
|
# explicit `pip install swig setuptools psutil`.
|
|
462
|
-
|
|
479
|
+
system_site_packages = True
|
|
480
|
+
#ssp = ' --system-site-packages'
|
|
463
481
|
log(f'OpenBSD: libclang not available from pypi.org.')
|
|
464
482
|
log(f'OpenBSD: system package `py3-llvm` must be installed.')
|
|
465
483
|
log(f'OpenBSD: creating venv with --system-site-packages.')
|
|
466
484
|
log(f'OpenBSD: `pip install .../PyMuPDF` must be preceded by install of swig etc.')
|
|
485
|
+
ssp = ' --system-site-packages' if system_site_packages else ''
|
|
467
486
|
if quick and os.path.isdir(venv_name):
|
|
468
487
|
log(f'{quick=}: Not creating venv because directory already exists: {venv_name}')
|
|
469
488
|
command2 += 'true'
|
|
@@ -544,8 +563,11 @@ def pyodide_setup(clean=False):
|
|
|
544
563
|
# Clone emsdk.
|
|
545
564
|
#
|
|
546
565
|
dir_emsdk = 'emsdk'
|
|
547
|
-
if clean
|
|
548
|
-
shutil.rmtree(
|
|
566
|
+
if clean:
|
|
567
|
+
shutil.rmtree(dir_emsdk, ignore_errors=1)
|
|
568
|
+
# 2024-06-25: old `.pyodide-xbuildenv` directory was breaking build, so
|
|
569
|
+
# important to remove it here.
|
|
570
|
+
shutil.rmtree('.pyodide-xbuildenv', ignore_errors=1)
|
|
549
571
|
if not os.path.exists(dir_emsdk):
|
|
550
572
|
command += f' && echo "### cloning emsdk.git"'
|
|
551
573
|
command += f' && git clone https://github.com/emscripten-core/emsdk.git {dir_emsdk}'
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
'''
|
|
4
4
|
Test for Linux system install of MuPDF and PyMuPDF.
|
|
5
5
|
|
|
6
|
-
We build and install MuPDF and PyMuPDF into a root directory, then
|
|
7
|
-
PyMuPDF's pytest tests with LD_PRELOAD_PATH and
|
|
6
|
+
We build and install MuPDF and PyMuPDF into a root directory, then use
|
|
7
|
+
scripts/test.py to run PyMuPDF's pytest tests with LD_PRELOAD_PATH and
|
|
8
|
+
PYTHONPATH set.
|
|
8
9
|
|
|
9
10
|
PyMuPDF itself is installed using `python -m install` with a wheel created with
|
|
10
11
|
`pip wheel`.
|
|
@@ -21,6 +22,8 @@ Args:
|
|
|
21
22
|
|
|
22
23
|
--mupdf-dir <mupdf_dir>
|
|
23
24
|
Path of MuPDF checkout; default is 'mupdf'.
|
|
25
|
+
--mupdf-do 0|1
|
|
26
|
+
Whether to build and install mupdf.
|
|
24
27
|
--mupdf-git <git_args>
|
|
25
28
|
Get or update `mupdf_dir` using git. If `mupdf_dir` already
|
|
26
29
|
exists we run `git pull` in it; otherwise we run `git
|
|
@@ -43,6 +46,8 @@ Args:
|
|
|
43
46
|
Directory within `root`; default is `/usr/local`. Must start with `/`.
|
|
44
47
|
--pymupdf-dir <pymupdf_dir>
|
|
45
48
|
Path of PyMuPDF checkout; default is 'PyMuPDF'.
|
|
49
|
+
--pymupdf-do 0|1
|
|
50
|
+
Whether to build and install pymupdf.
|
|
46
51
|
--root <root>
|
|
47
52
|
Root of install directory; default is `/`.
|
|
48
53
|
--tesseract5 0|1
|
|
@@ -57,15 +62,14 @@ Args:
|
|
|
57
62
|
If 1 (the default), we use `python -m installer` to install PyMuPDF
|
|
58
63
|
from a generated wheel. [Otherwise we use `pip install`, which refuses
|
|
59
64
|
to do a system install with `--root /`, referencing PEP-668.]
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-t
|
|
67
|
-
|
|
68
|
-
show what command we would have run.
|
|
65
|
+
-i <implementations>
|
|
66
|
+
Passed through to scripts/test.py.
|
|
67
|
+
-f <test-fitz>
|
|
68
|
+
Passed through to scripts/test.py.
|
|
69
|
+
-p <pytest-options>
|
|
70
|
+
Passed through to scripts/test.py.
|
|
71
|
+
-t <names>
|
|
72
|
+
Passed through to scripts/test.py.
|
|
69
73
|
|
|
70
74
|
To only show what commands would be run, but not actually run them, specify `-m
|
|
71
75
|
0 -p 0 -t 0`.
|
|
@@ -75,6 +79,7 @@ import glob
|
|
|
75
79
|
import multiprocessing
|
|
76
80
|
import os
|
|
77
81
|
import platform
|
|
82
|
+
import shlex
|
|
78
83
|
import subprocess
|
|
79
84
|
import sys
|
|
80
85
|
import sysconfig
|
|
@@ -117,19 +122,23 @@ def main():
|
|
|
117
122
|
# Set default behaviour.
|
|
118
123
|
#
|
|
119
124
|
use_installer = True
|
|
120
|
-
|
|
125
|
+
mupdf_do = True
|
|
121
126
|
mupdf_dir = 'mupdf'
|
|
122
127
|
mupdf_git = None
|
|
123
128
|
mupdf_so_mode = None
|
|
124
129
|
packages = True
|
|
125
130
|
prefix = '/usr/local'
|
|
126
|
-
|
|
131
|
+
pymupdf_do = True
|
|
127
132
|
pymupdf_dir = os.path.abspath( f'{__file__}/../..')
|
|
128
133
|
root = 'sysinstall_test'
|
|
129
134
|
tesseract5 = True
|
|
130
|
-
|
|
135
|
+
pytest_args = None
|
|
136
|
+
pytest_do = True
|
|
137
|
+
pytest_name = None
|
|
131
138
|
test_venv = 'venv-pymupdf-sysinstall-test'
|
|
132
139
|
pip = 'venv'
|
|
140
|
+
test_fitz = None
|
|
141
|
+
test_implementations = None
|
|
133
142
|
|
|
134
143
|
# Parse command-line.
|
|
135
144
|
#
|
|
@@ -142,20 +151,24 @@ def main():
|
|
|
142
151
|
if arg in ('-h', '--help'):
|
|
143
152
|
print(__doc__)
|
|
144
153
|
return
|
|
154
|
+
elif arg == '--mupdf-do': mupdf_do = int(next(args))
|
|
145
155
|
elif arg == '--mupdf-dir': mupdf_dir = next(args)
|
|
146
156
|
elif arg == '--mupdf-git': mupdf_git = next(args)
|
|
147
157
|
elif arg == '--mupdf-so-mode': mupdf_so_mode = next(args)
|
|
148
158
|
elif arg == '--packages': packages = int(next(args))
|
|
149
159
|
elif arg == '--prefix': prefix = next(args)
|
|
160
|
+
elif arg == '--pymupdf-do': pymupdf_do = int(next(args))
|
|
150
161
|
elif arg == '--pymupdf-dir': pymupdf_dir = next(args)
|
|
151
162
|
elif arg == '--root': root = next(args)
|
|
152
163
|
elif arg == '--tesseract5': tesseract5 = int(next(args))
|
|
164
|
+
elif arg == '--pytest-do': pytest_do = int(next(args))
|
|
153
165
|
elif arg == '--test-venv': test_venv = next(args)
|
|
154
166
|
elif arg == '--use-installer': use_installer = int(next(args))
|
|
155
167
|
elif arg == '--pip': pip = next(args)
|
|
156
|
-
elif arg == '-
|
|
157
|
-
elif arg == '-
|
|
158
|
-
elif arg == '-
|
|
168
|
+
elif arg == '-f': test_fitz = next(args)
|
|
169
|
+
elif arg == '-i': test_implementations = next(args)
|
|
170
|
+
elif arg == '-p': pytest_args = next(args)
|
|
171
|
+
elif arg == '-t': pytest_name = next(args)
|
|
159
172
|
else:
|
|
160
173
|
assert 0, f'Unrecognised arg: {arg!r}'
|
|
161
174
|
|
|
@@ -169,7 +182,7 @@ def main():
|
|
|
169
182
|
if root == '/':
|
|
170
183
|
sudo = f'sudo PATH={os.environ["PATH"]} '
|
|
171
184
|
def run(command):
|
|
172
|
-
return run_command(command, doit=
|
|
185
|
+
return run_command(command, doit=mupdf_do)
|
|
173
186
|
# Get MuPDF from git if specified.
|
|
174
187
|
#
|
|
175
188
|
if mupdf_git:
|
|
@@ -232,7 +245,7 @@ def main():
|
|
|
232
245
|
#
|
|
233
246
|
print('## Build and install PyMuPDF.')
|
|
234
247
|
def run(command):
|
|
235
|
-
return run_command(command, doit=
|
|
248
|
+
return run_command(command, doit=pymupdf_do)
|
|
236
249
|
flags_freetype2 = run_command('pkg-config --cflags freetype2', capture_output=1).stdout.strip()
|
|
237
250
|
compile_flags = f'-I {root_prefix}/include {flags_freetype2}'
|
|
238
251
|
link_flags = f'-L {root_prefix}/lib'
|
|
@@ -316,7 +329,7 @@ def main():
|
|
|
316
329
|
#
|
|
317
330
|
print('## Run PyMuPDF pytest tests.')
|
|
318
331
|
def run(command):
|
|
319
|
-
return run_command(command, doit=
|
|
332
|
+
return run_command(command, doit=pytest_do)
|
|
320
333
|
import gh_release
|
|
321
334
|
if pip == 'venv':
|
|
322
335
|
# Create venv.
|
|
@@ -342,9 +355,32 @@ def main():
|
|
|
342
355
|
run(f'ls -l {root_prefix}/bin/')
|
|
343
356
|
# 2024-03-20: Not sure whether/where `pymupdf` binary is installed, so we
|
|
344
357
|
# disable the test_cli* tests.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
358
|
+
command += f' {pymupdf_dir}/scripts/test.py'
|
|
359
|
+
command += f' -v 0'
|
|
360
|
+
if pytest_name is None:
|
|
361
|
+
excluded_tests = (
|
|
362
|
+
'test_color_count',
|
|
363
|
+
'test_3050',
|
|
364
|
+
'test_cli',
|
|
365
|
+
'test_cli_out',
|
|
366
|
+
'test_pylint',
|
|
367
|
+
'test_textbox3',
|
|
368
|
+
'test_3493',
|
|
369
|
+
)
|
|
370
|
+
excluded_tests = ' and not '.join(excluded_tests)
|
|
371
|
+
if not pytest_args:
|
|
372
|
+
pytest_args = ''
|
|
373
|
+
pytest_args += f' -k \'not {excluded_tests}\''
|
|
374
|
+
else:
|
|
375
|
+
command += f' -t {pytest_name}'
|
|
376
|
+
if test_fitz:
|
|
377
|
+
command += f' -f {test_fitz}'
|
|
378
|
+
if test_implementations:
|
|
379
|
+
command += f' -i {test_implementations}'
|
|
380
|
+
if pytest_args:
|
|
381
|
+
command += f' -p {shlex.quote(pytest_args)}'
|
|
382
|
+
if pytest_do:
|
|
383
|
+
command += ' test'
|
|
348
384
|
run(command)
|
|
349
385
|
|
|
350
386
|
|
|
@@ -54,6 +54,8 @@ Options:
|
|
|
54
54
|
'r' - rebased.
|
|
55
55
|
'R' - rebased without optimisations.
|
|
56
56
|
Default is 'rR'. Also see `PyMuPDF:tests/run_compound.py`.
|
|
57
|
+
-k <expression>
|
|
58
|
+
Passed straight through to pytest's `-k`.
|
|
57
59
|
-m <location> | --mupdf <location>
|
|
58
60
|
Location of local mupdf/ directory or 'git:...' to be used
|
|
59
61
|
when building PyMuPDF. [This sets environment variable
|
|
@@ -83,6 +85,8 @@ Options:
|
|
|
83
85
|
Whether to rebuild mupdf when we build PyMuPDF. Default is 1.
|
|
84
86
|
--gdb 0|1
|
|
85
87
|
Run tests under gdb.
|
|
88
|
+
--system-site-packages 0|1
|
|
89
|
+
If 1, use `--system-site-packages` when creating venv.
|
|
86
90
|
--timeout <seconds>
|
|
87
91
|
Sets timeout when running tests.
|
|
88
92
|
--valgrind 0|1
|
|
@@ -136,6 +140,8 @@ def main(argv):
|
|
|
136
140
|
venv = 2
|
|
137
141
|
pytest_options = None
|
|
138
142
|
timeout = None
|
|
143
|
+
pytest_k = None
|
|
144
|
+
system_site_packages = False
|
|
139
145
|
|
|
140
146
|
options = os.environ.get('PYMUDF_SCRIPTS_TEST_options', '')
|
|
141
147
|
options = shlex.split(options)
|
|
@@ -169,8 +175,12 @@ def main(argv):
|
|
|
169
175
|
assert os.path.isdir(mupdf), f'Not a directory: {mupdf=}.'
|
|
170
176
|
mupdf = os.path.abspath(mupdf)
|
|
171
177
|
os.environ['PYMUPDF_SETUP_MUPDF_BUILD'] = mupdf
|
|
178
|
+
elif arg == '-k':
|
|
179
|
+
pytest_k = next(args)
|
|
172
180
|
elif arg == '-p':
|
|
173
181
|
pytest_options = next(args)
|
|
182
|
+
elif arg == '--system-site-packages':
|
|
183
|
+
system_site_packages = int(next(args))
|
|
174
184
|
elif arg == '-t':
|
|
175
185
|
test_names += next(args).split(',')
|
|
176
186
|
elif arg == '--timeout':
|
|
@@ -206,7 +216,11 @@ def main(argv):
|
|
|
206
216
|
if venv and sys.prefix == sys.base_prefix:
|
|
207
217
|
# We are not running in a venv.
|
|
208
218
|
log(f'Re-running in venv {gh_release.venv_name!r}.')
|
|
209
|
-
gh_release.venv(
|
|
219
|
+
gh_release.venv(
|
|
220
|
+
['python'] + argv,
|
|
221
|
+
quick=venv_quick,
|
|
222
|
+
system_site_packages=system_site_packages,
|
|
223
|
+
)
|
|
210
224
|
return
|
|
211
225
|
|
|
212
226
|
def do_build():
|
|
@@ -227,6 +241,7 @@ def main(argv):
|
|
|
227
241
|
timeout=timeout,
|
|
228
242
|
gdb=gdb,
|
|
229
243
|
test_fitz=test_fitz,
|
|
244
|
+
pytest_k=pytest_k,
|
|
230
245
|
)
|
|
231
246
|
|
|
232
247
|
for command in commands:
|
|
@@ -360,6 +375,7 @@ def test(
|
|
|
360
375
|
timeout=None,
|
|
361
376
|
gdb=False,
|
|
362
377
|
test_fitz=True,
|
|
378
|
+
pytest_k=None
|
|
363
379
|
):
|
|
364
380
|
'''
|
|
365
381
|
Args:
|
|
@@ -384,6 +400,8 @@ def test(
|
|
|
384
400
|
pytest_options = '-s -vv'
|
|
385
401
|
else:
|
|
386
402
|
pytest_options = ''
|
|
403
|
+
if pytest_k:
|
|
404
|
+
pytest_options += f' -k {shlex.quote(pytest_k)}'
|
|
387
405
|
pytest_arg = ''
|
|
388
406
|
if test_names:
|
|
389
407
|
for test_name in test_names:
|
|
@@ -87,6 +87,9 @@ Environmental variables:
|
|
|
87
87
|
Otherwise:
|
|
88
88
|
Location of mupdf directory.
|
|
89
89
|
|
|
90
|
+
PYMUPDF_SETUP_MUPDF_BSYMBOLIC
|
|
91
|
+
If '0' we do not link libmupdf.so with -Bsymbolic.
|
|
92
|
+
|
|
90
93
|
PYMUPDF_SETUP_MUPDF_TESSERACT
|
|
91
94
|
If '0' we build MuPDF without Tesseract.
|
|
92
95
|
|
|
@@ -139,16 +142,6 @@ Environmental variables:
|
|
|
139
142
|
WDEV_VS_GRADE
|
|
140
143
|
If set, we use as Visual Studio grade, for example 'Community' or
|
|
141
144
|
'Professional' or 'Enterprise'.
|
|
142
|
-
|
|
143
|
-
Known build failures:
|
|
144
|
-
Linux:
|
|
145
|
-
*musllinux*.
|
|
146
|
-
Windows:
|
|
147
|
-
pp*:
|
|
148
|
-
fitz_wrap.obj : error LNK2001: unresolved external symbol PyUnicode_DecodeRawUnicodeEscape
|
|
149
|
-
|
|
150
|
-
When using cibuildwheel, one can avoid building these failing wheels with:
|
|
151
|
-
CIBW_SKIP='*musllinux* pp*'
|
|
152
145
|
'''
|
|
153
146
|
|
|
154
147
|
import glob
|
|
@@ -157,6 +150,7 @@ import os
|
|
|
157
150
|
import textwrap
|
|
158
151
|
import time
|
|
159
152
|
import platform
|
|
153
|
+
import re
|
|
160
154
|
import shlex
|
|
161
155
|
import shutil
|
|
162
156
|
import stat
|
|
@@ -386,7 +380,7 @@ def get_mupdf_internal(out, location=None, sha=None, local_tgz=None):
|
|
|
386
380
|
log(f'get_mupdf_internal(): {out=} {location=} {sha=}')
|
|
387
381
|
assert out in ('dir', 'tgz')
|
|
388
382
|
if location is None:
|
|
389
|
-
location = 'https://mupdf.com/downloads/archive/mupdf-1.24.
|
|
383
|
+
location = 'https://mupdf.com/downloads/archive/mupdf-1.24.4-source.tar.gz'
|
|
390
384
|
#location = 'git:--branch master https://github.com/ArtifexSoftware/mupdf.git'
|
|
391
385
|
|
|
392
386
|
if location == '':
|
|
@@ -788,6 +782,14 @@ def build_mupdf_unix( mupdf_local, env, build_type):
|
|
|
788
782
|
log(f'PYMUPDF_SETUP_MUPDF_TESSERACT=0 so building mupdf without tesseract.')
|
|
789
783
|
else:
|
|
790
784
|
build_prefix += 'tesseract-'
|
|
785
|
+
mupdf_version_tuple = get_mupdf_version(mupdf_local)
|
|
786
|
+
if (
|
|
787
|
+
linux
|
|
788
|
+
and os.environ.get('PYMUPDF_SETUP_MUPDF_BSYMBOLIC', '1') == '1'
|
|
789
|
+
and mupdf_version_tuple >= (1, 24, 3)
|
|
790
|
+
):
|
|
791
|
+
log(f'Appending `bsymbolic-` to MuPDF build path.')
|
|
792
|
+
build_prefix += 'bsymbolic-'
|
|
791
793
|
unix_build_dir = f'{mupdf_local}/build/{build_prefix}{build_type}'
|
|
792
794
|
# We need MuPDF's Python bindings, so we build MuPDF with
|
|
793
795
|
# `mupdf/scripts/mupdfwrap.py` instead of running `make`.
|
|
@@ -813,6 +815,19 @@ def build_mupdf_unix( mupdf_local, env, build_type):
|
|
|
813
815
|
return unix_build_dir
|
|
814
816
|
|
|
815
817
|
|
|
818
|
+
def get_mupdf_version(mupdf_dir):
|
|
819
|
+
path = f'{mupdf_dir}/include/mupdf/fitz/version.h'
|
|
820
|
+
with open(path) as f:
|
|
821
|
+
text = f.read()
|
|
822
|
+
v0 = re.search('#define FZ_VERSION_MAJOR ([0-9]+)', text)
|
|
823
|
+
v1 = re.search('#define FZ_VERSION_MINOR ([0-9]+)', text)
|
|
824
|
+
v2 = re.search('#define FZ_VERSION_PATCH ([0-9]+)', text)
|
|
825
|
+
assert v0 and v1 and v2, f'Cannot find MuPDF version numers in {path=}.'
|
|
826
|
+
v0 = int(v0.group(1))
|
|
827
|
+
v1 = int(v1.group(1))
|
|
828
|
+
v2 = int(v2.group(1))
|
|
829
|
+
return v0, v1, v2
|
|
830
|
+
|
|
816
831
|
def _fs_update(text, path):
|
|
817
832
|
try:
|
|
818
833
|
with open( path) as f:
|
|
@@ -1113,8 +1128,8 @@ classifier = [
|
|
|
1113
1128
|
# We generate different wheels depending on g_flavour.
|
|
1114
1129
|
#
|
|
1115
1130
|
|
|
1116
|
-
version = '1.24.
|
|
1117
|
-
version_b = '1.24.
|
|
1131
|
+
version = '1.24.7'
|
|
1132
|
+
version_b = '1.24.6'
|
|
1118
1133
|
|
|
1119
1134
|
if os.path.exists(f'{g_root}/{g_pymupdfb_sdist_marker}'):
|
|
1120
1135
|
|
|
@@ -1211,6 +1226,13 @@ else:
|
|
|
1211
1226
|
Adds to pyproject.toml:[build-system]:requires, allowing programmatic
|
|
1212
1227
|
control over what packages we require.
|
|
1213
1228
|
'''
|
|
1229
|
+
def platform_release_tuple():
|
|
1230
|
+
r = platform.release()
|
|
1231
|
+
r = r.split('.')
|
|
1232
|
+
r = tuple(int(i) for i in r)
|
|
1233
|
+
log(f'platform_release_tuple() returning {r=}.')
|
|
1234
|
+
return r
|
|
1235
|
+
|
|
1214
1236
|
ret = list()
|
|
1215
1237
|
ret.append('setuptools')
|
|
1216
1238
|
libclang = os.environ.get('PYMUPDF_SETUP_LIBCLANG')
|
|
@@ -1222,6 +1244,9 @@ else:
|
|
|
1222
1244
|
elif darwin and platform.machine() == 'arm64':
|
|
1223
1245
|
print(f'MacOS/arm64: forcing use of libclang 16.0.6 because 18.1.1 known to fail with `clang.cindex.TranslationUnitLoadError: Error parsing translation unit.`')
|
|
1224
1246
|
ret.append('libclang==16.0.6')
|
|
1247
|
+
elif darwin and platform_release_tuple() < (18,):
|
|
1248
|
+
# There are still of ptoblems when building on old macos.
|
|
1249
|
+
ret.append('libclang==14.0.6')
|
|
1225
1250
|
else:
|
|
1226
1251
|
ret.append('libclang')
|
|
1227
1252
|
if msys2:
|