[Git][debian-gis-team/pyepr][master] 6 commits: New upstream version 1.3.1

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Sun Sep 20 08:56:32 BST 2026



Antonio Valentino pushed to branch master at Debian GIS Project / pyepr


Commits:
5c1489e3 by Antonio Valentino at 2026-09-20T07:42:13+00:00
New upstream version 1.3.1
- - - - -
ff0af5bb by Antonio Valentino at 2026-09-20T07:42:15+00:00
Update upstream source from tag 'upstream/1.3.1'

Update to upstream version '1.3.1'
with Debian dir c59ed22140ca4a89fa988bfd173aac4f1b765b83
- - - - -
6f97cc86 by Antonio Valentino at 2026-09-20T07:42:55+00:00
New upstream release

- - - - -
804af0dd by Antonio Valentino at 2026-09-20T07:49:03+00:00
Refresh all patches

- - - - -
88d0ab89 by Antonio Valentino at 2026-09-20T07:52:53+00:00
Update homepage URL

- - - - -
73730393 by Antonio Valentino at 2026-09-20T07:53:23+00:00
Set distribution to unstable

- - - - -


27 changed files:

- .flake8
- + .github/dependabot.yml
- .github/workflows/ci.yml
- .github/workflows/docs.yml
- .github/workflows/lint.yml
- .github/workflows/wheels.yml
- .gitignore
- .pre-commit-config.yaml
- .readthedocs.yaml
- MANIFEST.in
- Makefile
- README.rst
- debian/changelog
- debian/control
- debian/patches/0001-Only-use-local-files-for-generating-sphinx-doc.patch
- debian/patches/0002-Use-local-mathjax.patch
- docs/NEWS.rst
- docs/_static/empty.txt → docs/_static/.gitkeep
- docs/conf.py
- docs/index.rst
- docs/spelling_wordlist.txt
- pyproject.toml
- − requirements-dev.txt
- setup.py
- src/epr/__init__.py
- + tests/data/registry.txt
- tests/test_all.py


Changes:

=====================================
.flake8
=====================================
@@ -1,4 +1,5 @@
 [flake8]
+min-python-version = 3.11
 # max_line_length = 79
 # max-complexity = 10
 doctests = true
@@ -23,6 +24,10 @@ doctests = true
 # - I  # flake8-import-order: not compatible with isort
 # - SC  # flake8-spellcheck: too aggressive
 # - CNL  # flake8-class-newline: incompatible with black
+# - JS  # flake8-multiline-containers: not compatibel with ruff preview
+# - ANN  # flake8-annotations: too aggressive
+# - C  # flake8-commas: too aggressive
+# - PT  # flake8-pytest-style: test suite compatibel with unittest
 extend-ignore = E203,E501,E701,W503,SC,CNL
 extend-select = W504,B950
 per-file-ignores =


=====================================
.github/dependabot.yml
=====================================
@@ -0,0 +1,15 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
+
+version: 2
+updates:
+  - package-ecosystem: "github-actions"
+    directory: "/"
+    schedule:
+      interval: "weekly"
+    groups:
+      github-actions:
+        patterns:
+          - "*"


=====================================
.github/workflows/ci.yml
=====================================
@@ -27,19 +27,16 @@ jobs:
       fail-fast: false
       matrix:
         os: [ubuntu-latest, macos-latest, windows-latest]
-        python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', '3.14t']
-        # include:
-        #   - os: ubuntu-latest
-        #     python-version: 'pypy3.9'
+        python-version: ['3.11', '3.12', '3.13', '3.14', '3.14t']
 
     steps:
-      - uses: actions/checkout at v6
+      - uses: actions/checkout at v7
         with:
           fetch-depth: 0
           submodules: 'true'
 
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python at v6
+        uses: actions/setup-python at v7
         with:
           python-version: ${{ matrix.python-version }}
 
@@ -63,7 +60,6 @@ jobs:
         shell: bash
         run: |
           python -m pip install --group test
-          if [ -f requirements-test.txt ]; then pip install -r requirements-test.txt; fi
 
       - name: Test with pytest
         run: |
@@ -77,16 +73,17 @@ jobs:
 
 
   syslibs:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-26.04
 
     steps:
-      - uses: actions/checkout at v6
+      - uses: actions/checkout at v7
         with:
           fetch-depth: 0
           submodules: true
 
       - name: Install system dependencies
         run: |
+          sudo apt update
           sudo apt-get -y install \
             libepr-api-dev \
             python3-all-dev \
@@ -110,12 +107,11 @@ jobs:
         env:
           PYEPR_EPRAPI_SRC: ""
         run: |
-          WHEELNAME=$(ls dist/${PACKAGE}-*.whl)
-          python -m pip install ${WHEELNAME}
+          python -m pip install --pre --only-binary ${PACKAGE} -f dist/ ${PACKAGE}
 
       - name: Install test dependencies
         run: |
-          sudo apt-get -y install python3-pytest
+          sudo apt-get -y install python3-pytest python3-pooch
 
       - name: Test with pytest
         run: |
@@ -140,13 +136,13 @@ jobs:
       PYTHON: "3.14"
 
     steps:
-      - uses: actions/checkout at v6
+      - uses: actions/checkout at v7
         with:
           fetch-depth: 0
           submodules: true
 
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python at v6
+        uses: actions/setup-python at v7
         with:
           python-version: ${{ matrix.python-version }}
 
@@ -154,8 +150,7 @@ jobs:
         shell: bash
         run: |
           python -m pip install --upgrade setuptools pip
-          python -m pip install --group dev
-          if [ -f requirements-dev.txt ]; then python -m pip install -r requirements-dev.txt; fi
+          python -m pip install --group coverage
 
       - name: Build and install
         run: |
@@ -171,7 +166,7 @@ jobs:
           print('Python: %s' % sys.version)"
 
       - name: Upload coverage to Codecov
-        uses: codecov/codecov-action at v5
+        uses: codecov/codecov-action at v7
         with:
           env_vars: OS,PYTHON
           verbose: true


=====================================
.github/workflows/docs.yml
=====================================
@@ -16,13 +16,13 @@ jobs:
     runs-on: ubuntu-latest
 
     steps:
-      - uses: actions/checkout at v6
+      - uses: actions/checkout at v7
         with:
           fetch-depth: 0
           submodules: 'true'
 
       - name: Set up Python
-        uses: actions/setup-python at v6
+        uses: actions/setup-python at v7
         with:
           python-version: "3.x"
 
@@ -31,8 +31,7 @@ jobs:
         run: |
           python -m pip install --upgrade pip
           python -m pip install --group docs
-          python -m pip install .
-          if [ -f requirements-dev.txt ]; then python -m pip install -r requirements-dev.txt; fi
+          python -m pip install .[all]
 
       - name: Build docs
         run: |


=====================================
.github/workflows/lint.yml
=====================================
@@ -19,10 +19,10 @@ jobs:
     runs-on: ubuntu-latest
 
     steps:
-      - uses: actions/checkout at v6
+      - uses: actions/checkout at v7
 
       - name: Set up Python
-        uses: actions/setup-python at v6
+        uses: actions/setup-python at v7
         with:
           python-version: "3.x"
 
@@ -31,7 +31,6 @@ jobs:
         run: |
           python -m pip install --upgrade pip
           python -m pip install --group lint
-          if [ -f requirements-lint.txt ]; then pip install -r requirements-lint.txt; fi
 
       - name: Lint (flake8)
         run: |


=====================================
.github/workflows/wheels.yml
=====================================
@@ -23,12 +23,12 @@ jobs:
     runs-on: ubuntu-latest
 
     steps:
-      - uses: actions/checkout at v6
+      - uses: actions/checkout at v7
         with:
           submodules: 'true'
 
       - name: Set up Python
-        uses: actions/setup-python at v6
+        uses: actions/setup-python at v7
         with:
           python-version: "3.x"
 
@@ -43,7 +43,7 @@ jobs:
           python -m twine check dist/*
 
       - name: Upload build artifacts
-        uses: actions/upload-artifact at v6
+        uses: actions/upload-artifact at v7
         with:
           name: dist
           path: |
@@ -58,15 +58,17 @@ jobs:
         os: [ubuntu-latest, macos-latest, windows-latest]
 
     steps:
-      - uses: actions/checkout at v6
+      - uses: actions/checkout at v7
         with:
           fetch-depth: 0
           submodules: 'true'
 
       - name: Build wheels
-        uses: pypa/cibuildwheel at v3.3.0
+        uses: pypa/cibuildwheel at v4.2.1
+        env:
+          PY_LIMITED_API: AUTO
 
-      - uses: actions/upload-artifact at v6
+      - uses: actions/upload-artifact at v7
         with:
           name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
           path: ./wheelhouse/*.whl


=====================================
.gitignore
=====================================
@@ -205,6 +205,3 @@ cython_debug/
 marimo/_static/
 marimo/_lsp/
 __marimo__/
-
-# misc
-SciTEDirectory.properties


=====================================
.pre-commit-config.yaml
=====================================
@@ -15,9 +15,9 @@ repos:
     -   id: detect-private-key
 
 -   repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: v0.14.10
+    rev: v0.16.6
     hooks:
-    -   id: ruff
+    -   id: ruff-check
         args: [--fix, --config=pyproject.toml]
     -   id: ruff-format
 
@@ -25,7 +25,7 @@ repos:
     rev: v3.21.2
     hooks:
     -   id: pyupgrade
-        args: [--py310-plus]
+        args: [--py311-plus]
 
 # -   repo: https://github.com/pycqa/flake8
 #     rev: 7.3.0
@@ -36,21 +36,21 @@ repos:
 #     rev: 6.3.0
 #     hooks:
 #     -   id: pydocstyle
-#         exclude: tests|examples|data|docs
+#         exclude: tests|examples|data|docs|setup.py
 
 # -   repo: https://github.com/pycqa/isort
-#     rev: 7.0.0
+#     rev: 9.0.1
 #     hooks:
 #     -   id: isort
 #         name: isort (python)
 
 # -   repo: https://github.com/psf/black-pre-commit-mirror
-#     rev: 25.12.0
+#     rev: 26.5.1
 #     hooks:
 #     -   id: black
-#         language_version: python3.10
+#         language_version: python3.11
 #     -   id: black-jupyter
-#         language_version: python3.10
+#         language_version: python3.11
 
 # -   repo: https://github.com/tweag/FawltyDeps
 #     rev: v0.20.0
@@ -59,7 +59,7 @@ repos:
 #     -   id: check-unused
 
 # -   repo: https://github.com/pre-commit/mirrors-mypy
-#     rev: v1.19.1
+#     rev: v2.3.1
 #     hooks:
 #     -   id: mypy
 #         additional_dependencies:
@@ -71,7 +71,7 @@ repos:
 #             )
 
 # -   repo: https://github.com/codespell-project/codespell
-#     rev: v2.4.1
+#     rev: v2.4.3
 #     hooks:
 #     -   id: codespell
 #         additional_dependencies: [tomli]


=====================================
.readthedocs.yaml
=====================================
@@ -6,9 +6,14 @@ version: 2
 
 # Set the OS, Python version and other tools you might need
 build:
-  os: ubuntu-22.04
+  os: ubuntu-lts-latest
   tools:
-    python: "3"
+    python: "latest"
+  jobs:
+    install:
+      # Since the install step is overridden, pip is no longer updated automatically.
+      - pip install --upgrade pip
+      - pip install --group docs
 
 # Build documentation in the "docs/" directory with Sphinx
 sphinx:
@@ -27,6 +32,5 @@ formats:
 
 python:
   install:
-    - requirements: requirements-dev.txt
     - method: pip
       path: .


=====================================
MANIFEST.in
=====================================
@@ -1,5 +1,6 @@
 recursive-include LICENSES *.txt
 recursive-include tests *.py
+include tests/data/registry.txt
 recursive-include src/epr *.pyx *.pxd
 recursive-include extern/epr-api/src *.c *.h
 


=====================================
Makefile
=====================================
@@ -7,7 +7,7 @@ TARGET=epr
 CYTHON=$(PYTHON) -m cython
 CYTHONFLAGS=-3
 
-TEST_DATSET = tests/$(shell grep N1 tests/test_all.py | cut -d '"' -f 2)
+TEST_DATSET = tests/data/$(shell grep N1 tests/test_all.py | cut -d '"' -f 2)
 
 EPRAPIROOT = extern/epr-api
 
@@ -52,12 +52,11 @@ coverage: clean ext-coverage
 	env PYTHONPATH=src $(PYTHON) -m pytest --doctest-modules --cov=$(TARGET) --cov-report=html --cov-report=term src/$(TARGET) tests
 
 clean:
-	# $(PYTHON) setup.py clean --all
 	$(RM) -r src/*.*-info build
 	find . -name __pycache__ -type d -exec $(RM) -r {} +
 	# $(RM) -r __pycache__ */__pycache__ */*/__pycache__ */*/*/__pycache__
 	$(RM) src/$(TARGET)/*.c src/$(TARGET)/*.cpp src/$(TARGET)/*.so src/$(TARGET)/*.o
-	if [ -f docs/Makefile ] ; then $(MAKE) -C docs clean; fi
+	# if [ -f docs/Makefile ] ; then $(MAKE) -C docs clean; fi
 	$(RM) -r docs/_build
 	$(RM) MANIFEST
 	find . -name '*~' -delete
@@ -90,6 +89,7 @@ lint:
 docs:
 	mkdir -p docs/_static
 	$(MAKE) -C docs html
+	$(MAKE) -C docs doctest
 	$(MAKE) -C docs linkcheck
 	$(MAKE) -C docs spelling
 


=====================================
README.rst
=====================================
@@ -6,7 +6,7 @@ ENVISAT Product Reader Python API
 :Author:    Antonio Valentino
 :Contact:   antonio.valentino at tiscali.it
 :Copyright: 2011-2026, Antonio Valentino <antonio.valentino at tiscali.it>
-:Version:   1.3.0
+:Version:   1.3.1
 
 |PyPI Status| |GHA Status| |Documentation Status| |Python Versions| |License| |Wheels| |Coverage|
 


=====================================
debian/changelog
=====================================
@@ -1,9 +1,16 @@
-pyepr (1.3.0-3) UNRELEASED; urgency=medium
+pyepr (1.3.1-1) unstable; urgency=medium
 
-  * Team upload.
+  [ Bas Couwenberg ]
   * Bump Standards-Version to 4.7.4, no changes.
 
- -- Bas Couwenberg <sebastic at debian.org>  Sat, 04 Apr 2026 10:18:36 +0200
+  [ Antonio Valentino ]
+  * New upstream release.
+  * debian/patches:
+    - Refresh all patches.
+  * debian/control:
+    - Update homepage URL.
+
+ -- Antonio Valentino <antonio.valentino at tiscali.it>  Sun, 20 Sep 2026 07:52:57 +0000
 
 pyepr (1.3.0-2) unstable; urgency=medium
 


=====================================
debian/control
=====================================
@@ -24,7 +24,7 @@ Build-Depends: debhelper-compat (= 13),
 Standards-Version: 4.7.4
 Vcs-Browser: https://salsa.debian.org/debian-gis-team/pyepr
 Vcs-Git: https://salsa.debian.org/debian-gis-team/pyepr.git
-Homepage: https://avalentino.github.io/pyepr
+Homepage: https://github.com/avalentino/pyepr
 Description: Python ENVISAT Product Reader API
  PyEPR provides Python bindings for the ENVISAT Product Reader C API
  (EPR API) for reading satellite data from ENVISAT ESA (European Space


=====================================
debian/patches/0001-Only-use-local-files-for-generating-sphinx-doc.patch
=====================================
@@ -13,10 +13,10 @@ Forwarded: not-needed
  1 file changed, 13 insertions(+), 11 deletions(-)
 
 diff --git a/docs/conf.py b/docs/conf.py
-index fffbd04..d0ebc34 100644
+index 011dfbe..ff74e85 100644
 --- a/docs/conf.py
 +++ b/docs/conf.py
-@@ -82,15 +82,15 @@ html_static_path = ["_static"]
+@@ -92,15 +92,15 @@ html_static_path = ["_static"]
  html_last_updated_fmt = "%b %d, %Y"
  html_sidebars = {
      "index": [
@@ -41,8 +41,8 @@ index fffbd04..d0ebc34 100644
      ],
  }
  html_domain_indices = False
-@@ -152,8 +152,10 @@ linkcheck_ignore = [f"https://pyepr.readthedocs.io/en/v{version}"]
- # -- Options for intersphinx extension ---------------------------------------
+@@ -144,8 +144,10 @@ linkcheck_ignore = [
+ # https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration
  
  intersphinx_mapping = {
 -    "python": ("https://docs.python.org/3", None),
@@ -53,4 +53,4 @@ index fffbd04..d0ebc34 100644
 +    #            "/usr/share/doc/python-numpy-doc/html/objects.inv"),
  }
  
- # -- Options for extlinks extension ------------------------------------------
+ 


=====================================
debian/patches/0002-Use-local-mathjax.patch
=====================================
@@ -8,14 +8,14 @@ Forwarded: not-needed
  1 file changed, 1 insertion(+)
 
 diff --git a/docs/conf.py b/docs/conf.py
-index d0ebc34..0aefcca 100644
+index ff74e85..7a6d2a7 100644
 --- a/docs/conf.py
 +++ b/docs/conf.py
-@@ -101,6 +101,7 @@ html_context = {
+@@ -111,6 +111,7 @@ html_context = {
      "github_version": "master",
      "conf_py_path": "/docs/",
  }
 +mathjax_path = "file:///usr/share/javascript/mathjax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
  
- # -- Options for HTMLHelp output ------------------------------------------
  
+ # -- Options for LaTeX output ------------------------------------------------


=====================================
docs/NEWS.rst
=====================================
@@ -2,6 +2,21 @@ Change history
 ==============
 
 
+PyEPR 1.3.1 (16/09/2026)
+------------------------
+
+* Update project fields.
+* The minimum required Cython_ version is now v3.1.
+* Update pre-commit configuration.
+* Update project configuration files.
+* Use Pooch_ for test data management.
+* Support builds with the Python stable API.
+* Drop support for Python < 3.11 and numpy < 2.
+* Build wheels for stable API ``cp311``.
+
+.. _Pooch: https://www.fatiando.org/pooch/latest/
+
+
 PyEPR 1.3.0 (03/01/2026)
 ------------------------
 


=====================================
docs/_static/empty.txt → docs/_static/.gitkeep
=====================================


=====================================
docs/conf.py
=====================================
@@ -3,15 +3,8 @@
 # For the full list of built-in configuration values, see the documentation:
 # https://www.sphinx-doc.org/en/master/usage/configuration.html
 
-# -- Project information -----------------------------------------------------
-# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
-
-project = "PyEPR"
-copyright = "2011-2026, Antonio Valentino"
-author = "Antonio Valentino"
-
-
-def get_version(filename):
+# -- Version utils -----------------------------------------------------------
+def _get_version(filename):
     import re
 
     from packaging.version import parse as Version
@@ -27,11 +20,20 @@ def get_version(filename):
     return Version(mobj.group("version"))
 
 
-_version = get_version("../src/epr/__init__.py")
+# -- Project information -----------------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
+
+project = "PyEPR"
+copyright = "2011-2026, Antonio Valentino"
+author = "Antonio Valentino"
+
+
+_version = _get_version("../src/epr/__init__.py")
 
 version = _version.base_version
 release = str(_version)
 
+
 # -- General configuration ---------------------------------------------------
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
 
@@ -40,7 +42,7 @@ extensions = [
     # "sphinx.ext.autosectionlabel",
     # "sphinx.ext.autosummary",
     # "sphinx.ext.coverage",
-    # "sphinx.ext.doctest",
+    "sphinx.ext.doctest",
     # "sphinx.ext.duration",
     "sphinx.ext.extlinks",
     # "sphinx.ext.githubpages",
@@ -61,15 +63,23 @@ extensions = [
     "IPython.sphinxext.ipython_directive",
 ]
 
+try:
+    import sphinxcontrib.spelling  # noqa: F401
+except ImportError:
+    pass
+else:
+    extensions.append("sphinxcontrib.spelling")
+
 templates_path = ["_templates"]
 master_doc = "index"
 exclude_patterns = [
     "_build",
     "Thumbs.db",
     ".DS_Store",
-    "**/empty.txt",
+    "**/.gitkeep",
 ]
 
+
 # -- Options for HTML output -------------------------------------------------
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
 
@@ -102,11 +112,9 @@ html_context = {
     "conf_py_path": "/docs/",
 }
 
-# -- Options for HTMLHelp output ------------------------------------------
 
-htmlhelp_basename = "PyEPRdoc"
-
-# -- Options for LaTeX output ---------------------------------------------
+# -- Options for LaTeX output ------------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-latex-output
 
 latex_elements = {
     "papersize": "a4paper",
@@ -119,49 +127,37 @@ latex_documents = [
 ]
 latex_domain_indices = False
 
-# -- Options for manual page output ---------------------------------------
-
-man_pages = [(master_doc, "pyepr", "PyEPR Documentation", [author], 1)]
-
-# -- Options for Texinfo output -------------------------------------------
-
-texinfo_documents = [
-    (
-        master_doc,
-        "PyEPR",
-        "PyEPR Documentation",
-        author,
-        "PyEPR",
-        "One line description of project.",
-        "Miscellaneous",
-    ),
-]
-
-# -- Options for Epub output ----------------------------------------------
-
-epub_exclude_files = ["search.html"]
-
 
 # -- Options for linkcheck ------------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-the-linkcheck-builder
 
-linkcheck_ignore = [f"https://pyepr.readthedocs.io/en/v{version}"]
+linkcheck_ignore = [
+    f"https://pyepr.readthedocs.io/en/v{version}",
+    "https://www.openhub.net",
+    "https://www.gnu.org/licenses/gpl-3.0.html",
+]
 
 
 # -- Extension configuration -------------------------------------------------
 
 # -- Options for intersphinx extension ---------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration
 
 intersphinx_mapping = {
     "python": ("https://docs.python.org/3", None),
     "numpy": ("https://docs.scipy.org/doc/numpy", None),
 }
 
+
 # -- Options for extlinks extension ------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html#module-sphinx.ext.extlinks
 
 extlinks = {
     "issue": ("https://github.com/avalentino/pyepr/issues/%s", "gh-%s"),
 }
 
+
 # -- Options for todo extension ----------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/extensions/todo.html#configuration
 
 todo_include_todos = True


=====================================
docs/index.rst
=====================================
@@ -77,6 +77,7 @@ ENVISAT Product Reader Python API
 
     ============ ======================================================
     PyEPR latest https://pyepr.readthedocs.io/en/latest (development)
+    PyEPR 1.3.1  https://pyepr.readthedocs.io/en/v1.3.1
     PyEPR 1.3.0  https://pyepr.readthedocs.io/en/v1.3.0
     PyEPR 1.2.0  https://pyepr.readthedocs.io/en/v1.2.0
     PyEPR 1.1.5  https://pyepr.readthedocs.io/en/v1.1.5


=====================================
docs/spelling_wordlist.txt
=====================================
@@ -1,6 +1,7 @@
 api
 config
 constness
+cython
 Cythonizing
 de
 dev


=====================================
pyproject.toml
=====================================
@@ -1,8 +1,8 @@
 [build-system]
 requires = [
-    "setuptools >=77.0.0",
+    "setuptools >=77.0.3",
     "packaging",
-    "cython >=3.0",
+    "cython >=3.1",
     "numpy >=2",
 ]
 build-backend = "setuptools.build_meta"
@@ -14,7 +14,7 @@ authors = [
     {name = "Antonio Valentino", email = "antonio.valentino at tiscali.it"},
 ]
 description = "Python ENVISAT Product Reader API"
-requires-python = ">=3.10, <4"
+requires-python = ">=3.11, <4"
 keywords = ["satellite", "reader", "envisat"]
 license = "GPL-3.0-or-later"
 license-files = ["LICENSE.txt", "LICENSES/*"]
@@ -37,7 +37,7 @@ classifiers = [
     "Topic :: Scientific/Engineering :: GIS",
 ]
 dependencies = [
-    "numpy >=1.26.4",
+    "numpy >=2",
 ]
 dynamic = ["version"]
 
@@ -78,16 +78,23 @@ docs = [
     "packaging",
     "ipython",
 ]
-test = ["pytest", "packaging"]
-coverage = ["pytest-cov", "coverage[toml]", {include-group = "test"}]
+test = ["pytest", "packaging", "pooch"]
+coverage = [
+    "pytest-cov",
+    "coverage[toml]",
+    "cython",
+    "numpy >=2",
+    {include-group = "test"},
+]
 lint = ["flake8", "pydocstyle", "isort", "black", "ruff", "mypy", "codespell"]
 dev = [
     "python-build",
     "twine",
-    "setuptools >=77",
+    "setuptools >=77.0.3",
     "packaging",
-    "cython >=3",
+    "cython >=3.1",
     "numpy >=2",
+    "tox",
     {include-group = "docs"},
     {include-group = "test"},
     {include-group = "coverage"},
@@ -109,29 +116,22 @@ epr = ["py.typed", "*.pyi"]
 
 
 [tool.cibuildwheel]
-skip = "pp*"
-enable = ["cpython-freethreading"]
-test-requires = "pytest"
+build = ["cp311-*", "cp31?t-*"]
+test-groups = ["test"]
 test-command = "pytest -v {project}/tests"
 
 
 [tool.pytest.ini_options]
 addopts = [
-    # "--ignore=examples/",
     "--import-mode=importlib",
 ]
-# markers = [
-    # "webtest: mark a test as a webtest.",
-    # builtin markers
-    # "slow: mark test as slow to run.",
-    # "remote_data: Apply to tests that require data from remote servers.",
-    # "hugemem: mark test as using a lot of memory.",
-# ]
+
 
 [tool.coverage.run]
 branch = true
+core = "ctrace"
 plugins = ["Cython.Coverage"]
-source = ["epr"]
+source_pkgs = ["epr"]
 
 
 [tool.black]
@@ -139,12 +139,10 @@ line-length = 79
 preview = true
 enable-unstable-feature = [
     "hug_parens_with_braces_and_square_brackets",
-    "multiline_string_handling",
     "string_processing",
     "wrap_long_dict_values_in_parens",
 ]
-# target-version = ['py310']
-# extend-exclude = "packagename/parse/*"
+target-version = ['py311']
 
 
 [tool.isort]
@@ -162,17 +160,15 @@ known_first_party = ["epr"]
 
 
 [tool.pydocstyle]
-# convention = "numpy"
 add-ignore = ["D105"]
 # add-ignore = ["D105", "D107"]
 match='(?!(test_|conf)).*\.py'
 
 
 [tool.codespell]
-skip = "*.pdf,*.ipynb,./docs/spelling_wordlist.txt,*.N1,extern,./src/epr/*.c,./docs/_build"
+skip = "*.pdf,*.ipynb,./docs/spelling_wordlist.txt,*.N1,extern,./src/epr/*.c,./docs/_build,./htmlcov"
 count = true
 quiet-level = 3
-# ignore-words-list = ""
 ignore-words="docs/spelling_wordlist.txt"
 
 
@@ -184,15 +180,15 @@ exclude = [
 
 [tool.ruff]
 line-length = 79
-# indent-width = 4
-# target-version = "py310"
+target-version = "py311"
 extend-exclude = ["docs/conf.py"]
 
 
 [tool.ruff.lint]
 preview = true
 select = [
-    # ruff --version  # ruff 0.11.6
+    # ruff --version  # ruff 0.16.3
+    # ruff linter
     "E",        #  E/W pycodestyle
     "W",        #  E/W pycodestyle
     "F",        #    F Pyflakes
@@ -261,12 +257,7 @@ extend-ignore = [
     # "D107",     # D107 Missing docstring in `__init__`
     "D203",     # D203 1 blank line required before class docstring
     "D213",     # D213 Multi-line docstring summary should start at the second line
-    # "ISC001",   # ISC001 Implicitly concatenated string literals on one line
-    # "PLR2004",  # PLR2004 Magic value used in comparison, consider replacing 2 with a constant variable
-    # "PLR0913",  # PLR0913 Too many arguments in function definition
-    # "PLW1514",  # PLW1514 `open` in text mode without explicit `encoding` argument
-    # "RET504",   # RET504 Unnecessary assignment before `return` statement
-    # "RET505",   # RET505 Unnecessary `elif` after `return` statement
+    "RUF105"    # RUF105 noqa-comments
 ]
 
 
@@ -294,7 +285,3 @@ known-first-party = ["epr"]
 
 [tool.ruff.lint.flake8-import-conventions.extend-aliases]
 "xml.etree.ElementTree" = "etree"
-
-
-# [tool.ruff.lint.pydocstyle]
-# convention = "numpy"  # Accepts: "google", "numpy", or "pep257".


=====================================
requirements-dev.txt deleted
=====================================
@@ -1,12 +0,0 @@
-coverage
-cython>=3.0
-ipython
-numpy>=1.26.4
-packaging
-pytest
-pytest-cov
-python-build
-sphinx
-sphinx_rtd_theme
-sphinxcontrib-spelling
-twine


=====================================
setup.py
=====================================
@@ -18,10 +18,13 @@
 # along with PyEPR.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
+import re
 import sys
+import glob
+import warnings
+import sysconfig
 
 import setuptools
-from packaging.version import Version
 
 try:
     import Cython
@@ -47,9 +50,25 @@ class NumpyExtension(setuptools.Extension):
         self._include_dirs = include_dirs
 
 
-def setup_extension(eprsrcdir=None, *, coverage: bool = False):
-    import glob
-
+def tag_to_packed_version(tag: str) -> tuple[int, bool]:
+    mobj = re.match(
+        r"cp(?P<major>\d{1})(?P<minor>\d{2})(?P<free_threading>t)?", tag
+    )
+    if mobj is None:
+        raise ValueError(f"invalid version tag: {tag!r}")
+    major = int(mobj.group("major"))
+    minor = int(mobj.group("minor"))
+    packed_version = (major << 24) + (minor << 16)
+    free_threading = bool(mobj.group("free_threading") is not None)
+    return packed_version, free_threading
+
+
+def setup_extension(
+    eprsrcdir=None,
+    *,
+    coverage: bool = False,
+    py_limited_api: str | None = None,
+):
     if eprsrcdir:
         print(f'EPR_API: using EPR C API sources at "{eprsrcdir}"')
         extra_sources = glob.glob(f"{eprsrcdir}/epr_*.c")
@@ -61,9 +80,32 @@ def setup_extension(eprsrcdir=None, *, coverage: bool = False):
         include_dirs = []
         libraries = ["epr_api"]
 
-    define_macros = [("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]
+    define_macros: list[tuple[str, str | None]] = [
+        ("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")
+    ]
     if coverage:
-        define_macros.extend([("CYTHON_TRACE_NOGIL", "1")])
+        define_macros.extend([
+            ("CYTHON_TRACE_NOGIL", "1"),
+            ("CYTHON_USE_SYS_MONITORING", "0"),
+        ])
+        if py_limited_api is not None:
+            warnings.warn(
+                "The use of 'limited_api` is not compatible with the "
+                "'coverage': 'limited_api' will be ignored",
+                stacklevel=2,
+            )
+    elif py_limited_api is not None:
+        packed_version, free_threading = tag_to_packed_version(py_limited_api)
+        macro_name = "Py_LIMITED_APIT" if free_threading else "Py_LIMITED_API"
+        hex_version = f"0x{packed_version:08X}"
+        print(f"{macro_name}: {hex_version} ({py_limited_api})")
+        if free_threading and not sysconfig.get_config_var("Py_GIL_DISABLED"):
+            warnings.warn(
+                "Trying to use a free-threading stable API with a Python "
+                "interpreter that has GIL enabled",
+                stacklevel=1,
+            )
+        define_macros.append((macro_name, hex_version))
 
     ext = NumpyExtension(
         "epr._epr",
@@ -72,6 +114,7 @@ def setup_extension(eprsrcdir=None, *, coverage: bool = False):
         libraries=libraries,
         language="c",
         define_macros=define_macros,
+        py_limited_api=bool(py_limited_api is not None),
     )
 
     # compiler directives
@@ -82,49 +125,84 @@ def setup_extension(eprsrcdir=None, *, coverage: bool = False):
     if coverage:
         ext.cython_directives["linetrace"] = True
 
-    try:
-        import Cython
-    except ImportError:
-        pass
-    else:
-        if Version(Cython.__version__) >= Version("3.1.0b1"):
-            ext.cython_directives["freethreading_compatible"] = True
+    ext.cython_directives["freethreading_compatible"] = True
 
     return ext
 
 
-def make_config(eprsrcdir=None, *, coverage=False):
-    return {
-        "ext_modules": [setup_extension(eprsrcdir, coverage=coverage)],
+def make_config(
+    eprsrcdir=None,
+    *,
+    coverage=False,
+    py_limited_api: str | None = None,
+):
+    if not py_limited_api:
+        py_limited_api = None
+    elif py_limited_api == "AUTO":
+        if not sysconfig.get_config_var("Py_GIL_DISABLED"):
+            py_limited_api = "cp311"
+        else:
+            py_limited_api = None
+
+    config = {
+        "ext_modules": [
+            setup_extension(
+                eprsrcdir, coverage=coverage, py_limited_api=py_limited_api
+            ),
+        ]
     }
 
+    if py_limited_api is not None:
+        config["options"] = {"bdist_wheel": {"py_limited_api": py_limited_api}}
+
+    return config
+
 
 def get_parser():
     import argparse
 
-    PYEPR_COVERAGE_STR = os.environ.get("PYEPR_COVERAGE", "").upper()
-    DEFAULT_COVERAGE = bool(
-        PYEPR_COVERAGE_STR in {"Y", "YES", "TRUE", "OK", "ON", "1"}
-    )
     DEFAULT_EPRAPI_SRC = "extern/epr-api/src"
     if not os.path.exists(DEFAULT_EPRAPI_SRC):
         DEFAULT_EPRAPI_SRC = ""
     DEFAULT_EPRAPI_SRC = os.environ.get("PYEPR_EPRAPI_SRC", DEFAULT_EPRAPI_SRC)
 
+    DEFAULT_PY_LIMITED_API = os.environ.get("PY_LIMITED_API", None)
+
+    PYEPR_COVERAGE_STR = os.environ.get("PYEPR_COVERAGE", "").upper()
+    DEFAULT_COVERAGE = bool(
+        PYEPR_COVERAGE_STR in {"Y", "YES", "TRUE", "OK", "ON", "1"}
+    )
+
     parser = argparse.ArgumentParser(add_help=False)
+    parser.add_argument(
+        "--epr-api-src",
+        default=DEFAULT_EPRAPI_SRC,
+        help=(
+            "set the path to the EPR-API source tree. "
+            "If not set uses the system libraries for epr-api. "
+            "Default: %(default)s"
+        ),
+    )
+    parser.add_argument(
+        "--use-stable-api",
+        dest="py_limited_api",
+        default=DEFAULT_PY_LIMITED_API,
+        help=(
+            "enable the use of the specified stable Python API "
+            "(and limited ABI)."
+            "If 'None', the use of limited API is disabled. "
+            "E.g.: 'cp312' for Python 3.12. "
+            f"Default: {DEFAULT_PY_LIMITED_API}."
+        ),
+    )
     parser.add_argument(
         "--coverage",
         action="store_true",
         default=DEFAULT_COVERAGE,
-        help="build the epr module to allow cython coverage measurement "
-        "(default: %(default)s)",
-    )
-    parser.add_argument(
-        "--epr-api-src",
-        default=DEFAULT_EPRAPI_SRC,
-        help="set the path to the EPR-API source tree. "
-        "If not set uses the system libraries for epr-api. "
-        "Default: %(default)s",
+        help=(
+            "build the epr module to allow cython coverage measurement "
+            "(default: %(default)s)"
+        ),
     )
 
     return parser
@@ -134,9 +212,14 @@ if __name__ == "__main__":
     parser = get_parser()
     extra_args, setup_argv = parser.parse_known_args(sys.argv)
     sys.argv[:] = setup_argv
+    print("PY_LIMITED_API:", extra_args.py_limited_api)
     print("PYEPR_COVERAGE:", extra_args.coverage)
 
-    config = make_config(extra_args.epr_api_src, coverage=extra_args.coverage)
+    config = make_config(
+        extra_args.epr_api_src,
+        coverage=extra_args.coverage,
+        py_limited_api=extra_args.py_limited_api,
+    )
 
     if "-h" in setup_argv or "--help" in setup_argv:
         msg = parser.format_help()


=====================================
src/epr/__init__.py
=====================================
@@ -81,4 +81,4 @@ from ._epr import (  # noqa: F401
     get_scaling_method_name,
 )
 
-__version__ = "1.3.0"
+__version__ = "1.3.1"


=====================================
tests/data/registry.txt
=====================================
@@ -0,0 +1 @@
+ASA_APM_1PNDSI20091007_025628_000000432083_00118_39751_0000.N1 425132d361595a53a2adff849e3e02429df1be9d4883015f104ce2387f4eb332


=====================================
tests/test_all.py
=====================================
@@ -22,15 +22,12 @@ import shutil
 import typing
 import numbers
 import pathlib
-import zipfile
 import operator
 import platform
 import tempfile
 import unittest
 import functools
-from urllib.request import urlopen
-
-from packaging.version import parse as Version  # noqa: N812
+import sysconfig
 
 try:
     import resource
@@ -41,17 +38,22 @@ else:
 
 
 import numpy as np
-import numpy.testing as npt
+import pooch
+from numpy import testing as npt
+from packaging.version import parse as Version  # noqa: N812
 
 import epr
-from epr._epr import (
-    _EPR_MAGIC_FIELD,  # noqa: PLC2701
-    _EPR_MAGIC_RASTER,  # noqa: PLC2701
-    _EPR_MAGIC_RECORD,  # noqa: PLC2701
-    _EPR_MAGIC_BAND_ID,  # noqa: PLC2701
-    _EPR_MAGIC_PRODUCT_ID,  # noqa: PLC2701
+from epr._epr import (  # noqa: PLC2701
+    _EPR_MAGIC_FIELD,
+    _EPR_MAGIC_RASTER,
+    _EPR_MAGIC_RECORD,
+    _EPR_MAGIC_BAND_ID,
+    _EPR_MAGIC_PRODUCT_ID,
 )
 
+FREE_THREAD = sysconfig.get_config_var("Py_GIL_DISABLED")
+
+
 EPR_TO_NUMPY_TYPE = {
     # epr.E_TID_UNKNOWN:  np.NPY_NOTYPE,
     epr.E_TID_UCHAR: np.ubyte,
@@ -84,9 +86,24 @@ EPR_C_BUG_BCEPR002 = EPR_C_BUG_PYEPR009
 
 
 TESTDIR = pathlib.Path(__file__).parent
-TEST_PRODUCT = "ASA_APM_1PNPDE20091007_025628_000000432083_00118_39751_9244.N1"
+TESTDATADIR = TESTDIR / "data"
+TEST_PRODUCT = "ASA_APM_1PNDSI20091007_025628_000000432083_00118_39751_0000.N1"
 TEST_PRODUCT_BM_EXPR = None
-PRODUCT_FILE = TESTDIR / TEST_PRODUCT
+PRODUCT_FILE = TESTDATADIR / TEST_PRODUCT
+
+
+def _create_pooch() -> pooch.Pooch:
+    pooch_obj = pooch.create(
+        path=TESTDATADIR,
+        base_url="https://github.com/avalentino/pyepr-test-data/raw/v1.0.0/",
+    )
+
+    registry_file = TESTDATADIR / "registry.txt"
+    pooch_obj.load_registry(registry_file)
+    return pooch_obj
+
+
+DATA_MANAGER = _create_pooch()
 
 
 def quiet(func):
@@ -96,7 +113,7 @@ def quiet(func):
         syserr = sys.stderr
         try:
             # using '/dev/null' doesn't work in python 3 because the file
-            # object coannot be converted into a C FILE*
+            # object cannot be converted into a C FILE*
             # with file(os.devnull) as fd:
             with tempfile.TemporaryFile("w+", encoding="utf-8") as fd:
                 sys.stdout = fd
@@ -132,21 +149,10 @@ def equal_products(product1, product2):
 
 
 def setUpModule():
-    filename = PRODUCT_FILE
-    baseurl = "http://www.brockmann-consult.de/beam/data/products/ASAR"
-    url = baseurl + "/" + pathlib.Path(TEST_PRODUCT).with_suffix(".zip").name
-    zipfilename = filename.with_name(filename.name + ".zip")
-    if not filename.exists():
-        with urlopen(url) as src, zipfilename.open("wb") as dst:
-            for data in src:
-                dst.write(data)
-
-        with zipfile.ZipFile(zipfilename) as arch:
-            arch.extractall(TESTDIR)
-
-        zipfilename.unlink()
-
+    filename_str = DATA_MANAGER.fetch(TEST_PRODUCT)
+    filename = pathlib.Path(filename_str)
     assert filename.exists()
+    assert filename == PRODUCT_FILE
 
 
 class TestOpenProduct(unittest.TestCase):
@@ -211,8 +217,8 @@ class TestOpenProduct(unittest.TestCase):
 
 class TestProduct(unittest.TestCase):  # noqa: PLR0904
     OPEN_MODE = "rb"
-    ID_STRING = "ASA_APM_1PNPDE20091007_025628_000000432083_00118"
-    TOT_SIZE = 22903686
+    ID_STRING = TEST_PRODUCT[:48]
+    TOT_SIZE = 22911746
 
     DATASET_NAMES = [
         "MDS1_SQ_ADS",
@@ -836,16 +842,16 @@ class TestBand(unittest.TestCase):  # noqa: PLR0904
     DATA_TYPE = np.float32
     # fmt: off
     TEST_DATA: np.typing.NDArray = np.asarray([
-        [228., 213., 235., 256., 239., 260., 210., 197., 233., 213.],
-        [246., 248., 333., 317., 272., 247., 247., 221., 221., 205.],
-        [239., 297., 412., 381., 301., 226., 262., 256., 229., 214.],
-        [212., 279., 328., 318., 279., 231., 253., 274., 240., 242.],
-        [199., 236., 245., 262., 282., 265., 261., 255., 255., 239.],
-        [214., 218., 284., 300., 269., 266., 272., 224., 292., 238.],
-        [240., 241., 300., 308., 248., 254., 269., 230., 276., 256.],
-        [256., 261., 265., 269., 263., 262., 279., 279., 300., 367.],
-        [273., 262., 262., 239., 270., 284., 344., 380., 416., 447.],
-        [292., 286., 303., 261., 284., 374., 445., 431., 422., 416.],
+        [255., 333., 313., 295., 264., 306., 299., 330., 399., 335.],
+        [254., 233., 320., 325., 281., 247., 249., 228., 217., 210.],
+        [243., 266., 399., 397., 320., 237., 251., 261., 236., 210.],
+        [216., 254., 323., 324., 286., 240., 242., 271., 253., 230.],
+        [199., 226., 241., 259., 276., 272., 261., 252., 259., 235.],
+        [221., 212., 264., 305., 271., 264., 275., 224., 284., 251.],
+        [243., 235., 285., 312., 260., 242., 270., 233., 267., 259.],
+        [248., 259., 266., 261., 269., 254., 274., 278., 287., 347.],
+        [270., 262., 263., 238., 260., 280., 323., 374., 406., 437.],
+        [303., 278., 303., 270., 264., 352., 434., 435., 423., 412.],
     ])
     # fmt: on
 
@@ -1309,26 +1315,26 @@ class TestAnnotationBand(TestBand):
     RTOL = 1e-7
     # fmt: off
     TEST_DATA: np.typing.NDArray = np.asarray([
-        [21.86950111, 21.86438370, 21.85926437, 21.85414696, 21.84902954,
-         21.84391022, 21.83879280, 21.83367538, 21.82855606, 21.82343864],
-        [21.86950302, 21.86438560, 21.85926628, 21.85414886, 21.84903145,
-         21.84391212, 21.83879471, 21.83367729, 21.82855797, 21.82344055],
-        [21.86950302, 21.86438560, 21.85926628, 21.85414886, 21.84903145,
-         21.84391212, 21.83879471, 21.83367729, 21.82855797, 21.82344055],
-        [21.86950302, 21.86438560, 21.85926628, 21.85414886, 21.84903145,
-         21.84391212, 21.83879471, 21.83367729, 21.82855797, 21.82344055],
-        [21.86950493, 21.86438751, 21.85926819, 21.85415077, 21.84903335,
-         21.84391403, 21.83879662, 21.83367920, 21.82855987, 21.82344246],
-        [21.86950493, 21.86438751, 21.85926819, 21.85415077, 21.84903335,
-         21.84391403, 21.83879661, 21.83367920, 21.82855987, 21.82344246],
-        [21.86950493, 21.86438751, 21.85926819, 21.85415077, 21.84903335,
-         21.84391403, 21.83879661, 21.83367912, 21.82855987, 21.82344246],
-        [21.86950683, 21.86438942, 21.85927009, 21.85415268, 21.84903526,
-         21.84391594, 21.83879852, 21.83368111, 21.82856178, 21.82344437],
-        [21.86950683, 21.86438942, 21.85927009, 21.85415268, 21.84903526,
-         21.84391594, 21.83879852, 21.83368111, 21.82856178, 21.82344437],
-        [21.86950683, 21.86438942, 21.85927009, 21.85415268, 21.84903526,
-         21.84391594, 21.83879852, 21.83368111, 21.82856178, 21.82344437],
+        [21.869589, 21.864470, 21.859352, 21.854235, 21.849115,
+         21.843998, 21.838880, 21.833761, 21.828644, 21.823524],
+        [21.869589, 21.864470, 21.859352, 21.854235, 21.849115,
+         21.843998, 21.838880, 21.833761, 21.828644, 21.823524],
+        [21.869590, 21.864471, 21.859354, 21.854237, 21.849117,
+         21.844000, 21.838882, 21.833763, 21.828646, 21.823526],
+        [21.869590, 21.864471, 21.859354, 21.854237, 21.849117,
+         21.844000, 21.838882, 21.833763, 21.828646, 21.823526],
+        [21.869590, 21.864471, 21.859354, 21.854237, 21.849117,
+         21.844000, 21.838882, 21.833763, 21.828646, 21.823526],
+        [21.869593, 21.864473, 21.859356, 21.854239, 21.849120,
+         21.844002, 21.838884, 21.833765, 21.828648, 21.823528],
+        [21.869593, 21.864473, 21.859356, 21.854239, 21.849120,
+         21.844002, 21.838884, 21.833765, 21.828648, 21.823528],
+        [21.869595, 21.864475, 21.859358, 21.854240, 21.849121,
+         21.844004, 21.838886, 21.833767, 21.828650, 21.823530],
+        [21.869595, 21.864475, 21.859358, 21.854240, 21.849121,
+         21.844004, 21.838886, 21.833767, 21.828650, 21.823530],
+        [21.869595, 21.864475, 21.859358, 21.854240, 21.849121,
+         21.844004, 21.838886, 21.833767, 21.828650, 21.823530],
     ])
     # fmt: on
 
@@ -2212,58 +2218,15 @@ class TestFieldWrite(unittest.TestCase):
     FIELD_UNIT = ""
     FIELD_INDEX = 3
     FIELD_NUM_ELEMS = 1452
+    # fmt: off
     FIELD_VALUES = (
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        2417,
-        2282,
-        2280,
-        2393,
-        2440,
-        2697,
-        3119,
-        3577,
-        3853,
-        3688,
-        3784,
-        4201,
-        3846,
-        2821,
-        2186,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 2264, 2123, 2187, 2255, 2332,
+        2646, 3065, 3496, 3622, 3436, 3694, 3921, 3298, 2368, 1974,
     )
+    # fmt: on
 
     def setUp(self):
         self.filename = PRODUCT_FILE.with_name(PRODUCT_FILE.name + "_")
@@ -2607,7 +2570,7 @@ class TestTimeField(TestField):
     FIELD_TYPE_NAME = "time"
     FIELD_NUM_ELEMS = 1
     FIELD_VALUES = (
-        epr.EPRTime(days=3567, seconds=10588, microseconds=239091),
+        epr.EPRTime(days=3567, seconds=10588, microseconds=239048),
     )
     FIELD_UNIT = "MJD"
     FIELD_OFFSET = 0
@@ -3112,12 +3075,14 @@ class TestLibVersion(unittest.TestCase):
         self.assertTrue(isinstance(epr.EPR_C_API_VERSION, str))
 
 
-# only PyPy 3 seems to be affected
 @unittest.skipIf(
     platform.python_implementation() == "PyPy",
     "skip memory leak check on PyPy",
 )
- at unittest.skipIf(not have_resource, '"resource" module not available')
+ at unittest.skipIf(
+    FREE_THREAD, "skip memory leak check on free threading builds"
+)
+ at unittest.skipIf(not have_resource, "'resource' module not available")
 class TestMemoryLeaks(unittest.TestCase):
     # See gh-10 (https://github.com/avalentino/pyepr/issues/10)
 



View it on GitLab: https://salsa.debian.org/debian-gis-team/pyepr/-/compare/e38ca2ac0472a9f934c5c47da072f08dca7242b2...73730393f5d1df12cfd66a7680c827c2438f1160

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pyepr/-/compare/e38ca2ac0472a9f934c5c47da072f08dca7242b2...73730393f5d1df12cfd66a7680c827c2438f1160
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


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


More information about the Pkg-grass-devel mailing list