From 769dbb63437e9e7653a1e92d97e21e9855ed1654 Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Sat, 5 Nov 2022 16:30:39 +0100 Subject: [PATCH 01/10] Consistent instructions for how to install and use pdfminer.six (#793) --- README.md | 15 ++++++++++++--- docs/source/index.rst | 21 +++++++++++++++++---- docs/source/tutorial/commandline.rst | 4 ++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b8c25422..182ffcf8 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ How to use ---------- * Install Python 3.6 or newer. -* Install +* Install pdfminer.six. `pip install pdfminer.six` @@ -48,9 +48,18 @@ How to use `pip install 'pdfminer.six[image]'` -* Use command-line interface to extract text from pdf: +* Use the command-line interface to extract text from pdf. - `python pdf2txt.py samples/simple1.pdf` + `pdf2txt.py example.pdf` + +* Or use it with Python. + +```python +from pdfminer.high_level import extract_text + +text = extract_text("example.pdf") +print(text) +``` Contributing ------------ diff --git a/docs/source/index.rst b/docs/source/index.rst index a6e666eb..8650b5d5 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -59,18 +59,31 @@ Features Installation instructions ========================= -Before using it, you must install it using Python 3.6 or newer. +* Install Python 3.6 or newer. +* Install pdfminer.six. :: + $ pip install pdfminer.six` - $ pip install pdfminer.six +* (Optionally) install extra dependencies for extracting images. +:: + $ pip install 'pdfminer.six[image]'` -Optionally install extra dependencies that are needed to extract jpg images. +* Use the command-line interface to extract text from pdf. :: + $ pdf2txt.py example.pdf` + +* Or use it with Python. + +.. code-block:: python + + from pdfminer.high_level import extract_text + + text = extract_text("example.pdf") + print(text) - $ pip install 'pdfminer.six[image]' Contributing diff --git a/docs/source/tutorial/commandline.rst b/docs/source/tutorial/commandline.rst index 5aa352da..f780d36a 100644 --- a/docs/source/tutorial/commandline.rst +++ b/docs/source/tutorial/commandline.rst @@ -18,7 +18,7 @@ pdf2txt.py :: - $ python tools/pdf2txt.py example.pdf + $ pdf2txt.py example.pdf all the text from the pdf appears on the command line The :ref:`api_pdf2txt` tool extracts all the text from a PDF. It uses layout @@ -29,7 +29,7 @@ dumppdf.py :: - $ python tools/dumppdf.py -a example.pdf + $ dumppdf.py -a example.pdf ... From fa71062c3501da9508d87d1b21493bb3d5f9d4d3 Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Sat, 5 Nov 2022 16:44:15 +0100 Subject: [PATCH 02/10] Fix `ValueError` when extracting images, due to breaking changes in Pillow (#827) * Fix #795 * Update CHANGELOG.md Co-authored-by: Kunal Gehlot --- CHANGELOG.md | 3 ++- pdfminer/image.py | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfe31f19..abc7362c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - `TypeError` when getting default width of font ([#720](https://github.com/pdfminer/pdfminer.six/issues/720)) - Installing typing-extensions on Python 3.6 and 3.7 ([#775](https://github.com/pdfminer/pdfminer.six/pull/775)) - `TypeError` in cmapdb.py when parsing null characters ([#768](https://github.com/pdfminer/pdfminer.six/pull/768)) -- Color "convenience operators" now (per spec) also set color space ([#779](https://github.com/pdfminer/pdfminer.six/issues/779)) +- Color "convenience operators" now (per spec) also set color space ([#794](https://github.com/pdfminer/pdfminer.six/pull/794)) +- `ValueError` when extracting images, due to breaking changes in Pillow ([#827](https://github.com/pdfminer/pdfminer.six/pull/827)) ### Deprecated diff --git a/pdfminer/image.py b/pdfminer/image.py index 54b14929..61c2673e 100644 --- a/pdfminer/image.py +++ b/pdfminer/image.py @@ -225,20 +225,24 @@ def _save_bytes(self, image: LTImage) -> str: with open(path, "wb") as fp: try: from PIL import Image # type: ignore[import] + from PIL import ImageOps except ImportError: raise ImportError(PIL_ERROR_MESSAGE) - mode: Literal["1", "8", "RGB", "CMYK"] + mode: Literal["1", "L", "RGB", "CMYK"] if image.bits == 1: mode = "1" elif image.bits == 8 and channels == 1: - mode = "8" + mode = "L" elif image.bits == 8 and channels == 3: mode = "RGB" elif image.bits == 8 and channels == 4: mode = "CMYK" img = Image.frombytes(mode, image.srcsize, image.stream.get_data(), "raw") + if mode == "L": + img = ImageOps.invert(img) + img.save(fp) return name From 3688911afe1029b59ae09275228fa889679f495b Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Sat, 5 Nov 2022 17:08:23 +0100 Subject: [PATCH 03/10] Fix small typos in documentation (#828) * Fix #795 * Documentation updates (FAQ and others) * New how-to for extracting coordinates * Indent fix in documentation * Revert "Fix #795" This reverts commit cac62171fc6c8458ff1673137eff233107cae47b. * Move description of iterating LTPage to the docstring of LTPage * Remove adding how-to for extracting coordinates from this pr * Add CHANGELOG.md * Remove FAQ from this branch * Only add one line to CHANGELOG.md Co-authored-by: Kunal Gehlot --- CHANGELOG.md | 1 + docs/source/faq.rst | 12 ++++++------ docs/source/howto/acro_forms.rst | 10 +++++----- docs/source/topic/converting_pdf_to_text.rst | 12 ++++++------ pdfminer/high_level.py | 2 +- pdfminer/layout.py | 4 ++-- 6 files changed, 21 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abc7362c..51ecc2c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - `TypeError` in cmapdb.py when parsing null characters ([#768](https://github.com/pdfminer/pdfminer.six/pull/768)) - Color "convenience operators" now (per spec) also set color space ([#794](https://github.com/pdfminer/pdfminer.six/pull/794)) - `ValueError` when extracting images, due to breaking changes in Pillow ([#827](https://github.com/pdfminer/pdfminer.six/pull/827)) +- Small typo's and issues in the documentation ([#828](https://github.com/pdfminer/pdfminer.six/pull/828)) ### Deprecated diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 5a742d64..34614924 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -7,11 +7,11 @@ Why is it called pdfminer.six? ============================== Pdfminer.six is a fork of the `original pdfminer created by Euske -`_. Almost all of the code and architecture is in -fact created by Euske. But, for a long time this original pdfminer did not +`_. Almost all of the code and architecture are in +-fact created by Euske. But, for a long time, this original pdfminer did not support Python 3. Until 2020 the original pdfminer only supported Python 2. The original goal of pdfminer.six was to add support for Python 3. This was -done with the six package. The six package helps to write code that is +done with the `six` package. The `six` package helps to write code that is compatible with both Python 2 and Python 3. Hence, pdfminer.six. As of 2020, pdfminer.six dropped the support for Python 2 because it was @@ -27,13 +27,13 @@ also equal to six feet. How does pdfminer.six compare to other forks of pdfminer? ========================================================== -Pdfminer.six is now an independent and community maintained package for -extracting text from PDF's with Python. We actively fix bugs (also for PDF's +Pdfminer.six is now an independent and community-maintained package for +extracting text from PDFs with Python. We actively fix bugs (also for PDFs that don't strictly follow the PDF Reference), add new features and improve the usability of pdfminer.six. This community separates pdfminer.six from the other forks of the original pdfminer. PDF as a format is very diverse and there are countless deviations from the official format. The only way to -support all the PDF's out there is to have a community that actively uses and +support all the PDFs out there is to have a community that actively uses and improves pdfminer. Since 2020, the original pdfminer is `dormant diff --git a/docs/source/howto/acro_forms.rst b/docs/source/howto/acro_forms.rst index 276dccff..c4932c34 100644 --- a/docs/source/howto/acro_forms.rst +++ b/docs/source/howto/acro_forms.rst @@ -65,7 +65,7 @@ Only AcroForm interactive forms are supported, XFA forms are not supported. print(name, values) -This code snippet will print all the fields name and value and save them in the "data" dictionary. +This code snippet will print all the fields' names and values and save them in the "data" dictionary. How it works: @@ -77,9 +77,9 @@ How it works: parser = PDFParser(fp) doc = PDFDocument(parser) -- Get the catalog +- Get the Catalog - (the catalog contains references to other objects defining the document structure, see section 7.7.2 of PDF 32000-1:2008 specs: https://www.adobe.com/devnet/pdf/pdf_reference.html) + (the catalog contains references to other objects defining the document structure, see section 7.7.2 of PDF 32000-1:2008 specs: https://opensource.adobe.com/dc-acrobat-sdk-docs/pdflsdk/index.html#pdf-reference) .. code-block:: python @@ -122,7 +122,7 @@ How it works: - Call the value(s) decoding method as needed - (a single field can hold multiple values, for example a combo box can hold more than one value at time) + (a single field can hold multiple values, for example, a combo box can hold more than one value at a time) .. code-block:: python @@ -131,7 +131,7 @@ How it works: else: values = decode_value(values) -(the decode_value method takes care of decoding the fields value returning a string) +(the decode_value method takes care of decoding the field's value, returning a string) - Decode PSLiteral and PSKeyword field values diff --git a/docs/source/topic/converting_pdf_to_text.rst b/docs/source/topic/converting_pdf_to_text.rst index 5194b114..18c1cba0 100644 --- a/docs/source/topic/converting_pdf_to_text.rst +++ b/docs/source/topic/converting_pdf_to_text.rst @@ -3,7 +3,7 @@ Converting a PDF file to text ***************************** -Most PDF files look like they contain well structured text. But the reality is +Most PDF files look like they contain well-structured text. But the reality is that a PDF file does not contain anything that resembles paragraphs, sentences or even words. When it comes to text, a PDF file is only aware of the characters and their placement. @@ -14,7 +14,7 @@ compose the table, the page footer or the description of a figure. Unlike other document formats, like a `.txt` file or a word document, the PDF format does not contain a stream of text. -A PDF document does consists of a collection of objects that together describe +A PDF document consists of a collection of objects that together describe the appearance of one or more pages, possibly accompanied by additional interactive elements and higher-level application data. A PDF file contains the objects making up a PDF document along with associated structural @@ -53,7 +53,7 @@ uses these bounding boxes to decide which characters belong together. Characters that are both horizontally and vertically close are grouped onto one line. How close they should be is determined by the `char_margin` -(M in figure) and the `line_overlap` (not in figure) parameter. The horizontal +(M in the figure) and the `line_overlap` (not in figure) parameter. The horizontal *distance* between the bounding boxes of two characters should be smaller than the `char_margin` and the vertical *overlap* between the bounding boxes should be smaller than the `line_overlap`. @@ -76,7 +76,7 @@ be separated by a space. The result of this stage is a list of lines. Each line consists of a list of characters. These characters are either original `LTChar` characters that -originate from the PDF file, or inserted `LTAnno` characters that +originate from the PDF file or inserted `LTAnno` characters that represent spaces between words or newlines at the end of each line. Grouping lines into boxes @@ -91,7 +91,7 @@ Lines that are both horizontally overlapping and vertically close are grouped. How vertically close the lines should be is determined by the `line_margin`. This margin is specified relative to the height of the bounding box. Lines are close if the gap between the tops (see L :sub:`1` in the figure) and bottoms -(see L :sub:`2`) in the figure) of the bounding boxes is closer together +(see L :sub:`2`) in the figure) of the bounding boxes are closer together than the absolute line margin, i.e. the `line_margin` multiplied by the height of the bounding box. @@ -120,7 +120,7 @@ Working with rotated characters The algorithm described above assumes that all characters have the same orientation. However, any writing direction is possible in a PDF. To -accommodate for this, pdfminer.six allows to detect vertical writing with the +accommodate for this, pdfminer.six allows detecting vertical writing with the `detect_vertical` parameter. This will apply all the grouping steps as if the pdf was rotated 90 (or 270) degrees diff --git a/pdfminer/high_level.py b/pdfminer/high_level.py index 94be9d42..6587fdee 100644 --- a/pdfminer/high_level.py +++ b/pdfminer/high_level.py @@ -195,7 +195,7 @@ def extract_pages( :param caching: If resources should be cached :param laparams: An LAParams object from pdfminer.layout. If None, uses some default settings that often work well. - :return: + :return: LTPage objects """ if laparams is None: laparams = LAParams() diff --git a/pdfminer/layout.py b/pdfminer/layout.py index 5158f0eb..5bfe759f 100644 --- a/pdfminer/layout.py +++ b/pdfminer/layout.py @@ -1011,8 +1011,8 @@ def analyze(self, laparams: LAParams) -> None: class LTPage(LTLayoutContainer): """Represents an entire page. - May contain child objects like LTTextBox, LTFigure, LTImage, LTRect, - LTCurve and LTLine. + Like any other LTLayoutContainer, an LTPage can be iterated to obtain child + objects like LTTextBox, LTFigure, LTImage, LTRect, LTCurve and LTLine. """ def __init__(self, pageid: int, bbox: Rect, rotate: float = 0) -> None: From ebf7bcdb983f36d0ff5b40e4f23b52525cb28f18 Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Sat, 5 Nov 2022 17:22:08 +0100 Subject: [PATCH 04/10] Add FAQ about special characters (#829) * Add FAQ for extracting special characters * Update CHANGELOG.md * Update faq.rst --- CHANGELOG.md | 1 + docs/source/faq.rst | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51ecc2c7..1a1ead61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Output converter for the hOCR format ([#651](https://github.com/pdfminer/pdfminer.six/pull/651)) - Font name aliases for Arial, Courier New and Times New Roman ([#790](https://github.com/pdfminer/pdfminer.six/pull/790)) +- Documentation on why special characters can sometimes not be extracted ([#829](https://github.com/pdfminer/pdfminer.six/pull/829)) ### Fixed diff --git a/docs/source/faq.rst b/docs/source/faq.rst index 34614924..b209c807 100644 --- a/docs/source/faq.rst +++ b/docs/source/faq.rst @@ -39,3 +39,30 @@ improves pdfminer. Since 2020, the original pdfminer is `dormant `_, and pdfminer.six is the fork which Euske recommends if you need an actively maintained version of pdfminer. + +Why are there `(cid:x)` values in the textual output? +===================================================== + +One of the most common issues with pdfminer.six is that the textual output +contains raw character id's `(cid:x)`. This is often experienced as confusing +because the text is shown fine in a PDF viewer and other text from the same +PDF is extracted properly. + +The underlying problem is that a PDF has two different representations +of each character. Each character is mapped to a glyph that determines +how the character is shown in a PDF viewer. And each character is also +mapped to its unicode value that is used when copy-pasting the character. +Some PDF's have incomplete unicode mappings and therefore it is impossible +to convert the character to unicode. In these cases pdfminer.six defaults +to showing the raw character id `(cid:x)` + +A quick test to see if pdfminer.six should be able to do better is to +copy-paste the text from a PDF viewer to a text editor. If the result +is proper text, pdfminer.six should also be able to extract proper text. +If the result is gibberish, pdfminer.six will also not be able to convert +the characters to unicode. + +References: + +#. `Chapter 5: Text, PDF Reference 1.7 `_ +#. `Text: PDF, Wikipedia `_ From 5114acdda61205009221ce4ebf2c68c144fc4ee5 Mon Sep 17 00:00:00 2001 From: Julian Date: Sun, 6 Nov 2022 16:50:37 +0100 Subject: [PATCH 05/10] Storing Bezier path and dashing style of line in LTCurve (#801) * Fixes #672 and #630 Add raw points to get full information from bezier segments and dashing style * Use intermediate variables for constructing tranformed_path Co-authored-by: Pieter Marsman --- CHANGELOG.md | 1 + pdfminer/converter.py | 22 +++++++++++++++++++++- pdfminer/layout.py | 23 +++++++++++++++++++++-- tests/test_converter.py | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a1ead61..3ffbe882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Output converter for the hOCR format ([#651](https://github.com/pdfminer/pdfminer.six/pull/651)) - Font name aliases for Arial, Courier New and Times New Roman ([#790](https://github.com/pdfminer/pdfminer.six/pull/790)) - Documentation on why special characters can sometimes not be extracted ([#829](https://github.com/pdfminer/pdfminer.six/pull/829)) +- Storing Bezier path and dashing style of line in LTCurve ([#801](https://github.com/pdfminer/pdfminer.six/pull/801)) ### Fixed diff --git a/pdfminer/converter.py b/pdfminer/converter.py index 6b367aa2..8e48d86a 100644 --- a/pdfminer/converter.py +++ b/pdfminer/converter.py @@ -138,6 +138,19 @@ def paint_path( ] pts = [apply_matrix_pt(self.ctm, pt) for pt in raw_pts] + operators = [str(operation[0]) for operation in path] + transformed_points = [ + [ + apply_matrix_pt(self.ctm, (float(operand1), float(operand2))) + for operand1, operand2 in zip(operation[1::2], operation[2::2]) + ] + for operation in path + ] + transformed_path = [ + cast(PathSegment, (o, *p)) + for o, p in zip(operators, transformed_points) + ] + if shape in {"mlh", "ml"}: # single line segment # @@ -152,6 +165,8 @@ def paint_path( evenodd, gstate.scolor, gstate.ncolor, + original_path=transformed_path, + dashing_style=gstate.dash, ) self.cur_item.add(line) @@ -171,6 +186,8 @@ def paint_path( evenodd, gstate.scolor, gstate.ncolor, + transformed_path, + gstate.dash, ) self.cur_item.add(rect) else: @@ -182,9 +199,10 @@ def paint_path( evenodd, gstate.scolor, gstate.ncolor, + transformed_path, + gstate.dash, ) self.cur_item.add(curve) - else: curve = LTCurve( gstate.linewidth, @@ -194,6 +212,8 @@ def paint_path( evenodd, gstate.scolor, gstate.ncolor, + transformed_path, + gstate.dash, ) self.cur_item.add(curve) diff --git a/pdfminer/layout.py b/pdfminer/layout.py index 5bfe759f..a4159e46 100644 --- a/pdfminer/layout.py +++ b/pdfminer/layout.py @@ -20,7 +20,7 @@ from .pdfinterp import Color from .pdfinterp import PDFGraphicState from .pdftypes import PDFStream -from .utils import INF +from .utils import INF, PathSegment from .utils import LTComponentT from .utils import Matrix from .utils import Plane @@ -210,7 +210,14 @@ def voverlap(self, obj: "LTComponent") -> float: class LTCurve(LTComponent): - """A generic Bezier curve""" + """ + A generic Bezier curve + + The parameter `original_path` contains the original + pathing information from the pdf (e.g. for reconstructing Bezier Curves). + + `dashing_style` contains the Dashing information if any. + """ def __init__( self, @@ -221,6 +228,8 @@ def __init__( evenodd: bool = False, stroking_color: Optional[Color] = None, non_stroking_color: Optional[Color] = None, + original_path: Optional[List[PathSegment]] = None, + dashing_style: Optional[Tuple[object, object]] = None, ) -> None: LTComponent.__init__(self, get_bound(pts)) self.pts = pts @@ -230,6 +239,8 @@ def __init__( self.evenodd = evenodd self.stroking_color = stroking_color self.non_stroking_color = non_stroking_color + self.original_path = original_path + self.dashing_style = dashing_style def get_pts(self) -> str: return ",".join("%.3f,%.3f" % p for p in self.pts) @@ -251,6 +262,8 @@ def __init__( evenodd: bool = False, stroking_color: Optional[Color] = None, non_stroking_color: Optional[Color] = None, + original_path: Optional[List[PathSegment]] = None, + dashing_style: Optional[Tuple[object, object]] = None, ) -> None: LTCurve.__init__( self, @@ -261,6 +274,8 @@ def __init__( evenodd, stroking_color, non_stroking_color, + original_path, + dashing_style, ) @@ -279,6 +294,8 @@ def __init__( evenodd: bool = False, stroking_color: Optional[Color] = None, non_stroking_color: Optional[Color] = None, + original_path: Optional[List[PathSegment]] = None, + dashing_style: Optional[Tuple[object, object]] = None, ) -> None: (x0, y0, x1, y1) = bbox LTCurve.__init__( @@ -290,6 +307,8 @@ def __init__( evenodd, stroking_color, non_stroking_color, + original_path, + dashing_style, ) diff --git a/tests/test_converter.py b/tests/test_converter.py index 80de019d..5bd560e9 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -216,6 +216,45 @@ def parse(path): (71.41, 434.89), ] + def test_paint_path_beziers_check_raw(self): + """See section 4.4, table 4.9 of the PDF reference manual""" + + def parse(path): + analyzer = self._get_analyzer() + analyzer.cur_item = LTContainer([0, 1000, 0, 1000]) + analyzer.paint_path(PDFGraphicState(), False, False, False, path) + return analyzer.cur_item._objs + + # "c" operator + assert parse( + [ + ("m", 72.41, 433.89), + ("c", 72.41, 434.45, 71.96, 434.89, 71.41, 434.89), + ] + )[0].original_path == [ + ("m", (72.41, 433.89)), + ("c", (72.41, 434.45), (71.96, 434.89), (71.41, 434.89)), + ] + + def test_paint_path_dashed(self): + """See section 4.4, table 4.9 of the PDF reference manual""" + + def parse(path): + analyzer = self._get_analyzer() + analyzer.cur_item = LTContainer([0, 1000, 0, 1000]) + graphicstate = PDFGraphicState() + graphicstate.dash = ([1, 1], 0) + analyzer.paint_path(graphicstate, False, False, False, path) + return analyzer.cur_item._objs + + # "c" operator + assert parse( + [ + ("m", 72.41, 433.89), + ("c", 72.41, 434.45, 71.96, 434.89, 71.41, 434.89), + ] + )[0].dashing_style == ([1, 1], 0) + def test_paint_path_without_starting_m(self): gs = PDFGraphicState() analyzer = self._get_analyzer() From 40b200d4f0bbaf533bbabe6743f5e5b3cd15c65d Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Fri, 24 Nov 2023 13:33:03 -0500 Subject: [PATCH 06/10] Minimally fix CI (#921) * fix(ci): update versions of everything including python * docs: add changelog entry * fix(ci): use black from last year * fix(ci): fix linting and typechecking issues * docs: put CHANGELOG entries in the right place * fix(ci): use older pip/setuptools to tolerate bogus -VERSION- * fix(ci): skip 3.12 for now, fix remaining nox * Update minimum Python version in the README.md * Simplify lines in CHANGELOG.md --------- Co-authored-by: Pieter Marsman --- .github/workflows/actions.yml | 24 ++++++++++++------------ CHANGELOG.md | 5 +++++ README.md | 2 +- noxfile.py | 10 +++++++--- pdfminer/image.py | 2 +- tests/test_converter.py | 2 +- 6 files changed, 27 insertions(+), 18 deletions(-) diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 25186bae..6a174ebe 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -20,9 +20,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up Python ${{ env.default-python }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.default-python }} - name: Upgrade pip, Install nox @@ -38,9 +38,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up Python ${{ env.default-python }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.default-python }} - name: Upgrade pip, Install nox @@ -75,12 +75,12 @@ jobs: strategy: matrix: os: [ ubuntu-latest ] - python-version: [ "3.6", "3.7", "3.8", "3.9", "3.10" ] + python-version: [ "3.8", "3.9", "3.10", "3.11" ] # should have 3.12 too! steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Determine pip cache directory @@ -88,7 +88,7 @@ jobs: run: | echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip cache - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip${{ matrix.python-version }} @@ -105,9 +105,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up Python ${{ env.default-python }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.default-python }} - name: Upgrade pip and install nox @@ -129,7 +129,7 @@ jobs: - build-docs steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Install dependencies run: python -m pip install wheel - name: Set version @@ -161,4 +161,4 @@ jobs: body_path: ${{ github.workspace }}-CHANGELOG.md files: | dist/*.tar.gz - dist/*.whl \ No newline at end of file + dist/*.whl diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ffbe882..f7e3b193 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +### Removed +- Support for Python 3.6 and 3.7 ([#921](https://github.com/pdfminer/pdfminer.six/pull/921)) + ### Added - Output converter for the hOCR format ([#651](https://github.com/pdfminer/pdfminer.six/pull/651)) @@ -14,6 +17,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed +- Broken CI/CD pipeline by setting upper version limit for black, mypy, pip and setuptools ([#921](https://github.com/pdfminer/pdfminer.six/pull/921)) +- `flake8` failures ([#921](https://github.com/pdfminer/pdfminer.six/pull/921)) - `ValueError` when bmp images with 1 bit channel are decoded ([#773](https://github.com/pdfminer/pdfminer.six/issues/773)) - `ValueError` when trying to decrypt empty metadata values ([#766](https://github.com/pdfminer/pdfminer.six/issues/766)) - Sphinx errors during building of documentation ([#760](https://github.com/pdfminer/pdfminer.six/pull/760)) diff --git a/README.md b/README.md index 182ffcf8..0015bb08 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Features How to use ---------- -* Install Python 3.6 or newer. +* Install Python 3.8 or newer. * Install pdfminer.six. `pip install pdfminer.six` diff --git a/noxfile.py b/noxfile.py index f55bbadb..95677bcf 100644 --- a/noxfile.py +++ b/noxfile.py @@ -3,13 +3,13 @@ import nox -PYTHON_ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10"] +PYTHON_ALL_VERSIONS = ["3.8", "3.9", "3.10", "3.11"] # should have 3.12 PYTHON_MODULES = ["pdfminer", "tools", "tests", "noxfile.py", "setup.py"] @nox.session def format(session): - session.install("black") + session.install("black<23") # Format files locally with black, but only check in cicd if "CI" in os.environ: session.run("black", "--check", *PYTHON_MODULES) @@ -25,7 +25,7 @@ def lint(session): @nox.session def types(session): - session.install("mypy") + session.install("mypy<1") session.run( "mypy", "--install-types", @@ -37,12 +37,16 @@ def types(session): @nox.session(python=PYTHON_ALL_VERSIONS) def tests(session): + session.install("pip<23") + session.install("setuptools<58") session.install("-e", ".[dev]") session.run("pytest") @nox.session def docs(session): + session.install("pip<23") + session.install("setuptools<58") session.install("-e", ".[docs]") session.run( "python", "-m", "sphinx", "-b", "html", "docs/source", "docs/build/html" diff --git a/pdfminer/image.py b/pdfminer/image.py index 61c2673e..d72a10cd 100644 --- a/pdfminer/image.py +++ b/pdfminer/image.py @@ -8,7 +8,7 @@ from typing import Literal except ImportError: # Literal was introduced in Python 3.8 - from typing_extensions import Literal # type: ignore[misc] + from typing_extensions import Literal # type: ignore[assignment] from .jbig2 import JBIG2StreamReader, JBIG2StreamWriter from .layout import LTImage diff --git a/tests/test_converter.py b/tests/test_converter.py index 5bd560e9..3a3fff90 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -173,7 +173,7 @@ def get_types(path): # they all have shape 'ml' not 'mlh' ml_pdf = extract_pages("samples/contrib/pr-00530-ml-lines.pdf") ml_pdf_page = list(ml_pdf)[0] - assert sum(type(item) == LTLine for item in ml_pdf_page) == 6 + assert sum(type(item) is LTLine for item in ml_pdf_page) == 6 def _get_analyzer(self): analyzer = PDFLayoutAnalyzer(None) From 997424deaadfa23e57f15561b492c194075f950f Mon Sep 17 00:00:00 2001 From: NAZADOTH <108572837+NAZADOTH@users.noreply.github.com> Date: Sat, 25 Nov 2023 11:16:26 +0100 Subject: [PATCH 07/10] Fix #791 (#806) * Skip non-Unicode cmaps in TrueType fonts * Prefer normal space when it has the same cid as a non-breaking one * Add test * Update CHANGELOG.md * Add brackets to make operator order explicit --------- Co-authored-by: Pieter Marsman --- CHANGELOG.md | 1 + pdfminer/cmapdb.py | 11 ++++++++--- pdfminer/pdffont.py | 8 +++++++- samples/contrib/issue-791-non-unicode-cmap.pdf | Bin 0 -> 95350 bytes tests/test_highlevel_extracttext.py | 6 ++++++ 5 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 samples/contrib/issue-791-non-unicode-cmap.pdf diff --git a/CHANGELOG.md b/CHANGELOG.md index f7e3b193..865ee52c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Color "convenience operators" now (per spec) also set color space ([#794](https://github.com/pdfminer/pdfminer.six/pull/794)) - `ValueError` when extracting images, due to breaking changes in Pillow ([#827](https://github.com/pdfminer/pdfminer.six/pull/827)) - Small typo's and issues in the documentation ([#828](https://github.com/pdfminer/pdfminer.six/pull/828)) +- Ignore non-Unicode cmaps in TrueType fonts ([#806](https://github.com/pdfminer/pdfminer.six/pull/806)) ### Deprecated diff --git a/pdfminer/cmapdb.py b/pdfminer/cmapdb.py index 01306ed2..f0c43ab7 100644 --- a/pdfminer/cmapdb.py +++ b/pdfminer/cmapdb.py @@ -195,15 +195,20 @@ def add_cid2unichr(self, cid: int, code: Union[PSLiteral, bytes, int]) -> None: if isinstance(code, PSLiteral): # Interpret as an Adobe glyph name. assert isinstance(code.name, str) - self.cid2unichr[cid] = name2unicode(code.name) + unichr = name2unicode(code.name) elif isinstance(code, bytes): # Interpret as UTF-16BE. - self.cid2unichr[cid] = code.decode("UTF-16BE", "ignore") + unichr = code.decode("UTF-16BE", "ignore") elif isinstance(code, int): - self.cid2unichr[cid] = chr(code) + unichr = chr(code) else: raise TypeError(code) + # A0 = non-breaking space, some weird fonts can have a collision on a cid here. + if unichr == "\u00A0" and self.cid2unichr.get(cid) == " ": + return + self.cid2unichr[cid] = unichr + class PyCMap(CMap): def __init__(self, name: str, module: Any) -> None: diff --git a/pdfminer/pdffont.py b/pdfminer/pdffont.py index 13629c77..63826b96 100644 --- a/pdfminer/pdffont.py +++ b/pdfminer/pdffont.py @@ -755,7 +755,11 @@ def create_unicode_map(self) -> FileUnicodeMap: ) char2gid: Dict[int, int] = {} # Only supports subtable type 0, 2 and 4. - for (_1, _2, st_offset) in subtables: + for (platform_id, encoding_id, st_offset) in subtables: + # Skip non-Unicode cmaps. + # https://docs.microsoft.com/en-us/typography/opentype/spec/cmap + if not (platform_id == 0 or (platform_id == 3 and encoding_id in [1, 10])): + continue fp.seek(base_offset + st_offset) (fmttype, fmtlen, fmtlang) = cast( Tuple[int, int, int], struct.unpack(">HHH", fp.read(6)) @@ -824,6 +828,8 @@ def create_unicode_map(self) -> FileUnicodeMap: char2gid[c] = (c + idd) & 0xFFFF else: assert False, str(("Unhandled", fmttype)) + if not char2gid: + raise TrueTypeFont.CMapNotFound # create unicode map unicode_map = FileUnicodeMap() for (char, gid) in char2gid.items(): diff --git a/samples/contrib/issue-791-non-unicode-cmap.pdf b/samples/contrib/issue-791-non-unicode-cmap.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8595bd6f5bf381b8c5b24354ce55af80f0c60901 GIT binary patch literal 95350 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

aLql}7L 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 QbF*=>qtnnxDNCdO53lLCF#rGn literal 0 HcmV?d00001 diff --git a/tests/test_highlevel_extracttext.py b/tests/test_highlevel_extracttext.py index 842459d2..1ea0e7f2 100644 --- a/tests/test_highlevel_extracttext.py +++ b/tests/test_highlevel_extracttext.py @@ -39,6 +39,7 @@ def run_with_file(sample_path): "contrib/issue_566_test_1.pdf": "ISSUE Date:2019-4-25 Buyer:黎荣", "contrib/issue_566_test_2.pdf": "甲方:中国饮料有限公司(盖章)", "contrib/issue-625-identity-cmap.pdf": "Termin płatności: 2021-05-03", + "contrib/issue-791-non-unicode-cmap.pdf": "Peněžní prostředky na účtech", } @@ -120,6 +121,11 @@ def test_issue_625_identity_cmap(self): self.assertEqual(lines[6], test_strings[test_file]) + def test_issue_791_non_unicode_cmap(self): + test_file = "contrib/issue-791-non-unicode-cmap.pdf" + s = run_with_file(test_file) + self.assertEqual(s.strip(), test_strings[test_file]) + class TestExtractPages(unittest.TestCase): def _get_test_file_path(self): From 38d48aa546d60ed951e096decc2357ce8d5983dd Mon Sep 17 00:00:00 2001 From: David Huggins-Daines Date: Thu, 28 Dec 2023 16:15:58 -0500 Subject: [PATCH 08/10] Fix from-source and Python 3.12 build by removing hard-coded version (#922) (#923) * fix(ci): update versions of everything including python * docs: add changelog entry * fix(ci): use black from last year * fix(ci): fix linting and typechecking issues * docs: put CHANGELOG entries in the right place * fix(ci): use older pip/setuptools to tolerate bogus -VERSION- * fix(ci): skip 3.12 for now, fix remaining nox * chore: ignore * fix: use setuptools_git_versioning instead of hack * fix(ci): re-enable python 3.12 * fix(ci): remove version hack from release workflow * fix(test): ensure path for tools in tests on 3.12 * Update documentation for minimum python version * Update CHANGELOG.md * Fix GitHub workflow by removing upper bound on pip and setuptools * Fix test imports by always importing from root * Fix import error in test_converter.py * black --------- Co-authored-by: Pieter Marsman --- .github/workflows/actions.yml | 16 +++------------- .gitignore | 1 + CHANGELOG.md | 9 +++++++++ noxfile.py | 10 +++++----- pdfminer/__init__.py | 8 +++++++- setup.py | 20 ++++++++++---------- tests/__init__.py | 0 tests/test_converter.py | 2 +- tests/test_font_size.py | 2 +- tests/test_highlevel_extracttext.py | 4 ++-- tests/test_layout.py | 2 +- tests/test_pdfdocument.py | 2 +- tests/test_pdfpage.py | 2 +- tests/test_tools_dumppdf.py | 4 ++-- tests/test_tools_pdf2txt.py | 6 +++--- tests/test_utils.py | 8 ++++---- 16 files changed, 51 insertions(+), 45 deletions(-) create mode 100644 tests/__init__.py diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 6a174ebe..47887ea8 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -56,9 +56,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up Python ${{ env.default-python }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.default-python }} - name: Upgrade pip, Install nox @@ -75,7 +75,7 @@ jobs: strategy: matrix: os: [ ubuntu-latest ] - python-version: [ "3.8", "3.9", "3.10", "3.11" ] # should have 3.12 too! + python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ] steps: - name: Checkout code uses: actions/checkout@v4 @@ -132,16 +132,6 @@ jobs: uses: actions/checkout@v4 - name: Install dependencies run: python -m pip install wheel - - name: Set version - run: | - if [[ "${{ github.ref }}" == "refs/tags/"* ]] - then - VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,' | sed -e 's/^v//') - else - VERSION=$(date +%Y%m%d).$(date +%H%M%S) - fi - echo ${VERSION} - sed -i "s/__VERSION__/${VERSION}/g" pdfminer/__init__.py - name: Build package run: python setup.py sdist bdist_wheel - name: Generate changelog diff --git a/.gitignore b/.gitignore index b155fbbd..c1642e11 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ Pipfile.lock .vscode/ pyproject.toml poetry.lock +.eggs diff --git a/CHANGELOG.md b/CHANGELOG.md index 865ee52c..d9c16648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,10 +30,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Small typo's and issues in the documentation ([#828](https://github.com/pdfminer/pdfminer.six/pull/828)) - Ignore non-Unicode cmaps in TrueType fonts ([#806](https://github.com/pdfminer/pdfminer.six/pull/806)) +### Changed + +- Using non-hardcoded version string and setuptools-git-versioning to enable installation from source and building on Python 3.12 ([#922](https://github.com/pdfminer/pdfminer.six/issues/922)) + + ### Deprecated - Usage of `if __name__ == "__main__"` where it was only intended for testing purposes ([#756](https://github.com/pdfminer/pdfminer.six/pull/756)) +### Removed + +- Support for Python 3.6 and 3.7 because they are end-of-life ([#923](https://github.com/pdfminer/pdfminer.six/pull/923)) + ## [20220524] ### Fixed diff --git a/noxfile.py b/noxfile.py index 95677bcf..52995e1b 100644 --- a/noxfile.py +++ b/noxfile.py @@ -3,7 +3,7 @@ import nox -PYTHON_ALL_VERSIONS = ["3.8", "3.9", "3.10", "3.11"] # should have 3.12 +PYTHON_ALL_VERSIONS = ["3.8", "3.9", "3.10", "3.11", "3.12"] PYTHON_MODULES = ["pdfminer", "tools", "tests", "noxfile.py", "setup.py"] @@ -37,16 +37,16 @@ def types(session): @nox.session(python=PYTHON_ALL_VERSIONS) def tests(session): - session.install("pip<23") - session.install("setuptools<58") + session.install("pip") + session.install("setuptools") session.install("-e", ".[dev]") session.run("pytest") @nox.session def docs(session): - session.install("pip<23") - session.install("setuptools<58") + session.install("pip") + session.install("setuptools") session.install("-e", ".[docs]") session.run( "python", "-m", "sphinx", "-b", "html", "docs/source", "docs/build/html" diff --git a/pdfminer/__init__.py b/pdfminer/__init__.py index e8e5221f..5bd4d50a 100644 --- a/pdfminer/__init__.py +++ b/pdfminer/__init__.py @@ -1,4 +1,10 @@ -__version__ = "__VERSION__" # auto replaced with tag in github actions +from importlib.metadata import version, PackageNotFoundError + +try: + __version__ = version("pdfminer.six") +except PackageNotFoundError: + # package is not installed, return default + __version__ = "0.0" if __name__ == "__main__": print(__version__) diff --git a/setup.py b/setup.py index 8f257c3f..516e6af6 100644 --- a/setup.py +++ b/setup.py @@ -1,24 +1,23 @@ -import sys from pathlib import Path - from setuptools import setup -from os import path - -sys.path.append(str(Path(__file__).parent)) -import pdfminer as package # noqa: E402 -with open(path.join(path.abspath(path.dirname(__file__)), "README.md")) as f: +root_dir = Path(__file__).parent +with open(root_dir / "README.md", "rt") as f: readme = f.read() setup( name="pdfminer.six", - version=package.__version__, + setuptools_git_versioning={ + "enabled": True, + }, + setup_requires=["setuptools-git-versioning<2"], packages=["pdfminer"], package_data={"pdfminer": ["cmap/*.pickle.gz", "py.typed"]}, install_requires=[ "charset-normalizer >= 2.0.0", "cryptography >= 36.0.0", 'typing_extensions; python_version < "3.8"', + 'importlib_metadata; python_version < "3.8"', ], extras_require={ "dev": ["pytest", "nox", "black", "mypy == 0.931"], @@ -45,10 +44,11 @@ python_requires=">=3.6", classifiers=[ "Programming Language :: Python", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3 :: Only", "Development Status :: 5 - Production/Stable", "Environment :: Console", diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_converter.py b/tests/test_converter.py index 3a3fff90..17d280cb 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -1,11 +1,11 @@ import io from tempfile import TemporaryFile -from helpers import absolute_sample_path from pdfminer.converter import PDFLayoutAnalyzer, PDFConverter from pdfminer.high_level import extract_pages from pdfminer.layout import LTChar, LTContainer, LTRect, LTLine, LTCurve from pdfminer.pdfinterp import PDFGraphicState +from tests.helpers import absolute_sample_path class TestPaintPath: diff --git a/tests/test_font_size.py b/tests/test_font_size.py index fca808c3..cac5b753 100644 --- a/tests/test_font_size.py +++ b/tests/test_font_size.py @@ -1,6 +1,6 @@ -from helpers import absolute_sample_path from pdfminer.high_level import extract_pages from pdfminer.layout import LTChar, LTTextBox +from tests.helpers import absolute_sample_path def test_font_size(): diff --git a/tests/test_highlevel_extracttext.py b/tests/test_highlevel_extracttext.py index 1ea0e7f2..cd7d8bfc 100644 --- a/tests/test_highlevel_extracttext.py +++ b/tests/test_highlevel_extracttext.py @@ -1,8 +1,8 @@ import unittest -from helpers import absolute_sample_path -from pdfminer.high_level import extract_text, extract_pages +from pdfminer.high_level import extract_pages, extract_text from pdfminer.layout import LAParams, LTTextContainer +from tests.helpers import absolute_sample_path def run_with_string(sample_path, laparams=None): diff --git a/tests/test_layout.py b/tests/test_layout.py index fd393a4e..85058cf3 100644 --- a/tests/test_layout.py +++ b/tests/test_layout.py @@ -10,7 +10,7 @@ LTTextBoxVertical, ) from pdfminer.utils import Plane -from helpers import absolute_sample_path +from tests.helpers import absolute_sample_path class TestGroupTextLines(unittest.TestCase): diff --git a/tests/test_pdfdocument.py b/tests/test_pdfdocument.py index 3c1f2430..c57126fb 100644 --- a/tests/test_pdfdocument.py +++ b/tests/test_pdfdocument.py @@ -2,10 +2,10 @@ import pytest -from helpers import absolute_sample_path from pdfminer.pdfdocument import PDFDocument, PDFNoPageLabels from pdfminer.pdfparser import PDFParser from pdfminer.pdftypes import PDFObjectNotFound, dict_value, int_value +from tests.helpers import absolute_sample_path class TestPdfDocument(object): diff --git a/tests/test_pdfpage.py b/tests/test_pdfpage.py index 0d3109f1..c3fe86c2 100644 --- a/tests/test_pdfpage.py +++ b/tests/test_pdfpage.py @@ -1,7 +1,7 @@ -from helpers import absolute_sample_path from pdfminer.pdfdocument import PDFDocument from pdfminer.pdfpage import PDFPage from pdfminer.pdfparser import PDFParser +from tests.helpers import absolute_sample_path class TestPdfPage(object): diff --git a/tests/test_tools_dumppdf.py b/tests/test_tools_dumppdf.py index 84e3111c..971c3d07 100644 --- a/tests/test_tools_dumppdf.py +++ b/tests/test_tools_dumppdf.py @@ -2,8 +2,8 @@ import pytest -from helpers import absolute_sample_path -from tempfilepath import TemporaryFilePath +from tests.helpers import absolute_sample_path +from tests.tempfilepath import TemporaryFilePath from tools import dumppdf diff --git a/tests/test_tools_pdf2txt.py b/tests/test_tools_pdf2txt.py index abd53074..f6eeefcf 100644 --- a/tests/test_tools_pdf2txt.py +++ b/tests/test_tools_pdf2txt.py @@ -1,11 +1,11 @@ +import filecmp import os from shutil import rmtree from tempfile import mkdtemp -import filecmp import tools.pdf2txt as pdf2txt -from helpers import absolute_sample_path -from tempfilepath import TemporaryFilePath +from tests.helpers import absolute_sample_path +from tests.tempfilepath import TemporaryFilePath def run(sample_path, options=None): diff --git a/tests/test_utils.py b/tests/test_utils.py index 062a9733..160b02b4 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,15 +2,15 @@ import pytest -from helpers import absolute_sample_path from pdfminer.layout import LTComponent from pdfminer.utils import ( - open_filename, Plane, - shorten_str, - format_int_roman, format_int_alpha, + format_int_roman, + open_filename, + shorten_str, ) +from tests.helpers import absolute_sample_path class TestOpenFilename: From bd252ef5a578694efffdb1e42b24deea22f78d17 Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 28 Dec 2023 22:20:33 +0100 Subject: [PATCH 09/10] Bump version in CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9c16648..40273f19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +Nothing yet. + +## [20231228] + ### Removed - Support for Python 3.6 and 3.7 ([#921](https://github.com/pdfminer/pdfminer.six/pull/921)) From 674fbbb1386ef6f6f476aff0472a4f265ef145a5 Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 28 Dec 2023 22:21:40 +0100 Subject: [PATCH 10/10] Bump version in CHANGELOG.md (#929) --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9c16648..40273f19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +Nothing yet. + +## [20231228] + ### Removed - Support for Python 3.6 and 3.7 ([#921](https://github.com/pdfminer/pdfminer.six/pull/921))