diff --git a/.github/workflows/github-ci.yaml b/.github/workflows/github-ci.yaml index 9e06ccab1..7d0f1426c 100644 --- a/.github/workflows/github-ci.yaml +++ b/.github/workflows/github-ci.yaml @@ -58,7 +58,7 @@ jobs: python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] use-crypto-lib: ["cryptography"] include: - - python-version: "3.6" + - python-version: "3.7" use-crypto-lib: "pycryptodome" - python-version: "3.7" use-crypto-lib: "none" @@ -81,7 +81,7 @@ jobs: key: cache-downloaded-files - name: Setup Python uses: actions/setup-python@v5 - if: matrix.python-version == '3.6' || matrix.python-version == '3.7' || matrix.python-version == '3.8' || matrix.python-version == '3.9' || matrix.python-version == '3.10' + if: matrix.python-version == '3.7' || matrix.python-version == '3.8' || matrix.python-version == '3.9' || matrix.python-version == '3.10' with: python-version: ${{ matrix.python-version }} cache: 'pip' @@ -100,7 +100,7 @@ jobs: - name: Install requirements (Python 3) run: | pip install -r requirements/ci.txt - if: matrix.python-version == '3.6' || matrix.python-version == '3.7' || matrix.python-version == '3.8' || matrix.python-version == '3.9' || matrix.python-version == '3.10' + if: matrix.python-version == '3.7' || matrix.python-version == '3.8' || matrix.python-version == '3.9' || matrix.python-version == '3.10' - name: Install requirements (Python 3.11+) run: | pip install -r requirements/ci-3.11.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ad3856f14..37c67efb6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ # pre-commit run --all-files repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.1.0 hooks: - id: check-ast - id: check-byte-order-marker @@ -18,34 +18,34 @@ repos: - id: check-added-large-files args: ['--maxkb=1000'] - repo: https://github.com/psf/black - rev: 23.10.1 + rev: 23.3.0 hooks: - id: black - args: [--target-version, py36] + args: [--target-version, py37] - repo: https://github.com/asottile/blacken-docs - rev: 1.16.0 + rev: 1.14.0 hooks: - id: blacken-docs additional_dependencies: [black==22.1.0] exclude: "docs/user/robustness.md" - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.1.3 + rev: v0.1.9 hooks: - id: ruff args: ['--fix'] - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.3.2 hooks: - id: pyupgrade - args: [--py36-plus] + args: [--py37-plus] - repo: https://github.com/pycqa/flake8 - rev: 6.1.0 + rev: 5.0.4 hooks: - id: flake8 args: ["--ignore", "E,W,F"] - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v1.6.1' + rev: 'v1.4.0' hooks: - id: mypy additional_dependencies: [types-Pillow==10.0.0.2] diff --git a/.pylintrc b/.pylintrc index 9956cc2fc..3ad613991 100644 --- a/.pylintrc +++ b/.pylintrc @@ -53,7 +53,7 @@ persistent=yes # Minimum Python version to use for version dependent checks. Will default to # the version used to run pylint. -py-version=3.6 +py-version=3.7 # Discover python modules and packages in the file system subtree. recursive=no diff --git a/Makefile b/Makefile index e7d34fbcc..2807d2cda 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,8 @@ maint: - pyenv local 3.6.15 + pyenv local 3.7.15 pre-commit autoupdate pip-compile -U requirements/ci.in - pyenv local 3.7.15 pip-compile -U requirements/dev.in - pyenv local 3.7.9 pip-compile -U requirements/docs.in release: diff --git a/docs/dev/testing.md b/docs/dev/testing.md index aa1b0a410..5ef32e15a 100644 --- a/docs/dev/testing.md +++ b/docs/dev/testing.md @@ -28,8 +28,7 @@ so that you can install the different Python versions: ``` pyenv install pypy3.8-7.3.7 -pyenv install 3.6.15 -pyenv install 3.7.12 +pyenv install 3.7.15 pyenv install 3.8.12 pyenv install 3.9.10 pyenv install 3.10.2 diff --git a/docs/user/encryption-decryption.md b/docs/user/encryption-decryption.md index c8a8700cd..8c8dbe953 100644 --- a/docs/user/encryption-decryption.md +++ b/docs/user/encryption-decryption.md @@ -6,8 +6,8 @@ with different key length. `pypdf` supports all of them until `PDF-2.0`, which is the latest PDF standard. `pypdf` use an extra dependency to do encryption or decryption for `AES` algorithms. -We recommend [`pyca/cryptography`](https://cryptography.io/en/latest/). For Python 3.6 -users, you can use [`pycryptodome`](https://pypi.org/project/pycryptodome/) as a fallback. +We recommend [`pyca/cryptography`](https://cryptography.io/en/latest/). Alternatively, +you can use [`pycryptodome`](https://pypi.org/project/pycryptodome/). > Please see the note in the [installation guide](installation.md) > for installing the extra dependencies if interacting with PDFs that use AES. diff --git a/docs/user/installation.md b/docs/user/installation.md index 20077f31f..d50578743 100644 --- a/docs/user/installation.md +++ b/docs/user/installation.md @@ -4,7 +4,7 @@ There are several ways to install pypdf. The most common option is to use pip. ## pip -pypdf requires Python 3.6+ to run. +pypdf requires Python 3.7+ to run. Typically Python comes with `pip`, a package installer. Using it you can install pypdf: @@ -52,6 +52,7 @@ pip install pypdf[image] | Python | 3.11 | 3.10 | 3.9 | 3.8 | 3.7 | 3.6 | 2.7 | | ---------------------- | ---- | ---- | --- | --- | --- | --- | --- | +| pypdf>=4.0 | YES | YES | YES | YES | YES | | | | pypdf>=3.0 | YES | YES | YES | YES | YES | YES | | | PyPDF2>=2.0 | YES | YES | YES | YES | YES | YES | | | PyPDF2 1.20.0 - 1.28.4 | | YES | YES | YES | YES | YES | YES | diff --git a/pypdf/_xobj_image_helpers.py b/pypdf/_xobj_image_helpers.py index 9041d7737..d18db1b28 100644 --- a/pypdf/_xobj_image_helpers.py +++ b/pypdf/_xobj_image_helpers.py @@ -20,7 +20,7 @@ else: # PEP 586 introduced typing.Literal with Python 3.8 # For older Python versions, the backport typing_extensions is necessary: - from typing_extensions import Literal # type: ignore[assignment] + from typing_extensions import Literal if sys.version_info[:2] >= (3, 10): from typing import TypeAlias diff --git a/pypdf/types.py b/pypdf/types.py index 0fb3c88b9..1a4d5478c 100644 --- a/pypdf/types.py +++ b/pypdf/types.py @@ -7,7 +7,7 @@ # Python 3.8+: https://peps.python.org/pep-0586 from typing import Literal else: - from typing_extensions import Literal # type: ignore[assignment] + from typing_extensions import Literal if sys.version_info[:2] >= (3, 10): # Python 3.10+: https://www.python.org/dev/peps/pep-0484/ diff --git a/pyproject.toml b/pyproject.toml index 7ab3c384d..e8b3f8d78 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,6 @@ classifiers = [ "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", diff --git a/requirements/ci.txt b/requirements/ci.txt index ebb121aa6..63c527ce4 100644 --- a/requirements/ci.txt +++ b/requirements/ci.txt @@ -1,57 +1,56 @@ # -# This file is autogenerated by pip-compile with python 3.6 +# This file is autogenerated by pip-compile with python 3.7 # To update, run: # # pip-compile requirements/ci.in # -attrs==20.3.0 - # via - # flake8-bugbear - # flake8-implicit-str-concat - # pytest -coverage[toml]==6.2 +attrs==23.1.0 + # via flake8-bugbear +coverage[toml]==7.2.7 # via # -r requirements/ci.in # pytest-cov -execnet==1.9.0 +exceptiongroup==1.2.0 + # via pytest +execnet==2.0.2 # via pytest-xdist flake8==5.0.4 # via # -r requirements/ci.in # flake8-bugbear # flake8-print -flake8-bugbear==22.9.23 +flake8-bugbear==23.3.12 # via -r requirements/ci.in -flake8-implicit-str-concat==0.2.0 +flake8-implicit-str-concat==0.4.0 # via -r requirements/ci.in -flake8-print==4.0.1 +flake8-print==5.0.0 # via -r requirements/ci.in fpdf2==2.4.1 # via -r requirements/ci.in importlib-metadata==4.2.0 # via + # attrs # flake8 # pluggy # pytest -iniconfig==1.1.1 + # typeguard +iniconfig==2.0.0 # via pytest mccabe==0.7.0 # via flake8 -more-itertools==8.14.0 +more-itertools==9.1.0 # via flake8-implicit-str-concat -mypy==0.971 +mypy==1.4.1 # via -r requirements/ci.in mypy-extensions==1.0.0 # via mypy -packaging==21.3 +packaging==23.2 # via pytest -pillow==8.4.0 +pillow==9.5.0 # via # -r requirements/ci.in # fpdf2 -pluggy==1.0.0 - # via pytest -py==1.11.0 +pluggy==1.2.0 # via pytest py-cpuinfo==9.0.0 # via pytest-benchmark @@ -63,9 +62,7 @@ pycryptodome==3.19.0 # via -r requirements/ci.in pyflakes==2.5.0 # via flake8 -pyparsing==3.1.1 - # via packaging -pytest==7.0.1 +pytest==7.4.3 # via # -r requirements/ci.in # pytest-benchmark @@ -73,36 +70,35 @@ pytest==7.0.1 # pytest-socket # pytest-timeout # pytest-xdist -pytest-benchmark==3.4.1 +pytest-benchmark==4.0.0 # via -r requirements/ci.in -pytest-cov==4.0.0 +pytest-cov==4.1.0 # via -r requirements/ci.in -pytest-socket==0.4.1 +pytest-socket==0.6.0 # via -r requirements/ci.in -pytest-timeout==2.1.0 +pytest-timeout==2.2.0 # via -r requirements/ci.in -pytest-xdist==3.0.2 +pytest-xdist==3.5.0 # via -r requirements/ci.in pyyaml==6.0.1 # via -r requirements/ci.in -six==1.16.0 - # via flake8-print -tomli==1.2.3 +tomli==2.0.1 # via # coverage # mypy # pytest typed-ast==1.5.5 # via mypy -typeguard==2.13.3 +typeguard==4.1.2 # via -r requirements/ci.in types-dataclasses==0.6.6 # via -r requirements/ci.in -types-pillow==10.0.0.3 +types-pillow==10.1.0.2 # via -r requirements/ci.in -typing-extensions==4.1.1 +typing-extensions==4.7.1 # via # importlib-metadata # mypy -zipp==3.6.0 + # typeguard +zipp==3.15.0 # via importlib-metadata diff --git a/requirements/dev.txt b/requirements/dev.txt index d5f0ffbf6..772f31b06 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -8,11 +8,11 @@ black==23.3.0 # via -r requirements/dev.in build==1.0.3 # via pip-tools -certifi==2023.7.22 +certifi==2023.11.17 # via requests cfgv==3.3.1 # via pre-commit -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 # via requests click==8.1.7 # via @@ -20,11 +20,11 @@ click==8.1.7 # pip-tools coverage[toml]==7.2.7 # via pytest-cov -distlib==0.3.7 +distlib==0.3.8 # via virtualenv docutils==0.20.1 # via flit -exceptiongroup==1.1.3 +exceptiongroup==1.2.0 # via pytest filelock==3.12.2 # via virtualenv @@ -34,7 +34,7 @@ flit-core==3.9.0 # via flit identify==2.5.24 # via pre-commit -idna==3.4 +idna==3.6 # via requests importlib-metadata==6.7.0 # via @@ -60,7 +60,7 @@ pillow==9.5.0 # via -r requirements/dev.in pip-tools==6.14.0 # via -r requirements/dev.in -platformdirs==3.11.0 +platformdirs==4.0.0 # via # black # virtualenv @@ -98,9 +98,9 @@ typing-extensions==4.7.1 # platformdirs urllib3==2.0.7 # via requests -virtualenv==20.24.6 +virtualenv==20.25.0 # via pre-commit -wheel==0.41.2 +wheel==0.42.0 # via # -r requirements/dev.in # pip-tools diff --git a/requirements/docs.in b/requirements/docs.in index 58eb4813c..4254003a6 100644 --- a/requirements/docs.in +++ b/requirements/docs.in @@ -1,4 +1,4 @@ sphinx -sphinx_rtd_theme +sphinx_rtd_theme<2.0.0 myst_parser==0.16.1 attrs # required for myst, but not automatically installed by myst diff --git a/requirements/docs.txt b/requirements/docs.txt index b4f9fa7a1..6a9c59d62 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,6 +1,6 @@ # -# This file is autogenerated by pip-compile with Python 3.7 -# by the following command: +# This file is autogenerated by pip-compile with python 3.7 +# To update, run: # # pip-compile requirements/docs.in # @@ -8,18 +8,18 @@ alabaster==0.7.13 # via sphinx attrs==23.1.0 # via -r requirements/docs.in -babel==2.13.1 +babel==2.14.0 # via sphinx -certifi==2023.7.22 +certifi==2023.11.17 # via requests -charset-normalizer==3.3.1 +charset-normalizer==3.3.2 # via requests docutils==0.17.1 # via # myst-parser # sphinx # sphinx-rtd-theme -idna==3.4 +idna==3.6 # via requests imagesize==1.4.1 # via sphinx @@ -45,7 +45,7 @@ myst-parser==0.16.1 # via -r requirements/docs.in packaging==23.2 # via sphinx -pygments==2.16.1 +pygments==2.17.2 # via sphinx pytz==2023.3.post1 # via babel diff --git a/tests/test_filters.py b/tests/test_filters.py index 873e7a957..1691c30b3 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -279,10 +279,9 @@ def test_image_without_pillow(tmp_path): ), exc.value.args[0] """ ) - result = subprocess.run( # noqa: UP022 + result = subprocess.run( [shutil.which("python"), source_file], # noqa: S603 - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + capture_output=True, ) assert result.returncode == 0 assert result.stdout == b""