Hello community,

here is the log from the commit of package python-tinyarray for 
openSUSE:Factory checked in at 2020-09-24 16:15:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tinyarray (Old)
 and      /work/SRC/openSUSE:Factory/.python-tinyarray.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tinyarray"

Thu Sep 24 16:15:29 2020 rev:2 rq:836464 version:1.2.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tinyarray/python-tinyarray.changes        
2020-06-09 00:11:48.134741754 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-tinyarray.new.4249/python-tinyarray.changes  
    2020-09-24 16:15:43.712987705 +0200
@@ -1,0 +2,14 @@
+Sat Sep 19 15:39:21 UTC 2020 - Atri Bhattacharya <[email protected]>
+
+- Update to version 1.2.3:
+  * Improve float->int overflow tests.
+  * Buffer protocol: support all integer formats.
+  * Tiny optimization.
+  * Restore compatibility with tuple hash from Python 3.8.
+  * setup.py: replace call to deprecated function.
+  * Get rid of warning about implicit conversion to integer.
+  * Get rid of PY_SSIZE_T_CLEAN warning.
+- %check: Disable conversion test on non x86 systems; see
+  https://gitlab.kwant-project.org/kwant/tinyarray/-/issues/19.
+
+-------------------------------------------------------------------

Old:
----
  tinyarray-1.2.2.tar.gz

New:
----
  tinyarray-1.2.3.tar.gz

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

Other differences:
------------------
++++++ python-tinyarray.spec ++++++
--- /var/tmp/diff_new_pack.5mfoDy/_old  2020-09-24 16:15:44.332988326 +0200
+++ /var/tmp/diff_new_pack.5mfoDy/_new  2020-09-24 16:15:44.340988334 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           python-tinyarray
-Version:        1.2.2
+Version:        1.2.3
 Release:        0
 Summary:        Arrays of numbers for Python, optimized for small sizes
 License:        BSD-2-Clause
@@ -57,7 +57,12 @@
 %python_expand %fdupes %{buildroot}%{$python_sitearch}
 
 %check
+# Disable conversion test on non x86 systems; see 
https://gitlab.kwant-project.org/kwant/tinyarray/-/issues/19
+%ifarch %ix86 x86_64
 %pytest_arch
+%else
+%pytest_arch -k 'not test_conversion'
+%endif
 
 %files %{python_files}
 %doc README.rst

++++++ tinyarray-1.2.2.tar.gz -> tinyarray-1.2.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinyarray-1.2.2/PKG-INFO new/tinyarray-1.2.3/PKG-INFO
--- old/tinyarray-1.2.2/PKG-INFO        2020-01-06 17:36:48.000000000 +0100
+++ new/tinyarray-1.2.3/PKG-INFO        2020-09-17 14:23:07.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: tinyarray
-Version: 1.2.2
+Version: 1.2.3
 Summary: Arrays of numbers for Python, optimized for small sizes
 Home-page: https://gitlab.kwant-project.org/kwant/tinyarray
 Author: Christoph Groth (CEA) and others
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinyarray-1.2.2/setup.py new/tinyarray-1.2.3/setup.py
--- old/tinyarray-1.2.2/setup.py        2017-05-22 14:59:27.000000000 +0200
+++ new/tinyarray-1.2.3/setup.py        2020-09-16 14:15:36.000000000 +0200
@@ -78,7 +78,7 @@
     configs = configparser.ConfigParser()
     try:
         with open(config_file) as f:
-            configs.readfp(f)
+            configs.read_file(f)
     except IOError:
         config_file_present = False
     else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinyarray-1.2.2/src/array.cc 
new/tinyarray-1.2.3/src/array.cc
--- old/tinyarray-1.2.2/src/array.cc    2018-09-25 22:06:30.000000000 +0200
+++ new/tinyarray-1.2.3/src/array.cc    2020-09-16 14:15:36.000000000 +0200
@@ -88,7 +88,7 @@
     // Currently, we only understand native endianness and alignment.
     if (*fmt == '@') fmt++;
 
-    if (strchr("cbB?hHiIlL", *fmt)) {
+    if (strchr("cbB?hHiIlLqQnN", *fmt)) {
         dtype = LONG;
         fmt++;
     } else if (strchr("fdg", *fmt)) {
@@ -103,7 +103,7 @@
     }
 
     // Right now, no composite data structures are supported; if we found a
-    // single supported data type, we should be a the end of the string.
+    // single supported data type, we should be at the end of the string.
     if (*fmt != '\0') return NONE;
 
     return dtype;
@@ -365,9 +365,9 @@
 
 int examine_buffer(PyObject *in, Py_buffer *view, Dtype *dtype)
 {
+    if (!PyObject_CheckBuffer(in)) return -1;
     Dtype dt = NONE;
     memset(view, 0, sizeof(Py_buffer));
-    if (!PyObject_CheckBuffer(in)) return -1;
 
     // I don't know if the following makes much sense: I try to get the buffer
     // using less and less demanding flags. NumPy does the same.
@@ -458,6 +458,10 @@
         return number_from_ptr<T, long long>;
     case 'Q':
         return number_from_ptr<T, unsigned long long>;
+    case 'n':
+        return number_from_ptr<T, ssize_t>;
+    case 'N':
+        return number_from_ptr<T, size_t>;
     case 'f':
         return number_from_ptr<T, float>;
     case 'd':
@@ -850,8 +854,19 @@
     return hash(x.real()) + HASH_IMAG * hash(x.imag());
 }
 
-// This routine calculates the hash of a multi-dimensional array.  The hash is
-// equal to that of an arrangement of nested tuples equivalent to the array.
+// The following routine calculates the hash of a multi-dimensional array.  The
+// hash is equal to that of an arrangement of nested tuples equivalent to the
+// array.
+//
+// It exists in two versions because Python's tuplehash has changed in Python
+// 3.8 with the following motivation: "The hash function for tuples is now
+// based on xxHash which gives better collision results on (formerly)
+// pathological cases. Additionally, on 64-bit systems it improves tuple hashes
+// in general."
+
+#if (PY_MAJOR_VERSION < 3 || PY_MINOR_VERSION < 8) && PY_MAJOR_VERSION < 4
+
+// Version for Python < 3.8
 template <typename T>
 Py_hash_t hash(PyObject *obj)
 {
@@ -875,16 +890,20 @@
         if (i[d]) {
             --i[d];
             if (d == ndim) {
+                // Innermost loop body.
                 r[d] = (r[d] ^ hash(*p++)) * mult[d];
                 mult[d] += mul_addend + 2 * i[d];
             } else {
+                // Entering a loop.
                 ++d;
                 i[d] = shape[d];
                 mult[d] = mult_init;
                 r[d] = r_init;
             }
         } else {
+            // Exiting a loop.
             if (d == 0) {
+                // Exiting the outermost loop.
                 Py_uhash_t r_next = r[0] + r_addend;
                 return r_next == Py_uhash_t(-1) ? -2 : r_next;
             }
@@ -897,6 +916,77 @@
     }
 }
 
+#else
+
+#if SIZEOF_PY_UHASH_T > 4
+
+const Py_uhash_t _hash_init = 2870177450012600261U;
+
+inline void _hash_inner_loop(Py_uhash_t &acc, Py_uhash_t lane)
+{
+    acc += lane * 14029467366897019727U;
+    acc = ((acc << 31) | (acc >> 33)); // Rotate left 31 bits.
+    acc *= 11400714785074694791U;
+}
+
+#else
+
+const Py_uhash_t _hash_init = 374761393U;
+
+inline void _hash_inner_loop(Py_uhash_t &acc, Py_uhash_t lane)
+{
+    acc += lane * 2246822519U;
+    acc = ((acc << 13) | (acc >> 19)); // Rotate left 13 bits.
+    acc *= 2654435761U;
+}
+
+#endif
+
+inline Py_uhash_t _hash_loop_end(Py_uhash_t acc, Py_uhash_t len)
+{
+    acc += len ^ (_hash_init ^ 3527539UL);
+    if (acc == Py_uhash_t(-1)) return 1546275796;
+    return acc;
+}
+
+// Version for Python >= 3.8
+template <typename T>
+Py_hash_t hash(PyObject *obj)
+{
+    int ndim;
+    size_t *shape;
+    Array<T> *self = reinterpret_cast<Array<T> *>(obj);
+    self->ndim_shape(&ndim, &shape);
+    T *p = self->data();
+    if (ndim == 0) return hash(*p);
+
+    Py_ssize_t i[max_ndim];
+    Py_uhash_t acc[max_ndim];
+    --ndim;                     // For convenience.
+    int d = 0;
+    i[0] = shape[0];
+    acc[0] = _hash_init;
+    // The following is equivalent to 'ndim' (the original value) nested loops.
+    while (true) {
+        if (i[d]) {
+            --i[d];
+            if (d == ndim) {
+                _hash_inner_loop(acc[d], hash(*p++));
+            } else {
+                ++d;
+                i[d] = shape[d];
+                acc[d] = _hash_init;
+            }
+        } else {
+            if (d == 0) return _hash_loop_end(acc[0], shape[0]);
+            --d;
+            _hash_inner_loop(acc[d], _hash_loop_end(acc[d+1], shape[d+1]));
+        }
+    }
+}
+
+#endif
+
 template <typename T>
 bool compare_scalar(const int op, const T a, const T b) {
     switch(op){
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinyarray-1.2.2/src/conversion.hh 
new/tinyarray-1.2.3/src/conversion.hh
--- old/tinyarray-1.2.2/src/conversion.hh       2017-05-22 14:59:27.000000000 
+0200
+++ new/tinyarray-1.2.3/src/conversion.hh       2020-09-16 14:15:36.000000000 
+0200
@@ -59,7 +59,22 @@
 template <>
 inline long number_from_pyobject(PyObject *obj)
 {
-    return PyInt_AsLong(obj);
+    // Before, we solely used PyInt_AsLong, but with Python 3.8 this started to
+    // trigger warnings of implicit truncation
+    // (https://bugs.python.org/issue36048).
+    //
+    // However, truncation is exactly the desired behavior when explicitly
+    // creating a dtype=int array from floats.  To solve the problem, we now
+    // explicitly convert to a Python integer before converting to C long.
+#if PY_MAJOR_VERSION >= 3
+    obj = PyNumber_Long(obj);
+#else
+    obj = PyNumber_Int(obj);
+#endif
+    if (!obj) return -1;
+    long ret = PyInt_AsLong(obj);
+    Py_DECREF(obj);
+    return ret;
 }
 
 template <>
@@ -165,10 +180,10 @@
     const Tsrc *ptr = reinterpret_cast<const Tsrc*>(data);
     Tdest result = static_cast<Tdest>(*ptr);
 
-    // Note: the > max and < min tests are unreliable if the float obtained
-    // after rounding has less precision than necessary (which is typically the
-    // case for float and double). The two other tests are supposed to catch
-    // those problems.
+    // Note: the > max and < min tests are unreliable since the floating point
+    // representation of the maximal/minimal value may not be exact. The two
+    // other tests catch these problems.  This approach looks flimsy and is
+    // implementation-dependent, but it is tested rigourosly.
     if (*ptr > std::numeric_limits<Tdest>::max() ||
         *ptr < std::numeric_limits<Tdest>::min() ||
         (*ptr > 0 && result < 0) || (*ptr < 0 && result > 0)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinyarray-1.2.2/src/functions.cc 
new/tinyarray-1.2.3/src/functions.cc
--- old/tinyarray-1.2.2/src/functions.cc        2017-05-22 14:59:27.000000000 
+0200
+++ new/tinyarray-1.2.3/src/functions.cc        2020-09-16 14:15:36.000000000 
+0200
@@ -7,6 +7,7 @@
 // top-level directory of this distribution and at
 // https://gitlab.kwant-project.org/kwant/tinyarray.
 
+#define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include "array.hh"
 #include "arithmetic.hh"
@@ -62,7 +63,7 @@
     PyObject *pyshape;
     Format format;
     const void *data;
-    unsigned size_in_bytes;
+    Py_ssize_t size_in_bytes;
     if (!PyArg_ParseTuple(args, "Ois#", &pyshape, &format,
                           &data, &size_in_bytes))
         return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinyarray-1.2.2/test_tinyarray.py 
new/tinyarray-1.2.3/test_tinyarray.py
--- old/tinyarray-1.2.2/test_tinyarray.py       2019-12-30 09:56:26.000000000 
+0100
+++ new/tinyarray-1.2.3/test_tinyarray.py       2020-09-17 13:11:34.000000000 
+0200
@@ -11,7 +11,7 @@
 import platform
 import itertools as it
 import tinyarray as ta
-from pytest import raises, xfail
+from pytest import raises
 import numpy as np
 from numpy.testing import assert_equal, assert_almost_equal
 import sys
@@ -166,15 +166,47 @@
                     assert isinstance(dest[0], dest_dtype)
                     assert src == dest
 
-    # Check for overflow.
-    long_overflow = [1e300, np.array([1e300])]
-    # This check only works for Python 2.
-    if 18446744073709551615 > sys.maxsize:
-        long_overflow.extend([np.array([18446744073709551615], np.uint64),
-                              18446744073709551615])
-
-    for s in long_overflow:
-        raises(OverflowError, ta.array, s, int)
+    # Check correct overflow detection.  We assume a typical architecture:
+    # sys.maxsize is also the maximum size of an integer held in a tinyarray
+    # array, and that Python floats are double-precision IEEE numbers.
+    for n in [10**100, -10**100, 123 * 10**20, -2 * sys.maxsize,
+              sys.maxsize + 1, np.array(sys.maxsize + 1),
+              -sys.maxsize - 2]:
+        raises(OverflowError, ta.array, n, int)
+
+    # Check that values just below the threshold of overflow work.
+    for n in [sys.maxsize, np.array(sys.maxsize),
+              -sys.maxsize - 1, np.array(-sys.maxsize - 1)]:
+        ta.array(n, int)
+
+    # If tinyarray integers are longer than 32 bit, numbers around the maximal
+    # and minimal values cannot be represented exactly as double precision
+    # floating point numbers.  Check correct overflow detection also in this
+    # case.
+    n = sys.maxsize + 1
+    for dtype in [float, np.float64, np.float32]:
+        # The following assumes that n can be represented exactly.  This should
+        # be true for typical (all?) architectures.
+        assert dtype(n) == n
+        for factor in [1, 1.0001, 1.1, 2, 5, 123, 1e5]:
+
+            for x in [n, min(-n-1, np.nextafter(-n, -np.inf, dtype=dtype))]:
+                x = dtype(factor) * dtype(x)
+                raises(OverflowError, ta.array, x, int)
+                if dtype is not float:
+                    # This solicitates the buffer interface.
+                    x = np.array(x)
+                    assert(x.dtype == dtype)
+                    raises(OverflowError, ta.array, x, int)
+
+            for x in [-n, min(n-1, np.nextafter(n, 0, dtype=dtype))]:
+                x = dtype(x) / dtype(factor)
+                ta.array(x, int)
+                if dtype is not float:
+                    # This solicitates the buffer interface.
+                    x = np.array(x)
+                    assert(x.dtype == dtype)
+                    ta.array(x, int)
 
 
 def test_special_constructors():
@@ -264,10 +296,6 @@
 
 
 def test_as_dict_key():
-    # TODO: remove this once gitlab issue 16 is closed
-    if sys.version_info >= (3, 8, 0):
-        xfail('New version of tuple hash not supported yet.')
-
     n = 100
     d = {}
     for dtype in dtypes + dtypes:
@@ -279,10 +307,6 @@
 
 
 def test_hash_equality():
-    # TODO: remove this once gitlab issue 16 is closed
-    if sys.version_info >= (3, 8, 0):
-        xfail('New version of tuple hash not supported yet.')
-
     random.seed(123)
 
     # These refer to the width of integers stored in a tinyarray.ndarray_int.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinyarray-1.2.2/tinyarray.egg-info/PKG-INFO 
new/tinyarray-1.2.3/tinyarray.egg-info/PKG-INFO
--- old/tinyarray-1.2.2/tinyarray.egg-info/PKG-INFO     2020-01-06 
17:36:48.000000000 +0100
+++ new/tinyarray-1.2.3/tinyarray.egg-info/PKG-INFO     2020-09-17 
14:23:07.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: tinyarray
-Version: 1.2.2
+Version: 1.2.3
 Summary: Arrays of numbers for Python, optimized for small sizes
 Home-page: https://gitlab.kwant-project.org/kwant/tinyarray
 Author: Christoph Groth (CEA) and others
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tinyarray-1.2.2/version new/tinyarray-1.2.3/version
--- old/tinyarray-1.2.2/version 2020-01-06 17:36:48.000000000 +0100
+++ new/tinyarray-1.2.3/version 2020-09-17 14:23:07.000000000 +0200
@@ -1,2 +1,2 @@
 # This file has been generated by setup.py.
-1.2.2
+1.2.3


Reply via email to