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]:
