From 1f28448827cf1c11035924b94c8f7077ca8fde94 Mon Sep 17 00:00:00 2001 From: Anderson Herzogenrath da Costa Date: Wed, 11 Dec 2024 14:42:24 -0500 Subject: [PATCH] Support Python 3.13 (#1291) * Support Python 3.13 * remove numpy from test/requirements.txt --------- Co-authored-by: Lucas Cimon <925560+Lucas-C@users.noreply.github.com> --- .../continuous-integration-workflow.yml | 20 +++++++++--------- CHANGELOG.md | 1 + fpdf/drawing.py | 4 ++++ setup.cfg | 1 + test/embed_file_all_optionals.pdf | Bin 1525 -> 1419 bytes test/embed_file_self.pdf | Bin 1638 -> 1447 bytes test/file_attachment_annotation.pdf | Bin 1810 -> 1619 bytes test/requirements.txt | 1 - tox.ini | 3 ++- 9 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index e8145b400..d0351b1bc 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -12,7 +12,7 @@ jobs: test: strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] platform: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.platform }} steps: @@ -34,7 +34,7 @@ jobs: python -m pip install --upgrade pip setuptools wheel pip install --upgrade . -r test/requirements.txt -r docs/requirements.txt -r contributors/requirements.txt - name: Statically checking code 🔎 - if: matrix.python-version == '3.12' && matrix.platform == 'ubuntu-latest' + if: matrix.python-version == '3.13' && matrix.platform == 'ubuntu-latest' run: | pip install --upgrade . -r test/linters-requirements.txt black --check . @@ -42,13 +42,13 @@ jobs: bandit -c .banditrc.yml -r contributors/ fpdf/ tutorial/ semgrep scan --config auto --error --strict --exclude-rule=python.lang.security.insecure-hash-function.insecure-hash-function fpdf - name: Scan current project - if: matrix.python-version == '3.12' && matrix.platform == 'ubuntu-latest' + if: matrix.python-version == '3.13' && matrix.platform == 'ubuntu-latest' uses: anchore/scan-action@v3 with: path: "." fail-build: true - name: Checking all PDF samples ☑ - if: matrix.python-version == '3.12' && matrix.platform == 'ubuntu-latest' + if: matrix.python-version == '3.13' && matrix.platform == 'ubuntu-latest' run: | # Using qpdf find . -name '*.pdf' | xargs -n 1 sh -c 'qpdf --check --password=fpdf2 $0 || exit 255' @@ -64,7 +64,7 @@ jobs: - name: Running tests ☑ env: CHECK_EXEC_TIME: ${{ matrix.python-version == '3.9' && 'test-enabled' || '' }} - CHECK_RSS_MEMORY: ${{ matrix.python-version == '3.12' && 'test-enabled' || '' }} + CHECK_RSS_MEMORY: ${{ matrix.python-version == '3.13' && 'test-enabled' || '' }} run: | # Ensuring there is no `generate=True` left remaining in calls to assert_pdf_equal: grep -IRF generate=True test/ && exit 1 @@ -79,12 +79,12 @@ jobs: # Targetting only a subset of tests because: A) it's faster and B) some tests are dependant on a specific version of fonttools or Pillow pytest -vv test/barcodes test/drawing test/errors test/image/test_load_image.py test/metadata test/shapes test/signing test/text_region test/utils - name: Uploading coverage report to codecov.io ☑ - if: matrix.python-version == '3.12' && matrix.platform == 'ubuntu-latest' + if: matrix.python-version == '3.13' && matrix.platform == 'ubuntu-latest' run: bash <(curl -s https://codecov.io/bash) - name: Generating HTML documentation 🏗️ # As build_contributors_html_page.py can hang due to GitHub rate-limiting, # we only execute this on master for now. And it should always be executed for one Python version only. - if: github.ref == 'refs/heads/master' && matrix.python-version == '3.12' && matrix.platform == 'ubuntu-latest' + if: github.ref == 'refs/heads/master' && matrix.python-version == '3.13' && matrix.platform == 'ubuntu-latest' env: # Needed by contributors/build_contributors_html_page.py: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -101,7 +101,7 @@ jobs: - name: Deploy documentation 🚀 # GitHub Pages deployment should not be done for all Python versions, # otherwise commits will conflict on the gh-pages branch: - if: github.ref == 'refs/heads/master' && matrix.python-version == '3.12' && matrix.platform == 'ubuntu-latest' + if: github.ref == 'refs/heads/master' && matrix.python-version == '3.13' && matrix.platform == 'ubuntu-latest' uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} @@ -118,10 +118,10 @@ jobs: steps: - name: Checkout 🛎️ uses: actions/checkout@v3 - - name: Set up Python 3.12 🔧 + - name: Set up Python 3.13 🔧 uses: actions/setup-python@v4 with: - python-version: '3.12' + python-version: '3.13' - name: Building distributions for Pypi 🏗️ id: build run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index a8a3a345e..770633f4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ This can also be enabled programmatically with `warnings.simplefilter('default', * new optional parameter `border` for table cells: users can define specific borders (left, right, top, bottom) for individual cells - [issue #1192](https://github.com/py-pdf/fpdf2/issues/1192) * [`FPDF.write_html()`](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.write_html): now parses `` tags to set the [document title](https://py-pdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.set_title). By default, it is added as PDF metadata, but not rendered in the document body. However, this can be enabled by passing `render_title_tag=True` to `FPDF.write_html()`. * support for LZWDecode compression [issue #1271](https://github.com/py-pdf/fpdf2/issues/1271) +* Python 3.13 is now officially supported * support for [page labels](https://py-pdf.github.io/fpdf2/PageLabels.html) and created a [reference table of contents](https://py-pdf.github.io/fpdf2/DocumentOutlineAndTableOfContents.html) implementation * documentation on how to: [render spreadsheets as PDF tables](https://py-pdf.github.io/fpdf2/RenderingSpreadsheetsAsPDFTables.html) ### Fixed diff --git a/fpdf/drawing.py b/fpdf/drawing.py index feedacaf5..458d4e3d2 100644 --- a/fpdf/drawing.py +++ b/fpdf/drawing.py @@ -8,6 +8,10 @@ import copy, decimal, math, re from collections import OrderedDict + +# disable import error temporarily until pylint fixed colections.abc issue with python 3.13 +# https://github.com/pylint-dev/pylint/issues/10112 +# pylint: disable=import-error from collections.abc import Sequence from contextlib import contextmanager from typing import Optional, NamedTuple, Union diff --git a/setup.cfg b/setup.cfg index 8f893e638..bf95dd025 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,6 +21,7 @@ classifiers = Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 + Programming Language :: Python :: 3.13 Operating System :: OS Independent Topic :: Printing Topic :: Software Development :: Libraries :: Python Modules diff --git a/test/embed_file_all_optionals.pdf b/test/embed_file_all_optionals.pdf index f0d63e812ce8618c7f06356831fb5d75af9069a5..01d23885706c50e0b82c285de9fc7bf88c865c15 100644 GIT binary patch delta 398 zcmey$-OarrkxAUp(v(X-Ah9Shw^+f(Mn5>SDpkSQ+;Z|n7UjvanKTs4O-+r>O$<^k zlg!M`3=PsOQWFhL%#Dl<Eew;AlT8yRKW0*`pRlp-kb!_pb^TGVmCdZYLHi#5dr)%p zR$Nl|k?cL$i$8pAD0#t^v3{1O+h;f9hT~Jku5HY@&(~U)&~!j$Lgd3!UwIY^YB-1J z8bw;G_nv)gvwqw19_e|<r!HEg`*2Cjr<}<i${T<0{rTE#3bW^{lxHUvJ<8VNGH_Vx z?LC!g$J<=TQ(riLak0MA&%b-<+&T@ft6Z7dyEpO1w=aI^bo0CWLbr4O`>P8)zJ$A- zzZ<jaxr5uqt*rCyw{(1ca_eo{yE}(ES8g_95oVMyu(U8!FaQCCJOwT=!@$tM)Od0% zt97iUk%gOqvyrQlxuuh{qpO9nft#6&k%_B;xwDalg|msB4M7#LTy}O`#U+VFB^5=f RX<UYe1{PeZs;>TSTmXq@noa-! delta 501 zcmeC?{>r@}kxAUxz>rHnAh9Shw^+f(Mn5>SDpkSM++cDAledC_MWSg^nu%p%YNDBm zNuqh8Wm;OArKw43vSG4;k%i^t$4sjA6K%5(8wj+O|L<yE<LR<V#7CT8mP^)aTaed; zHJf#lUQfAv^4QO>p_f`N^lzQava5RDcR%hGUmI*sYMpuS=KiNaNGFlSpGo*5V~&$R zlb_0wpq1A=r=Qui%(3^}>qz-9=CVbh8+rpitSvHB>&e=z`R)zV-lH$vbZ+%6Ix;I( zprM}CKyGsKmV{^Vfv5H_*{;<6`0Y9$e>Yw$u1#GUnrja4skmt;V#k|Ucjuo-phJBB zO=a1iPyen|JXh@hyzr~Xxu$O)Y*>;ilhpJc9y)C(aozdV(abbk=f$z}cNb6JEuwF{ z;(g|?NvUqCht8=S)J}_kTXyyKzN*@NYj!StqU$63OGo>_Pq9~p(KV-k{=a=nuBXU0 z%(VCD#OzHG9cC-9KhO7>`|Q|~%PW7d@Uop-xA_FKFr$Q_fu)gx0SGAMDR6-q28M>F zmXklTSjQSWnwmPBJDNJX7&{rbSh$(EnY+50I-44s7+9D%85!Ey5L6M%WoO4#T#{H+ VQc;we#${+^Xu_qc>gw;t1pr<L%O3y$ diff --git a/test/embed_file_self.pdf b/test/embed_file_self.pdf index 7ce04d648a15c448e0bfcfe36c53552faaf31777..a6c843299ad1e1521b9930487a20ce1d58c49ccc 100644 GIT binary patch delta 162 zcmaFHvz&W_A(ObVxh0o=Kw?p1Zn1)mjec-uRjL9|Y_SIu<7Rf24UFOjh9(LIAfS+^ zzy)R)7#dg@PCmzK9cy6bWbA70WZ-P>>|$tcYGmwYZsg`->gsB2Y;0ui>}qF2P(>`4 cogG(kNn%k+MNw)Rm!YAt8JDW6tG^o;0R9Xo?f?J) delta 354 zcmaitJx;?w5Jr_Cngxk6?MNtHNbC(J0W71<k0BLNs3@XnW3S0d_O6+%ZA`-<I06MN zh&yo(j1`HJsYdg?dEfiN_u+@#Y&ipq^yVCSvIW=e-N|PG)$Q%3*?3V|l9nz7I0h7t znM4u7x&)mH733#rX*ODQ{-Q`DC|!Wjz;i7_;0k6*s?kglHC{mN>joM{H_2inIU+A1 z;xewp)t9W{4n#VRbs?_mwo1Z`LAlP1*m+iLv0(QrHlI~}rouB7La`BQXOQXvf}DO` z?|n8})N;W39Z*2(#j@#uz8>vgF72_;CPQjXPT7c^pZUyph7;!7<0)g#nDssPUt&o- Vk8BM`^MoQIcApMNyFI=2$q!lLZR7v| diff --git a/test/file_attachment_annotation.pdf b/test/file_attachment_annotation.pdf index 166e581f69ce9505d52a12c151255386aca6b63a..a484e7a0fd82018ba0359bc8422477d2bc579edd 100644 GIT binary patch delta 162 zcmbQlcbR9yT_$m3b4xD$fW)H2++qbA8~xzSs#FD_*y1ltjGH&JY+w{Ov@laJ00D(O z1uihdz|hFlcybk+b*!bKv#GI}xskcEshP8dvx}vfg|UT;sj;Pni>0fftBaitK^3uF cc6MCFC5c5P6-B9OT!zL57F?>TuKsRZ0NR8pb^rhX delta 354 zcmait!A`<J5QYQB%f@)+I*H+iKxxUg+SF`ANjORH<bjZdZe^2pw+>sdUVI0A1Ybbo z(Z}%YQ|JR&8xoJsX)^ye-~Vy+c>MC&Yz=9j^rjqnwgKPoUCDa^)$RGa*?3SzmY4nj z-~>?I77|4a%Mx@h)M|U0mu9V1=Pyb$g3>!M8u(Vr7`TE-mTNQ-qQ*0*echEt(anm~ zNRG%$NVrTZarGr@xC4n!Q@s-xbz3E2#-LmlM(jNcHk+~Q1)EN)K2za^iea}FYHyJ0 z23Fg_+t<Nsqh(VH{oervq+a@#<2X<6hv#!Qbfa+;g_OEsICLG?@$3<GDH~bLjs|w% a|4YnC5Ri@GXzoxX#Bw~3wA<0;nEU{1DR1}y diff --git a/test/requirements.txt b/test/requirements.txt index dd37ed35f..fd3f79bb0 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -2,7 +2,6 @@ camelot-py endesive ghostscript # required by camelot-py[base]: https://github.com/camelot-dev/camelot/blob/master/setup.py#L27 -numpy<2 # required by opencv-python, required for now to avoid an ImportError: numpy.core.multiarray failed to import, followed by an AttributeError: _ARRAY_API not found when importing cv2 opencv-python # required by camelot-py[base]: https://github.com/camelot-dev/camelot/blob/master/setup.py#L27 pytest pytest-cov diff --git a/tox.ini b/tox.ini index 80992fe01..ea3a47548 100644 --- a/tox.ini +++ b/tox.ini @@ -7,7 +7,7 @@ # [tox] -envlist = py38, py39, py310, py311, py312 +envlist = py38, py39, py310, py311, py312, py313 [gh-actions] python = @@ -16,6 +16,7 @@ python = 3.10: py310 3.11: py311 3.12: py312 + 3.13: py313 [testenv] deps = -rtest/requirements.txt