[Git][debian-gis-team/rasterio][master] 4 commits: New upstream version 1.3.9

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Thu Oct 19 04:34:09 BST 2023



Bas Couwenberg pushed to branch master at Debian GIS Project / rasterio


Commits:
3a06e6a7 by Bas Couwenberg at 2023-10-19T05:22:18+02:00
New upstream version 1.3.9
- - - - -
dad6a04c by Bas Couwenberg at 2023-10-19T05:22:43+02:00
Update upstream source from tag 'upstream/1.3.9'

Update to upstream version '1.3.9'
with Debian dir 4f480f27b67ca20f8ce0b1676ed2ece06aeeae16
- - - - -
1efc5bca by Bas Couwenberg at 2023-10-19T05:23:13+02:00
New upstream release.

- - - - -
bbada558 by Bas Couwenberg at 2023-10-19T05:28:29+02:00
Set distribution to unstable.

- - - - -


19 changed files:

- .github/workflows/tests.yaml
- + .readthedocs.yaml
- CHANGES.txt
- debian/changelog
- environment.yml → docs/environment.yml
- docs/topics/reproject.rst
- pyproject.toml
- rasterio/__init__.py
- rasterio/_filepath.pyx
- rasterio/_io.pyx
- rasterio/crs.pyx
- rasterio/dtypes.py
- rasterio/gdal.pxi
- rasterio/rio/edit_info.py
- − readthedocs.yml
- setup.py
- tests/test_features.py
- tests/test_merge.py
- tests/test_rio_shapes.py


Changes:

=====================================
.github/workflows/tests.yaml
=====================================
@@ -73,13 +73,12 @@ jobs:
           . testenv/bin/activate
           python -m pip install --upgrade pip
           python -m pip wheel -r requirements-dev.txt
-          python -m pip install -r requirements-dev.txt
-          python setup.py clean
-          python -m pip install --no-deps --force-reinstall --no-use-pep517 -e .[test]
+          python -m pip install --no-deps --force-reinstall -e .[test]
 
       - name: run tests
         run: |
           . testenv/bin/activate
+          python -m pip install -r requirements-dev.txt
           python -m pytest -v -m "not wheel" -rxXs --cov rasterio --cov-report term-missing
 
   conda_test:


=====================================
.readthedocs.yaml
=====================================
@@ -0,0 +1,20 @@
+version: 2
+
+build:
+  os: "ubuntu-22.04"
+  tools:
+    python: "mambaforge-4.10"
+
+sphinx:
+  configuration: docs/conf.py
+  fail_on_warning: false
+
+formats: all
+
+conda:
+  environment: docs/environment.yml
+
+python:
+  install:
+    - method: setuptools
+      path: .


=====================================
CHANGES.txt
=====================================
@@ -1,7 +1,36 @@
 Changes
 =======
 
-1.3.8 (2023-06-26)
+1.3.9 (2023-10-18)
+------------------
+
+Bug fixes:
+
+- Lean on numpy for minimum and maximum values of float data types (#2946).
+- Replace rasterio.dtypes.in_dtype_range() with the version inside the
+  edit-info command (#2946).
+- Deallocate _filepath VSI filesystem plugin callback structs to prevent the
+  memory leak reported in #2932.
+
+Packaging:
+
+GDAL 3.6.4 is patched in the PyPI wheels to fix the potential GTiff
+multithreading deadlock reported in https://github.com/OSGeo/gdal/issues/8470.
+
+1.3.8.post2 (2023-10-11)
+------------------------
+
+There are no code changes in this release. This is only to create new wheels
+that update curl to version 8.4.0 to address CVE-2023-38545 and CVE-38546.
+
+1.3.8.post1 (2023-10-09)
+------------------------
+
+There are no code changes in this release. This is only to create new wheels
+that update libwebp to version 1.3.2 to address CVE-2023-4863, and to publish
+wheels for Python 3.12.
+
+1.3.8 (2023-06-28)
 ------------------
 
 - Rasterio's Python file VSI plugin is now compatible with GDAL VRTs such as


=====================================
debian/changelog
=====================================
@@ -1,6 +1,7 @@
-rasterio (1.3.8-2) UNRELEASED; urgency=medium
+rasterio (1.3.9-1) unstable; urgency=medium
 
   * Team upload.
+  * New upstream release.
   * Use autopkgtest-pkg-pybuild testsuite.
   * Enable Salsa CI.
   * Remove generated files in clean target.
@@ -9,7 +10,7 @@ rasterio (1.3.8-2) UNRELEASED; urgency=medium
   * Update lintian overrides.
   * Switch to dh-sequence-*.
 
- -- Bas Couwenberg <sebastic at debian.org>  Sun, 16 Jul 2023 18:38:07 +0200
+ -- Bas Couwenberg <sebastic at debian.org>  Thu, 19 Oct 2023 05:28:17 +0200
 
 rasterio (1.3.8-1) unstable; urgency=medium
 


=====================================
environment.yml → docs/environment.yml
=====================================
@@ -3,5 +3,9 @@ channels:
 - conda-forge
 - defaults
 dependencies:
-- python=3.8.*
-- libgdal=3.4.*
+- python=3.11.*
+- libgdal=3.6.*
+- cython=3.0.*
+- numpy=1.25.*
+- sphinx-click
+- sphinx-rtd-theme


=====================================
docs/topics/reproject.rst
=====================================
@@ -177,11 +177,12 @@ reference system with a newly computed geotransform.
 
 .. code-block:: python
 
+    import numpy as np
     import rasterio
     from rasterio.warp import reproject
     from rasterio.enums import Resampling
 
-    with rasterio.open('RGB.byte.tif') as source:
+    with rasterio.open('RGB.byte.rpc.vrt') as source:
         print(source.rpcs)
         src_crs = "EPSG:4326"  # This is the crs of the rpcs
 
@@ -196,7 +197,7 @@ reference system with a newly computed geotransform.
         dst_crs = "EPSG:3857"
 
         _, dst_transform = reproject(
-            source,
+            rasterio.band(source, 1),
             destination,
             rpcs=source.rpcs,
             src_crs=src_crs,


=====================================
pyproject.toml
=====================================
@@ -1,5 +1,6 @@
 [build-system]
-requires = ["setuptools", "wheel", "cython>=0.29.29", "oldest-supported-numpy"]
+requires = ["setuptools>=67.8", "wheel", "cython~=3.0.2", "oldest-supported-numpy"]
+build-backend = "setuptools.build_meta"
 
 [tool.pytest.ini_options]
 markers = [


=====================================
rasterio/__init__.py
=====================================
@@ -81,7 +81,7 @@ except ImportError:
     have_vsi_plugin = False
 
 __all__ = ['band', 'open', 'pad', 'Env', 'CRS']
-__version__ = "1.3.8"
+__version__ = "1.3.9"
 __gdal_version__ = gdal_version()
 __proj_version__ = ".".join([str(version) for version in get_proj_version()])
 __geos_version__ = ".".join([str(version) for version in get_geos_version()])


=====================================
rasterio/_filepath.pyx
=====================================
@@ -73,17 +73,22 @@ cdef _OPEN_FILE_OBJS = set()
 
 cdef int install_filepath_plugin(VSIFilesystemPluginCallbacksStruct *callbacks_struct):
     """Install handlers for python file-like objects if it isn't already installed."""
-    callbacks_struct = VSIAllocFilesystemPluginCallbacksStruct()
-    callbacks_struct.open = <VSIFilesystemPluginOpenCallback>filepath_open
-    callbacks_struct.tell = <VSIFilesystemPluginTellCallback>filepath_tell
-    callbacks_struct.seek = <VSIFilesystemPluginSeekCallback>filepath_seek
-    callbacks_struct.read = <VSIFilesystemPluginReadCallback>filepath_read
-    callbacks_struct.close = <VSIFilesystemPluginCloseCallback>filepath_close
-    callbacks_struct.pUserData = <void*>_FILESYSTEM_INFO
-
-    if VSIFileManager.GetHandler("") == VSIFileManager.GetHandler(FILESYSTEM_PREFIX_BYTES):
+    cdef char **registered_prefixes = VSIGetFileSystemsPrefixes()
+    cdef int prefix_index = CSLFindString(registered_prefixes, FILESYSTEM_PREFIX_BYTES)
+    CSLDestroy(registered_prefixes)
+
+    if prefix_index < 0:
+        callbacks_struct = VSIAllocFilesystemPluginCallbacksStruct()
+        callbacks_struct.open = <VSIFilesystemPluginOpenCallback>filepath_open
+        callbacks_struct.tell = <VSIFilesystemPluginTellCallback>filepath_tell
+        callbacks_struct.seek = <VSIFilesystemPluginSeekCallback>filepath_seek
+        callbacks_struct.read = <VSIFilesystemPluginReadCallback>filepath_read
+        callbacks_struct.close = <VSIFilesystemPluginCloseCallback>filepath_close
+        callbacks_struct.pUserData = <void*>_FILESYSTEM_INFO
         log.debug("Installing FilePath filesystem handler plugin...")
-        return VSIInstallPluginHandler(FILESYSTEM_PREFIX_BYTES, callbacks_struct)
+        retval = VSIInstallPluginHandler(FILESYSTEM_PREFIX_BYTES, callbacks_struct)
+        VSIFreeFilesystemPluginCallbacksStruct(callbacks_struct)
+        return retval
     else:
         return 0
 


=====================================
rasterio/_io.pyx
=====================================
@@ -191,7 +191,7 @@ cdef int io_multi_band(GDALDatasetH hds, int mode, double x0, double y0,
                                     retval = GDALRasterIOEx(
                                         band,
                                         <GDALRWFlag>mode, xoff, yoff, xsize, ysize,
-                                        buf + i * bufbandspace,
+                                        <void *>(<char *>buf + i * bufbandspace),
                                         bufxsize, bufysize, buftype,
                                         bufpixelspace, buflinespace, &extras)
 


=====================================
rasterio/crs.pyx
=====================================
@@ -943,56 +943,6 @@ cdef class CRS:
                 _safe_osr_release(osr_o)
 
 
-    def _matches(self, confidence_threshold=70):
-        """Find matches in authority files.
-
-        Parameters
-        ----------
-        confidence_threshold : int
-            Percent match confidence threshold (0-100).
-
-        Returns
-        -------
-        dict : {name: [codes]}
-            A dictionary in which capitalized authority names are the
-            keys and lists of codes ordered by match confidence,
-            descending, are the values.
-
-        """
-        cdef OGRSpatialReferenceH osr = NULL
-        cdef OGRSpatialReferenceH *matches = NULL
-        cdef int *confidences = NULL
-        cdef int num_matches = 0
-        cdef int i = 0
-
-        results = defaultdict(list)
-
-        try:
-            osr = exc_wrap_pointer(OSRClone(self._osr))
-
-            matches = OSRFindMatches(osr, NULL, &num_matches, &confidences)
-
-            for i in range(num_matches):
-                confidence = confidences[i]
-                c_code = OSRGetAuthorityCode(matches[i], NULL)
-                c_name = OSRGetAuthorityName(matches[i], NULL)
-
-                log.debug(
-                    "Matched. confidence=%r, c_code=%r, c_name=%r",
-                    confidence, c_code, c_name)
-
-                if c_code != NULL and c_name != NULL and confidence >= confidence_threshold:
-                    code = c_code.decode('utf-8')
-                    name = c_name.decode('utf-8')
-                    results[name].append(code)
-
-            return results
-
-        finally:
-            _safe_osr_release(osr)
-            OSRFreeSRSArray(matches)
-            CPLFree(confidences)
-
     def _projjson(self):
         """Get a PROJ JSON representation.
 


=====================================
rasterio/dtypes.py
=====================================
@@ -93,29 +93,39 @@ if _GDAL_AT_LEAST_37:
 
 typename_rev = dict((v, k) for k, v in typename_fwd.items())
 
+f32i = numpy.finfo("float32")
+f64i = numpy.finfo("float64")
+
 dtype_ranges = {
-    'int8': (-128, 127),
-    'uint8': (0, 255),
-    'uint16': (0, 65535),
-    'int16': (-32768, 32767),
-    'uint32': (0, 4294967295),
-    'int32': (-2147483648, 2147483647),
-    'float32': (-3.4028235e+38, 3.4028235e+38),
-    'float64': (-1.7976931348623157e+308, 1.7976931348623157e+308)}
+    "int8": (-128, 127),
+    "uint8": (0, 255),
+    "uint16": (0, 65535),
+    "int16": (-32768, 32767),
+    "uint32": (0, 4294967295),
+    "int32": (-2147483648, 2147483647),
+    "float32": (float(f32i.min), float(f32i.max)),
+    "float64": (float(f64i.min), float(f64i.max)),
+}
 
 if _GDAL_AT_LEAST_35:
     dtype_ranges['int64'] = (-9223372036854775808, 9223372036854775807)
     dtype_ranges['uint64'] = (0, 18446744073709551615)
 
+dtype_info_registry = {"c": numpy.finfo, "f": numpy.finfo, "i": numpy.iinfo, "u": numpy.iinfo}
+
 
 def in_dtype_range(value, dtype):
-    """
-    Check if the value is within the dtype range
-    """
-    if numpy.dtype(dtype).kind == "f" and (numpy.isinf(value) or numpy.isnan(value)):
+    """Test if the value is within the dtype's range of values, Nan, or Inf."""
+    # The name of this function is a misnomer. What we're actually
+    # testing is whether the value can be represented by the data type.
+    kind = numpy.dtype(dtype).kind
+
+    # Nan and infinity are special cases.
+    if kind == "f" and (numpy.isnan(value) or numpy.isinf(value)):
         return True
-    range_min, range_max = dtype_ranges[dtype]
-    return range_min <= value <= range_max
+
+    info = dtype_info_registry[kind](dtype)
+    return info.min <= value <= info.max
 
 
 def _gdal_typename(dt):


=====================================
rasterio/gdal.pxi
=====================================
@@ -50,6 +50,7 @@ cdef extern from "cpl_string.h" nogil:
                            const char *pszValue)
     char **CSLDuplicate(char **papszStrList)
     int CSLFindName(char **papszStrList, const char *pszName)
+    int CSLFindString(char **papszStrList, const char *pszString)
     int CSLFetchBoolean(char **papszStrList, const char *pszName, int default)
     const char *CSLFetchNameValue(char **papszStrList, const char *pszName)
     char **CSLSetNameValue(char **list, char *name, char *val)
@@ -121,6 +122,7 @@ cdef extern from "cpl_vsi.h" nogil:
     int VSIInstallPluginHandler(const char*, const VSIFilesystemPluginCallbacksStruct*)
     VSIFilesystemPluginCallbacksStruct* VSIAllocFilesystemPluginCallbacksStruct()
     void VSIFreeFilesystemPluginCallbacksStruct(VSIFilesystemPluginCallbacksStruct*)
+    char** VSIGetFileSystemsPrefixes()
 
     unsigned char *VSIGetMemFileBuffer(const char *path,
                                        vsi_l_offset *data_len,


=====================================
rasterio/rio/edit_info.py
=====================================
@@ -10,6 +10,7 @@ import click
 import rasterio
 import rasterio.crs
 from rasterio.crs import CRS
+from rasterio.dtypes import in_dtype_range
 from rasterio.enums import ColorInterp
 from rasterio.errors import CRSError
 from rasterio.rio import options
@@ -164,17 +165,6 @@ def edit(ctx, input, bidx, nodata, unset_nodata, crs, unset_crs, transform,
       rio edit-info example.tif --like template.tif --transform like
 
     """
-    import numpy as np
-
-    def in_dtype_range(value, dtype):
-        kind = np.dtype(dtype).kind
-        if kind == 'f' and (np.isnan(value) or np.isinf(value)):
-            return True
-        infos = {'c': np.finfo, 'f': np.finfo, 'i': np.iinfo,
-                 'u': np.iinfo}
-        rng = infos[kind](dtype)
-        return rng.min <= value <= rng.max
-
     # If '--all' is given before '--like' on the commandline then 'allmd'
     # is the string 'like'.  This is caused by '--like' not having an
     # opportunity to populate metadata before '--all' is evaluated.


=====================================
readthedocs.yml deleted
=====================================
@@ -1,5 +0,0 @@
-python:
-  version: 3
-  pip_install: true
-conda:
-  file: environment.yml


=====================================
setup.py
=====================================
@@ -267,7 +267,7 @@ inst_reqs = [
     "certifi",
     "click>=4.0",
     "cligj>=0.5",
-    "numpy>=1.18",
+    "numpy",
     "snuggs>=1.4.1",
     "click-plugins",
     "setuptools",
@@ -284,7 +284,7 @@ extra_reqs = {
         "packaging",
         "pytest-cov>=2.2.0",
         "pytest>=2.8.2",
-        "shapely",
+        "shapely ; python_version < '3.12'",
     ],
 }
 
@@ -307,6 +307,7 @@ setup_args = dict(
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
+        "Programming Language :: Python :: 3.11",
         "Programming Language :: Python :: 3",
         "Topic :: Multimedia :: Graphics :: Graphics Conversion",
         "Topic :: Scientific/Engineering :: GIS",


=====================================
tests/test_features.py
=====================================
@@ -5,7 +5,6 @@ from unittest import mock
 from affine import Affine
 import numpy as np
 import pytest
-import shapely.geometry
 
 import rasterio
 from rasterio.enums import MergeAlg
@@ -901,6 +900,7 @@ def test_rasterize__numpy_coordinates__fail():
 
 def test_shapes(basic_image):
     """Test creation of shapes from pixel values."""
+    shapely = pytest.importorskip("shapely", reason="Test requires shapely.")
     results = list(shapes(basic_image))
 
     assert len(results) == 2
@@ -921,6 +921,7 @@ def test_shapes(basic_image):
 
 def test_shapes_2509(basic_image):
     """Test creation of shapes from pixel values, issue #2509."""
+    shapely = pytest.importorskip("shapely", reason="Test requires shapely.")
     image_with_strides = np.pad(basic_image, 1)[1:-1, 1:-1]
     np.testing.assert_array_equal(basic_image, image_with_strides)
     assert image_with_strides.__array_interface__["strides"] is not None


=====================================
tests/test_merge.py
=====================================
@@ -84,6 +84,7 @@ def test_unsafe_casting():
     dy=floats(min_value=-0.05, max_value=0.05),
 )
 def test_issue2202(dx, dy):
+    shapely = pytest.importorskip("shapely", reason="Test requires shapely.")
     import rasterio.merge
     from shapely import wkt
     from shapely.affinity import translate


=====================================
tests/test_rio_shapes.py
=====================================
@@ -6,7 +6,6 @@ import re
 
 import numpy as np
 import pytest
-from shapely.geometry import shape
 
 import rasterio
 from rasterio.rio.main import main_group
@@ -73,6 +72,8 @@ def test_shapes_with_nodata(runner, pixelated_image, pixelated_image_file):
     An area of nodata should also be represented with a shape when using
     --with-nodata option
     """
+    shapely = pytest.importorskip("shapely", reason="Test requires shapely.")
+    from shapely.geometry import shape
 
     pixelated_image[0:2, 8:10] = 255
 
@@ -139,6 +140,8 @@ def test_shapes_precision(runner, pixelated_image_file):
 
 def test_shapes_mask(runner, pixelated_image, pixelated_image_file):
     """ --mask should extract the nodata area of the image """
+    shapely = pytest.importorskip("shapely", reason="Test requires shapely.")
+    from shapely.geometry import shape
 
     pixelated_image[0:5, 0:10] = 255
     pixelated_image[0:10, 0:3] = 255
@@ -160,6 +163,9 @@ def test_shapes_mask_sampling(runner, pixelated_image, pixelated_image_file):
     """using --sampling with the mask should snap coordinates to the nearest
     factor of 5
     """
+    shapely = pytest.importorskip("shapely", reason="Test requires shapely.")
+    from shapely.geometry import shape
+
     pixelated_image[0:5, 0:10] = 255
     pixelated_image[0:10, 0:3] = 255
     pixelated_image[8:10, 8:10] = 255
@@ -184,6 +190,8 @@ def test_shapes_band1_as_mask(runner, pixelated_image, pixelated_image_file):
     When using --as-mask option, pixel value should not matter, only depends
     on pixels being contiguous.
     """
+    shapely = pytest.importorskip("shapely", reason="Test requires shapely.")
+    from shapely.geometry import shape
 
     pixelated_image[2:3, 2:3] = 4
 



View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/-/compare/8c7cb3fbd8768041baabb040af2769c470d61c5c...bbada558d755c2b1a5449af2c140da10aca392e2

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/rasterio/-/compare/8c7cb3fbd8768041baabb040af2769c470d61c5c...bbada558d755c2b1a5449af2c140da10aca392e2
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/20231019/ffc65136/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list