PyMuPDF 1.23.23__tar.gz → 1.23.25__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.23.23 → PyMuPDF-1.23.25}/PKG-INFO +1 -1
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/changes.txt +27 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/pipcl.py +40 -35
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/scripts/sysinstall.py +98 -49
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/scripts/test.py +3 -2
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/setup.py +1 -1
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src/__init__.py +10 -9
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src/table.py +90 -46
- PyMuPDF-1.23.25/src_classic/version.i +7 -0
- PyMuPDF-1.23.25/tests/resources/test_3179.pdf +0 -0
- PyMuPDF-1.23.25/tests/resources/test_3186.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_geometry.py +7 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_optional_content.py +65 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_tables.py +37 -0
- PyMuPDF-1.23.25/tests/test_textextract.py +241 -0
- PyMuPDF-1.23.23/src_classic/version.i +0 -7
- PyMuPDF-1.23.23/tests/test_textextract.py +0 -218
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/COPYING +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/MANIFEST.in +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/README.md +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/READMErb.md +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/mupdf.tgz +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/pyproject.toml +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/pytest.ini +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/scripts/gh_release.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src/__main__.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src/extra.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src/fitz.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src/utils.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/__init__.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/__main__.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/_config.h +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/fitz_old.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-annot.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-convert.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-defines.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-devices.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-fields.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-fileobj.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-geo-c.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-geo-py.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-globals.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-other.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-pdfinfo.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-pixmap.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-portfolio.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-python.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-select.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-stext.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/helper-xobject.i +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/src_classic/utils.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/README.md +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/001003ED.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/1.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/2.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/2201.00069.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/3.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/4.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/Bezier.epub +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/PragmaticaC.otf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/bug1945.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/bug1971.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/chinese-tables.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/chinese-tables.pickle +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/circular-toc.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/cython.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/cython.pickle +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/full_toc.txt +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/full_toc2.txt +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/github_sample.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/has-bad-fonts.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/image-file1.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/img-transparent.png +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/joined.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/metadata.txt +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/mupdf_explored.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/nur-ruhig.jpg +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/quad-calc-0.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/simple_toc.txt +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/small-table.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/strict-yes-no.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/symbol-list.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/symbols.txt +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test-2333.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test-2462.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test-3143.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test-3150.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test2093.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test2182.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test2238.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_1645_expected.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_1645_expected_1.22.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_1645_expected_1.24.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_1824.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2108.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2270.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2533.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2548.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2553-2.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2553.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2596.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2608_expected +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2634.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2635.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2645_1.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2645_2.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2645_3.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2710.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2730.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2742.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2788.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2791_content.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2791_coverpage.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2861.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2871.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2885.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2904.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2907.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2954.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2957_1.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2957_2.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2969.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_2979.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_3058.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_3062.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_3070.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_3072.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_3087.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_annot_file_info.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/test_delete_image.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/type3font.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/v110-changes.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/resources/widgettest.pdf +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/run_compound.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_2548.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_2634.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_2791.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_2904.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_2907.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_annots.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_badfonts.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_crypting.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_docs_samples.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_drawings.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_embeddedfiles.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_extractimage.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_flake8.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_font.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_general.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_imagebbox.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_insertimage.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_insertpdf.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_linequad.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_metadata.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_named_links.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_nonpdf.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_object_manipulation.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_page_links.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_pagedelete.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_pagelabels.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_pixmap.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_showpdfpage.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_story.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_tesseract.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_textbox.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_textsearch.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_toc.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_widgets.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/tests/test_word_delimiters.py +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/valgrind.supp +0 -0
- {PyMuPDF-1.23.23 → PyMuPDF-1.23.25}/wdev.py +0 -0
|
@@ -2,6 +2,33 @@ Change Log
|
|
|
2
2
|
==========
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
**Changes in version 1.23.25 (2024-02-20)**
|
|
6
|
+
|
|
7
|
+
* Fixed issues:
|
|
8
|
+
|
|
9
|
+
* **Fixed** `3182 <https://github.com/pymupdf/PyMuPDF/issues/3182>`_: Pixmap.invert_irect argument type error
|
|
10
|
+
* **Fixed** `3186 <https://github.com/pymupdf/PyMuPDF/issues/3186>`_: extractText() extracts broken text from pdf
|
|
11
|
+
* **Fixed** `3191 <https://github.com/pymupdf/PyMuPDF/issues/3191>`_: Error on .find_tables()
|
|
12
|
+
|
|
13
|
+
* Other:
|
|
14
|
+
|
|
15
|
+
* When building, be able to specify python-config directly, with environment
|
|
16
|
+
variable `PIPCL_PYTHON_CONFIG`.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
**Changes in version 1.23.24 (2024-02-19)**
|
|
20
|
+
|
|
21
|
+
* Fixed issues:
|
|
22
|
+
|
|
23
|
+
* **Fixed** `3148 <https://github.com/pymupdf/PyMuPDF/issues/3148>`_: Table extraction - vertical text not handled correctly
|
|
24
|
+
* **Fixed** `3179 <https://github.com/pymupdf/PyMuPDF/issues/3179>`_: Table Detection: Incorrect Separation of Vector Graphics Clusters
|
|
25
|
+
* **Fixed** `3180 <https://github.com/pymupdf/PyMuPDF/issues/3180>`_: Cannot show optional content group: AttributeError: module 'fitz.mupdf' has no attribute 'pdf_array_push_drop'
|
|
26
|
+
|
|
27
|
+
* Other:
|
|
28
|
+
|
|
29
|
+
* Be able to test system install using `sudo pip install` instead of a venv.
|
|
30
|
+
|
|
31
|
+
|
|
5
32
|
**Changes in version 1.23.23 (2024-02-18)**
|
|
6
33
|
|
|
7
34
|
* Fixed issues:
|
|
@@ -1769,6 +1769,9 @@ class PythonFlags:
|
|
|
1769
1769
|
Compile/link flags for the current python, for example the include path
|
|
1770
1770
|
needed to get `Python.h`.
|
|
1771
1771
|
|
|
1772
|
+
The 'PIPCL_PYTHON_CONFIG' environment variable allows to override
|
|
1773
|
+
the location of the python-config executable.
|
|
1774
|
+
|
|
1772
1775
|
Members:
|
|
1773
1776
|
.includes:
|
|
1774
1777
|
String containing compiler flags for include paths.
|
|
@@ -1789,43 +1792,45 @@ class PythonFlags:
|
|
|
1789
1792
|
self.ldflags = f'-L {_lib_dir}'
|
|
1790
1793
|
|
|
1791
1794
|
else:
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
# libpython on the link command. The manylinux docker containers
|
|
1798
|
-
# don't actually contain libpython.so, and it seems that this
|
|
1799
|
-
# deliberate. And the link command runs ok.
|
|
1800
|
-
#
|
|
1801
|
-
python_exe = os.path.realpath( sys.executable)
|
|
1802
|
-
if darwin():
|
|
1803
|
-
# Basic install of dev tools with `xcode-select --install` doesn't
|
|
1804
|
-
# seem to provide a `python3-config` or similar, but there is a
|
|
1805
|
-
# `python-config.py` accessible via sysconfig.
|
|
1795
|
+
python_config = os.environ.get("PIPCL_PYTHON_CONFIG")
|
|
1796
|
+
if not python_config:
|
|
1797
|
+
# We use python-config which appears to work better than pkg-config
|
|
1798
|
+
# because it copes with multiple installed python's, e.g.
|
|
1799
|
+
# manylinux_2014's /opt/python/cp*-cp*/bin/python*.
|
|
1806
1800
|
#
|
|
1807
|
-
#
|
|
1808
|
-
#
|
|
1801
|
+
# But... on non-macos it seems that we should not attempt to specify
|
|
1802
|
+
# libpython on the link command. The manylinux docker containers
|
|
1803
|
+
# don't actually contain libpython.so, and it seems that this
|
|
1804
|
+
# deliberate. And the link command runs ok.
|
|
1809
1805
|
#
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
).
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1806
|
+
python_exe = os.path.realpath( sys.executable)
|
|
1807
|
+
if darwin():
|
|
1808
|
+
# Basic install of dev tools with `xcode-select --install` doesn't
|
|
1809
|
+
# seem to provide a `python3-config` or similar, but there is a
|
|
1810
|
+
# `python-config.py` accessible via sysconfig.
|
|
1811
|
+
#
|
|
1812
|
+
# We try different possibilities and use the last one that
|
|
1813
|
+
# works.
|
|
1814
|
+
#
|
|
1815
|
+
python_config = None
|
|
1816
|
+
for pc in (
|
|
1817
|
+
f'python3-config',
|
|
1818
|
+
f'{sys.executable} {sysconfig.get_config_var("srcdir")}/python-config.py',
|
|
1819
|
+
f'{python_exe}-config',
|
|
1820
|
+
):
|
|
1821
|
+
e = subprocess.run(
|
|
1822
|
+
f'{pc} --includes',
|
|
1823
|
+
shell=1,
|
|
1824
|
+
stdout=subprocess.DEVNULL,
|
|
1825
|
+
stderr=subprocess.DEVNULL,
|
|
1826
|
+
check=0,
|
|
1827
|
+
).returncode
|
|
1828
|
+
log1(f'{e=} from {pc!r}.')
|
|
1829
|
+
if e == 0:
|
|
1830
|
+
python_config = pc
|
|
1831
|
+
assert python_config, f'Cannot find python-config'
|
|
1832
|
+
else:
|
|
1833
|
+
python_config = f'{python_exe}-config'
|
|
1829
1834
|
log1(f'Using {python_config=}.')
|
|
1830
1835
|
try:
|
|
1831
1836
|
self.includes = run( f'{python_config} --includes', capture=1).strip()
|
|
@@ -24,28 +24,39 @@ Args:
|
|
|
24
24
|
--mupdf-git <git_args>
|
|
25
25
|
Get or update `mupdf_dir` using git. If `mupdf_dir` already
|
|
26
26
|
exists we run `git pull` in it; otherwise we run `git
|
|
27
|
-
clone` with
|
|
27
|
+
clone` with `<git_args> <mupdf_dir>`. For example:
|
|
28
28
|
--mupdf-git "--branch master https://github.com/ArtifexSoftware/mupdf.git"
|
|
29
|
-
--
|
|
30
|
-
|
|
29
|
+
--mupdf-so-mode <mode>
|
|
30
|
+
Used with `install -m <mode> ...` when installing MuPDF. For example
|
|
31
|
+
`--mupdf-so-mode 744`.
|
|
32
|
+
--packages 0|1
|
|
33
|
+
If 1 (the default) we install required system packages such as
|
|
34
|
+
`libfreetype-dev`.
|
|
35
|
+
--pip 0|venv|sudo
|
|
36
|
+
Whether/how to install Python packages.
|
|
37
|
+
If '0' we assume required packages are already available.
|
|
38
|
+
If 'sudo' we install required Python packages using `sudo pip install
|
|
39
|
+
...`.
|
|
40
|
+
If 'venv' (the default) we install Python packages and run installer
|
|
41
|
+
and test commands inside venv's.
|
|
31
42
|
--prefix:
|
|
32
43
|
Directory within `root`; default is `/usr/local`. Must start with `/`.
|
|
44
|
+
--pymupdf-dir <pymupdf_dir>
|
|
45
|
+
Path of PyMuPDF checkout; default is 'PyMuPDF'.
|
|
33
46
|
--root <root>
|
|
34
47
|
Root of install directory; default is `/`.
|
|
35
48
|
--tesseract5 0|1
|
|
36
49
|
If 1 (the default), we force installation of libtesseract-dev version
|
|
37
50
|
5 (which is not available as a default package in Ubuntu-22.04) from
|
|
38
51
|
package repository ppa:alex-p/tesseract-ocr-devel.
|
|
39
|
-
--test-venv <
|
|
40
|
-
|
|
41
|
-
venv
|
|
42
|
-
|
|
43
|
-
instead attempt to install required packages with `pip` in the current
|
|
44
|
-
Python environment.
|
|
52
|
+
--test-venv <test_venv>
|
|
53
|
+
Set the name of the venv in which we run tests (only with `--pip
|
|
54
|
+
venv`); the default is a hard-coded venv name. The venv will be
|
|
55
|
+
created, and required packages installed using `pip`.
|
|
45
56
|
--use-installer 0|1
|
|
46
57
|
If 1 (the default), we use `python -m installer` to install PyMuPDF
|
|
47
|
-
from a generated wheel. Otherwise we use `pip install`, which refuses
|
|
48
|
-
to do a system install with `--root /`, referencing PEP-668.
|
|
58
|
+
from a generated wheel. [Otherwise we use `pip install`, which refuses
|
|
59
|
+
to do a system install with `--root /`, referencing PEP-668.]
|
|
49
60
|
-m 0|1
|
|
50
61
|
If 1 (the default) we build and install MuPDF, otherwise we just show
|
|
51
62
|
what command we would have run.
|
|
@@ -61,12 +72,14 @@ To only show what commands would be run, but not actually run them, specify `-m
|
|
|
61
72
|
'''
|
|
62
73
|
|
|
63
74
|
import glob
|
|
75
|
+
import multiprocessing
|
|
64
76
|
import os
|
|
65
77
|
import platform
|
|
66
78
|
import subprocess
|
|
67
79
|
import sys
|
|
68
80
|
import sysconfig
|
|
69
81
|
|
|
82
|
+
import test as test_py
|
|
70
83
|
|
|
71
84
|
# Requirements for a system build and install:
|
|
72
85
|
#
|
|
@@ -107,6 +120,8 @@ def main():
|
|
|
107
120
|
mupdf = True
|
|
108
121
|
mupdf_dir = 'mupdf'
|
|
109
122
|
mupdf_git = None
|
|
123
|
+
mupdf_so_mode = None
|
|
124
|
+
packages = True
|
|
110
125
|
prefix = '/usr/local'
|
|
111
126
|
pymupdf = True
|
|
112
127
|
pymupdf_dir = os.path.abspath( f'{__file__}/../..')
|
|
@@ -114,6 +129,7 @@ def main():
|
|
|
114
129
|
tesseract5 = True
|
|
115
130
|
test = True
|
|
116
131
|
test_venv = 'venv-pymupdf-sysinstall-test'
|
|
132
|
+
pip = 'venv'
|
|
117
133
|
|
|
118
134
|
# Parse command-line.
|
|
119
135
|
#
|
|
@@ -128,12 +144,15 @@ def main():
|
|
|
128
144
|
return
|
|
129
145
|
elif arg == '--mupdf-dir': mupdf_dir = next(args)
|
|
130
146
|
elif arg == '--mupdf-git': mupdf_git = next(args)
|
|
147
|
+
elif arg == '--mupdf-so-mode': mupdf_so_mode = next(args)
|
|
148
|
+
elif arg == '--packages': packages = int(next(args))
|
|
131
149
|
elif arg == '--prefix': prefix = next(args)
|
|
132
150
|
elif arg == '--pymupdf-dir': pymupdf_dir = next(args)
|
|
133
151
|
elif arg == '--root': root = next(args)
|
|
134
152
|
elif arg == '--tesseract5': tesseract5 = int(next(args))
|
|
135
153
|
elif arg == '--test-venv': test_venv = next(args)
|
|
136
154
|
elif arg == '--use-installer': use_installer = int(next(args))
|
|
155
|
+
elif arg == '--pip': pip = next(args)
|
|
137
156
|
elif arg == '-m': mupdf = int(next(args))
|
|
138
157
|
elif arg == '-p': pymupdf = int(next(args))
|
|
139
158
|
elif arg == '-t': test = int(next(args))
|
|
@@ -141,6 +160,8 @@ def main():
|
|
|
141
160
|
assert 0, f'Unrecognised arg: {arg!r}'
|
|
142
161
|
|
|
143
162
|
assert prefix.startswith('/')
|
|
163
|
+
pip_values = ('0', 'sudo', 'venv')
|
|
164
|
+
assert pip in pip_values, f'Unrecognised --pip value {pip!r} should be one of: {pip_values!r}'
|
|
144
165
|
root = os.path.abspath(root)
|
|
145
166
|
root_prefix = f'{root}{prefix}'.replace('//', '/')
|
|
146
167
|
|
|
@@ -161,44 +182,54 @@ def main():
|
|
|
161
182
|
print(f'## Clone MuPDF into {mupdf_dir}.')
|
|
162
183
|
run(f'git clone --recursive --depth 1 --shallow-submodules {mupdf_git} {mupdf_dir}')
|
|
163
184
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
print('## Install system packages required by MuPDF.')
|
|
167
|
-
run(f'sudo apt update')
|
|
168
|
-
run(f'sudo apt install {" ".join(g_sys_packages)}')
|
|
169
|
-
# Ubuntu-22.04 has freeglut3-dev, not libglut-dev.
|
|
170
|
-
run(f'sudo apt install libglut-dev | sudo apt install freeglut3-dev')
|
|
171
|
-
if tesseract5:
|
|
172
|
-
print(f'## Force installation of libtesseract-dev version 5.')
|
|
173
|
-
# https://stackoverflow.com/questions/76834972/how-can-i-run-pytesseract-python-library-in-ubuntu-22-04
|
|
185
|
+
if packages:
|
|
186
|
+
# Install required system packages. We assume a Debian package system.
|
|
174
187
|
#
|
|
175
|
-
|
|
176
|
-
run('sudo
|
|
177
|
-
run('sudo apt
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
188
|
+
print('## Install system packages required by MuPDF.')
|
|
189
|
+
run(f'sudo apt update')
|
|
190
|
+
run(f'sudo apt install {" ".join(g_sys_packages)}')
|
|
191
|
+
# Ubuntu-22.04 has freeglut3-dev, not libglut-dev.
|
|
192
|
+
run(f'sudo apt install libglut-dev | sudo apt install freeglut3-dev')
|
|
193
|
+
if tesseract5:
|
|
194
|
+
print(f'## Force installation of libtesseract-dev version 5.')
|
|
195
|
+
# https://stackoverflow.com/questions/76834972/how-can-i-run-pytesseract-python-library-in-ubuntu-22-04
|
|
196
|
+
#
|
|
197
|
+
run('sudo apt install -y software-properties-common')
|
|
198
|
+
run('sudo add-apt-repository ppa:alex-p/tesseract-ocr-devel')
|
|
199
|
+
run('sudo apt update')
|
|
200
|
+
run('sudo apt install -y libtesseract-dev')
|
|
201
|
+
else:
|
|
202
|
+
run('sudo apt install libtesseract-dev')
|
|
181
203
|
|
|
182
204
|
# Build+install MuPDF. We use mupd:Makefile's install-shared-python target.
|
|
183
205
|
#
|
|
206
|
+
if pip == 'sudo':
|
|
207
|
+
print('## Installing Python packages required for building MuPDF and PyMuPDF.')
|
|
208
|
+
run(f'sudo pip install --upgrade pip')
|
|
209
|
+
names = (''
|
|
210
|
+
+ test_py.get_pyproject_required(os.path.abspath(f'{__file__}/../../pyproject.toml'))
|
|
211
|
+
+ ' '
|
|
212
|
+
+ test_py.get_pyproject_required(os.path.abspath(f'{mupdf_dir}/pyproject.toml'))
|
|
213
|
+
)
|
|
214
|
+
run(f'sudo pip install {names}')
|
|
215
|
+
|
|
184
216
|
print('## Build and install MuPDF.')
|
|
185
|
-
if 1:
|
|
186
|
-
# Current MuPDF creates softlinks with `ln -s` which breaks if there
|
|
187
|
-
# was a previous build; it should do `ln -sf`. We make things work by
|
|
188
|
-
# deleting any existing softlinks here.
|
|
189
|
-
run(f'rm {root_prefix}/lib/libmupdf.so || true')
|
|
190
|
-
run(f'rm {root_prefix}/lib/libmupdfcpp.so || true')
|
|
191
217
|
command = f'cd {mupdf_dir}'
|
|
192
218
|
command += f' && {sudo}make'
|
|
219
|
+
command += f' -j {multiprocessing.cpu_count()}'
|
|
193
220
|
#command += f' EXE_LDFLAGS=-Wl,--trace' # Makes linker generate diagnostics as it runs.
|
|
194
221
|
command += f' DESTDIR={root}'
|
|
195
222
|
command += f' HAVE_LEPTONICA=yes'
|
|
196
223
|
command += f' HAVE_TESSERACT=yes'
|
|
197
224
|
command += f' USE_SYSTEM_LIBS=yes'
|
|
225
|
+
command += f' VENV_FLAG={"--venv" if pip == "venv" else ""}'
|
|
226
|
+
if mupdf_so_mode:
|
|
227
|
+
command += f' SO_INSTALL_MODE={mupdf_so_mode}'
|
|
198
228
|
command += f' build_prefix=system-libs-'
|
|
199
229
|
command += f' prefix={prefix}'
|
|
200
230
|
command += f' verbose=yes'
|
|
201
231
|
command += f' install-shared-python'
|
|
232
|
+
command += f' INSTALL_MODE=755'
|
|
202
233
|
run( command)
|
|
203
234
|
|
|
204
235
|
# Build+install PyMuPDF.
|
|
@@ -217,23 +248,34 @@ def main():
|
|
|
217
248
|
env += f'PYMUPDF_SETUP_IMPLEMENTATIONS=b' # Only build the rebased implementation.
|
|
218
249
|
if use_installer:
|
|
219
250
|
print(f'## Building wheel.')
|
|
251
|
+
if pip == 'venv':
|
|
252
|
+
venv_name = 'venv-pymupdf-sysinstall'
|
|
220
253
|
run(f'pwd')
|
|
221
254
|
run(f'rm dist/* || true')
|
|
222
|
-
|
|
255
|
+
if pip == 'venv':
|
|
256
|
+
run(f'{sys.executable} -m venv {venv_name}')
|
|
257
|
+
run(f'. {venv_name}/bin/activate && pip install --upgrade pip')
|
|
258
|
+
run(f'. {venv_name}/bin/activate && pip install --upgrade installer')
|
|
259
|
+
run(f'{env} {venv_name}/bin/python -m pip wheel -vv -w dist {os.path.abspath(pymupdf_dir)}')
|
|
260
|
+
elif pip == 'sudo':
|
|
261
|
+
run(f'sudo pip install --upgrade pip')
|
|
262
|
+
run(f'sudo pip install installer')
|
|
263
|
+
run(f'{env} pip wheel -vv -w dist {os.path.abspath(pymupdf_dir)}')
|
|
264
|
+
else:
|
|
265
|
+
log(f'Not installing "installer" because {pip=}.')
|
|
223
266
|
wheel = glob.glob(f'dist/*')
|
|
224
267
|
assert len(wheel) == 1, f'{wheel=}'
|
|
225
268
|
wheel = wheel[0]
|
|
226
269
|
print(f'## Installing wheel using `installer`.')
|
|
227
|
-
venv = 'venv-pymupdf-sysinstall'
|
|
228
|
-
run(f'{sys.executable} -m venv {venv}')
|
|
229
|
-
run(f'. {venv}/bin/activate && pip install --upgrade pip')
|
|
230
|
-
run(f'. {venv}/bin/activate && pip install --upgrade installer')
|
|
231
270
|
pv = '.'.join(platform.python_version_tuple()[:2])
|
|
232
271
|
p = f'{root_prefix}/lib/python{pv}'
|
|
233
272
|
# `python -m installer` fails to overwrite existing files.
|
|
234
273
|
run(f'{sudo}rm -r {p}/site-packages/fitz || true')
|
|
235
274
|
run(f'{sudo}rm -r {p}/site-packages/PyMuPDF-*.dist-info || true')
|
|
236
|
-
|
|
275
|
+
if pip == 'venv':
|
|
276
|
+
run(f'{sudo}{venv_name}/bin/python -m installer --destdir {root} --prefix {prefix} {wheel}')
|
|
277
|
+
else:
|
|
278
|
+
run(f'{sudo}{sys.executable} -m installer --destdir {root} --prefix {prefix} {wheel}')
|
|
237
279
|
# It seems that MuPDF Python bindings are installed into
|
|
238
280
|
# `.../dist-packages` (from mupdf:Mafile's call of `$(shell python3
|
|
239
281
|
# -c "import sysconfig; print(sysconfig.get_path('platlib'))")` while
|
|
@@ -267,7 +309,7 @@ def main():
|
|
|
267
309
|
del sys.path[0]
|
|
268
310
|
pythonpath = pipcl.install_dir(root)
|
|
269
311
|
|
|
270
|
-
# Show contents of installation
|
|
312
|
+
# Show contents of installation directory. This is very slow on github,
|
|
271
313
|
# where /usr/local contains lots of things.
|
|
272
314
|
#run(f'find {root_prefix}|sort')
|
|
273
315
|
|
|
@@ -277,20 +319,27 @@ def main():
|
|
|
277
319
|
def run(command):
|
|
278
320
|
return run_command(command, doit=test)
|
|
279
321
|
import gh_release
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
322
|
+
if pip == 'venv':
|
|
323
|
+
# Create venv.
|
|
324
|
+
run(f'{sys.executable} -m venv {test_venv}')
|
|
325
|
+
# Install required packages.
|
|
326
|
+
command = f'. {test_venv}/bin/activate'
|
|
327
|
+
command += f' && pip install --upgrade pip'
|
|
328
|
+
command += f' && pip install --upgrade {gh_release.test_packages}'
|
|
329
|
+
run(command)
|
|
330
|
+
elif pip == 'sudo':
|
|
331
|
+
run(f'sudo pip install --upgrade {gh_release.test_packages}')
|
|
332
|
+
else:
|
|
333
|
+
log(f'Not installing packages for testing because {pip=}.')
|
|
287
334
|
# Run pytest.
|
|
288
335
|
#
|
|
289
336
|
# We need to set PYTHONPATH and LD_LIBRARY_PATH. In particular we
|
|
290
337
|
# use pipcl.install_dir() to find where pipcl will have installed
|
|
291
338
|
# PyMuPDF.
|
|
292
|
-
command =
|
|
293
|
-
|
|
339
|
+
command = ''
|
|
340
|
+
if pip == 'venv':
|
|
341
|
+
command += f'. {test_venv}/bin/activate &&'
|
|
342
|
+
command += f' LD_LIBRARY_PATH={root_prefix}/lib PYTHONPATH={pythonpath}'
|
|
294
343
|
command += f' pytest -k "not test_color_count and not test_3050" {pymupdf_dir}'
|
|
295
344
|
run(command)
|
|
296
345
|
|
|
@@ -410,12 +410,13 @@ def test(
|
|
|
410
410
|
log('\n' + venv_info(pytest_args=f'{pytest_options} {pytest_arg}'))
|
|
411
411
|
|
|
412
412
|
|
|
413
|
-
def get_pyproject_required():
|
|
413
|
+
def get_pyproject_required(ppt=None):
|
|
414
414
|
'''
|
|
415
415
|
Returns space-separated names of required packages in pyproject.toml. We
|
|
416
416
|
do not do a proper parse and rely on the packages being in a single line.
|
|
417
417
|
'''
|
|
418
|
-
ppt
|
|
418
|
+
if ppt is None:
|
|
419
|
+
ppt = os.path.abspath(f'{__file__}/../../pyproject.toml')
|
|
419
420
|
with open(ppt) as f:
|
|
420
421
|
for line in f:
|
|
421
422
|
m = re.match('^requires = \\[(.*)\\]$', line)
|
|
@@ -16259,7 +16259,7 @@ def JM_invert_pixmap_rect( dest, b):
|
|
|
16259
16259
|
|
|
16260
16260
|
def JM_irect_from_py(r):
|
|
16261
16261
|
'''
|
|
16262
|
-
PySequence to
|
|
16262
|
+
PySequence to mupdf.FzIrect. Default: infinite irect
|
|
16263
16263
|
'''
|
|
16264
16264
|
if isinstance(r, mupdf.FzIrect):
|
|
16265
16265
|
return r
|
|
@@ -16267,7 +16267,11 @@ def JM_irect_from_py(r):
|
|
|
16267
16267
|
r = mupdf.FzIrect( r.x0, r.y0, r.x1, r.y1)
|
|
16268
16268
|
return r
|
|
16269
16269
|
if isinstance(r, Rect):
|
|
16270
|
-
ret = mupdf.
|
|
16270
|
+
ret = mupdf.FzRect(r.x0, r.y0, r.x1, r.y1)
|
|
16271
|
+
ret = mupdf.FzIrect(ret) # Uses fz_irect_from_rect().
|
|
16272
|
+
return ret
|
|
16273
|
+
if isinstance(r, mupdf.FzRect):
|
|
16274
|
+
ret = mupdf.FzIrect(r) # Uses fz_irect_from_rect().
|
|
16271
16275
|
return ret
|
|
16272
16276
|
if not r or not PySequence_Check(r) or PySequence_Size(r) != 4:
|
|
16273
16277
|
return mupdf.FzIrect(mupdf.fz_infinite_irect)
|
|
@@ -16275,7 +16279,7 @@ def JM_irect_from_py(r):
|
|
|
16275
16279
|
for i in range(4):
|
|
16276
16280
|
f[i] = r[i]
|
|
16277
16281
|
if f[i] is None:
|
|
16278
|
-
return mupdf.
|
|
16282
|
+
return mupdf.FzIrect(mupdf.fz_infinite_irect)
|
|
16279
16283
|
if f[i] < FZ_MIN_INF_RECT:
|
|
16280
16284
|
f[i] = FZ_MIN_INF_RECT
|
|
16281
16285
|
if f[i] > FZ_MAX_INF_RECT:
|
|
@@ -17437,7 +17441,7 @@ def JM_set_ocg_arrays_imp(arr, list_):
|
|
|
17437
17441
|
# Not found.
|
|
17438
17442
|
continue
|
|
17439
17443
|
obj = mupdf.pdf_new_indirect(pdf, xref, 0)
|
|
17440
|
-
mupdf.
|
|
17444
|
+
mupdf.pdf_array_push(arr, obj)
|
|
17441
17445
|
|
|
17442
17446
|
|
|
17443
17447
|
def JM_set_resource_property(ref, name, xref):
|
|
@@ -17814,9 +17818,6 @@ def PyUnicode_DecodeRawUnicodeEscape(s, errors='strict'):
|
|
|
17814
17818
|
elif isinstance(s, bytes):
|
|
17815
17819
|
rc = s[:]
|
|
17816
17820
|
ret = rc.decode('raw_unicode_escape', errors=errors)
|
|
17817
|
-
z = ret.find(chr(0))
|
|
17818
|
-
if z >= 0:
|
|
17819
|
-
ret = ret[:z]
|
|
17820
17821
|
return ret
|
|
17821
17822
|
|
|
17822
17823
|
|
|
@@ -21729,8 +21730,8 @@ def int_rc(text):
|
|
|
21729
21730
|
return int(text)
|
|
21730
21731
|
|
|
21731
21732
|
VersionFitz = "1.23.10" # MuPDF version.
|
|
21732
|
-
VersionBind = "1.23.
|
|
21733
|
-
VersionDate = "2024-02-
|
|
21733
|
+
VersionBind = "1.23.25" # PyMuPDF version.
|
|
21734
|
+
VersionDate = "2024-02-20 00:00:01"
|
|
21734
21735
|
VersionDate2 = VersionDate.replace('-', '').replace(' ', '').replace(':', '')
|
|
21735
21736
|
version = (VersionBind, VersionFitz, VersionDate2)
|
|
21736
21737
|
pymupdf_version_tuple = tuple( [int_rc(i) for i in VersionBind.split('.')])
|