summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/dev/index.rst17
-rw-r--r--environment.yml2
-rw-r--r--numpy/__init__.py8
-rw-r--r--numpy/__init__.pyi87
-rw-r--r--numpy/core/_add_newdocs.py35
-rw-r--r--numpy/core/multiarray.py2
-rw-r--r--numpy/core/multiarray.pyi415
-rw-r--r--numpy/core/shape_base.pyi65
-rw-r--r--numpy/core/src/umath/reduction.c46
-rw-r--r--numpy/f2py/cfuncs.py153
-rwxr-xr-xnumpy/f2py/rules.py6
-rw-r--r--numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c2
-rw-r--r--numpy/f2py/tests/test_return_character.py4
-rw-r--r--numpy/f2py/tests/test_string.py146
-rw-r--r--numpy/lib/function_base.py7
-rw-r--r--numpy/lib/twodim_base.py37
-rw-r--r--numpy/lib/twodim_base.pyi265
-rw-r--r--numpy/typing/tests/data/fail/array_constructors.py4
-rw-r--r--numpy/typing/tests/data/fail/multiarray.py17
-rw-r--r--numpy/typing/tests/data/fail/twodim_base.py37
-rw-r--r--numpy/typing/tests/data/pass/lib_utils.py2
-rw-r--r--numpy/typing/tests/data/reveal/array_constructors.py69
-rw-r--r--numpy/typing/tests/data/reveal/arrayterator.py2
-rw-r--r--numpy/typing/tests/data/reveal/multiarray.py50
-rw-r--r--numpy/typing/tests/data/reveal/testing.py4
-rw-r--r--numpy/typing/tests/data/reveal/twodim_base.py72
-rw-r--r--test_requirements.txt4
27 files changed, 1131 insertions, 427 deletions
diff --git a/doc/source/dev/index.rst b/doc/source/dev/index.rst
index 8843d380a..aaf9fe4a0 100644
--- a/doc/source/dev/index.rst
+++ b/doc/source/dev/index.rst
@@ -4,23 +4,6 @@
Contributing to NumPy
#####################
-.. TODO: this is hidden because there's a bug in the pydata theme that won't render TOC items under headers
-
-.. toctree::
- :hidden:
-
- Git Basics <gitwash/index>
- development_environment
- development_gitpod
- development_workflow
- development_advanced_debugging
- ../benchmarking
- NumPy C style guide <https://numpy.org/neps/nep-0045-c_style_guide.html>
- releasing
- governance/index
- howto-docs
-
-
Not a coder? Not a problem! NumPy is multi-faceted, and we can use a lot of help.
These are all activities we'd like to get help with (they're all important, so
we list them in alphabetical order):
diff --git a/environment.yml b/environment.yml
index 5e1d4df23..22ce617af 100644
--- a/environment.yml
+++ b/environment.yml
@@ -21,7 +21,7 @@ dependencies:
- mypy=0.812
- typing_extensions
# For building docs
- - sphinx=3.5.4
+ - sphinx=4.0.1
- numpydoc=1.1.0
- ipython
- scipy
diff --git a/numpy/__init__.py b/numpy/__init__.py
index baff5e141..8546238ec 100644
--- a/numpy/__init__.py
+++ b/numpy/__init__.py
@@ -383,10 +383,10 @@ else:
error_message = "{}: {}".format(w[-1].category.__name__, str(w[-1].message))
msg = (
"Polyfit sanity test emitted a warning, most likely due "
- "to using a buggy Accelerate backend. If you compiled "
- "yourself, more information is available at "
- "https://numpy.org/doc/stable/user/building.html#accelerated-blas-lapack-libraries "
- "Otherwise report this to the vendor "
+ "to using a buggy Accelerate backend."
+ "\nIf you compiled yourself, more information is available at:"
+ "\nhttps://numpy.org/doc/stable/user/building.html#accelerated-blas-lapack-libraries"
+ "\nOtherwise report this to the vendor "
"that provided NumPy.\n{}\n".format(error_message))
raise RuntimeError(msg)
del _mac_os_check
diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi
index 85ab4e8d8..6e24f6bff 100644
--- a/numpy/__init__.pyi
+++ b/numpy/__init__.pyi
@@ -1,6 +1,8 @@
import builtins
import os
import sys
+import mmap
+import array as _array
import datetime as dt
from abc import abstractmethod
from types import TracebackType
@@ -324,6 +326,21 @@ from numpy.core.multiarray import (
asanyarray as asanyarray,
ascontiguousarray as ascontiguousarray,
asfortranarray as asfortranarray,
+ arange as arange,
+ busday_count as busday_count,
+ busday_offset as busday_offset,
+ compare_chararrays as compare_chararrays,
+ datetime_as_string as datetime_as_string,
+ datetime_data as datetime_data,
+ frombuffer as frombuffer,
+ fromfile as fromfile,
+ fromiter as fromiter,
+ is_busday as is_busday,
+ promote_types as promote_types,
+ seterrobj as seterrobj,
+ geterrobj as geterrobj,
+ fromstring as fromstring,
+ frompyfunc as frompyfunc,
)
from numpy.core.numeric import (
@@ -609,10 +626,6 @@ class MachAr:
) -> None: ...
def __getattr__(self, key: str) -> Any: ...
-class busdaycalendar:
- def __new__(cls, weekmask: Any = ..., holidays: Any = ...) -> Any: ...
- def __getattr__(self, key: str) -> Any: ...
-
class chararray(ndarray[_ShapeType, _DType_co]):
def __new__(
subtype,
@@ -876,46 +889,8 @@ def round(a, decimals=..., out=...): ...
def round_(a, decimals=..., out=...): ...
def show_config(): ...
-# Placeholders for C-based functions
# TODO: Sort out which parameters are positional-only
-@overload
-def arange(stop, dtype=..., *, like=...): ...
-@overload
-def arange(start, stop, step=..., dtype=..., *, like=...): ...
-def busday_count(
- begindates,
- enddates,
- weekmask=...,
- holidays=...,
- busdaycal=...,
- out=...,
-): ...
-def busday_offset(
- dates,
- offsets,
- roll=...,
- weekmask=...,
- holidays=...,
- busdaycal=...,
- out=...,
-): ...
-def compare_chararrays(a, b, cmp_op, rstrip): ...
-def datetime_as_string(arr, unit=..., timezone=..., casting=...): ...
-def datetime_data(__dtype): ...
-def frombuffer(buffer, dtype=..., count=..., offset=..., *, like=...): ...
-def fromfile(
- file, dtype=..., count=..., sep=..., offset=..., *, like=...
-): ...
-def fromiter(iter, dtype, count=..., *, like=...): ...
-def frompyfunc(func, nin, nout, * identity): ...
-def fromstring(string, dtype=..., count=..., sep=..., *, like=...): ...
-def geterrobj(): ...
-def is_busday(
- dates, weekmask=..., holidays=..., busdaycal=..., out=...
-): ...
-def nested_iters(*args, **kwargs): ... # TODO: Sort out parameters
-def promote_types(type1, type2): ...
-def seterrobj(errobj): ...
+def nested_iters(*args, **kwargs): ... # TODO: Sort out parameters
_NdArraySubClass = TypeVar("_NdArraySubClass", bound=ndarray)
_DTypeScalar_co = TypeVar("_DTypeScalar_co", covariant=True, bound=generic)
@@ -1626,7 +1601,18 @@ _DType_co = TypeVar("_DType_co", covariant=True, bound=dtype[Any])
# have proper shape support
_ShapeType = TypeVar("_ShapeType", bound=Any)
_NumberType = TypeVar("_NumberType", bound=number[Any])
-_BufferType = Union[ndarray, bytes, bytearray, memoryview]
+
+# There is currently no exhaustive way to type the buffer protocol,
+# as it is implemented exclusivelly in the C API (python/typing#593)
+_SupportsBuffer = Union[
+ bytes,
+ bytearray,
+ memoryview,
+ _array.array[Any],
+ mmap.mmap,
+ NDArray[Any],
+ generic,
+]
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
@@ -1668,7 +1654,7 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
cls: Type[_ArraySelf],
shape: _ShapeLike,
dtype: DTypeLike = ...,
- buffer: _BufferType = ...,
+ buffer: _SupportsBuffer = ...,
offset: int = ...,
strides: _ShapeLike = ...,
order: _OrderKACF = ...,
@@ -3736,3 +3722,14 @@ class broadcast:
def __next__(self) -> Tuple[Any, ...]: ...
def __iter__(self: _T) -> _T: ...
def reset(self) -> None: ...
+
+class busdaycalendar:
+ def __new__(
+ cls,
+ weekmask: ArrayLike = ...,
+ holidays: ArrayLike = ...,
+ ) -> busdaycalendar: ...
+ @property
+ def weekmask(self) -> NDArray[bool_]: ...
+ @property
+ def holidays(self) -> NDArray[datetime64]: ...
diff --git a/numpy/core/_add_newdocs.py b/numpy/core/_add_newdocs.py
index 448f6a0c0..a29e2e8a8 100644
--- a/numpy/core/_add_newdocs.py
+++ b/numpy/core/_add_newdocs.py
@@ -1280,7 +1280,7 @@ add_newdoc('numpy.core.multiarray', 'set_typeDict',
add_newdoc('numpy.core.multiarray', 'fromstring',
"""
- fromstring(string, dtype=float, count=-1, sep='', *, like=None)
+ fromstring(string, dtype=float, count=-1, *, sep, like=None)
A new 1-D array initialized from text data in a string.
@@ -1346,16 +1346,16 @@ add_newdoc('numpy.core.multiarray', 'fromstring',
add_newdoc('numpy.core.multiarray', 'compare_chararrays',
"""
- compare_chararrays(a, b, cmp_op, rstrip)
+ compare_chararrays(a1, a2, cmp, rstrip)
Performs element-wise comparison of two string arrays using the
comparison operator specified by `cmp_op`.
Parameters
----------
- a, b : array_like
+ a1, a2 : array_like
Arrays to be compared.
- cmp_op : {"<", "<=", "==", ">=", ">", "!="}
+ cmp : {"<", "<=", "==", ">=", ">", "!="}
Type of comparison.
rstrip : Boolean
If True, the spaces at the end of Strings are removed before the comparison.
@@ -1585,8 +1585,8 @@ add_newdoc('numpy.core.multiarray', 'arange',
For integer arguments the function is equivalent to the Python built-in
`range` function, but returns an ndarray rather than a list.
- When using a non-integer step, such as 0.1, the results will often not
- be consistent. It is better to use `numpy.linspace` for these cases.
+ When using a non-integer step, such as 0.1, it is often better to use
+ `numpy.linspace`. See the warnings section below for more information.
Parameters
----------
@@ -1619,6 +1619,25 @@ add_newdoc('numpy.core.multiarray', 'arange',
this rule may result in the last element of `out` being greater
than `stop`.
+ Warnings
+ --------
+ The length of the output might not be numerically stable.
+
+ Another stability issue is due to the internal implementation of
+ `numpy.arange`.
+ The actual step value used to populate the array is
+ ``dtype(start + step) - dtype(start)`` and not `step`. Precision loss
+ can occur here, due to casting or due to using floating points when
+ `start` is much larger than `step`. This can lead to unexpected
+ behaviour. For example::
+
+ >>> np.arange(0, 5, 0.5, dtype=int)
+ array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
+ >>> np.arange(-3, 3, 0.5, dtype=int)
+ array([-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8])
+
+ In such cases, the use of `numpy.linspace` should be preferred.
+
See Also
--------
numpy.linspace : Evenly spaced numbers with careful handling of endpoints.
@@ -4475,7 +4494,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('view',
add_newdoc('numpy.core.umath', 'frompyfunc',
"""
- frompyfunc(func, nin, nout, *[, identity])
+ frompyfunc(func, /, nin, nout, *[, identity])
Takes an arbitrary Python function and returns a NumPy ufunc.
@@ -4589,7 +4608,7 @@ add_newdoc('numpy.core.umath', 'geterrobj',
add_newdoc('numpy.core.umath', 'seterrobj',
"""
- seterrobj(errobj)
+ seterrobj(errobj, /)
Set the object that defines floating-point error handling.
diff --git a/numpy/core/multiarray.py b/numpy/core/multiarray.py
index 78aa7a65c..3205f4ecd 100644
--- a/numpy/core/multiarray.py
+++ b/numpy/core/multiarray.py
@@ -31,7 +31,7 @@ __all__ = [
'busday_count', 'busday_offset', 'busdaycalendar', 'can_cast',
'compare_chararrays', 'concatenate', 'copyto', 'correlate', 'correlate2',
'count_nonzero', 'c_einsum', 'datetime_as_string', 'datetime_data',
- 'digitize', 'dot', 'dragon4_positional', 'dragon4_scientific', 'dtype',
+ 'dot', 'dragon4_positional', 'dragon4_scientific', 'dtype',
'empty', 'empty_like', 'error', 'flagsobj', 'flatiter', 'format_longfloat',
'frombuffer', 'fromfile', 'fromiter', 'fromstring', 'inner',
'interp', 'interp_complex', 'is_busday', 'lexsort',
diff --git a/numpy/core/multiarray.pyi b/numpy/core/multiarray.pyi
index 30b3f416a..bc33165be 100644
--- a/numpy/core/multiarray.pyi
+++ b/numpy/core/multiarray.pyi
@@ -1,8 +1,13 @@
# TODO: Sort out any and all missing functions in this namespace
+import os
import sys
+import datetime as dt
from typing import (
Any,
+ Callable,
+ IO,
+ Iterable,
Optional,
overload,
TypeVar,
@@ -14,15 +19,24 @@ from typing import (
)
from numpy import (
+ # Re-exports
busdaycalendar as busdaycalendar,
- ndarray,
- dtype,
+ broadcast as broadcast,
+ dtype as dtype,
+ ndarray as ndarray,
+ nditer as nditer,
+
+ # The rest
+ nditer,
+ ufunc,
str_,
bool_,
uint8,
intp,
+ int_,
float64,
timedelta64,
+ datetime64,
generic,
unsignedinteger,
signedinteger,
@@ -32,6 +46,7 @@ from numpy import (
_OrderCF,
_CastingKind,
_ModeKind,
+ _SupportsBuffer,
)
from numpy.typing import (
@@ -53,8 +68,14 @@ from numpy.typing import (
_ArrayLikeFloat_co,
_ArrayLikeComplex_co,
_ArrayLikeTD64_co,
+ _ArrayLikeDT64_co,
_ArrayLikeObject_co,
+ _ArrayLikeStr_co,
+ _ArrayLikeBytes_co,
+ _ScalarLike_co,
_IntLike_co,
+ _FloatLike_co,
+ _TD64Like_co,
)
if sys.version_info >= (3, 8):
@@ -65,6 +86,7 @@ else:
_SCT = TypeVar("_SCT", bound=generic)
_ArrayType = TypeVar("_ArrayType", bound=NDArray[Any])
+# Subscriptable subsets of `npt.DTypeLike` and `npt.ArrayLike`
_DTypeLike = Union[
dtype[_SCT],
Type[_SCT],
@@ -72,6 +94,31 @@ _DTypeLike = Union[
]
_ArrayLike = _NestedSequence[_SupportsArray[dtype[_SCT]]]
+# Valid time units
+_UnitKind = L[
+ "Y",
+ "M",
+ "D",
+ "h",
+ "m",
+ "s",
+ "ms",
+ "us", "μs",
+ "ns",
+ "ps",
+ "fs",
+ "as",
+]
+_RollKind = L[ # `raise` is deliberately excluded
+ "nat",
+ "forward",
+ "following",
+ "backward",
+ "preceding",
+ "modifiedfollowing",
+ "modifiedpreceding",
+]
+
__all__: List[str]
ALLOW_THREADS: Final[int] # 0 or 1 (system-specific)
@@ -537,3 +584,367 @@ def asfortranarray(
*,
like: ArrayLike = ...,
) -> NDArray[Any]: ...
+
+# In practice `List[Any]` is list with an int, int and a valid
+# `np.seterrcall()` object
+def geterrobj() -> List[Any]: ...
+def seterrobj(__errobj: List[Any]) -> None: ...
+
+def promote_types(__type1: DTypeLike, __type2: DTypeLike) -> dtype[Any]: ...
+
+# `sep` is a de facto mandatory argument, as its default value is deprecated
+@overload
+def fromstring(
+ string: str | bytes,
+ dtype: None = ...,
+ count: SupportsIndex = ...,
+ *,
+ sep: str,
+ like: ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def fromstring(
+ string: str | bytes,
+ dtype: _DTypeLike[_SCT],
+ count: SupportsIndex = ...,
+ *,
+ sep: str,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def fromstring(
+ string: str | bytes,
+ dtype: DTypeLike,
+ count: SupportsIndex = ...,
+ *,
+ sep: str,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+def frompyfunc(
+ __func: Callable[..., Any],
+ nin: SupportsIndex,
+ nout: SupportsIndex,
+ *,
+ identity: Any = ...,
+) -> ufunc: ...
+
+@overload
+def fromfile(
+ file: str | bytes | os.PathLike[Any] | IO[Any],
+ dtype: None = ...,
+ count: SupportsIndex = ...,
+ sep: str = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def fromfile(
+ file: str | bytes | os.PathLike[Any] | IO[Any],
+ dtype: _DTypeLike[_SCT],
+ count: SupportsIndex = ...,
+ sep: str = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def fromfile(
+ file: str | bytes | os.PathLike[Any] | IO[Any],
+ dtype: DTypeLike,
+ count: SupportsIndex = ...,
+ sep: str = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def fromiter(
+ iter: Iterable[Any],
+ dtype: _DTypeLike[_SCT],
+ count: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def fromiter(
+ iter: Iterable[Any],
+ dtype: DTypeLike,
+ count: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def frombuffer(
+ buffer: _SupportsBuffer,
+ dtype: None = ...,
+ count: SupportsIndex = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def frombuffer(
+ buffer: _SupportsBuffer,
+ dtype: _DTypeLike[_SCT],
+ count: SupportsIndex = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def frombuffer(
+ buffer: _SupportsBuffer,
+ dtype: DTypeLike,
+ count: SupportsIndex = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def arange( # type: ignore[misc]
+ __stop: _IntLike_co,
+ *,
+ dtype: None = ...,
+ like: ArrayLike = ...,
+) -> NDArray[signedinteger[Any]]: ...
+@overload
+def arange( # type: ignore[misc]
+ start: _IntLike_co,
+ stop: _IntLike_co,
+ step: _IntLike_co = ...,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[signedinteger[Any]]: ...
+@overload
+def arange( # type: ignore[misc]
+ __stop: _FloatLike_co,
+ *,
+ dtype: None = ...,
+ like: ArrayLike = ...,
+) -> NDArray[floating[Any]]: ...
+@overload
+def arange( # type: ignore[misc]
+ start: _FloatLike_co,
+ stop: _FloatLike_co,
+ step: _FloatLike_co = ...,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[floating[Any]]: ...
+@overload
+def arange(
+ __stop: _TD64Like_co,
+ *,
+ dtype: None = ...,
+ like: ArrayLike = ...,
+) -> NDArray[timedelta64]: ...
+@overload
+def arange(
+ start: _TD64Like_co,
+ stop: _TD64Like_co,
+ step: _TD64Like_co = ...,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[timedelta64]: ...
+@overload
+def arange( # both start and stop must always be specified for datetime64
+ start: datetime64,
+ stop: datetime64,
+ step: datetime64 = ...,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[datetime64]: ...
+@overload
+def arange(
+ __stop: Any,
+ *,
+ dtype: _DTypeLike[_SCT],
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def arange(
+ start: Any,
+ stop: Any,
+ step: Any = ...,
+ dtype: _DTypeLike[_SCT] = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def arange(
+ __stop: Any,
+ *,
+ dtype: DTypeLike,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+@overload
+def arange(
+ start: Any,
+ stop: Any,
+ step: Any = ...,
+ dtype: DTypeLike = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+def datetime_data(
+ __dtype: str | _DTypeLike[datetime64] | _DTypeLike[timedelta64],
+) -> Tuple[str, int]: ...
+
+# The datetime functions perform unsafe casts to `datetime64[D]`,
+# so a lot of different argument types are allowed here
+
+@overload
+def busday_count( # type: ignore[misc]
+ begindates: _ScalarLike_co,
+ enddates: _ScalarLike_co,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> int_: ...
+@overload
+def busday_count( # type: ignore[misc]
+ begindates: ArrayLike,
+ enddates: ArrayLike,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> NDArray[int_]: ...
+@overload
+def busday_count(
+ begindates: ArrayLike,
+ enddates: ArrayLike,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: _ArrayType = ...,
+) -> _ArrayType: ...
+
+# `roll="raise"` is (more or less?) equivalent to `casting="safe"`
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: datetime64,
+ offsets: _TD64Like_co,
+ roll: L["raise"] = ...,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> datetime64: ...
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: _ArrayLike[datetime64],
+ offsets: _ArrayLikeTD64_co,
+ roll: L["raise"] = ...,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> NDArray[datetime64]: ...
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: _ArrayLike[datetime64],
+ offsets: _ArrayLike[timedelta64],
+ roll: L["raise"] = ...,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: _ArrayType = ...,
+) -> _ArrayType: ...
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: _ScalarLike_co,
+ offsets: _ScalarLike_co,
+ roll: _RollKind,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> datetime64: ...
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: ArrayLike,
+ offsets: ArrayLike,
+ roll: _RollKind,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> NDArray[datetime64]: ...
+@overload
+def busday_offset(
+ dates: ArrayLike,
+ offsets: ArrayLike,
+ roll: _RollKind,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: _ArrayType = ...,
+) -> _ArrayType: ...
+
+@overload
+def is_busday( # type: ignore[misc]
+ dates: _ScalarLike_co,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> bool_: ...
+@overload
+def is_busday( # type: ignore[misc]
+ dates: ArrayLike,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> NDArray[bool_]: ...
+@overload
+def is_busday(
+ dates: ArrayLike,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: _ArrayType = ...,
+) -> _ArrayType: ...
+
+@overload
+def datetime_as_string( # type: ignore[misc]
+ arr: datetime64,
+ unit: None | L["auto"] | _UnitKind = ...,
+ timezone: L["naive", "UTC", "local"] | dt.tzinfo = ...,
+ casting: _CastingKind = ...,
+) -> str_: ...
+@overload
+def datetime_as_string(
+ arr: _ArrayLikeDT64_co,
+ unit: None | L["auto"] | _UnitKind = ...,
+ timezone: L["naive", "UTC", "local"] | dt.tzinfo = ...,
+ casting: _CastingKind = ...,
+) -> NDArray[str_]: ...
+
+@overload
+def compare_chararrays(
+ a1: _ArrayLikeStr_co,
+ a2: _ArrayLikeStr_co,
+ cmp: L["<", "<=", "==", ">=", ">", "!="],
+ rstrip: bool,
+) -> NDArray[bool_]: ...
+@overload
+def compare_chararrays(
+ a1: _ArrayLikeBytes_co,
+ a2: _ArrayLikeBytes_co,
+ cmp: L["<", "<=", "==", ">=", ">", "!="],
+ rstrip: bool,
+) -> NDArray[bool_]: ...
+
+def add_docstring(__obj: Callable[..., Any], __docstring: str) -> None: ...
diff --git a/numpy/core/shape_base.pyi b/numpy/core/shape_base.pyi
index ec40a8814..9aaeceed7 100644
--- a/numpy/core/shape_base.pyi
+++ b/numpy/core/shape_base.pyi
@@ -1,39 +1,72 @@
import sys
-from typing import TypeVar, overload, List, Sequence
+from typing import TypeVar, overload, List, Sequence, Any
-from numpy import ndarray
-from numpy.typing import ArrayLike
+from numpy import generic, dtype
+from numpy.typing import ArrayLike, NDArray, _NestedSequence, _SupportsArray
if sys.version_info >= (3, 8):
from typing import SupportsIndex
else:
from typing_extensions import SupportsIndex
-_ArrayType = TypeVar("_ArrayType", bound=ndarray)
+_SCT = TypeVar("_SCT", bound=generic)
+_ArrayType = TypeVar("_ArrayType", bound=NDArray[Any])
+_ArrayLike = _NestedSequence[_SupportsArray[dtype[_SCT]]]
+
+__all__: List[str]
+
+@overload
+def atleast_1d(__arys: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def atleast_1d(__arys: ArrayLike) -> NDArray[Any]: ...
+@overload
+def atleast_1d(*arys: ArrayLike) -> List[NDArray[Any]]: ...
+
+@overload
+def atleast_2d(__arys: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def atleast_2d(__arys: ArrayLike) -> NDArray[Any]: ...
@overload
-def atleast_1d(__arys: ArrayLike) -> ndarray: ...
+def atleast_2d(*arys: ArrayLike) -> List[NDArray[Any]]: ...
+
+@overload
+def atleast_3d(__arys: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
@overload
-def atleast_1d(*arys: ArrayLike) -> List[ndarray]: ...
+def atleast_3d(__arys: ArrayLike) -> NDArray[Any]: ...
+@overload
+def atleast_3d(*arys: ArrayLike) -> List[NDArray[Any]]: ...
@overload
-def atleast_2d(__arys: ArrayLike) -> ndarray: ...
+def vstack(tup: Sequence[_ArrayLike[_SCT]]) -> NDArray[_SCT]: ...
@overload
-def atleast_2d(*arys: ArrayLike) -> List[ndarray]: ...
+def vstack(tup: Sequence[ArrayLike]) -> NDArray[Any]: ...
@overload
-def atleast_3d(__arys: ArrayLike) -> ndarray: ...
+def hstack(tup: Sequence[_ArrayLike[_SCT]]) -> NDArray[_SCT]: ...
@overload
-def atleast_3d(*arys: ArrayLike) -> List[ndarray]: ...
+def hstack(tup: Sequence[ArrayLike]) -> NDArray[Any]: ...
-def vstack(tup: Sequence[ArrayLike]) -> ndarray: ...
-def hstack(tup: Sequence[ArrayLike]) -> ndarray: ...
@overload
def stack(
- arrays: Sequence[ArrayLike], axis: SupportsIndex = ..., out: None = ...
-) -> ndarray: ...
+ arrays: Sequence[_ArrayLike[_SCT]],
+ axis: SupportsIndex = ...,
+ out: None = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def stack(
+ arrays: Sequence[ArrayLike],
+ axis: SupportsIndex = ...,
+ out: None = ...,
+) -> NDArray[Any]: ...
@overload
def stack(
- arrays: Sequence[ArrayLike], axis: SupportsIndex = ..., out: _ArrayType = ...
+ arrays: Sequence[ArrayLike],
+ axis: SupportsIndex = ...,
+ out: _ArrayType = ...,
) -> _ArrayType: ...
-def block(arrays: ArrayLike) -> ndarray: ...
+
+@overload
+def block(arrays: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def block(arrays: ArrayLike) -> NDArray[Any]: ...
diff --git a/numpy/core/src/umath/reduction.c b/numpy/core/src/umath/reduction.c
index f1423d8b9..86cc20eb1 100644
--- a/numpy/core/src/umath/reduction.c
+++ b/numpy/core/src/umath/reduction.c
@@ -166,7 +166,7 @@ PyArray_CopyInitialReduceValues(
* identity : If Py_None, PyArray_CopyInitialReduceValues is used, otherwise
* this value is used to initialize the result to
* the reduction's unit.
- * loop : The loop which does the reduction.
+ * loop : `reduce_loop` from `ufunc_object.c`. TODO: Refactor
* data : Data which is passed to the inner loop.
* buffersize : Buffer size for the iterator. For the default, pass in 0.
* funcname : The name of the reduction function, for error messages.
@@ -182,18 +182,15 @@ PyArray_CopyInitialReduceValues(
* generalized ufuncs!)
*/
NPY_NO_EXPORT PyArrayObject *
-PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
- PyArrayObject *wheremask,
- PyArray_Descr *operand_dtype,
- PyArray_Descr *result_dtype,
- NPY_CASTING casting,
- npy_bool *axis_flags, int reorderable,
- int keepdims,
- PyObject *identity,
- PyArray_ReduceLoopFunc *loop,
- void *data, npy_intp buffersize, const char *funcname,
- int errormask)
+PyUFunc_ReduceWrapper(
+ PyArrayObject *operand, PyArrayObject *out, PyArrayObject *wheremask,
+ PyArray_Descr *operand_dtype, PyArray_Descr *result_dtype,
+ NPY_CASTING casting,
+ npy_bool *axis_flags, int reorderable, int keepdims,
+ PyObject *identity, PyArray_ReduceLoopFunc *loop,
+ void *data, npy_intp buffersize, const char *funcname, int errormask)
{
+ assert(loop != NULL);
PyArrayObject *result = NULL;
npy_intp skip_first_count = 0;
@@ -201,7 +198,7 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
NpyIter *iter = NULL;
PyArrayObject *op[3];
PyArray_Descr *op_dtypes[3];
- npy_uint32 flags, op_flags[3];
+ npy_uint32 it_flags, op_flags[3];
/* More than one axis means multiple orders are possible */
if (!reorderable && count_axes(PyArray_NDIM(operand), axis_flags) > 1) {
@@ -227,7 +224,7 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
op_dtypes[0] = result_dtype;
op_dtypes[1] = operand_dtype;
- flags = NPY_ITER_BUFFERED |
+ it_flags = NPY_ITER_BUFFERED |
NPY_ITER_EXTERNAL_LOOP |
NPY_ITER_GROWINNER |
NPY_ITER_DONT_NEGATE_STRIDES |
@@ -293,7 +290,7 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
}
}
- iter = NpyIter_AdvancedNew(wheremask == NULL ? 2 : 3, op, flags,
+ iter = NpyIter_AdvancedNew(wheremask == NULL ? 2 : 3, op, it_flags,
NPY_KEEPORDER, casting,
op_flags,
op_dtypes,
@@ -304,11 +301,14 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
result = NpyIter_GetOperandArray(iter)[0];
+ int needs_api = NpyIter_IterationNeedsAPI(iter);
+ /* Start with the floating-point exception flags cleared */
+ npy_clear_floatstatus_barrier((char*)&iter);
+
/*
* Initialize the result to the reduction unit if possible,
* otherwise copy the initial values and get a view to the rest.
*/
-
if (identity != Py_None) {
if (PyArray_FillWithScalar(result, identity) < 0) {
goto fail;
@@ -331,15 +331,11 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
goto fail;
}
- /* Start with the floating-point exception flags cleared */
- npy_clear_floatstatus_barrier((char*)&iter);
-
if (NpyIter_GetIterSize(iter) != 0) {
NpyIter_IterNextFunc *iternext;
char **dataptr;
npy_intp *strideptr;
npy_intp *countptr;
- int needs_api;
iternext = NpyIter_GetIterNext(iter, NULL);
if (iternext == NULL) {
@@ -349,16 +345,6 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
strideptr = NpyIter_GetInnerStrideArray(iter);
countptr = NpyIter_GetInnerLoopSizePtr(iter);
- needs_api = NpyIter_IterationNeedsAPI(iter);
-
- /* Straightforward reduction */
- if (loop == NULL) {
- PyErr_Format(PyExc_RuntimeError,
- "reduction operation %s did not supply an "
- "inner loop function", funcname);
- goto fail;
- }
-
if (loop(iter, dataptr, strideptr, countptr,
iternext, needs_api, skip_first_count, data) < 0) {
goto fail;
diff --git a/numpy/f2py/cfuncs.py b/numpy/f2py/cfuncs.py
index 60685be8a..f403a66b5 100644
--- a/numpy/f2py/cfuncs.py
+++ b/numpy/f2py/cfuncs.py
@@ -469,7 +469,7 @@ cppmacros['MEMCOPY'] = """\
"""
cppmacros['STRINGMALLOC'] = """\
#define STRINGMALLOC(str,len)\\
- if ((str = (string)malloc(len+1)) == NULL) {\\
+ if ((str = (string)malloc(sizeof(char)*(len+1))) == NULL) {\\
PyErr_SetString(PyExc_MemoryError, \"out of memory\");\\
goto capi_fail;\\
} else {\\
@@ -481,18 +481,18 @@ cppmacros['STRINGFREE'] = """\
"""
needs['STRINGCOPYN'] = ['string.h', 'FAILNULL']
cppmacros['STRINGCOPYN'] = """\
-/*
-STRINGCOPYN copies N bytes.
-
-`to` and `from` buffers must have sizes of at least N bytes.
-*/
-#define STRINGCOPYN(to,from,N) \\
+#define STRINGCOPYN(to,from,buf_size) \\
do { \\
- int _m = (N); \\
+ int _m = (buf_size); \\
char *_to = (to); \\
char *_from = (from); \\
FAILNULL(_to); FAILNULL(_from); \\
- (void)strncpy(_to, _from, _m); \\
+ (void)strncpy(_to, _from, sizeof(char)*_m); \\
+ _to[_m-1] = '\\0'; \\
+ /* Padding with spaces instead of nulls */ \\
+ for (_m -= 2; _m >= 0 && _to[_m] == '\\0'; _m--) { \\
+ _to[_m] = ' '; \\
+ } \\
} while (0)
"""
needs['STRINGCOPY'] = ['string.h', 'FAILNULL']
@@ -623,121 +623,71 @@ static int *nextforcomb(void) {
}"""
needs['try_pyarr_from_string'] = ['STRINGCOPYN', 'PRINTPYOBJERR', 'string']
cfuncs['try_pyarr_from_string'] = """\
-/*
- try_pyarr_from_string copies str[:len(obj)] to the data of an `ndarray`.
-
- If obj is an `ndarray`, it is assumed to be contiguous.
-
- If the specified len==-1, str must be null-terminated.
-*/
-static int try_pyarr_from_string(PyObject *obj,
- const string str, const int len) {
-#ifdef DEBUGCFUNCS
-fprintf(stderr, "try_pyarr_from_string(str='%s', len=%d, obj=%p)\\n",
- (char*)str,len, obj);
-#endif
- if (PyArray_Check(obj)) {
- PyArrayObject *arr = (PyArrayObject *)obj;
- assert(ISCONTIGUOUS(arr));
- string buf = PyArray_DATA(arr);
- npy_intp n = len;
- if (n == -1) {
- /* Assuming null-terminated str. */
- n = strlen(str);
- }
- if (n > PyArray_NBYTES(arr)) {
- n = PyArray_NBYTES(arr);
- }
- STRINGCOPYN(buf, str, n);
- return 1;
- }
+static int try_pyarr_from_string(PyObject *obj,const string str) {
+ PyArrayObject *arr = NULL;
+ if (PyArray_Check(obj) && (!((arr = (PyArrayObject *)obj) == NULL)))
+ { STRINGCOPYN(PyArray_DATA(arr),str,PyArray_NBYTES(arr)); }
+ return 1;
capi_fail:
PRINTPYOBJERR(obj);
- PyErr_SetString(#modulename#_error, \"try_pyarr_from_string failed\");
+ PyErr_SetString(#modulename#_error,\"try_pyarr_from_string failed\");
return 0;
}
"""
needs['string_from_pyobj'] = ['string', 'STRINGMALLOC', 'STRINGCOPYN']
cfuncs['string_from_pyobj'] = """\
-/*
- Create a new string buffer `str` of at most length `len` from a
- Python string-like object `obj`.
-
- The string buffer has given size (len) or the size of inistr when len==-1.
-
- The string buffer is null-terminated.
- */
static int
-string_from_pyobj(string *str, int *len, const string inistr, PyObject *obj,
- const char *errmess)
+string_from_pyobj(string *str,int *len,const string inistr,PyObject *obj,const char *errmess)
{
+ PyArrayObject *arr = NULL;
PyObject *tmp = NULL;
- string buf = NULL;
- npy_intp n = -1;
#ifdef DEBUGCFUNCS
-fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",
- (char*)str, *len, (char *)inistr, obj);
+fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",(char*)str,*len,(char *)inistr,obj);
#endif
if (obj == Py_None) {
- n = strlen(inistr);
- buf = inistr;
+ if (*len == -1)
+ *len = strlen(inistr); /* Will this cause problems? */
+ STRINGMALLOC(*str,*len);
+ STRINGCOPYN(*str,inistr,*len+1);
+ return 1;
}
- else if (PyArray_Check(obj)) {
- PyArrayObject *arr = (PyArrayObject *)obj;
+ if (PyArray_Check(obj)) {
+ if ((arr = (PyArrayObject *)obj) == NULL)
+ goto capi_fail;
if (!ISCONTIGUOUS(arr)) {
- PyErr_SetString(PyExc_ValueError,
- \"array object is non-contiguous.\");
+ PyErr_SetString(PyExc_ValueError,\"array object is non-contiguous.\");
goto capi_fail;
}
- n = PyArray_NBYTES(arr);
- buf = PyArray_DATA(arr);
+ if (*len == -1)
+ *len = (PyArray_ITEMSIZE(arr))*PyArray_SIZE(arr);
+ STRINGMALLOC(*str,*len);
+ STRINGCOPYN(*str,PyArray_DATA(arr),*len+1);
+ return 1;
+ }
+ if (PyBytes_Check(obj)) {
+ tmp = obj;
+ Py_INCREF(tmp);
+ }
+ else if (PyUnicode_Check(obj)) {
+ tmp = PyUnicode_AsASCIIString(obj);
}
else {
- if (PyBytes_Check(obj)) {
- tmp = obj;
- Py_INCREF(tmp);
- }
- else if (PyUnicode_Check(obj)) {
- tmp = PyUnicode_AsASCIIString(obj);
+ PyObject *tmp2;
+ tmp2 = PyObject_Str(obj);
+ if (tmp2) {
+ tmp = PyUnicode_AsASCIIString(tmp2);
+ Py_DECREF(tmp2);
}
else {
- PyObject *tmp2;
- tmp2 = PyObject_Str(obj);
- if (tmp2) {
- tmp = PyUnicode_AsASCIIString(tmp2);
- Py_DECREF(tmp2);
- }
- else {
- tmp = NULL;
- }
+ tmp = NULL;
}
- if (tmp == NULL) goto capi_fail;
- n = PyBytes_GET_SIZE(tmp);
- buf = PyBytes_AS_STRING(tmp);
}
- if (*len == -1) {
- /* TODO: change the type of `len` so that we can remove this */
- if (n > NPY_MAX_INT) {
- PyErr_SetString(PyExc_OverflowError,
- "object too large for a 32-bit int");
- goto capi_fail;
- }
- *len = n;
- }
- else if (*len < n) {
- /* discard the last (len-n) bytes of input buf */
- n = *len;
- }
- if (n < 0 || *len < 0 || buf == NULL) {
- goto capi_fail;
- }
- STRINGMALLOC(*str, *len); // *str is allocated with size (*len + 1)
- if (n < *len) {
- /* Pad fixed-width string with nulls */
- memset(*str + n, '\\0', *len - n);
- }
- STRINGCOPYN(*str, buf, n);
- Py_XDECREF(tmp);
+ if (tmp == NULL) goto capi_fail;
+ if (*len == -1)
+ *len = PyBytes_GET_SIZE(tmp);
+ STRINGMALLOC(*str,*len);
+ STRINGCOPYN(*str,PyBytes_AS_STRING(tmp),*len+1);
+ Py_DECREF(tmp);
return 1;
capi_fail:
Py_XDECREF(tmp);
@@ -752,6 +702,7 @@ capi_fail:
}
"""
+
needs['char_from_pyobj'] = ['int_from_pyobj']
cfuncs['char_from_pyobj'] = """\
static int
diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py
index f01b2bcfa..63e47baa2 100755
--- a/numpy/f2py/rules.py
+++ b/numpy/f2py/rules.py
@@ -561,8 +561,7 @@ rout_rules = [
'\tint #name#_return_value_len = 0;'],
'callfortran':'#name#_return_value,#name#_return_value_len,',
'callfortranroutine':['\t#name#_return_value_len = #rlength#;',
- '\tif ((#name#_return_value = (string)malloc('
- '#name#_return_value_len+1) == NULL) {',
+ '\tif ((#name#_return_value = (string)malloc(sizeof(char)*(#name#_return_value_len+1))) == NULL) {',
'\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");',
'\t\tf2py_success = 0;',
'\t} else {',
@@ -964,8 +963,7 @@ if (#varname#_cb.capi==Py_None) {
'args_capi': {isrequired: ',&#varname#_capi'},
'keys_capi': {isoptional: ',&#varname#_capi'},
'pyobjfrom': {isintent_inout: '''\
-\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi, #varname#,
-\t slen(#varname#));
+\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,#varname#);
\tif (f2py_success) {'''},
'closepyobjfrom': {isintent_inout: '\t} /*if (f2py_success) of #varname# pyobjfrom*/'},
'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
diff --git a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
index fe21d4b9b..0411b62e0 100644
--- a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
+++ b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
@@ -93,7 +93,7 @@ static PyObject *f2py_rout_wrap_attrs(PyObject *capi_self,
PyObject *strides = NULL;
char s[100];
int i;
- memset(s,0,100);
+ memset(s,0,100*sizeof(char));
if (!PyArg_ParseTuple(capi_args,"O!|:wrap.attrs",
&PyArray_Type,&arr_capi))
return NULL;
diff --git a/numpy/f2py/tests/test_return_character.py b/numpy/f2py/tests/test_return_character.py
index dc524e60c..429e69bb4 100644
--- a/numpy/f2py/tests/test_return_character.py
+++ b/numpy/f2py/tests/test_return_character.py
@@ -24,8 +24,8 @@ class TestReturnCharacter(util.F2PyTest):
assert_(t(23) == b'23 ', repr(t(23)))
assert_(t('123456789abcdef') == b'123456789a')
elif tname in ['t5', 's5']:
- assert_(t(23) == b'23', repr(t(23)))
- assert_(t('ab') == b'ab', repr(t('ab')))
+ assert_(t(23) == b'23 ', repr(t(23)))
+ assert_(t('ab') == b'ab ', repr(t('ab')))
assert_(t('123456789abcdef') == b'12345')
else:
raise NotImplementedError
diff --git a/numpy/f2py/tests/test_string.py b/numpy/f2py/tests/test_string.py
index 1530c58f6..e3ec96af9 100644
--- a/numpy/f2py/tests/test_string.py
+++ b/numpy/f2py/tests/test_string.py
@@ -1,6 +1,6 @@
import os
import pytest
-import textwrap
+
from numpy.testing import assert_array_equal
import numpy as np
from . import util
@@ -9,156 +9,14 @@ from . import util
def _path(*a):
return os.path.join(*((os.path.dirname(__file__),) + a))
-
class TestString(util.F2PyTest):
sources = [_path('src', 'string', 'char.f90')]
@pytest.mark.slow
def test_char(self):
strings = np.array(['ab', 'cd', 'ef'], dtype='c').T
- inp, out = self.module.char_test.change_strings(strings,
- strings.shape[1])
+ inp, out = self.module.char_test.change_strings(strings, strings.shape[1])
assert_array_equal(inp, strings)
expected = strings.copy()
expected[1, :] = 'AAA'
assert_array_equal(out, expected)
-
-
-class TestDocStringArguments(util.F2PyTest):
- suffix = '.f'
-
- code = """
-C FILE: STRING.F
- SUBROUTINE FOO(A,B,C,D)
- CHARACTER*5 A, B
- CHARACTER*(*) C,D
-Cf2py intent(in) a,c
-Cf2py intent(inout) b,d
- PRINT*, "A=",A
- PRINT*, "B=",B
- PRINT*, "C=",C
- PRINT*, "D=",D
- PRINT*, "CHANGE A,B,C,D"
- A(1:1) = 'A'
- B(1:1) = 'B'
- C(1:1) = 'C'
- D(1:1) = 'D'
- PRINT*, "A=",A
- PRINT*, "B=",B
- PRINT*, "C=",C
- PRINT*, "D=",D
- END
-C END OF FILE STRING.F
- """
-
- def test_example(self):
- a = np.array(b'123\0\0')
- b = np.array(b'123\0\0')
- c = np.array(b'123')
- d = np.array(b'123')
-
- self.module.foo(a, b, c, d)
-
- assert a.tobytes() == b'123\0\0'
- assert b.tobytes() == b'B23\0\0', (b.tobytes(),)
- assert c.tobytes() == b'123'
- assert d.tobytes() == b'D23'
-
-
-class TestFixedString(util.F2PyTest):
- suffix = '.f90'
-
- code = textwrap.dedent("""
- function sint(s) result(i)
- implicit none
- character(len=*) :: s
- integer :: j, i
- i = 0
- do j=1, len(s)
- i = i + ichar(s(j:j)) * 10 ** (j - 1)
- end do
- return
- end function sint
-
- function test_in_bytes4(a) result (i)
- implicit none
- integer :: sint
- character(len=4) :: a
- integer :: i
- i = sint(a)
- a(1:1) = 'A'
- return
- end function test_in_bytes4
-
- function test_inout_bytes4(a) result (i)
- implicit none
- integer :: sint
- character(len=4), intent(inout) :: a
- integer :: i
- if (ichar(a(1:1)).ne.0) then
- a(1:1) = 'E'
- endif
- i = sint(a)
- return
- end function test_inout_bytes4
- """)
-
- @staticmethod
- def _sint(s, start=0, end=None):
- """Return the content of a string buffer as integer value.
-
- For example:
- _sint('1234') -> 4321
- _sint('123A') -> 17321
- """
- if isinstance(s, np.ndarray):
- s = s.tobytes()
- elif isinstance(s, str):
- s = s.encode()
- assert isinstance(s, bytes)
- if end is None:
- end = len(s)
- i = 0
- for j in range(start, min(end, len(s))):
- i += s[j] * 10 ** j
- return i
-
- def _get_input(self, intent='in'):
- if intent in ['in']:
- yield ''
- yield '1'
- yield '1234'
- yield '12345'
- yield b''
- yield b'\0'
- yield b'1'
- yield b'\01'
- yield b'1\0'
- yield b'1234'
- yield b'12345'
- yield np.ndarray((), np.bytes_, buffer=b'') # array(b'', dtype='|S0')
- yield np.array(b'') # array(b'', dtype='|S1')
- yield np.array(b'\0')
- yield np.array(b'1')
- yield np.array(b'1\0')
- yield np.array(b'\01')
- yield np.array(b'1234')
- yield np.array(b'123\0')
- yield np.array(b'12345')
-
- def test_intent_in(self):
- for s in self._get_input():
- r = self.module.test_in_bytes4(s)
- # also checks that s is not changed inplace
- expected = self._sint(s, end=4)
- assert r == expected, (s)
-
- def test_intent_inout(self):
- for s in self._get_input(intent='inout'):
- rest = self._sint(s, start=4)
- r = self.module.test_inout_bytes4(s)
- expected = self._sint(s, end=4)
- assert r == expected
-
- # check that the rest of input string is preserved
- assert rest == self._sint(s, start=4)
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 783d45c2f..2e9ae6644 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -88,8 +88,11 @@ def rot90(m, k=1, axes=(0, 1)):
Notes
-----
- rot90(m, k=1, axes=(1,0)) is the reverse of rot90(m, k=1, axes=(0,1))
- rot90(m, k=1, axes=(1,0)) is equivalent to rot90(m, k=-1, axes=(0,1))
+ ``rot90(m, k=1, axes=(1,0))`` is the reverse of
+ ``rot90(m, k=1, axes=(0,1))``
+
+ ``rot90(m, k=1, axes=(1,0))`` is equivalent to
+ ``rot90(m, k=-1, axes=(0,1))``
Examples
--------
diff --git a/numpy/lib/twodim_base.py b/numpy/lib/twodim_base.py
index ac5fe1c6b..83c028061 100644
--- a/numpy/lib/twodim_base.py
+++ b/numpy/lib/twodim_base.py
@@ -439,10 +439,12 @@ def tril(m, k=0):
Lower triangle of an array.
Return a copy of an array with elements above the `k`-th diagonal zeroed.
+ For arrays with ``ndim`` exceeding 2, `tril` will apply to the final two
+ axes.
Parameters
----------
- m : array_like, shape (M, N)
+ m : array_like, shape (..., M, N)
Input array.
k : int, optional
Diagonal above which to zero elements. `k = 0` (the default) is the
@@ -450,7 +452,7 @@ def tril(m, k=0):
Returns
-------
- tril : ndarray, shape (M, N)
+ tril : ndarray, shape (..., M, N)
Lower triangle of `m`, of same shape and data-type as `m`.
See Also
@@ -465,6 +467,20 @@ def tril(m, k=0):
[ 7, 8, 0],
[10, 11, 12]])
+ >>> np.tril(np.arange(3*4*5).reshape(3, 4, 5))
+ array([[[ 0, 0, 0, 0, 0],
+ [ 5, 6, 0, 0, 0],
+ [10, 11, 12, 0, 0],
+ [15, 16, 17, 18, 0]],
+ [[20, 0, 0, 0, 0],
+ [25, 26, 0, 0, 0],
+ [30, 31, 32, 0, 0],
+ [35, 36, 37, 38, 0]],
+ [[40, 0, 0, 0, 0],
+ [45, 46, 0, 0, 0],
+ [50, 51, 52, 0, 0],
+ [55, 56, 57, 58, 0]]])
+
"""
m = asanyarray(m)
mask = tri(*m.shape[-2:], k=k, dtype=bool)
@@ -478,7 +494,8 @@ def triu(m, k=0):
Upper triangle of an array.
Return a copy of an array with the elements below the `k`-th diagonal
- zeroed.
+ zeroed. For arrays with ``ndim`` exceeding 2, `triu` will apply to the final
+ two axes.
Please refer to the documentation for `tril` for further details.
@@ -494,6 +511,20 @@ def triu(m, k=0):
[ 0, 8, 9],
[ 0, 0, 12]])
+ >>> np.triu(np.arange(3*4*5).reshape(3, 4, 5))
+ array([[[ 0, 1, 2, 3, 4],
+ [ 0, 6, 7, 8, 9],
+ [ 0, 0, 12, 13, 14],
+ [ 0, 0, 0, 18, 19]],
+ [[20, 21, 22, 23, 24],
+ [ 0, 26, 27, 28, 29],
+ [ 0, 0, 32, 33, 34],
+ [ 0, 0, 0, 38, 39]],
+ [[40, 41, 42, 43, 44],
+ [ 0, 46, 47, 48, 49],
+ [ 0, 0, 52, 53, 54],
+ [ 0, 0, 0, 58, 59]]])
+
"""
m = asanyarray(m)
mask = tri(*m.shape[-2:], k=k-1, dtype=bool)
diff --git a/numpy/lib/twodim_base.pyi b/numpy/lib/twodim_base.pyi
index 79b9511b8..007338d77 100644
--- a/numpy/lib/twodim_base.pyi
+++ b/numpy/lib/twodim_base.pyi
@@ -1,32 +1,255 @@
-from typing import List, Optional, Any
+from typing import (
+ Any,
+ Callable,
+ List,
+ Sequence,
+ overload,
+ Tuple,
+ Type,
+ TypeVar,
+ Union,
+)
-from numpy import ndarray, _OrderCF
-from numpy.typing import ArrayLike, DTypeLike
+from numpy import (
+ ndarray,
+ dtype,
+ generic,
+ number,
+ bool_,
+ timedelta64,
+ datetime64,
+ int_,
+ intp,
+ float64,
+ signedinteger,
+ floating,
+ complexfloating,
+ object_,
+ _OrderCF,
+)
+
+from numpy.typing import (
+ DTypeLike,
+ _SupportsDType,
+ ArrayLike,
+ NDArray,
+ _NestedSequence,
+ _SupportsArray,
+ _ArrayLikeInt_co,
+ _ArrayLikeFloat_co,
+ _ArrayLikeComplex_co,
+ _ArrayLikeObject_co,
+)
+
+_T = TypeVar("_T")
+_SCT = TypeVar("_SCT", bound=generic)
+
+# The returned arrays dtype must be compatible with `np.equal`
+_MaskFunc = Callable[
+ [NDArray[int_], _T],
+ NDArray[Union[number[Any], bool_, timedelta64, datetime64, object_]],
+]
+
+_DTypeLike = Union[
+ Type[_SCT],
+ dtype[_SCT],
+ _SupportsDType[dtype[_SCT]],
+]
+_ArrayLike = _NestedSequence[_SupportsArray[dtype[_SCT]]]
__all__: List[str]
-def fliplr(m): ...
-def flipud(m): ...
+@overload
+def fliplr(m: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def fliplr(m: ArrayLike) -> NDArray[Any]: ...
+
+@overload
+def flipud(m: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def flipud(m: ArrayLike) -> NDArray[Any]: ...
+@overload
def eye(
N: int,
- M: Optional[int] = ...,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: None = ...,
+ order: _OrderCF = ...,
+ *,
+ like: None | ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def eye(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: _DTypeLike[_SCT] = ...,
+ order: _OrderCF = ...,
+ *,
+ like: None | ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def eye(
+ N: int,
+ M: None | int = ...,
k: int = ...,
dtype: DTypeLike = ...,
order: _OrderCF = ...,
*,
- like: Optional[ArrayLike] = ...
-) -> ndarray[Any, Any]: ...
-
-def diag(v, k=...): ...
-def diagflat(v, k=...): ...
-def tri(N, M=..., k=..., dtype = ..., *, like=...): ...
-def tril(m, k=...): ...
-def triu(m, k=...): ...
-def vander(x, N=..., increasing=...): ...
-def histogram2d(x, y, bins=..., range=..., normed=..., weights=..., density=...): ...
-def mask_indices(n, mask_func, k=...): ...
-def tril_indices(n, k=..., m=...): ...
-def tril_indices_from(arr, k=...): ...
-def triu_indices(n, k=..., m=...): ...
-def triu_indices_from(arr, k=...): ...
+ like: None | ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def diag(v: _ArrayLike[_SCT], k: int = ...) -> NDArray[_SCT]: ...
+@overload
+def diag(v: ArrayLike, k: int = ...) -> NDArray[Any]: ...
+
+@overload
+def diagflat(v: _ArrayLike[_SCT], k: int = ...) -> NDArray[_SCT]: ...
+@overload
+def diagflat(v: ArrayLike, k: int = ...) -> NDArray[Any]: ...
+
+@overload
+def tri(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: None = ...,
+ *,
+ like: None | ArrayLike = ...
+) -> NDArray[float64]: ...
+@overload
+def tri(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: _DTypeLike[_SCT] = ...,
+ *,
+ like: None | ArrayLike = ...
+) -> NDArray[_SCT]: ...
+@overload
+def tri(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: DTypeLike = ...,
+ *,
+ like: None | ArrayLike = ...
+) -> NDArray[Any]: ...
+
+@overload
+def tril(v: _ArrayLike[_SCT], k: int = ...) -> NDArray[_SCT]: ...
+@overload
+def tril(v: ArrayLike, k: int = ...) -> NDArray[Any]: ...
+
+@overload
+def triu(v: _ArrayLike[_SCT], k: int = ...) -> NDArray[_SCT]: ...
+@overload
+def triu(v: ArrayLike, k: int = ...) -> NDArray[Any]: ...
+
+@overload
+def vander( # type: ignore[misc]
+ x: _ArrayLikeInt_co,
+ N: None | int = ...,
+ increasing: bool = ...,
+) -> NDArray[signedinteger[Any]]: ...
+@overload
+def vander( # type: ignore[misc]
+ x: _ArrayLikeFloat_co,
+ N: None | int = ...,
+ increasing: bool = ...,
+) -> NDArray[floating[Any]]: ...
+@overload
+def vander(
+ x: _ArrayLikeComplex_co,
+ N: None | int = ...,
+ increasing: bool = ...,
+) -> NDArray[complexfloating[Any, Any]]: ...
+@overload
+def vander(
+ x: _ArrayLikeObject_co,
+ N: None | int = ...,
+ increasing: bool = ...,
+) -> NDArray[object_]: ...
+
+@overload
+def histogram2d( # type: ignore[misc]
+ x: _ArrayLikeFloat_co,
+ y: _ArrayLikeFloat_co,
+ bins: int | Sequence[int] = ...,
+ range: None | _ArrayLikeFloat_co = ...,
+ normed: None | bool = ...,
+ weights: None | _ArrayLikeFloat_co = ...,
+ density: None | bool = ...,
+) -> Tuple[
+ NDArray[float64],
+ NDArray[floating[Any]],
+ NDArray[floating[Any]],
+]: ...
+@overload
+def histogram2d(
+ x: _ArrayLikeComplex_co,
+ y: _ArrayLikeComplex_co,
+ bins: int | Sequence[int] = ...,
+ range: None | _ArrayLikeFloat_co = ...,
+ normed: None | bool = ...,
+ weights: None | _ArrayLikeFloat_co = ...,
+ density: None | bool = ...,
+) -> Tuple[
+ NDArray[float64],
+ NDArray[complexfloating[Any, Any]],
+ NDArray[complexfloating[Any, Any]],
+]: ...
+@overload # TODO: Sort out `bins`
+def histogram2d(
+ x: _ArrayLikeComplex_co,
+ y: _ArrayLikeComplex_co,
+ bins: Sequence[_ArrayLikeInt_co],
+ range: None | _ArrayLikeFloat_co = ...,
+ normed: None | bool = ...,
+ weights: None | _ArrayLikeFloat_co = ...,
+ density: None | bool = ...,
+) -> Tuple[
+ NDArray[float64],
+ NDArray[Any],
+ NDArray[Any],
+]: ...
+
+# NOTE: we're assuming/demanding here the `mask_func` returns
+# an ndarray of shape `(n, n)`; otherwise there is the possibility
+# of the output tuple having more or less than 2 elements
+@overload
+def mask_indices(
+ n: int,
+ mask_func: _MaskFunc[int],
+ k: int = ...,
+) -> Tuple[NDArray[intp], NDArray[intp]]: ...
+@overload
+def mask_indices(
+ n: int,
+ mask_func: _MaskFunc[_T],
+ k: _T,
+) -> Tuple[NDArray[intp], NDArray[intp]]: ...
+
+def tril_indices(
+ n: int,
+ k: int = ...,
+ m: None | int = ...,
+) -> Tuple[NDArray[int_], NDArray[int_]]: ...
+
+def tril_indices_from(
+ arr: NDArray[Any],
+ k: int = ...,
+) -> Tuple[NDArray[int_], NDArray[int_]]: ...
+
+def triu_indices(
+ n: int,
+ k: int = ...,
+ m: None | int = ...,
+) -> Tuple[NDArray[int_], NDArray[int_]]: ...
+
+def triu_indices_from(
+ arr: NDArray[Any],
+ k: int = ...,
+) -> Tuple[NDArray[int_], NDArray[int_]]: ...
diff --git a/numpy/typing/tests/data/fail/array_constructors.py b/numpy/typing/tests/data/fail/array_constructors.py
index eb57e5c00..0e2250513 100644
--- a/numpy/typing/tests/data/fail/array_constructors.py
+++ b/numpy/typing/tests/data/fail/array_constructors.py
@@ -27,5 +27,5 @@ np.logspace(0, 2, base=None) # E: Argument "base"
np.geomspace(None, 'bob') # E: Argument 1
np.stack(generator) # E: No overload variant
-np.hstack({1, 2}) # E: incompatible type
-np.vstack(1) # E: incompatible type
+np.hstack({1, 2}) # E: No overload variant
+np.vstack(1) # E: No overload variant
diff --git a/numpy/typing/tests/data/fail/multiarray.py b/numpy/typing/tests/data/fail/multiarray.py
index e931e9d5c..50361ec43 100644
--- a/numpy/typing/tests/data/fail/multiarray.py
+++ b/numpy/typing/tests/data/fail/multiarray.py
@@ -10,8 +10,12 @@ AR_i8: npt.NDArray[np.int64]
AR_f8: npt.NDArray[np.float64]
AR_M: npt.NDArray[np.datetime64]
+M: np.datetime64
+
AR_LIKE_f: List[float]
+def func(a: int) -> None: ...
+
np.where(AR_b, 1) # E: No overload variant
np.can_cast(AR_f8, 1) # E: incompatible type
@@ -30,3 +34,16 @@ np.unpackbits(AR_u1, bitorder=">") # E: incompatible type
np.shares_memory(1, 1, max_work=i8) # E: incompatible type
np.may_share_memory(1, 1, max_work=i8) # E: incompatible type
+
+np.arange(M) # E: No overload variant
+np.arange(stop=10) # E: No overload variant
+
+np.datetime_data(int) # E: incompatible type
+
+np.busday_offset("2012", 10) # E: incompatible type
+
+np.datetime_as_string("2012") # E: incompatible type
+
+np.compare_chararrays("a", b"a", "==", False) # E: No overload variant
+
+np.add_docstring(func, None) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/twodim_base.py b/numpy/typing/tests/data/fail/twodim_base.py
new file mode 100644
index 000000000..ab34a374c
--- /dev/null
+++ b/numpy/typing/tests/data/fail/twodim_base.py
@@ -0,0 +1,37 @@
+from typing import Any, List, TypeVar
+
+import numpy as np
+import numpy.typing as npt
+
+
+def func1(ar: npt.NDArray[Any], a: int) -> npt.NDArray[np.str_]:
+ pass
+
+
+def func2(ar: npt.NDArray[Any], a: float) -> float:
+ pass
+
+
+AR_b: npt.NDArray[np.bool_]
+AR_m: npt.NDArray[np.timedelta64]
+
+AR_LIKE_b: List[bool]
+
+np.eye(10, M=20.0) # E: No overload variant
+np.eye(10, k=2.5, dtype=int) # E: No overload variant
+
+np.diag(AR_b, k=0.5) # E: No overload variant
+np.diagflat(AR_b, k=0.5) # E: No overload variant
+
+np.tri(10, M=20.0) # E: No overload variant
+np.tri(10, k=2.5, dtype=int) # E: No overload variant
+
+np.tril(AR_b, k=0.5) # E: No overload variant
+np.triu(AR_b, k=0.5) # E: No overload variant
+
+np.vander(AR_m) # E: incompatible type
+
+np.histogram2d(AR_m) # E: No overload variant
+
+np.mask_indices(10, func1) # E: incompatible type
+np.mask_indices(10, func2, 10.5) # E: incompatible type
diff --git a/numpy/typing/tests/data/pass/lib_utils.py b/numpy/typing/tests/data/pass/lib_utils.py
index c602923d9..0a15dad22 100644
--- a/numpy/typing/tests/data/pass/lib_utils.py
+++ b/numpy/typing/tests/data/pass/lib_utils.py
@@ -6,7 +6,7 @@ from typing import Any
import numpy as np
FILE = StringIO()
-AR: np.ndarray[Any, np.dtype[np.float64]] = np.arange(10).astype(np.float64)
+AR = np.arange(10, dtype=np.float64)
def func(a: int) -> bool: ...
diff --git a/numpy/typing/tests/data/reveal/array_constructors.py b/numpy/typing/tests/data/reveal/array_constructors.py
index ed966679d..44c85e988 100644
--- a/numpy/typing/tests/data/reveal/array_constructors.py
+++ b/numpy/typing/tests/data/reveal/array_constructors.py
@@ -67,6 +67,41 @@ reveal_type(np.asfortranarray([1, 1.0])) # E: numpy.ndarray[Any, numpy.dtype[An
reveal_type(np.asfortranarray(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
reveal_type(np.asfortranarray(A, dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.fromstring("1 1 1", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.fromstring(b"1 1 1", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.fromstring("1 1 1", dtype=np.int64, sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.fromstring(b"1 1 1", dtype=np.int64, sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.fromstring("1 1 1", dtype="c16", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.fromstring(b"1 1 1", dtype="c16", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.fromfile("test.txt", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.fromfile("test.txt", dtype=np.int64, sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.fromfile("test.txt", dtype="c16", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+with open("test.txt") as f:
+ reveal_type(np.fromfile(f, sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+ reveal_type(np.fromfile(b"test.txt", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+ reveal_type(np.fromfile(Path("test.txt"), sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+
+reveal_type(np.fromiter("12345", np.float64)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.fromiter("12345", float)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.frombuffer(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.frombuffer(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.frombuffer(A, dtype="c16")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.arange(False, True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.arange(10)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.arange(0, 10, step=2)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.arange(10.0)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.arange(start=0, stop=10.0)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.arange(np.timedelta64(0))) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(np.arange(0, np.timedelta64(10))) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(np.arange(np.datetime64("0"), np.datetime64("10"))) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(np.arange(10, dtype=np.float64)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.arange(0, 10, step=2, dtype=np.int16)) # E: numpy.ndarray[Any, numpy.dtype[{int16}]]
+reveal_type(np.arange(10, dtype=int)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.arange(0, 10, dtype="f8")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
reveal_type(np.require(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
reveal_type(np.require(B)) # E: SubClass[{float64}]
reveal_type(np.require(B, requirements=None)) # E: SubClass[{float64}]
@@ -112,25 +147,27 @@ reveal_type(np.fromfunction(func, (3, 5))) # E: SubClass[{float64}]
reveal_type(np.identity(10)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.atleast_1d(A)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.atleast_1d(C)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.atleast_1d(A, A)) # E: list[numpy.ndarray[Any, Any]]
-reveal_type(np.atleast_1d(A, C)) # E: list[numpy.ndarray[Any, Any]]
-reveal_type(np.atleast_1d(C, C)) # E: list[numpy.ndarray[Any, Any]]
+reveal_type(np.atleast_1d(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.atleast_1d(C)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.atleast_1d(A, A)) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+reveal_type(np.atleast_1d(A, C)) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+reveal_type(np.atleast_1d(C, C)) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
-reveal_type(np.atleast_2d(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.atleast_2d(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
-reveal_type(np.atleast_3d(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.atleast_3d(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
-reveal_type(np.vstack([A, A])) # E: numpy.ndarray[Any, Any]
-reveal_type(np.vstack([A, C])) # E: numpy.ndarray[Any, Any]
-reveal_type(np.vstack([C, C])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.vstack([A, A])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.vstack([A, C])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.vstack([C, C])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
-reveal_type(np.hstack([A, A])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.hstack([A, A])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
-reveal_type(np.stack([A, A])) # E: numpy.ndarray[Any, Any]
-reveal_type(np.stack([A, A], axis=0)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.stack([A, A], out=B)) # E: SubClass
+reveal_type(np.stack([A, A])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.stack([A, C])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.stack([C, C])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.stack([A, A], axis=0)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.stack([A, A], out=B)) # E: SubClass[{float64}]
-reveal_type(np.block([[A, A], [A, A]])) # E: numpy.ndarray[Any, Any]
-reveal_type(np.block(C)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.block([[A, A], [A, A]])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.block(C)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
diff --git a/numpy/typing/tests/data/reveal/arrayterator.py b/numpy/typing/tests/data/reveal/arrayterator.py
index b57861d00..ea4e75612 100644
--- a/numpy/typing/tests/data/reveal/arrayterator.py
+++ b/numpy/typing/tests/data/reveal/arrayterator.py
@@ -10,7 +10,7 @@ reveal_type(ar_iter.start) # E: builtins.list[builtins.int]
reveal_type(ar_iter.stop) # E: builtins.list[builtins.int]
reveal_type(ar_iter.step) # E: builtins.list[builtins.int]
reveal_type(ar_iter.shape) # E: builtins.tuple[builtins.int]
-reveal_type(ar_iter.flat) # E: 'typing.Generator[{int64}, None, None]
+reveal_type(ar_iter.flat) # E: typing.Generator[{int64}, None, None]
reveal_type(ar_iter.__array__()) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
diff --git a/numpy/typing/tests/data/reveal/multiarray.py b/numpy/typing/tests/data/reveal/multiarray.py
index 2811b1f35..cee51975e 100644
--- a/numpy/typing/tests/data/reveal/multiarray.py
+++ b/numpy/typing/tests/data/reveal/multiarray.py
@@ -1,17 +1,32 @@
-from typing import Any, List
+from typing import Any, List, TypeVar
+from pathlib import Path
+
import numpy as np
import numpy.typing as npt
+_SCT = TypeVar("_SCT", bound=np.generic, covariant=True)
+
+class SubClass(np.ndarray[Any, np.dtype[_SCT]]): ...
+
+subclass: SubClass[np.float64]
+
AR_f8: npt.NDArray[np.float64]
AR_i8: npt.NDArray[np.int64]
AR_u1: npt.NDArray[np.uint8]
+AR_m: npt.NDArray[np.timedelta64]
+AR_M: npt.NDArray[np.datetime64]
AR_LIKE_f: List[float]
AR_LIKE_i: List[int]
+m: np.timedelta64
+M: np.datetime64
+
b_f8 = np.broadcast(AR_f8)
b_i8_f8_f8 = np.broadcast(AR_i8, AR_f8, AR_f8)
+def func(a: int) -> bool: ...
+
reveal_type(next(b_f8)) # E: tuple[Any]
reveal_type(b_f8.reset()) # E: None
reveal_type(b_f8.index) # E: int
@@ -75,3 +90,36 @@ reveal_type(np.shares_memory(AR_f8, AR_f8, max_work=1)) # E: bool
reveal_type(np.may_share_memory(1, 2)) # E: bool
reveal_type(np.may_share_memory(AR_f8, AR_f8, max_work=1)) # E: bool
+
+reveal_type(np.geterrobj()) # E: list[Any]
+
+reveal_type(np.seterrobj([8192, 521, None])) # E: None
+
+reveal_type(np.promote_types(np.int32, np.int64)) # E: numpy.dtype[Any]
+reveal_type(np.promote_types("f4", float)) # E: numpy.dtype[Any]
+
+reveal_type(np.frompyfunc(func, 1, 1, identity=None)) # numpy.ufunc
+
+reveal_type(np.datetime_data("m8[D]")) # E: Tuple[builtins.str, builtins.int]
+reveal_type(np.datetime_data(np.datetime64)) # E: Tuple[builtins.str, builtins.int]
+reveal_type(np.datetime_data(np.dtype(np.timedelta64))) # E: Tuple[builtins.str, builtins.int]
+
+reveal_type(np.busday_count("2011-01", "2011-02")) # E: {int_}
+reveal_type(np.busday_count(["2011-01"], "2011-02")) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(np.busday_offset(M, m)) # E: numpy.datetime64
+reveal_type(np.busday_offset(M, 5)) # E: numpy.datetime64
+reveal_type(np.busday_offset(AR_M, m)) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(np.busday_offset("2011-01", "2011-02", roll="forward")) # E: numpy.datetime64
+reveal_type(np.busday_offset(["2011-01"], "2011-02", roll="forward")) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+
+reveal_type(np.is_busday("2012")) # E: numpy.bool_
+reveal_type(np.is_busday(["2012"])) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+
+reveal_type(np.datetime_as_string(M)) # E: numpy.str_
+reveal_type(np.datetime_as_string(AR_M)) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+
+reveal_type(np.compare_chararrays("a", "b", "!=", rstrip=False)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.compare_chararrays(b"a", b"a", "==", True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+
+reveal_type(np.add_docstring(func, "test")) # E: None
diff --git a/numpy/typing/tests/data/reveal/testing.py b/numpy/typing/tests/data/reveal/testing.py
index e244c225c..2b040ff60 100644
--- a/numpy/typing/tests/data/reveal/testing.py
+++ b/numpy/typing/tests/data/reveal/testing.py
@@ -29,8 +29,8 @@ reveal_type(np.testing.clear_and_catch_warnings(modules=[np.testing])) # E: _cl
reveal_type(np.testing.clear_and_catch_warnings(True)) # E: _clear_and_catch_warnings_with_records
reveal_type(np.testing.clear_and_catch_warnings(False)) # E: _clear_and_catch_warnings_without_records
reveal_type(np.testing.clear_and_catch_warnings(bool_obj)) # E: clear_and_catch_warnings
-reveal_type(np.testing.clear_and_catch_warnings.class_modules) # E: tuple[_importlib_modulespec.ModuleType]
-reveal_type(np.testing.clear_and_catch_warnings.modules) # E: set[_importlib_modulespec.ModuleType]
+reveal_type(np.testing.clear_and_catch_warnings.class_modules) # E: tuple[types.ModuleType]
+reveal_type(np.testing.clear_and_catch_warnings.modules) # E: set[types.ModuleType]
with np.testing.clear_and_catch_warnings(True) as c1:
reveal_type(c1) # E: builtins.list[warnings.WarningMessage]
diff --git a/numpy/typing/tests/data/reveal/twodim_base.py b/numpy/typing/tests/data/reveal/twodim_base.py
new file mode 100644
index 000000000..b95fbc71e
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/twodim_base.py
@@ -0,0 +1,72 @@
+from typing import Any, List, TypeVar
+
+import numpy as np
+import numpy.typing as npt
+
+_SCT = TypeVar("_SCT", bound=np.generic)
+
+
+def func1(ar: npt.NDArray[_SCT], a: int) -> npt.NDArray[_SCT]:
+ pass
+
+
+def func2(ar: npt.NDArray[np.number[Any]], a: str) -> npt.NDArray[np.float64]:
+ pass
+
+
+AR_b: npt.NDArray[np.bool_]
+AR_u: npt.NDArray[np.uint64]
+AR_i: npt.NDArray[np.int64]
+AR_f: npt.NDArray[np.float64]
+AR_c: npt.NDArray[np.complex128]
+AR_O: npt.NDArray[np.object_]
+
+AR_LIKE_b: List[bool]
+
+reveal_type(np.fliplr(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.fliplr(AR_LIKE_b)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.flipud(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.flipud(AR_LIKE_b)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.eye(10)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.eye(10, M=20, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.eye(10, k=2, dtype=int)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.diag(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.diag(AR_LIKE_b, k=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.diagflat(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.diagflat(AR_LIKE_b, k=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.tri(10)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.tri(10, M=20, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.tri(10, k=2, dtype=int)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.tril(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.tril(AR_LIKE_b, k=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.triu(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.triu(AR_LIKE_b, k=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.vander(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.vander(AR_u)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.vander(AR_i, N=2)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.vander(AR_f, increasing=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.vander(AR_c)) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(np.vander(AR_O)) # E: numpy.ndarray[Any, numpy.dtype[numpy.object_]]
+
+reveal_type(np.histogram2d(AR_i, AR_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{float64}]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]]
+reveal_type(np.histogram2d(AR_f, AR_f)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{float64}]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]]
+reveal_type(np.histogram2d(AR_f, AR_c, weights=AR_LIKE_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{float64}]], numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]], numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]]
+
+reveal_type(np.mask_indices(10, func1)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{intp}]], numpy.ndarray[Any, numpy.dtype[{intp}]]]
+reveal_type(np.mask_indices(8, func2, "0")) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{intp}]], numpy.ndarray[Any, numpy.dtype[{intp}]]]
+
+reveal_type(np.tril_indices(10)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{int_}]], numpy.ndarray[Any, numpy.dtype[{int_}]]]
+
+reveal_type(np.tril_indices_from(AR_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{int_}]], numpy.ndarray[Any, numpy.dtype[{int_}]]]
+
+reveal_type(np.triu_indices(10)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{int_}]], numpy.ndarray[Any, numpy.dtype[{int_}]]]
+
+reveal_type(np.triu_indices_from(AR_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{int_}]], numpy.ndarray[Any, numpy.dtype[{int_}]]]
diff --git a/test_requirements.txt b/test_requirements.txt
index ca0edfbb4..35a78aff1 100644
--- a/test_requirements.txt
+++ b/test_requirements.txt
@@ -1,7 +1,7 @@
cython==0.29.23
wheel<0.36.3
setuptools<49.2.0
-hypothesis==6.13.14
+hypothesis==6.14.0
pytest==6.2.4
pytz==2021.1
pytest-cov==2.12.1
@@ -11,5 +11,5 @@ cffi
# For testing types. Notes on the restrictions:
# - Mypy relies on C API features not present in PyPy
# - There is no point in installing typing_extensions without mypy
-mypy==0.812; platform_python_implementation != "PyPy"
+mypy==0.902; platform_python_implementation != "PyPy"
typing_extensions==3.10.0.0; platform_python_implementation != "PyPy"