]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: fix compatibility with numpy 2.0
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 23 Jun 2024 11:12:34 +0000 (13:12 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 15 Sep 2024 17:45:47 +0000 (19:45 +0200)
The only meaningful code change is with the bool class, whose type name
changed from `numpy.bool_` to `numpy.bool`. Note that using `bool`
causes a FutureWarning on import for numpy > 1.20, therefore we avoid
testing it (we still successfully test the `bool_` alias).

Other changes are related to tests: certain constant aliases are no more
available, so we skip those tests conditionally to numpy version.

Pin a minimum numpy version, to make sure we test also a numpy v1.
Picking 1.18,  released back in Dec 2019, as it's the first minor
version offering binary packages for Python 3.8. This min dependency will
need to be updated when dropping Python 3.8 support.

.github/workflows/tests.yml
psycopg/psycopg/types/numpy.py
tests/constraints.txt
tests/fix_faker.py
tests/types/test_numpy.py

index c91e939c55e654ac55f8a67820b254ab5baec195..d73982a7b0abedf37d4d6349ca6225dcdc83c407 100644 (file)
@@ -46,6 +46,9 @@ jobs:
           - {impl: c, python: "3.11", ext: numpy, postgres: "postgres:15"}
 
           # Test with minimum dependencies versions
+          # WARNING: when bumping min version, make sure that the dependencies
+          # # in tests/constraints.txt are updated and that binary packages
+          # are available for such version.
           - {impl: c, python: "3.8", ext: min, postgres: "postgres:15"}
 
           # Test with PyPy.
index 261c1f1336e598b95a0ce37a89b2926f5c4fdc23..9427a22135ddfe540e1b0f588a1dd2c5d11dcd4c 100644 (file)
@@ -71,6 +71,7 @@ def register_default_adapters(context: AdaptContext) -> None:
     adapters.register_dumper("numpy.int32", NPInt32Dumper)
     adapters.register_dumper("numpy.int64", NPInt64Dumper)
     adapters.register_dumper("numpy.longlong", NPInt64Dumper)
+    adapters.register_dumper("numpy.bool", BoolDumper)
     adapters.register_dumper("numpy.bool_", BoolDumper)
     adapters.register_dumper("numpy.uint8", NPInt16Dumper)
     adapters.register_dumper("numpy.uint16", NPInt32Dumper)
@@ -86,6 +87,7 @@ def register_default_adapters(context: AdaptContext) -> None:
     adapters.register_dumper("numpy.int32", NPInt32BinaryDumper)
     adapters.register_dumper("numpy.int64", NPInt64BinaryDumper)
     adapters.register_dumper("numpy.longlong", NPInt64BinaryDumper)
+    adapters.register_dumper("numpy.bool", BoolBinaryDumper)
     adapters.register_dumper("numpy.bool_", BoolBinaryDumper)
     adapters.register_dumper("numpy.uint8", NPInt16BinaryDumper)
     adapters.register_dumper("numpy.uint16", NPInt32BinaryDumper)
index 6737025b2300d1c4ecd9aa48ee618434497d7d06..b4756b327e7a1941985b116ed5459db958ea6dc8 100644 (file)
@@ -36,4 +36,8 @@ Cython == 3.0.0
 tomli == 2.0.1
 
 # Undeclared extras to "unblock" extra features
+
 shapely == 1.7.0
+# Warning: binary package only available up to python < 3.9.
+# Bump to a higher version when min supported python version increases past it.
+numpy == 1.20.0
index e302d22e5aed413ebe215a663dd3fdd648017dfb..9833b230faa8caf68b98affa557cbe83b01465f0 100644 (file)
@@ -228,6 +228,10 @@ class Faker:
         rv = set()
         for cls in dumpers.keys():
             if isinstance(cls, str):
+                if cls == "numpy.bool":
+                    # An alias of numpy.bool_ for numpy > 2.
+                    # Raises a warning in numpy > 1.20.
+                    continue
                 try:
                     cls = deep_import(cls)
                 except ImportError:
index ba5856cda839f9b4688f9e33d23b556b37b50a6c..f9fabc48719644ea43b4bdad97d35123d98ffb0e 100644 (file)
@@ -1,6 +1,8 @@
 from math import isnan
 
 import pytest
+from packaging.version import parse as ver  # noqa: F401  # used in skipif
+
 from psycopg.adapt import PyFormat
 from psycopg.pq import Format
 
@@ -13,6 +15,10 @@ pytest.importorskip("numpy")
 
 pytestmark = [pytest.mark.numpy]
 
+skip_numpy2 = pytest.mark.skipif(
+    "ver(np.__version__) >= ver('2.0.0')", reason="not available since numpy >= 2"
+)
+
 
 def test_classes_identities():
     # Check if we know the class identities correctly. Maybe on different
@@ -31,13 +37,13 @@ def test_classes_identities():
     "name, equiv",
     [
         ("inf", "inf"),
-        ("infty", "inf"),
-        ("NINF", "-inf"),
+        pytest.param("infty", "inf", marks=skip_numpy2),
+        pytest.param("NINF", "-inf", marks=skip_numpy2),
         ("nan", "nan"),
-        ("NaN", "nan"),
-        ("NAN", "nan"),
-        ("PZERO", "0.0"),
-        ("NZERO", "-0.0"),
+        pytest.param("NaN", "nan", marks=skip_numpy2),
+        pytest.param("NAN", "nan", marks=skip_numpy2),
+        pytest.param("PZERO", "0.0", marks=skip_numpy2),
+        pytest.param("NZERO", "-0.0", marks=skip_numpy2),
     ],
 )
 def test_special_values(name, equiv):