Imported Upstream version 1.21.3 upstream/1.21.3
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 15 Jul 2022 02:14:50 +0000 (11:14 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 15 Jul 2022 02:14:50 +0000 (11:14 +0900)
19 files changed:
PKG-INFO
doc/changelog/1.21.3-changelog.rst [new file with mode: 0644]
doc/release/upcoming_changes/20049.change.rst [new file with mode: 0644]
doc/source/release.rst
doc/source/release/1.21.3-notes.rst [new file with mode: 0644]
numpy/__init__.pyi
numpy/_version.py
numpy/core/src/multiarray/arraytypes.c.src
numpy/core/src/multiarray/compiled_base.c
numpy/core/src/multiarray/convert_datatype.c
numpy/core/src/npymath/npy_math_internal.h.src
numpy/core/src/umath/loops_unary_fp.dispatch.c.src
numpy/core/tests/test_dtype.py
numpy/random/src/pcg64/pcg64.c
numpy/random/tests/test_direct.py
numpy/typing/__init__.py
numpy/typing/tests/data/reveal/ndarray_conversion.py
numpy/typing/tests/data/reveal/scalars.py
pavement.py

index 26d4e367db792883f476a501feb4351b21709bfa..9e8286d671f5d5f9d5d4d82622a441b4ff7f65b3 100644 (file)
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: numpy
-Version: 1.21.2
+Version: 1.21.3
 Summary:  NumPy is the fundamental package for array computing with Python.
 Home-page: https://www.numpy.org
 Author: Travis E. Oliphant et al.
diff --git a/doc/changelog/1.21.3-changelog.rst b/doc/changelog/1.21.3-changelog.rst
new file mode 100644 (file)
index 0000000..7677947
--- /dev/null
@@ -0,0 +1,28 @@
+
+Contributors
+============
+
+A total of 7 people contributed to this release.  People with a "+" by their
+names contributed a patch for the first time.
+
+* Aaron Meurer
+* Bas van Beek
+* Charles Harris
+* Developer-Ecosystem-Engineering +
+* Kevin Sheppard
+* Sebastian Berg
+* Warren Weckesser
+
+Pull requests merged
+====================
+
+A total of 8 pull requests were merged for this release.
+
+* `#19745 <https://github.com/numpy/numpy/pull/19745>`__: ENH: Add dtype-support to 3 `generic`/`ndarray` methods
+* `#19955 <https://github.com/numpy/numpy/pull/19955>`__: BUG: Resolve Divide by Zero on Apple silicon + test failures...
+* `#19958 <https://github.com/numpy/numpy/pull/19958>`__: MAINT: Mark type-check-only ufunc subclasses as ufunc aliases...
+* `#19994 <https://github.com/numpy/numpy/pull/19994>`__: BUG: np.tan(np.inf) test failure
+* `#20080 <https://github.com/numpy/numpy/pull/20080>`__: BUG: Correct incorrect advance in PCG with emulated int128
+* `#20081 <https://github.com/numpy/numpy/pull/20081>`__: BUG: Fix NaT handling in the PyArray_CompareFunc for datetime...
+* `#20082 <https://github.com/numpy/numpy/pull/20082>`__: DOC: Ensure that we add documentation also as to the dict for...
+* `#20106 <https://github.com/numpy/numpy/pull/20106>`__: BUG: core: result_type(0, np.timedelta64(4)) would seg. fault.
diff --git a/doc/release/upcoming_changes/20049.change.rst b/doc/release/upcoming_changes/20049.change.rst
new file mode 100644 (file)
index 0000000..e1f08b3
--- /dev/null
@@ -0,0 +1,5 @@
+Corrected ``advance`` in ``PCG64DSXM`` and ``PCG64``
+----------------------------------------------------
+Fixed a bug in the ``advance`` method of ``PCG64DSXM`` and ``PCG64``. The bug only
+affects results when the step was larger than :math:`2^{64}` on platforms
+that do not support 128-bit integers(e.g., Windows and 32-bit Linux).
index 99856e990d96458302b0821ad6c5f3a8d95c3b69..bef6e8e4d6f74d26de4fdf0d7ab774595d3dfb55 100644 (file)
@@ -5,6 +5,7 @@ Release Notes
 .. toctree::
     :maxdepth: 3
 
+    1.21.3 <release/1.21.3-notes>
     1.21.2 <release/1.21.2-notes>
     1.21.1 <release/1.21.1-notes>
     1.21.0 <release/1.21.0-notes>
diff --git a/doc/source/release/1.21.3-notes.rst b/doc/source/release/1.21.3-notes.rst
new file mode 100644 (file)
index 0000000..c0ef5a4
--- /dev/null
@@ -0,0 +1,44 @@
+.. currentmodule:: numpy
+
+==========================
+NumPy 1.21.3 Release Notes
+==========================
+
+The NumPy 1.21.3 is a maintenance release the fixes a few bugs discovered after
+1.21.2. It also provides 64 bit Python 3.10.0 wheels. Note a few oddities about
+Python 3.10:
+
+* There are no 32 bit wheels for Windows, Mac, or Linux.
+* The Mac Intel builds are only available in universal2 wheels.
+
+The Python versions supported in this release are 3.7-3.10. If you want to
+compile your own version using gcc-11 you will need to use gcc-11.2+ to avoid
+problems.
+
+Contributors
+============
+
+A total of 7 people contributed to this release.  People with a "+" by their
+names contributed a patch for the first time.
+
+* Aaron Meurer
+* Bas van Beek
+* Charles Harris
+* Developer-Ecosystem-Engineering +
+* Kevin Sheppard
+* Sebastian Berg
+* Warren Weckesser
+
+Pull requests merged
+====================
+
+A total of 8 pull requests were merged for this release.
+
+* `#19745 <https://github.com/numpy/numpy/pull/19745>`__: ENH: Add dtype-support to 3 ```generic``/``ndarray`` methods
+* `#19955 <https://github.com/numpy/numpy/pull/19955>`__: BUG: Resolve Divide by Zero on Apple silicon + test failures...
+* `#19958 <https://github.com/numpy/numpy/pull/19958>`__: MAINT: Mark type-check-only ufunc subclasses as ufunc aliases...
+* `#19994 <https://github.com/numpy/numpy/pull/19994>`__: BUG: np.tan(np.inf) test failure
+* `#20080 <https://github.com/numpy/numpy/pull/20080>`__: BUG: Correct incorrect advance in PCG with emulated int128
+* `#20081 <https://github.com/numpy/numpy/pull/20081>`__: BUG: Fix NaT handling in the PyArray_CompareFunc for datetime...
+* `#20082 <https://github.com/numpy/numpy/pull/20082>`__: DOC: Ensure that we add documentation also as to the dict for...
+* `#20106 <https://github.com/numpy/numpy/pull/20106>`__: BUG: core: result_type(0, np.timedelta64(4)) would seg. fault.
index d07e32f1c27628d0c68b0fac8070442d1b38ce98..dfec6af94b74ef42e94727c71e93bbf4c5033b1a 100644 (file)
@@ -1254,20 +1254,9 @@ class _ArrayOrScalarCommon:
     def __deepcopy__(self: _ArraySelf, __memo: Optional[dict] = ...) -> _ArraySelf: ...
     def __eq__(self, other): ...
     def __ne__(self, other): ...
-    def astype(
-        self: _ArraySelf,
-        dtype: DTypeLike,
-        order: _OrderKACF = ...,
-        casting: _Casting = ...,
-        subok: bool = ...,
-        copy: bool = ...,
-    ) -> _ArraySelf: ...
     def copy(self: _ArraySelf, order: _OrderKACF = ...) -> _ArraySelf: ...
     def dump(self, file: str) -> None: ...
     def dumps(self) -> bytes: ...
-    def getfield(
-        self: _ArraySelf, dtype: DTypeLike, offset: int = ...
-    ) -> _ArraySelf: ...
     def tobytes(self, order: _OrderKACF = ...) -> bytes: ...
     # NOTE: `tostring()` is deprecated and therefore excluded
     # def tostring(self, order=...): ...
@@ -1276,14 +1265,6 @@ class _ArrayOrScalarCommon:
     ) -> None: ...
     # generics and 0d arrays return builtin scalars
     def tolist(self) -> Any: ...
-    @overload
-    def view(self, type: Type[_NdArraySubClass]) -> _NdArraySubClass: ...
-    @overload
-    def view(self: _ArraySelf, dtype: DTypeLike = ...) -> _ArraySelf: ...
-    @overload
-    def view(
-        self, dtype: DTypeLike, type: Type[_NdArraySubClass]
-    ) -> _NdArraySubClass: ...
 
     # TODO: Add proper signatures
     def __getitem__(self, key) -> Any: ...
@@ -1665,6 +1646,12 @@ _T_co = TypeVar("_T_co", covariant=True)
 _2Tuple = Tuple[_T, _T]
 _Casting = L["no", "equiv", "safe", "same_kind", "unsafe"]
 
+_DTypeLike = Union[
+    dtype[_ScalarType],
+    Type[_ScalarType],
+    _SupportsDType[dtype[_ScalarType]],
+]
+
 _ArrayUInt_co = NDArray[Union[bool_, unsignedinteger[Any]]]
 _ArrayInt_co = NDArray[Union[bool_, integer[Any]]]
 _ArrayFloat_co = NDArray[Union[bool_, integer[Any], floating[Any]]]
@@ -1914,6 +1901,53 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
         self, *shape: SupportsIndex, order: _OrderACF = ...
     ) -> ndarray[Any, _DType_co]: ...
 
+    @overload
+    def astype(
+        self,
+        dtype: _DTypeLike[_ScalarType],
+        order: _OrderKACF = ...,
+        casting: _Casting = ...,
+        subok: bool = ...,
+        copy: bool = ...,
+    ) -> NDArray[_ScalarType]: ...
+    @overload
+    def astype(
+        self,
+        dtype: DTypeLike,
+        order: _OrderKACF = ...,
+        casting: _Casting = ...,
+        subok: bool = ...,
+        copy: bool = ...,
+    ) -> NDArray[Any]: ...
+
+    @overload
+    def view(self: _ArraySelf) -> _ArraySelf: ...
+    @overload
+    def view(self, type: Type[_NdArraySubClass]) -> _NdArraySubClass: ...
+    @overload
+    def view(self, dtype: _DTypeLike[_ScalarType]) -> NDArray[_ScalarType]: ...
+    @overload
+    def view(self, dtype: DTypeLike) -> NDArray[Any]: ...
+    @overload
+    def view(
+        self,
+        dtype: DTypeLike,
+        type: Type[_NdArraySubClass],
+    ) -> _NdArraySubClass: ...
+
+    @overload
+    def getfield(
+        self,
+        dtype: _DTypeLike[_ScalarType],
+        offset: SupportsIndex = ...
+    ) -> NDArray[_ScalarType]: ...
+    @overload
+    def getfield(
+        self,
+        dtype: DTypeLike,
+        offset: SupportsIndex = ...
+    ) -> NDArray[Any]: ...
+
     # Dispatch to the underlying `generic` via protocols
     def __int__(
         self: ndarray[Any, dtype[SupportsInt]],  # type: ignore[type-var]
@@ -2886,6 +2920,59 @@ class generic(_ArrayOrScalarCommon):
     def byteswap(self: _ScalarType, inplace: L[False] = ...) -> _ScalarType: ...
     @property
     def flat(self: _ScalarType) -> flatiter[ndarray[Any, dtype[_ScalarType]]]: ...
+
+    @overload
+    def astype(
+        self,
+        dtype: _DTypeLike[_ScalarType],
+        order: _OrderKACF = ...,
+        casting: _Casting = ...,
+        subok: bool = ...,
+        copy: bool = ...,
+    ) -> _ScalarType: ...
+    @overload
+    def astype(
+        self,
+        dtype: DTypeLike,
+        order: _OrderKACF = ...,
+        casting: _Casting = ...,
+        subok: bool = ...,
+        copy: bool = ...,
+    ) -> Any: ...
+
+    # NOTE: `view` will perform a 0D->scalar cast,
+    # thus the array `type` is irrelevant to the output type
+    @overload
+    def view(
+        self: _ScalarType,
+        type: Type[ndarray[Any, Any]] = ...,
+    ) -> _ScalarType: ...
+    @overload
+    def view(
+        self,
+        dtype: _DTypeLike[_ScalarType],
+        type: Type[ndarray[Any, Any]] = ...,
+    ) -> _ScalarType: ...
+    @overload
+    def view(
+        self,
+        dtype: DTypeLike,
+        type: Type[ndarray[Any, Any]] = ...,
+    ) -> Any: ...
+
+    @overload
+    def getfield(
+        self,
+        dtype: _DTypeLike[_ScalarType],
+        offset: SupportsIndex = ...
+    ) -> _ScalarType: ...
+    @overload
+    def getfield(
+        self,
+        dtype: DTypeLike,
+        offset: SupportsIndex = ...
+    ) -> Any: ...
+
     def item(
         self,
         __args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
index 582f1962caf7909c95273c3d85cec89e4a3ccee8..723d927dedec175bbdaa4f6a718f7abe7ab4e15b 100644 (file)
@@ -8,11 +8,11 @@ import json
 
 version_json = '''
 {
- "date": "2021-08-15T12:15:47-0600",
+ "date": "2021-10-19T18:45:47-0600",
  "dirty": false,
  "error": null,
- "full-revisionid": "2fe48d2d98a85c8ea3f3d5caffd952ea69e99335",
- "version": "1.21.2"
+ "full-revisionid": "d4d0584ccb508cad69288b504e6c8b04aa0d5caf",
+ "version": "1.21.3"
 }
 '''  # END VERSION_JSON
 
index ad74612272b248eeaea2744cfabd2dba5cf486e7..b3ea7544d974607610a24bdaf6f78c38d7df4ba1 100644 (file)
@@ -2805,11 +2805,9 @@ BOOL_compare(npy_bool *ip1, npy_bool *ip2, PyArrayObject *NPY_UNUSED(ap))
 
 /**begin repeat
  * #TYPE = BYTE, UBYTE, SHORT, USHORT, INT, UINT,
- *         LONG, ULONG, LONGLONG, ULONGLONG,
- *         DATETIME, TIMEDELTA#
+ *         LONG, ULONG, LONGLONG, ULONGLONG#
  * #type = npy_byte, npy_ubyte, npy_short, npy_ushort, npy_int, npy_uint,
- *         npy_long, npy_ulong, npy_longlong, npy_ulonglong,
- *         npy_datetime, npy_timedelta#
+ *         npy_long, npy_ulong, npy_longlong, npy_ulonglong#
  */
 
 static int
@@ -2920,6 +2918,37 @@ C@TYPE@_compare(@type@ *pa, @type@ *pb)
 
 /**end repeat**/
 
+/**begin repeat
+ * #TYPE = DATETIME, TIMEDELTA#
+ * #type = npy_datetime, npy_timedelta#
+ */
+
+static int
+@TYPE@_compare(@type@ *pa, @type@ *pb)
+{
+    const @type@ a = *pa;
+    const @type@ b = *pb;
+    int ret;
+
+    if (a == NPY_DATETIME_NAT) {
+        if (b == NPY_DATETIME_NAT) {
+            ret = 0;
+        }
+        else {
+            ret = 1;
+        }
+    }
+    else if (b == NPY_DATETIME_NAT) {
+        ret = -1;
+    }
+    else {
+        ret = a < b ? -1 : a == b ? 0 : 1;
+    }
+    return ret;
+}
+
+/**end repeat**/
+
 static int
 HALF_compare (npy_half *pa, npy_half *pb, PyArrayObject *NPY_UNUSED(ap))
 {
index de793f87c156cc2c74539259ac003b7c8a1ab119..6b76e570f8e6e08e4b891af46d16a38fa6d168f9 100644 (file)
@@ -1425,9 +1425,26 @@ arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *args)
         PyCFunctionObject *new = (PyCFunctionObject *)obj;
         _ADDDOC(new->m_ml->ml_doc, new->m_ml->ml_name);
     }
-    else if (Py_TYPE(obj) == &PyType_Type) {
+    else if (PyObject_TypeCheck(obj, &PyType_Type)) {
+        /*
+         * We add it to both `tp_doc` and `__doc__` here.  Note that in theory
+         * `tp_doc` extracts the signature line, but we currently do not use
+         * it.  It may make sense to only add it as `__doc__` and
+         * `__text_signature__` to the dict in the future.
+         * The dictionary path is only necessary for heaptypes (currently not
+         * used) and metaclasses.
+         * If `__doc__` as stored in `tp_dict` is None, we assume this was
+         * filled in by `PyType_Ready()` and should also be replaced.
+         */
         PyTypeObject *new = (PyTypeObject *)obj;
         _ADDDOC(new->tp_doc, new->tp_name);
+        if (new->tp_dict != NULL && PyDict_CheckExact(new->tp_dict) &&
+                PyDict_GetItemString(new->tp_dict, "__doc__") == Py_None) {
+            /* Warning: Modifying `tp_dict` is not generally safe! */
+            if (PyDict_SetItemString(new->tp_dict, "__doc__", str) < 0) {
+                return NULL;
+            }
+        }
     }
     else if (Py_TYPE(obj) == &PyMemberDescr_Type) {
         PyMemberDescrObject *new = (PyMemberDescrObject *)obj;
index cd0e21098bcdba2eb6fe428a219bf608f61365df..49e4550804b6abd905df36896ef6cfec2a1f11b8 100644 (file)
@@ -1536,6 +1536,40 @@ should_use_min_scalar(npy_intp narrs, PyArrayObject **arr,
 }
 
 
+/*
+ * Utility function used only in PyArray_ResultType for value-based logic.
+ * See that function for the meaning and contents of the parameters.
+ */
+static PyArray_Descr *
+get_descr_from_cast_or_value(
+        npy_intp i,
+        PyArrayObject *arrs[],
+        npy_intp ndtypes,
+        PyArray_Descr *descriptor,
+        PyArray_DTypeMeta *common_dtype)
+{
+    PyArray_Descr *curr;
+    if (NPY_LIKELY(i < ndtypes ||
+            !(PyArray_FLAGS(arrs[i-ndtypes]) & _NPY_ARRAY_WAS_PYSCALAR))) {
+        curr = PyArray_CastDescrToDType(descriptor, common_dtype);
+    }
+    else {
+        /*
+         * Unlike `PyArray_CastToDTypeAndPromoteDescriptors`, deal with
+         * plain Python values "graciously". This recovers the original
+         * value the long route, but it should almost never happen...
+         */
+        PyObject *tmp = PyArray_GETITEM(arrs[i-ndtypes],
+                                        PyArray_BYTES(arrs[i-ndtypes]));
+        if (tmp == NULL) {
+            return NULL;
+        }
+        curr = common_dtype->discover_descr_from_pyobject(common_dtype, tmp);
+        Py_DECREF(tmp);
+    }
+    return curr;
+}
+
 /*NUMPY_API
  *
  * Produces the result type of a bunch of inputs, using the same rules
@@ -1672,28 +1706,15 @@ PyArray_ResultType(
         result = common_dtype->default_descr(common_dtype);
     }
     else {
-        result = PyArray_CastDescrToDType(all_descriptors[0], common_dtype);
+        result = get_descr_from_cast_or_value(
+                    0, arrs, ndtypes, all_descriptors[0], common_dtype);
+        if (result == NULL) {
+            goto error;
+        }
 
         for (npy_intp i = 1; i < ndtypes+narrs; i++) {
-            PyArray_Descr *curr;
-            if (NPY_LIKELY(i < ndtypes ||
-                    !(PyArray_FLAGS(arrs[i-ndtypes]) & _NPY_ARRAY_WAS_PYSCALAR))) {
-                curr = PyArray_CastDescrToDType(all_descriptors[i], common_dtype);
-            }
-            else {
-                /*
-                 * Unlike `PyArray_CastToDTypeAndPromoteDescriptors` deal with
-                 * plain Python values "graciously". This recovers the original
-                 * value the long route, but it should almost never happen...
-                 */
-                PyObject *tmp = PyArray_GETITEM(
-                        arrs[i-ndtypes], PyArray_BYTES(arrs[i-ndtypes]));
-                if (tmp == NULL) {
-                    goto error;
-                }
-                curr = common_dtype->discover_descr_from_pyobject(common_dtype, tmp);
-                Py_DECREF(tmp);
-            }
+            PyArray_Descr *curr = get_descr_from_cast_or_value(
+                    i, arrs, ndtypes, all_descriptors[i], common_dtype);
             if (curr == NULL) {
                 goto error;
             }
index ff4663dc3e50f686ad24306330b0104bfb647178..d692aa7953e99bddcd7050a025123884e6dd3e49 100644 (file)
@@ -483,21 +483,40 @@ NPY_INPLACE @type@ npy_frexp@c@(@type@ x, int* exp)
  * #c = l,,f#
  * #C = L,,F#
  */
+
+/*
+ * On arm64 macOS, there's a bug with sin, cos, and tan where they don't
+ * raise "invalid" when given INFINITY as input.
+ */
+#if defined(__APPLE__) && defined(__arm64__)
+#define WORKAROUND_APPLE_TRIG_BUG 1
+#else
+#define WORKAROUND_APPLE_TRIG_BUG 0
+#endif
+
 /**begin repeat1
  * #kind = sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,rint,trunc,sqrt,log10,
  *         log,exp,expm1,asin,acos,atan,asinh,acosh,atanh,log1p,exp2,log2#
  * #KIND = SIN,COS,TAN,SINH,COSH,TANH,FABS,FLOOR,CEIL,RINT,TRUNC,SQRT,LOG10,
  *         LOG,EXP,EXPM1,ASIN,ACOS,ATAN,ASINH,ACOSH,ATANH,LOG1P,EXP2,LOG2#
+ * #TRIG_WORKAROUND = WORKAROUND_APPLE_TRIG_BUG*3, 0*22#
  */
 #ifdef HAVE_@KIND@@C@
 NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
 {
+#if @TRIG_WORKAROUND@
+    if (!npy_isfinite(x)) {
+        return (x - x);
+    }
+#endif
     return @kind@@c@(x);
 }
 #endif
 
 /**end repeat1**/
 
+#undef WORKAROUND_APPLE_TRIG_BUG
+
 /**begin repeat1
  * #kind = atan2,hypot,pow,copysign#
  * #KIND = ATAN2,HYPOT,POW,COPYSIGN#
index 3a1ea82f94609822d3fc383b0127a27c9271fca9..2d5917282c26b2e5d37d4e512487bbce2244853f 100644 (file)
@@ -77,6 +77,56 @@ NPY_FINLINE double c_square_f64(double a)
  */
 #define CONTIG  0
 #define NCONTIG 1
+
+/*
+ * clang has a bug that's present at -O1 or greater.  When partially loading a
+ * vector register for a reciprocal operation, the remaining elements are set
+ * to 1 to avoid divide-by-zero.  The partial load is paired with a partial
+ * store after the reciprocal operation.  clang notices that the entire register
+ * is not needed for the store and optimizes out the fill of 1 to the remaining
+ * elements.  This causes either a divide-by-zero or 0/0 with invalid exception
+ * that we were trying to avoid by filling.
+ *
+ * Using a dummy variable marked 'volatile' convinces clang not to ignore
+ * the explicit fill of remaining elements.  If `-ftrapping-math` is
+ * supported, then it'll also avoid the bug.  `-ftrapping-math` is supported
+ * on Apple clang v12+ for x86_64.  It is not currently supported for arm64.
+ * `-ftrapping-math` is set by default of Numpy builds in
+ * numpy/distutils/ccompiler.py.
+ *
+ * Note: Apple clang and clang upstream have different versions that overlap
+ */
+#if defined(__clang__)
+    #if defined(__apple_build_version__)
+    // Apple Clang
+        #if __apple_build_version__ < 12000000
+        // Apple Clang before v12
+        #define WORKAROUND_CLANG_RECIPROCAL_BUG 1
+        #elif defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64)
+        // Apple Clang after v12, targeting i386 or x86_64
+        #define WORKAROUND_CLANG_RECIPROCAL_BUG 0
+        #else
+        // Apple Clang after v12, not targeting i386 or x86_64
+        #define WORKAROUND_CLANG_RECIPROCAL_BUG 1
+        #endif
+    #else
+    // Clang, not Apple Clang
+        #if __clang_major__ < 10
+        // Clang before v10
+        #define WORKAROUND_CLANG_RECIPROCAL_BUG 1
+        #elif defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64)
+        // Clang v10+, targeting i386 or x86_64
+        #define WORKAROUND_CLANG_RECIPROCAL_BUG 0
+        #else
+        // Clang v10+, not targeting i386 or x86_64
+        #define WORKAROUND_CLANG_RECIPROCAL_BUG 1
+        #endif
+    #endif
+#else
+// Not a Clang compiler
+#define WORKAROUND_CLANG_RECIPROCAL_BUG 0
+#endif
+
 /**begin repeat
  * #TYPE = FLOAT, DOUBLE#
  * #sfx  = f32, f64#
@@ -87,6 +137,7 @@ NPY_FINLINE double c_square_f64(double a)
  * #kind     = sqrt, absolute, square, reciprocal#
  * #intr     = sqrt, abs,      square, recip#
  * #repl_0w1 = 0,    0,        0,      1#
+ * #RECIP_WORKAROUND = 0, 0,   0,      WORKAROUND_CLANG_RECIPROCAL_BUG#
  */
 /**begin repeat2
  * #STYPE  = CONTIG, NCONTIG, CONTIG,  NCONTIG#
@@ -101,6 +152,8 @@ static void simd_@TYPE@_@kind@_@STYPE@_@DTYPE@
 
     const int vstep = npyv_nlanes_@sfx@;
     const int wstep = vstep * @unroll@;
+
+    // unrolled iterations
     for (; len >= wstep; len -= wstep, src += ssrc*wstep, dst += sdst*wstep) {
         /**begin repeat3
          * #N  = 0, 1, 2, 3#
@@ -126,7 +179,24 @@ static void simd_@TYPE@_@kind@_@STYPE@_@DTYPE@
         #endif
         /**end repeat3**/
     }
-    for (; len > 0; len -= vstep, src += ssrc*vstep, dst += sdst*vstep) {
+
+    // vector-sized iterations
+    for (; len >= vstep; len -= vstep, src += ssrc*vstep, dst += sdst*vstep) {
+    #if @STYPE@ == CONTIG
+        npyv_@sfx@ v_src0 = npyv_load_@sfx@(src);
+    #else
+        npyv_@sfx@ v_src0 = npyv_loadn_@sfx@(src, ssrc);
+    #endif
+        npyv_@sfx@ v_unary0 = npyv_@intr@_@sfx@(v_src0);
+    #if @DTYPE@ == CONTIG
+        npyv_store_@sfx@(dst, v_unary0);
+    #else
+        npyv_storen_@sfx@(dst, sdst, v_unary0);
+    #endif
+    }
+
+    // last partial iteration, if needed
+    if(len > 0){
     #if @STYPE@ == CONTIG
         #if @repl_0w1@
             npyv_@sfx@ v_src0 = npyv_load_till_@sfx@(src, len, 1);
@@ -140,6 +210,15 @@ static void simd_@TYPE@_@kind@_@STYPE@_@DTYPE@
             npyv_@sfx@ v_src0 = npyv_loadn_tillz_@sfx@(src, ssrc, len);
         #endif
     #endif
+        #if @RECIP_WORKAROUND@
+            /*
+             * Workaround clang bug.  We use a dummy variable marked 'volatile'
+             * to convince clang that the entire vector is needed.  We only
+             * want to do this for the last iteration / partial load-store of
+             * the loop since 'volatile' forces a refresh of the contents.
+             */
+             volatile npyv_@sfx@ unused_but_workaround_bug = v_src0;
+        #endif // @RECIP_WORKAROUND@
         npyv_@sfx@ v_unary0 = npyv_@intr@_@sfx@(v_src0);
     #if @DTYPE@ == CONTIG
         npyv_store_till_@sfx@(dst, len, v_unary0);
@@ -147,6 +226,7 @@ static void simd_@TYPE@_@kind@_@STYPE@_@DTYPE@
         npyv_storen_till_@sfx@(dst, sdst, len, v_unary0);
     #endif
     }
+
     npyv_cleanup();
 }
 /**end repeat2**/
@@ -154,6 +234,8 @@ static void simd_@TYPE@_@kind@_@STYPE@_@DTYPE@
 #endif // @VCHK@
 /**end repeat**/
 
+#undef WORKAROUND_CLANG_RECIPROCAL_BUG
+
 /********************************************************************************
  ** Defining ufunc inner functions
  ********************************************************************************/
index 3d15009ea765b1d0388352fbd0bea3f43169d35e..1dcf1fb8ebd8f55d091c516039ed907b7efdd406 100644 (file)
@@ -1539,3 +1539,11 @@ class TestUserDType:
             # Tests that a dtype must have its type field set up to np.dtype
             # or in this case a builtin instance.
             create_custom_field_dtype(blueprint, mytype, 2)
+
+
+def test_result_type_integers_and_unitless_timedelta64():
+    # Regression test for gh-20077.  The following call of `result_type`
+    # would cause a seg. fault.
+    td = np.timedelta64(4)
+    result = np.result_type(0, td)
+    assert_dtype_equal(result, td.dtype)
index c623c809b02ed821c0f19925c558c66cc32d56bc..b9be1e39d3506231e2b9b2b2afc2516eb175565d 100644 (file)
@@ -109,8 +109,7 @@ pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, pcg128_t cur_mult,
     cur_plus = pcg128_mult(pcg128_add(cur_mult, PCG_128BIT_CONSTANT(0u, 1u)),
                             cur_plus);
     cur_mult = pcg128_mult(cur_mult, cur_mult);
-    delta.low >>= 1;
-    delta.low += delta.high & 1;
+    delta.low = (delta.low >> 1) | (delta.high << 63);
     delta.high >>= 1;
   }
   return pcg128_add(pcg128_mult(acc_mult, state), acc_plus);
index 29054b70b95a01227351dba02040aac7d82c2bb2..ea1ebacb63c836134bb751c5651ffc26c4b5b4f2 100644 (file)
@@ -358,6 +358,17 @@ class TestPCG64(Base):
         assert val_neg == val_pos
         assert val_big == val_pos
 
+    def test_advange_large(self):
+        rs = Generator(self.bit_generator(38219308213743))
+        pcg = rs.bit_generator
+        state = pcg.state["state"]
+        initial_state = 287608843259529770491897792873167516365
+        assert state["state"] == initial_state
+        pcg.advance(sum(2**i for i in (96, 64, 32, 16, 8, 4, 2, 1)))
+        state = pcg.state["state"]
+        advanced_state = 135275564607035429730177404003164635391
+        assert state["state"] == advanced_state
+
 
 class TestPCG64DXSM(Base):
     @classmethod
@@ -386,6 +397,17 @@ class TestPCG64DXSM(Base):
         assert val_neg == val_pos
         assert val_big == val_pos
 
+    def test_advange_large(self):
+        rs = Generator(self.bit_generator(38219308213743))
+        pcg = rs.bit_generator
+        state = pcg.state
+        initial_state = 287608843259529770491897792873167516365
+        assert state["state"]["state"] == initial_state
+        pcg.advance(sum(2**i for i in (96, 64, 32, 16, 8, 4, 2, 1)))
+        state = pcg.state["state"]
+        advanced_state = 277778083536782149546677086420637664879
+        assert state["state"] == advanced_state
+
 
 class TestMT19937(Base):
     @classmethod
index 8e758b26cb6fbd04ea8c89798297bac837fccbd2..0cf534bc01b6ccf59dd689ad3d97e5821c522671 100644 (file)
@@ -161,7 +161,8 @@ API
 # NOTE: The API section will be appended with additional entries
 # further down in this file
 
-from typing import TYPE_CHECKING, List, Any
+from numpy import ufunc
+from typing import TYPE_CHECKING, List
 
 if TYPE_CHECKING:
     import sys
@@ -364,14 +365,16 @@ if TYPE_CHECKING:
         _GUFunc_Nin2_Nout1,
     )
 else:
-    _UFunc_Nin1_Nout1 = Any
-    _UFunc_Nin2_Nout1 = Any
-    _UFunc_Nin1_Nout2 = Any
-    _UFunc_Nin2_Nout2 = Any
-    _GUFunc_Nin2_Nout1 = Any
+    # Declare the (type-check-only) ufunc subclasses as ufunc aliases during
+    # runtime; this helps autocompletion tools such as Jedi (numpy/numpy#19834)
+    _UFunc_Nin1_Nout1 = ufunc
+    _UFunc_Nin2_Nout1 = ufunc
+    _UFunc_Nin1_Nout2 = ufunc
+    _UFunc_Nin2_Nout2 = ufunc
+    _GUFunc_Nin2_Nout1 = ufunc
 
 # Clean up the namespace
-del TYPE_CHECKING, final, List, Any
+del TYPE_CHECKING, final, List, ufunc
 
 if __doc__ is not None:
     from ._add_docstring import _docstrings
index 4ee637b752fa61ed2b3dd5993cd819be6672578d..03f2faf4337e97b965879515ab50365f43674049 100644 (file)
@@ -1,12 +1,13 @@
 import numpy as np
+import numpy.typing as npt
 
-nd = np.array([[1, 2], [3, 4]])
+nd: npt.NDArray[np.int_] = np.array([[1, 2], [3, 4]])
 
 # item
-reveal_type(nd.item())  # E: Any
-reveal_type(nd.item(1))  # E: Any
-reveal_type(nd.item(0, 1))  # E: Any
-reveal_type(nd.item((0, 1)))  # E: Any
+reveal_type(nd.item())  # E: int
+reveal_type(nd.item(1))  # E: int
+reveal_type(nd.item(0, 1))  # E: int
+reveal_type(nd.item((0, 1)))  # E: int
 
 # tolist
 reveal_type(nd.tolist())  # E: Any
@@ -19,36 +20,32 @@ reveal_type(nd.tolist())  # E: Any
 # dumps is pretty simple
 
 # astype
-reveal_type(nd.astype("float"))  # E: numpy.ndarray
-reveal_type(nd.astype(float))  # E: numpy.ndarray
-reveal_type(nd.astype(float, "K"))  # E: numpy.ndarray
-reveal_type(nd.astype(float, "K", "unsafe"))  # E: numpy.ndarray
-reveal_type(nd.astype(float, "K", "unsafe", True))  # E: numpy.ndarray
-reveal_type(nd.astype(float, "K", "unsafe", True, True))  # E: numpy.ndarray
+reveal_type(nd.astype("float"))  # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.astype(float))  # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.astype(np.float64))  # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.astype(np.float64, "K"))  # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.astype(np.float64, "K", "unsafe"))  # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.astype(np.float64, "K", "unsafe", True))  # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.astype(np.float64, "K", "unsafe", True, True))  # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
 
 # byteswap
-reveal_type(nd.byteswap())  # E: numpy.ndarray
-reveal_type(nd.byteswap(True))  # E: numpy.ndarray
+reveal_type(nd.byteswap())  # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(nd.byteswap(True))  # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
 
 # copy
-reveal_type(nd.copy())  # E: numpy.ndarray
-reveal_type(nd.copy("C"))  # E: numpy.ndarray
+reveal_type(nd.copy())  # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(nd.copy("C"))  # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
 
-# view
-class SubArray(np.ndarray):
-    pass
-
-
-reveal_type(nd.view())  # E: numpy.ndarray
-reveal_type(nd.view(np.int64))  # E: numpy.ndarray
-# replace `Any` with `numpy.matrix` when `matrix` will be added to stubs
-reveal_type(nd.view(np.int64, np.matrix))  # E: Any
-reveal_type(nd.view(np.int64, SubArray))  # E: SubArray
+reveal_type(nd.view())  # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(nd.view(np.float64))  # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.view(float))  # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.view(np.float64, np.matrix))  # E: numpy.matrix[Any, Any]
 
 # getfield
-reveal_type(nd.getfield("float"))  # E: numpy.ndarray
-reveal_type(nd.getfield(float))  # E: numpy.ndarray
-reveal_type(nd.getfield(float, 8))  # E: numpy.ndarray
+reveal_type(nd.getfield("float"))  # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.getfield(float))  # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.getfield(np.float64))  # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.getfield(np.float64, 8))  # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
 
 # setflags does not return a value
 # fill does not return a value
index 8d1181f84607845c3c0ed0b3742315ea6d020b70..ac6d2560f5e213092f7639fd4761282a6aa989ba 100644 (file)
@@ -144,3 +144,15 @@ reveal_type(round(f8, 3))  # E: {float64}
 if sys.version_info >= (3, 9):
     reveal_type(f8.__ceil__())  # E: int
     reveal_type(f8.__floor__())  # E: int
+
+reveal_type(i8.astype(float))  # E: Any
+reveal_type(i8.astype(np.float64))  # E: {float64}
+
+reveal_type(i8.view())  # E: {int64}
+reveal_type(i8.view(np.float64))  # E: {float64}
+reveal_type(i8.view(float))  # E: Any
+reveal_type(i8.view(np.float64, np.ndarray))  # E: {float64}
+
+reveal_type(i8.getfield(float))  # E: Any
+reveal_type(i8.getfield(np.float64))  # E: {float64}
+reveal_type(i8.getfield(np.float64, 8))  # E: {float64}
index 572e9d8f6a24477091885f1b45f518f558ac1fa4..e33695d99d5ee6fdd842989d3f09792f70d0c4d8 100644 (file)
@@ -38,7 +38,7 @@ from paver.easy import Bunch, options, task, sh
 #-----------------------------------
 
 # Path to the release notes
-RELEASE_NOTES = 'doc/source/release/1.21.2-notes.rst'
+RELEASE_NOTES = 'doc/source/release/1.21.3-notes.rst'
 
 
 #-------------------------------------------------------