Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-numpy1 for openSUSE:Factory 
checked in at 2026-04-28 13:22:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-numpy1 (Old)
 and      /work/SRC/openSUSE:Factory/.python-numpy1.new.11940 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-numpy1"

Tue Apr 28 13:22:28 2026 rev:7 rq:1349732 version:1.26.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-numpy1/python-numpy1.changes      
2025-04-07 17:37:51.231927734 +0200
+++ /work/SRC/openSUSE:Factory/.python-numpy1.new.11940/python-numpy1.changes   
2026-04-28 13:22:31.851102833 +0200
@@ -1,0 +2,7 @@
+Tue Apr 28 06:37:23 UTC 2026 - Daniel Garcia <[email protected]>
+
+- Add support for Python 3.14, with a couple of upstream patches:
+  gh#numpy/numpy#28928 and gh#numpy/numpy#28748, backported in
+  python314.patch
+
+-------------------------------------------------------------------

New:
----
  python314.patch

----------(New B)----------
  New:  gh#numpy/numpy#28928 and gh#numpy/numpy#28748, backported in
  python314.patch
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-numpy1.spec ++++++
--- /var/tmp/diff_new_pack.OGBLRl/_old  2026-04-28 13:22:32.647135508 +0200
+++ /var/tmp/diff_new_pack.OGBLRl/_new  2026-04-28 13:22:32.647135508 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-numpy1
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -46,6 +46,8 @@
 Patch3:         0001-feature-module-Fix-handling-of-multiple-conflicts-pe.patch
 # PATCH-FIX-UPSTREAM Based on gh#numpy/numpy#25839
 Patch4:         fix-meson-multiple-python-versions.patch
+# PATCH-FIX-UPSTREAM gh#numpy/numpy#28928, gh#numpy/numpy#28748
+Patch5:         python314.patch
 BuildRequires:  %{python_module Cython >= 3.0}
 BuildRequires:  %{python_module base >= 3.9}
 BuildRequires:  %{python_module devel}

++++++ python314.patch ++++++
>From a5f915876d49387b1e8cafd6d58883f3a802822b Mon Sep 17 00:00:00 2001
From: Nathan Goldbaum <[email protected]>
Date: Thu, 8 May 2025 08:26:13 -0600
Subject: [PATCH] MNT: add support for 3.14.0b1

---
 numpy/_core/src/multiarray/temp_elide.c | 39 ++++---------------------
 pytest.ini                              |  3 ++
 2 files changed, 8 insertions(+), 34 deletions(-)

Index: numpy-1.26.4/pytest.ini
===================================================================
--- numpy-1.26.4.orig/pytest.ini
+++ numpy-1.26.4/pytest.ini
@@ -27,3 +27,8 @@ filterwarnings =
     ignore:\n\n  `numpy.distutils`:DeprecationWarning
 # Ignore mypy >= 0.971 DeprecationWarnings
     ignore:path is deprecated\. Use files\(\) instead:DeprecationWarning:mypy
+# Ignore DeprecationWarning from typing.mypy_plugin
+     ignore:`numpy.typing.mypy_plugin` is deprecated:DeprecationWarning
+# Ignore DeprecationWarning from struct module
+# see https://github.com/numpy/numpy/issues/28926
+    ignore:Due to \'_pack_\', the
Index: numpy-1.26.4/numpy/core/src/multiarray/temp_elide.c
===================================================================
--- numpy-1.26.4.orig/numpy/core/src/multiarray/temp_elide.c
+++ numpy-1.26.4/numpy/core/src/multiarray/temp_elide.c
@@ -62,6 +62,13 @@
 
 #include <feature_detection_misc.h>
 
+#if PY_VERSION_HEX >= 0x030E00A7 && !defined(PYPY_VERSION)
+#define Py_BUILD_CORE
+#include "internal/pycore_frame.h"
+#include "internal/pycore_interpframe.h"
+#undef Py_BUILD_CORE
+#endif
+
 /* 1 prints elided operations, 2 prints stacktraces */
 #define NPY_ELIDE_DEBUG 0
 #define NPY_MAX_STACKSIZE 10
@@ -110,6 +117,41 @@ find_addr(void * addresses[], npy_intp n
 }
 
 static int
+check_unique_temporary(PyObject *lhs)
+{
+#if PY_VERSION_HEX >= 0x030E00A7 && !defined(PYPY_VERSION)
+    // In Python 3.14.0a7 and later, a reference count of one doesn't guarantee
+    // that an object is a unique temporary variable. We scan the top of the
+    // interpreter stack to check if the object exists as an "owned" reference
+    // in the temporary stack.
+    PyFrameObject *frame = PyEval_GetFrame();
+    if (frame == NULL) {
+        return 0;
+    }
+    _PyInterpreterFrame *f = frame->f_frame;
+    _PyStackRef *base = _PyFrame_Stackbase(f);
+    _PyStackRef *stackpointer = f->stackpointer;
+    int found_once = 0;
+    while (stackpointer > base) {
+        stackpointer--;
+        PyObject *obj = PyStackRef_AsPyObjectBorrow(*stackpointer);
+        if (obj == lhs) {
+            if (!found_once && PyStackRef_IsHeapSafe(*stackpointer)) {
+                found_once = 1;
+            }
+            else {
+                return 0;
+            }
+        }
+        return found_once;
+    }
+    return 0;
+#else
+    return 1;
+#endif
+}
+
+static int
 check_callers(int * cannot)
 {
     /*
@@ -295,7 +337,8 @@ can_elide_temp(PyObject *olhs, PyObject
             !PyArray_CHKFLAGS(alhs, NPY_ARRAY_OWNDATA) ||
             !PyArray_ISWRITEABLE(alhs) ||
             PyArray_CHKFLAGS(alhs, NPY_ARRAY_WRITEBACKIFCOPY) ||
-            PyArray_NBYTES(alhs) < NPY_MIN_ELIDE_BYTES) {
+            PyArray_NBYTES(alhs) < NPY_MIN_ELIDE_BYTES ||
+            !check_unique_temporary(olhs)) {
         return 0;
     }
     if (PyArray_CheckExact(orhs) ||
@@ -372,7 +415,8 @@ can_elide_temp_unary(PyArrayObject * m1)
             !PyArray_ISNUMBER(m1) ||
             !PyArray_CHKFLAGS(m1, NPY_ARRAY_OWNDATA) ||
             !PyArray_ISWRITEABLE(m1) ||
-            PyArray_NBYTES(m1) < NPY_MIN_ELIDE_BYTES) {
+            PyArray_NBYTES(m1) < NPY_MIN_ELIDE_BYTES ||
+            !check_unique_temporary((PyObject *)m1)) {
         return 0;
     }
     if (check_callers(&cannot)) {
Index: numpy-1.26.4/numpy/core/tests/test_dlpack.py
===================================================================
--- numpy-1.26.4.orig/numpy/core/tests/test_dlpack.py
+++ numpy-1.26.4/numpy/core/tests/test_dlpack.py
@@ -5,14 +5,25 @@ import numpy as np
 from numpy.testing import assert_array_equal, IS_PYPY
 
 
+def new_and_old_dlpack():
+    yield np.arange(5)
+
+    class OldDLPack(np.ndarray):
+        # Support only the "old" version
+        def __dlpack__(self, stream=None):
+            return super().__dlpack__(stream=None)
+
+    yield np.arange(5).view(OldDLPack)
+
+
 class TestDLPack:
     @pytest.mark.skipif(IS_PYPY, reason="PyPy can't get refcounts.")
     def test_dunder_dlpack_refcount(self):
         x = np.arange(5)
         y = x.__dlpack__()
-        assert sys.getrefcount(x) == 3
+        startcount = sys.getrefcount(x)
         del y
-        assert sys.getrefcount(x) == 2
+        assert startcount - sys.getrefcount(x) == 1
 
     def test_dunder_dlpack_stream(self):
         x = np.arange(5)
@@ -30,12 +41,13 @@ class TestDLPack:
             np.from_dlpack(z)
 
     @pytest.mark.skipif(IS_PYPY, reason="PyPy can't get refcounts.")
-    def test_from_dlpack_refcount(self):
-        x = np.arange(5)
-        y = np.from_dlpack(x)
-        assert sys.getrefcount(x) == 3
+    @pytest.mark.parametrize("arr", new_and_old_dlpack())
+    def test_from_dlpack_refcount(self, arr):
+        arr = arr.copy()
+        y = np.from_dlpack(arr)
+        startcount = sys.getrefcount(arr)
         del y
-        assert sys.getrefcount(x) == 2
+        assert startcount - sys.getrefcount(arr) == 1
 
     @pytest.mark.parametrize("dtype", [
         np.bool_,
Index: numpy-1.26.4/numpy/core/tests/test_indexing.py
===================================================================
--- numpy-1.26.4.orig/numpy/core/tests/test_indexing.py
+++ numpy-1.26.4/numpy/core/tests/test_indexing.py
@@ -1147,6 +1147,8 @@ class TestMultiIndexingAutomated:
         """Compare mimicked result to indexing result.
         """
         arr = arr.copy()
+        if HAS_REFCOUNT:
+            startcount = sys.getrefcount(arr)
         indexed_arr = arr[index]
         assert_array_equal(indexed_arr, mimic_get)
         # Check if we got a view, unless its a 0-sized or 0-d array.
@@ -1157,9 +1159,9 @@ class TestMultiIndexingAutomated:
             if HAS_REFCOUNT:
                 if no_copy:
                     # refcount increases by one:
-                    assert_equal(sys.getrefcount(arr), 3)
+                    assert_equal(sys.getrefcount(arr), startcount + 1)
                 else:
-                    assert_equal(sys.getrefcount(arr), 2)
+                    assert_equal(sys.getrefcount(arr), startcount)
 
         # Test non-broadcast setitem:
         b = arr.copy()
Index: numpy-1.26.4/numpy/core/tests/test_item_selection.py
===================================================================
--- numpy-1.26.4.orig/numpy/core/tests/test_item_selection.py
+++ numpy-1.26.4/numpy/core/tests/test_item_selection.py
@@ -50,19 +50,23 @@ class TestTake:
 
     def test_refcounting(self):
         objects = [object() for i in range(10)]
+        if HAS_REFCOUNT:
+            orig_rcs = [sys.getrefcount(o) for o in objects]
         for mode in ('raise', 'clip', 'wrap'):
             a = np.array(objects)
             b = np.array([2, 2, 4, 5, 3, 5])
             a.take(b, out=a[:6], mode=mode)
             del a
             if HAS_REFCOUNT:
-                assert_(all(sys.getrefcount(o) == 3 for o in objects))
+                assert_(all(sys.getrefcount(o) == rc + 1
+                            for o, rc in zip(objects, orig_rcs)))
             # not contiguous, example:
             a = np.array(objects * 2)[::2]
             a.take(b, out=a[:6], mode=mode)
             del a
             if HAS_REFCOUNT:
-                assert_(all(sys.getrefcount(o) == 3 for o in objects))
+                assert_(all(sys.getrefcount(o) == rc + 1
+                            for o, rc in zip(objects, orig_rcs)))
 
     def test_unicode_mode(self):
         d = np.arange(10)
Index: numpy-1.26.4/numpy/core/tests/test_multiarray.py
===================================================================
--- numpy-1.26.4.orig/numpy/core/tests/test_multiarray.py
+++ numpy-1.26.4/numpy/core/tests/test_multiarray.py
@@ -6644,10 +6644,12 @@ class TestDot:
         v = np.random.random_sample((16, 32))
 
         r = np.empty((1024, 32))
+        if HAS_REFCOUNT:
+            orig_refcount = sys.getrefcount(r)
         for i in range(12):
             dot(f, v, r)
         if HAS_REFCOUNT:
-            assert_equal(sys.getrefcount(r), 2)
+            assert_equal(sys.getrefcount(r), orig_refcount)
         r2 = dot(f, v, out=None)
         assert_array_equal(r2, r)
         assert_(r is dot(f, v, out=r))
Index: numpy-1.26.4/numpy/core/tests/test_nditer.py
===================================================================
--- numpy-1.26.4.orig/numpy/core/tests/test_nditer.py
+++ numpy-1.26.4/numpy/core/tests/test_nditer.py
@@ -1122,8 +1122,9 @@ def test_iter_object_arrays_conversions(
             rc = sys.getrefcount(ob)
         for x in i:
             x[...] += 1
-    if HAS_REFCOUNT:
-        assert_(sys.getrefcount(ob) == rc-1)
+        if HAS_REFCOUNT:
+            newrc = sys.getrefcount(ob)
+            assert_(newrc == rc - 1)
     assert_equal(a, np.arange(6)+98172489)
 
 def test_iter_common_dtype():
Index: numpy-1.26.4/numpy/core/tests/test_regression.py
===================================================================
--- numpy-1.26.4.orig/numpy/core/tests/test_regression.py
+++ numpy-1.26.4/numpy/core/tests/test_regression.py
@@ -1600,29 +1600,26 @@ class TestRegression:
     def test_fromfile_tofile_seeks(self):
         # On Python 3, tofile/fromfile used to get (#1610) the Python
         # file handle out of sync
-        f0 = tempfile.NamedTemporaryFile()
-        f = f0.file
-        f.write(np.arange(255, dtype='u1').tobytes())
+        with tempfile.NamedTemporaryFile() as f:
+            f.write(np.arange(255, dtype='u1').tobytes())
 
-        f.seek(20)
-        ret = np.fromfile(f, count=4, dtype='u1')
-        assert_equal(ret, np.array([20, 21, 22, 23], dtype='u1'))
-        assert_equal(f.tell(), 24)
-
-        f.seek(40)
-        np.array([1, 2, 3], dtype='u1').tofile(f)
-        assert_equal(f.tell(), 43)
-
-        f.seek(40)
-        data = f.read(3)
-        assert_equal(data, b"\x01\x02\x03")
-
-        f.seek(80)
-        f.read(4)
-        data = np.fromfile(f, dtype='u1', count=4)
-        assert_equal(data, np.array([84, 85, 86, 87], dtype='u1'))
-
-        f.close()
+            f.seek(20)
+            ret = np.fromfile(f, count=4, dtype='u1')
+            assert_equal(ret, np.array([20, 21, 22, 23], dtype='u1'))
+            assert_equal(f.tell(), 24)
+
+            f.seek(40)
+            np.array([1, 2, 3], dtype='u1').tofile(f)
+            assert_equal(f.tell(), 43)
+
+            f.seek(40)
+            data = f.read(3)
+            assert_equal(data, b"\x01\x02\x03")
+
+            f.seek(80)
+            f.read(4)
+            data = np.fromfile(f, dtype='u1', count=4)
+            assert_equal(data, np.array([84, 85, 86, 87], dtype='u1'))
 
     def test_complex_scalar_warning(self):
         for tp in [np.csingle, np.cdouble, np.clongdouble]:

Reply via email to