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