[Git][debian-gis-team/aggdraw][upstream] New upstream version 1.4.1

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Fri Dec 5 18:48:20 GMT 2025



Antonio Valentino pushed to branch upstream at Debian GIS Project / aggdraw


Commits:
af1bd906 by Antonio Valentino at 2025-12-05T18:41:25+00:00
New upstream version 1.4.1
- - - - -


11 changed files:

- .github/workflows/ci.yml
- + .readthedocs.yml
- CHANGELOG.md
- README.rst
- aggdraw.cxx
- ci/environment.yaml
- + doc/source/_static/.gitkeep
- doc/source/conf.py
- doc/source/index.rst
- selftest.py
- setup.py


Changes:

=====================================
.github/workflows/ci.yml
=====================================
@@ -8,10 +8,10 @@ jobs:
     strategy:
       matrix:
         os: [ubuntu-latest, macos-latest, windows-latest]
-        python-version: ["3.9", "3.10", "3.11", "3.12"]
+        python-version: ["3.11", "3.12", "3.14"]
 
     steps:
-      - uses: actions/checkout at v4
+      - uses: actions/checkout at v6
 
       - name: Setup Conda Environment
         uses: conda-incubator/setup-miniconda at v3
@@ -20,8 +20,9 @@ jobs:
           python-version: ${{ matrix.python-version }}
           environment-file: ci/environment.yaml
           activate-environment: test-environment
-          mamba-version: "*"
           channels: conda-forge
+          conda-remove-defaults: true
+          channel-priority: strict
 
       - name: Run tests
         shell: bash -l {0}
@@ -36,23 +37,21 @@ jobs:
       fail-fast: false
       matrix:
         include:
-          - os: windows-2019
-            cibw_archs: "AMD64 ARM64"
+          - os: windows-2022
+            cibw_archs: "AMD64"
+          - os: windows-11-arm
+            cibw_archs: "ARM64"
+          - os: macos-15-intel
+            cibw_archs: "x86_64"
           - os: macos-14          # The macos-14 runner is arm64, while up until macos-13 the runners are x86_64.
             cibw_archs: "arm64"
-          - os: "ubuntu-20.04"
+          - os: "ubuntu-24.04-arm"
             cibw_archs: "aarch64"
-          - os: "ubuntu-20.04"
+          - os: "ubuntu-22.04"
             cibw_archs: "x86_64"
 
     steps:
-      - uses: actions/checkout at v4
-
-      - name: Set up QEMU
-        if: runner.os == 'Linux'
-        uses: docker/setup-qemu-action at v3
-        with:
-          platforms: all
+      - uses: actions/checkout at v6
 
       # See discussion here: https://github.com/actions/runner-images/issues/9256
       - name: Make sure pipx is installed for the arm64 macOS runners.
@@ -62,13 +61,13 @@ jobs:
             pipx ensurepath
 
       - name: Build wheels
-        uses: pypa/cibuildwheel at v2.20.0
+        uses: pypa/cibuildwheel at v3.3.0
         env:
           CIBW_TEST_COMMAND: python {project}/selftest.py
           CIBW_BEFORE_BUILD_LINUX: yum install -y freetype-devel
-          CIBW_SKIP: "cp36-* cp37-* cp38-* pp* *-win32 *-manylinux_i686 *-musllinux*"
+          CIBW_SKIP: "cp39-* cp310-* *-win32 *i686 *-musllinux*"
           CIBW_TEST_REQUIRES: numpy pillow pytest
-          CIBW_TEST_SKIP: "*_arm64 *_universal2:arm64"
+          CIBW_TEST_SKIP: "*-win_arm64"
           CIBW_ARCHS: "${{ matrix.cibw_archs }}"
           # disable finding unintended freetype installations
           CIBW_ENVIRONMENT_WINDOWS: "AGGDRAW_FREETYPE_ROOT=''"
@@ -76,9 +75,9 @@ jobs:
           # macos 14
           CIBW_ENVIRONMENT_MACOS: MACOSX_DEPLOYMENT_TARGET=14
       - name: upload
-        uses: actions/upload-artifact at v3
+        uses: actions/upload-artifact at v5
         with:
-          name: wheelhouse
+          name: wheels-${{ matrix.os }}-${{ matrix.cibw_archs }}
           path: "./wheelhouse/*.whl"
 
   publish:
@@ -86,9 +85,11 @@ jobs:
     needs:
        - build
     steps:
-      - uses: actions/checkout at v4
+      - uses: actions/checkout at v6
 
-      - uses: actions/setup-python at v4
+      - uses: actions/setup-python at v6
+        with:
+          python-version: "3.14"
 
       - name: sdist
         run: |
@@ -96,14 +97,16 @@ jobs:
           python -m build -s 
 
       - name: download
-        uses: actions/download-artifact at v3
+        uses: actions/download-artifact at v6
         with:
-          name: wheelhouse
+          pattern: wheels-*
+          merge-multiple: true
           path: dist
 
       - name: Publish package to PyPI
         if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
-        uses: pypa/gh-action-pypi-publish at v1.8.10
+        uses: pypa/gh-action-pypi-publish at v1.13.0
         with:
           user: __token__
           password: ${{ secrets.pypi_password }}
+          skip-existing: true


=====================================
.readthedocs.yml
=====================================
@@ -0,0 +1,22 @@
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+version: 2
+# Build documentation in the docs/ directory with Sphinx
+sphinx:
+  configuration: doc/source/conf.py
+  fail_on_warning: true
+
+# Optionally build your docs in additional formats such as PDF and ePub
+formats: all
+
+build:
+  os: "ubuntu-22.04"
+  tools:
+    python: "3.13"
+
+python:
+  install:
+    - method: pip
+      path: .
+      extra_requirements:
+        - docs


=====================================
CHANGELOG.md
=====================================
@@ -1,5 +1,16 @@
 # The aggdraw Library
 
+## Version 1.4.1
+
+- Fix point arrays not being deleted as arrays
+
+## Version 1.4.0
+
+- Add Python 3.14 wheels
+- Add initial free-threading (3.14t) compatibility and wheels
+- Drop Python 3.9 and 3.10 support
+- Add `Draw.rounded_rectangle` method
+
 ## Version 1.3.19
 
 - Add Python 3.13 wheels


=====================================
README.rst
=====================================
@@ -2,11 +2,15 @@
 The aggdraw module
 ==================
 
-.. image:: https://github.com/pytroll/aggdraw/workflows/CI/badge.svg?branch=main
+.. image:: https://github.com/pytroll/aggdraw/actions/workflows/ci.yml/badge.svg?branch=main
     :target: https://github.com/pytroll/aggdraw/actions?query=workflow%3A%22CI%22
 
 A high-quality graphics engine for PIL, based on Maxim Shemanarev's
 Anti-Grain Geometry library (from http://antigrain.com).
+The aggdraw module implements the basic WCK 2D Drawing Interface on
+top of the AGG library. This library provides high-quality drawing,
+with anti-aliasing and alpha compositing, while being fully compatible
+with the WCK renderer.
 
 The necessary AGG sources are included in the aggdraw source kit.
 
@@ -31,28 +35,38 @@ Build instructions (all platforms)
    To enable freetype, you need to build the library somewhere and
    make sure the `freetype-config` command is available on your PATH. The
    setup.py file will call `freetype-config --prefix` to locate
-   all of the necessary libraries and headers.
+   all of the necessary libraries and headers as part of installation.
 
-3. Build.
+3. Build and Install
 
-   The library uses a standard setup.py file, and you can use all
-   standard setup.py commands.   I recommend the following steps::
+   The library uses a standard setup.py file. Install the library
+   using ``pip`` from the root of the aggdraw repository::
 
-        $ python setup.py build_ext -i
-        $ python selftest.py
+        $ python -m pip3 install .
+
+   Alternatively, it is possible to install the library in an "editable"
+   manner where the python environment will point to the local development
+   aggdraw directory.
+
+   ::
 
-   (if you're lazy, you can skip the above and just install the
-   library; setup.py will make sure the right stuff is built before
-   it's installed).
+        $ python -m pip3 install -e .
 
-4. Install.
+   However, since aggdraw depends on compiling extension code, it must be
+   re-installed to re-build the extension.
 
-   If the selftest succeeds, you can install the library::
+4. Once aggdraw is installed run the tests::
 
-        $ python setup.py install
+        $ python selftest.py
 
 5. Enjoy!
 
+Free-threading support
+----------------------
+
+See the documentation site for current information for free-threading
+support: https://aggdraw.readthedocs.io/en/stable/
+
 AGG2 License
 ------------
 


=====================================
aggdraw.cxx
=====================================
@@ -82,6 +82,7 @@
 #include "agg_conv_stroke.h"
 #include "agg_conv_transform.h"
 #include "agg_ellipse.h"
+#include "agg_rounded_rect.h"
 #if defined(HAVE_FREETYPE2)
 #include "agg_font_freetype.h"
 #endif
@@ -1189,7 +1190,7 @@ draw_line(DrawObject* self, PyObject* args)
         path.move_to(xy[0].X, xy[0].Y);
         for (int i = 1; i < count; i++)
             path.line_to(xy[i].X, xy[i].Y);
-        delete xy;
+        delete [] xy;
         self->draw->draw(path, pen);
     }
 
@@ -1285,7 +1286,7 @@ draw_polygon(DrawObject* self, PyObject* args)
         for (int i = 1; i < count; i++)
             path.line_to(xy[i].X, xy[i].Y);
         path.close_polygon();
-        delete xy;
+        delete [] xy;
         self->draw->draw(path, pen, brush);
     }
 
@@ -1302,7 +1303,8 @@ const char *draw_rectangle_doc = "Draw a rectangle.\n"
                                  "Parameters\n"
                                  "----------\n"
                                  "xy : iterable\n"
-                                 "    A Python sequence (x, y, x, y, …).\n"
+                                 "    A 4-element Python sequence (x, y, x, y), with the\n"
+                                 "    upper left corner given first.\n"
                                  "pen : Pen\n"
                                  "    Optional pen object created by the `Pen` factory.\n"
                                  "brush : Brush\n"
@@ -1331,6 +1333,45 @@ draw_rectangle(DrawObject* self, PyObject* args)
     return Py_None;
 }
 
+const char *draw_rounded_rectangle_doc = "Draw a rounded rectangle.\n"
+                               "\n"
+                               "If a brush is given, it is used to fill the rounded rectangle.\n"
+                               "If a pen is given, it is used to draw an outline around the rounded rectangle.\n"
+                               "Either one (or both) can be left out.\n"
+                               "\n"
+                               "Parameters\n"
+                               "----------\n"
+                               "xy : iterable\n"
+                               "    A 4-element Python sequence (x, y, x, y), with the\n"
+                               "    upper left corner given first.\n"
+                               "radius : float\n"
+                               "    The corner radius\n"
+                               "pen : Pen\n"
+                               "    Optional pen object created by the `Pen` factory.\n"
+                               "brush : Brush\n"
+                               "    Optional brush object created by the `Brush` factory.\n";
+
+static PyObject*
+draw_rounded_rectangle(DrawObject* self, PyObject* args)
+{
+    float x0, y0, x1, y1, r;
+    PyObject* brush = NULL;
+    PyObject* pen = NULL;
+    if (!PyArg_ParseTuple(args, "(ffff)f|OO:rounded_rectangle",
+                          &x0, &y0, &x1, &y1, &r, &brush, &pen))
+        return NULL;
+
+    agg::path_storage path;
+    agg::rounded_rect rr(x0, y0, x1, y1, r);
+    rr.approximation_scale(1);
+    path.add_path(rr);
+
+    self->draw->draw(path, pen, brush);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
 const char *draw_path_doc = "Draw the given path.\n"
                             "\n"
                             "If a brush is given, it is used to fill the path.\n"
@@ -1409,7 +1450,7 @@ draw_symbol(DrawObject* self, PyObject* args)
         self->draw->draw(p, pen, brush);
     }
 
-    delete xy;
+    delete [] xy;
 
     Py_INCREF(Py_None);
     return Py_None;
@@ -1726,6 +1767,7 @@ static PyMethodDef draw_methods[] = {
     {"line", (PyCFunction) draw_line, METH_VARARGS, draw_line_doc},
     {"polygon", (PyCFunction) draw_polygon, METH_VARARGS, draw_polygon_doc},
     {"rectangle", (PyCFunction) draw_rectangle, METH_VARARGS, draw_rectangle_doc},
+    {"rounded_rectangle", (PyCFunction) draw_rounded_rectangle, METH_VARARGS, draw_rounded_rectangle_doc},
 
 #if defined(HAVE_FREETYPE2)
     {"text", (PyCFunction) draw_text, METH_VARARGS, draw_text_doc},
@@ -2078,7 +2120,7 @@ path_new(PyObject* self_, PyObject* args)
         self->path->move_to(xy[0].X, xy[0].Y);
         for (int i = 1; i < count; i++)
             self->path->line_to(xy[i].X, xy[i].Y);
-        delete xy;
+        delete [] xy;
     }
 
     return (PyObject*) self;
@@ -2467,7 +2509,7 @@ path_polygon(PathObject* self, PyObject* args)
     for (int i = 1; i < count; i++)
         path.line_to(xy[i].X, xy[i].Y);
     path.close_polygon();
-    delete xy;
+    delete [] xy;
 
     self->path->add_path(path, 0, false);
 
@@ -2652,6 +2694,11 @@ aggdraw_init(void)
         );
 
     aggdraw_getcolor_obj = PyDict_GetItemString(g, "getcolor");
+
+#ifdef Py_GIL_DISABLED
+    PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED);
+#endif
+
     return module;
 }
 


=====================================
ci/environment.yaml
=====================================
@@ -5,3 +5,4 @@ dependencies:
   - numpy
   - pillow
   - pytest
+  - freetype


=====================================
doc/source/_static/.gitkeep
=====================================


=====================================
doc/source/conf.py
=====================================
@@ -67,7 +67,7 @@ master_doc = 'index'
 #
 # This is also used if you do content translation via gettext catalogs.
 # Usually you set "language" from the command line for these cases.
-language = None
+language = "en"
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
@@ -83,7 +83,7 @@ pygments_style = None
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
 #
-html_theme = 'alabaster'
+html_theme = 'sphinx_rtd_theme'
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
@@ -187,9 +187,11 @@ epub_exclude_files = ['search.html']
 # -- Options for intersphinx extension ---------------------------------------
 
 # Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {'https://docs.python.org/3/': None}
+intersphinx_mapping = {
+    "python": ('https://docs.python.org/3/', None),
+}
 
 # -- Options for todo extension ----------------------------------------------
 
 # If true, `todo` and `todoList` produce output, else they produce nothing.
-todo_include_todos = True
\ No newline at end of file
+todo_include_todos = True


=====================================
doc/source/index.rst
=====================================
@@ -15,7 +15,7 @@ of date with the current version of the library. Original examples will be
 migrated as time is available (pull requests welcome).
 
 Installation
-============
+------------
 
 Aggdraw is available on Linux, OSX, and Windows. It can be installed from PyPI
 with pip:
@@ -30,8 +30,25 @@ Or from conda with the conda-forge channel:
 
     conda install -c conda-forge aggdraw
 
+Free-threading support
+----------------------
+
+Basic free-threading compatibility has been enabled starting with the Python
+3.14 wheels of aggdraw 1.4.0. However, only the minimum steps have been taken
+to let Python 3.14's free-threaded build know that aggdraw could be used
+without the GIL. No additional locking or redesign of the library has been
+done.
+
+Aggdraw itself should have no global state, but each individual object is free
+to have internal state. It is up to the user to limit interactions for an
+aggdraw object to a single thread or to protect against concurrent access
+using locks. Even with this in mind, free-threading support in aggdraw is
+extremely unstable and experimental. If you have a use case for aggdraw
+in a free-threading environment please file an issue on GitHub to describe
+your use case and how it is going.
+
 API
-===
+---
 
 .. automodule:: aggdraw
     :members:
@@ -40,7 +57,7 @@ API
 
 
 Indices and tables
-==================
+------------------
 
 * :ref:`genindex`
 * :ref:`modindex`


=====================================
selftest.py
=====================================
@@ -98,7 +98,7 @@ def test_graphics2():
     import numpy as np
     symbol = Symbol("M400 200 L400 400")
     pen = Pen("red")
-    image = Image.fromarray(np.zeros((800, 600, 3)), mode="RGB")
+    image = Image.fromarray(np.zeros((800, 600, 3), dtype=np.uint8), mode="RGB")
     canvas = Draw(image)
     canvas.symbol((0, 0), symbol, pen)
     canvas.flush()


=====================================
setup.py
=====================================
@@ -21,18 +21,10 @@ from sysconfig import get_config_var
 from packaging.version import Version
 from setuptools import setup, Extension
 
-VERSION = "1.3.19"
+VERSION = "1.4.1"
 
 SUMMARY = "High quality drawing interface for PIL."
-
-DESCRIPTION = """\
-
-The aggdraw module implements the basic WCK 2D Drawing Interface on
-top of the AGG library. This library provides high-quality drawing,
-with anti-aliasing and alpha compositing, while being fully compatible
-with the WCK renderer.
-
-"""
+README = open("README.rst", "r").read()
 
 
 def is_platform_mac():
@@ -115,6 +107,7 @@ sources = [
     "agg2/src/agg_arc.cpp",
     "agg2/src/agg_bezier_arc.cpp",
     "agg2/src/agg_curves.cpp",
+    "agg2/src/agg_rounded_rect.cpp",
     "agg2/src/agg_path_storage.cpp",
     "agg2/src/agg_rasterizer_scanline_aa.cpp",
     "agg2/src/agg_trans_affine.cpp",
@@ -155,11 +148,13 @@ setup(
         "Development Status :: 4 - Beta",
         # "Development Status :: 5 - Production/Stable",
         "Topic :: Multimedia :: Graphics",
+        "Programming Language :: Python :: Free Threading :: 1 - Unstable",
         ],
     description=SUMMARY,
+    long_description=README,
+    long_description_content_type="text/x-rst",
     download_url="http://www.effbot.org/downloads#aggdraw",
     license="Python (MIT style)",
-    long_description=DESCRIPTION.strip(),
     url="https://github.com/pytroll/aggdraw",
     ext_modules=[
         Extension("aggdraw", ["aggdraw.cxx"] + sources,
@@ -168,5 +163,12 @@ setup(
                   library_dirs=library_dirs, libraries=libraries,
                   )
         ],
-    python_requires='>=3.9',
+    extras_require={
+        "tests": ["pytest"],
+        "docs": [
+            "sphinx",
+            "sphinx_rtd_theme",
+        ],
+    },
+    python_requires='>=3.11',
     )



View it on GitLab: https://salsa.debian.org/debian-gis-team/aggdraw/-/commit/af1bd906a7e52c6cfc6f4474c08754995d10cba5

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/aggdraw/-/commit/af1bd906a7e52c6cfc6f4474c08754995d10cba5
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20251205/94eaba29/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list