summaryrefslogtreecommitdiff
path: root/numpy/lib
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/lib')
-rw-r--r--numpy/lib/__init__.pyi1
-rw-r--r--numpy/lib/_datasource.py2
-rw-r--r--numpy/lib/arraypad.pyi17
-rw-r--r--numpy/lib/arrayterator.pyi1
-rw-r--r--numpy/lib/format.py5
-rw-r--r--numpy/lib/format.pyi8
-rw-r--r--numpy/lib/function_base.py4
-rw-r--r--numpy/lib/index_tricks.py18
-rw-r--r--numpy/lib/index_tricks.pyi8
-rw-r--r--numpy/lib/npyio.py321
-rw-r--r--numpy/lib/npyio.pyi335
-rw-r--r--numpy/lib/polynomial.py23
-rw-r--r--numpy/lib/shape_base.pyi13
-rw-r--r--numpy/lib/stride_tricks.pyi83
-rw-r--r--numpy/lib/tests/test__datasource.py6
-rw-r--r--numpy/lib/tests/test_function_base.py20
-rw-r--r--numpy/lib/tests/test_io.py28
-rw-r--r--numpy/lib/tests/test_shape_base.py10
-rw-r--r--numpy/lib/tests/test_utils.py6
-rw-r--r--numpy/lib/type_check.pyi8
-rw-r--r--numpy/lib/utils.py6
-rw-r--r--numpy/lib/utils.pyi12
22 files changed, 541 insertions, 394 deletions
diff --git a/numpy/lib/__init__.pyi b/numpy/lib/__init__.pyi
index 25640ec07..ae23b2ec4 100644
--- a/numpy/lib/__init__.pyi
+++ b/numpy/lib/__init__.pyi
@@ -130,7 +130,6 @@ from numpy.lib.npyio import (
recfromtxt as recfromtxt,
recfromcsv as recfromcsv,
load as load,
- loads as loads,
save as save,
savez as savez,
savez_compressed as savez_compressed,
diff --git a/numpy/lib/_datasource.py b/numpy/lib/_datasource.py
index c790a6462..56b94853d 100644
--- a/numpy/lib/_datasource.py
+++ b/numpy/lib/_datasource.py
@@ -530,7 +530,7 @@ class DataSource:
return _file_openers[ext](found, mode=mode,
encoding=encoding, newline=newline)
else:
- raise IOError("%s not found." % path)
+ raise FileNotFoundError(f"{path} not found.")
class Repository (DataSource):
diff --git a/numpy/lib/arraypad.pyi b/numpy/lib/arraypad.pyi
index df9538dd7..49ce8e683 100644
--- a/numpy/lib/arraypad.pyi
+++ b/numpy/lib/arraypad.pyi
@@ -1,11 +1,12 @@
-import sys
from typing import (
+ Literal as L,
Any,
Dict,
List,
overload,
Tuple,
TypeVar,
+ Protocol,
)
from numpy import ndarray, dtype, generic
@@ -18,20 +19,16 @@ from numpy.typing import (
_SupportsArray,
)
-if sys.version_info >= (3, 8):
- from typing import Literal as L, Protocol
-else:
- from typing_extensions import Literal as L, Protocol
-
_SCT = TypeVar("_SCT", bound=generic)
class _ModeFunc(Protocol):
def __call__(
self,
- __vector: NDArray[Any],
- __iaxis_pad_width: Tuple[int, int],
- __iaxis: int,
- __kwargs: Dict[str, Any],
+ vector: NDArray[Any],
+ iaxis_pad_width: Tuple[int, int],
+ iaxis: int,
+ kwargs: Dict[str, Any],
+ /,
) -> None: ...
_ModeKind = L[
diff --git a/numpy/lib/arrayterator.pyi b/numpy/lib/arrayterator.pyi
index 39d6fd843..82c669206 100644
--- a/numpy/lib/arrayterator.pyi
+++ b/numpy/lib/arrayterator.pyi
@@ -1,4 +1,3 @@
-import sys
from typing import (
List,
Any,
diff --git a/numpy/lib/format.py b/numpy/lib/format.py
index 6ac66c22a..e566e253d 100644
--- a/numpy/lib/format.py
+++ b/numpy/lib/format.py
@@ -162,7 +162,6 @@ evolved with time and this document is more current.
"""
import numpy
-import io
import warnings
from numpy.lib.utils import safe_eval
from numpy.compat import (
@@ -831,7 +830,7 @@ def open_memmap(filename, mode='r+', dtype=None, shape=None,
------
ValueError
If the data or the mode is invalid.
- IOError
+ OSError
If the file is not found or cannot be opened correctly.
See Also
@@ -909,7 +908,7 @@ def _read_bytes(fp, size, error_template="ran out of data"):
data += r
if len(r) == 0 or len(data) == size:
break
- except io.BlockingIOError:
+ except BlockingIOError:
pass
if len(data) != size:
msg = "EOF: reading %s, expected %d bytes got %d"
diff --git a/numpy/lib/format.pyi b/numpy/lib/format.pyi
index 4c44d57bf..092245daf 100644
--- a/numpy/lib/format.pyi
+++ b/numpy/lib/format.pyi
@@ -1,10 +1,4 @@
-import sys
-from typing import Any, List, Set
-
-if sys.version_info >= (3, 8):
- from typing import Literal, Final
-else:
- from typing_extensions import Literal, Final
+from typing import Any, List, Set, Literal, Final
__all__: List[str]
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index b43a1d666..d875a00ae 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -1512,7 +1512,7 @@ def unwrap(p, discont=None, axis=-1, *, period=2*pi):
difference from their predecessor of more than ``max(discont, period/2)``
to their `period`-complementary values.
- For the default case where `period` is :math:`2\pi` and is `discont` is
+ For the default case where `period` is :math:`2\pi` and `discont` is
:math:`\pi`, this unwraps a radian phase `p` such that adjacent differences
are never greater than :math:`\pi` by adding :math:`2k\pi` for some
integer :math:`k`.
@@ -1866,6 +1866,8 @@ def _parse_gufunc_signature(signature):
Tuple of input and output core dimensions parsed from the signature, each
of the form List[Tuple[str, ...]].
"""
+ signature = re.sub(r'\s+', '', signature)
+
if not re.match(_SIGNATURE, signature):
raise ValueError(
'not a valid gufunc signature: {}'.format(signature))
diff --git a/numpy/lib/index_tricks.py b/numpy/lib/index_tricks.py
index 8d1b6e5be..2a4402c89 100644
--- a/numpy/lib/index_tricks.py
+++ b/numpy/lib/index_tricks.py
@@ -149,9 +149,9 @@ class nd_grid:
try:
size = []
typ = int
- for k in range(len(key)):
- step = key[k].step
- start = key[k].start
+ for kk in key:
+ step = kk.step
+ start = kk.start
if start is None:
start = 0
if step is None:
@@ -161,19 +161,19 @@ class nd_grid:
typ = float
else:
size.append(
- int(math.ceil((key[k].stop - start)/(step*1.0))))
+ int(math.ceil((kk.stop - start) / (step * 1.0))))
if (isinstance(step, (_nx.floating, float)) or
isinstance(start, (_nx.floating, float)) or
- isinstance(key[k].stop, (_nx.floating, float))):
+ isinstance(kk.stop, (_nx.floating, float))):
typ = float
if self.sparse:
nn = [_nx.arange(_x, dtype=_t)
for _x, _t in zip(size, (typ,)*len(size))]
else:
nn = _nx.indices(size, typ)
- for k in range(len(size)):
- step = key[k].step
- start = key[k].start
+ for k, kk in enumerate(key):
+ step = kk.step
+ start = kk.start
if start is None:
start = 0
if step is None:
@@ -181,7 +181,7 @@ class nd_grid:
if isinstance(step, (_nx.complexfloating, complex)):
step = int(abs(step))
if step != 1:
- step = (key[k].stop - start)/float(step-1)
+ step = (kk.stop - start) / float(step - 1)
nn[k] = (nn[k]*step+start)
if self.sparse:
slobj = [_nx.newaxis]*len(size)
diff --git a/numpy/lib/index_tricks.pyi b/numpy/lib/index_tricks.pyi
index 0f9ae94a9..530be3cae 100644
--- a/numpy/lib/index_tricks.pyi
+++ b/numpy/lib/index_tricks.pyi
@@ -1,4 +1,3 @@
-import sys
from typing import (
Any,
Tuple,
@@ -8,6 +7,8 @@ from typing import (
List,
Union,
Sequence,
+ Literal,
+ SupportsIndex,
)
from numpy import (
@@ -49,11 +50,6 @@ from numpy.core.multiarray import (
ravel_multi_index as ravel_multi_index,
)
-if sys.version_info >= (3, 8):
- from typing import Literal, SupportsIndex
-else:
- from typing_extensions import Literal, SupportsIndex
-
_T = TypeVar("_T")
_DType = TypeVar("_DType", bound=dtype[Any])
_BoolType = TypeVar("_BoolType", Literal[True], Literal[False])
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py
index 7c73d9655..b91bf440f 100644
--- a/numpy/lib/npyio.py
+++ b/numpy/lib/npyio.py
@@ -5,7 +5,7 @@ import itertools
import warnings
import weakref
import contextlib
-from operator import itemgetter, index as opindex
+from operator import itemgetter, index as opindex, methodcaller
from collections.abc import Mapping
import numpy as np
@@ -26,18 +26,9 @@ from numpy.compat import (
)
-@set_module('numpy')
-def loads(*args, **kwargs):
- # NumPy 1.15.0, 2017-12-10
- warnings.warn(
- "np.loads is deprecated, use pickle.loads instead",
- DeprecationWarning, stacklevel=2)
- return pickle.loads(*args, **kwargs)
-
-
__all__ = [
- 'savetxt', 'loadtxt', 'genfromtxt', 'ndfromtxt', 'mafromtxt',
- 'recfromtxt', 'recfromcsv', 'load', 'loads', 'save', 'savez',
+ 'savetxt', 'loadtxt', 'genfromtxt',
+ 'recfromtxt', 'recfromcsv', 'load', 'save', 'savez',
'savez_compressed', 'packbits', 'unpackbits', 'fromregex', 'DataSource'
]
@@ -333,10 +324,12 @@ def load(file, mmap_mode=None, allow_pickle=False, fix_imports=True,
Raises
------
- IOError
+ OSError
If the input file does not exist or cannot be read.
+ UnpicklingError
+ If ``allow_pickle=True``, but the file cannot be loaded as a pickle.
ValueError
- The file contains an object array, but allow_pickle=False given.
+ The file contains an object array, but ``allow_pickle=False`` given.
See Also
--------
@@ -445,8 +438,8 @@ def load(file, mmap_mode=None, allow_pickle=False, fix_imports=True,
try:
return pickle.load(fid, **pickle_kwargs)
except Exception as e:
- raise IOError(
- "Failed to interpret file %s as a pickle" % repr(file)) from e
+ raise pickle.UnpicklingError(
+ f"Failed to interpret file {file!r} as a pickle") from e
def _save_dispatcher(file, arr, allow_pickle=None, fix_imports=None):
@@ -728,41 +721,42 @@ def _savez(file, args, kwds, compress, allow_pickle=True, pickle_kwargs=None):
zipf.close()
+def _floatconv(x):
+ try:
+ return float(x) # The fastest path.
+ except ValueError:
+ if '0x' in x: # Don't accidentally convert "a" ("0xa") to 10.
+ try:
+ return float.fromhex(x)
+ except ValueError:
+ pass
+ raise # Raise the original exception, which makes more sense.
+
+
+_CONVERTERS = [ # These converters only ever get strs (not bytes) as input.
+ (np.bool_, lambda x: bool(int(x))),
+ (np.uint64, np.uint64),
+ (np.int64, np.int64),
+ (np.integer, lambda x: int(float(x))),
+ (np.longdouble, np.longdouble),
+ (np.floating, _floatconv),
+ (complex, lambda x: complex(x.replace('+-', '-'))),
+ (np.bytes_, methodcaller('encode', 'latin-1')),
+ (np.unicode_, str),
+]
+
+
def _getconv(dtype):
- """ Find the correct dtype converter. Adapted from matplotlib """
+ """
+ Find the correct dtype converter. Adapted from matplotlib.
- def floatconv(x):
- try:
- return float(x) # The fastest path.
- except ValueError:
- if '0x' in x: # Don't accidentally convert "a" ("0xa") to 10.
- try:
- return float.fromhex(x)
- except ValueError:
- pass
- raise # Raise the original exception, which makes more sense.
-
- typ = dtype.type
- if issubclass(typ, np.bool_):
- return lambda x: bool(int(x))
- if issubclass(typ, np.uint64):
- return np.uint64
- if issubclass(typ, np.int64):
- return np.int64
- if issubclass(typ, np.integer):
- return lambda x: int(float(x))
- elif issubclass(typ, np.longdouble):
- return np.longdouble
- elif issubclass(typ, np.floating):
- return floatconv
- elif issubclass(typ, complex):
- return lambda x: complex(asstr(x).replace('+-', '-'))
- elif issubclass(typ, np.bytes_):
- return asbytes
- elif issubclass(typ, np.unicode_):
- return asunicode
- else:
- return asstr
+ Even when a lambda is returned, it is defined at the toplevel, to allow
+ testing for equality and enabling optimization for single-type data.
+ """
+ for base, conv in _CONVERTERS:
+ if issubclass(dtype.type, base):
+ return conv
+ return str
# _loadtxt_flatten_dtype_internal and _loadtxt_pack_items are loadtxt helpers
@@ -978,52 +972,13 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
# Nested functions used by loadtxt.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- def split_line(line):
- """Chop off comments, strip, and split at delimiter. """
- line = _decode_line(line, encoding=encoding)
+ def split_line(line: str):
+ """Chop off comments, strip, and split at delimiter."""
for comment in comments: # Much faster than using a single regex.
line = line.split(comment, 1)[0]
line = line.strip('\r\n')
return line.split(delimiter) if line else []
- def read_data(chunk_size):
- """Parse each line, including the first.
-
- The file read, `fh`, is a global defined above.
-
- Parameters
- ----------
- chunk_size : int
- At most `chunk_size` lines are read at a time, with iteration
- until all lines are read.
-
- """
- X = []
- line_iter = itertools.chain([first_line], fh)
- line_iter = itertools.islice(line_iter, max_rows)
- for i, line in enumerate(line_iter):
- vals = split_line(line)
- if len(vals) == 0:
- continue
- if usecols:
- vals = [vals[j] for j in usecols]
- if len(vals) != ncols:
- line_num = i + skiprows + 1
- raise ValueError("Wrong number of columns at line %d"
- % line_num)
-
- # Convert each value according to its column and store
- items = [conv(val) for (conv, val) in zip(converters, vals)]
-
- # Then pack it according to the dtype's nesting
- items = packer(items)
- X.append(items)
- if len(X) > chunk_size:
- yield X
- X = []
- if X:
- yield X
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Main body of loadtxt.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -1051,14 +1006,14 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
byte_converters = True
if usecols is not None:
- # Allow usecols to be a single int or a sequence of ints
+ # Copy usecols, allowing it to be a single int or a sequence of ints.
try:
- usecols_as_list = list(usecols)
+ usecols = list(usecols)
except TypeError:
- usecols_as_list = [usecols]
- for col_idx in usecols_as_list:
+ usecols = [usecols]
+ for i, col_idx in enumerate(usecols):
try:
- opindex(col_idx)
+ usecols[i] = opindex(col_idx) # Cast to builtin int now.
except TypeError as e:
e.args = (
"usecols must be an int or a sequence of ints but "
@@ -1066,8 +1021,13 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
type(col_idx),
)
raise
- # Fall back to existing code
- usecols = usecols_as_list
+ if len(usecols) > 1:
+ usecols_getter = itemgetter(*usecols)
+ else:
+ # Get an iterable back, even if using a single column.
+ usecols_getter = lambda obj, c=usecols[0]: [obj[c]]
+ else:
+ usecols_getter = None
# Make sure we're dealing with a proper dtype
dtype = np.dtype(dtype)
@@ -1075,50 +1035,70 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
dtype_types, packer = _loadtxt_flatten_dtype_internal(dtype)
- fown = False
+ fh_closing_ctx = contextlib.nullcontext()
try:
if isinstance(fname, os_PathLike):
fname = os_fspath(fname)
if _is_string_like(fname):
fh = np.lib._datasource.open(fname, 'rt', encoding=encoding)
fencoding = getattr(fh, 'encoding', 'latin1')
- fh = iter(fh)
- fown = True
+ line_iter = iter(fh)
+ fh_closing_ctx = contextlib.closing(fh)
else:
- fh = iter(fname)
+ line_iter = iter(fname)
fencoding = getattr(fname, 'encoding', 'latin1')
+ try:
+ first_line = next(line_iter)
+ except StopIteration:
+ pass # Nothing matters if line_iter is empty.
+ else:
+ # Put first_line back.
+ line_iter = itertools.chain([first_line], line_iter)
+ if isinstance(first_line, bytes):
+ # Using latin1 matches _decode_line's behavior.
+ decoder = methodcaller(
+ "decode",
+ encoding if encoding is not None else "latin1")
+ line_iter = map(decoder, line_iter)
except TypeError as e:
raise ValueError(
f"fname must be a string, filehandle, list of strings,\n"
f"or generator. Got {type(fname)} instead."
) from e
- # input may be a python2 io stream
- if encoding is not None:
- fencoding = encoding
- # we must assume local encoding
- # TODO emit portability warning?
- elif fencoding is None:
- import locale
- fencoding = locale.getpreferredencoding()
+ with fh_closing_ctx:
+
+ # input may be a python2 io stream
+ if encoding is not None:
+ fencoding = encoding
+ # we must assume local encoding
+ # TODO emit portability warning?
+ elif fencoding is None:
+ import locale
+ fencoding = locale.getpreferredencoding()
- try:
# Skip the first `skiprows` lines
for i in range(skiprows):
- next(fh)
+ next(line_iter)
# Read until we find a line with some values, and use it to determine
# the need for decoding and estimate the number of columns.
- for first_line in fh:
+ for first_line in line_iter:
ncols = len(usecols or split_line(first_line))
if ncols:
+ # Put first_line back.
+ line_iter = itertools.chain([first_line], line_iter)
break
else: # End of lines reached
- first_line = ''
ncols = len(usecols or [])
warnings.warn('loadtxt: Empty input file: "%s"' % fname,
stacklevel=2)
+ line_iter = itertools.islice(line_iter, max_rows)
+ lineno_words_iter = filter(
+ itemgetter(1), # item[1] is words; filter skips empty lines.
+ enumerate(map(split_line, line_iter), 1 + skiprows))
+
# Now that we know ncols, create the default converters list, and
# set packing, if necessary.
if len(dtype_types) > 1:
@@ -1144,36 +1124,55 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
continue
if byte_converters:
# converters may use decode to workaround numpy's old
- # behaviour, so encode the string again before passing to
- # the user converter
- def tobytes_first(x, conv):
- if type(x) is bytes:
- return conv(x)
+ # behaviour, so encode the string again (converters are only
+ # called with strings) before passing to the user converter.
+ def tobytes_first(conv, x):
return conv(x.encode("latin1"))
- converters[i] = functools.partial(tobytes_first, conv=conv)
+ converters[i] = functools.partial(tobytes_first, conv)
else:
converters[i] = conv
- converters = [conv if conv is not bytes else
- lambda x: x.encode(fencoding) for conv in converters]
+ fencode = methodcaller("encode", fencoding)
+ converters = [conv if conv is not bytes else fencode
+ for conv in converters]
+ if len(set(converters)) == 1:
+ # Optimize single-type data. Note that this is only reached if
+ # `_getconv` returns equal callables (i.e. not local lambdas) on
+ # equal dtypes.
+ def convert_row(vals, _conv=converters[0]):
+ return [*map(_conv, vals)]
+ else:
+ def convert_row(vals):
+ return [conv(val) for conv, val in zip(converters, vals)]
# read data in chunks and fill it into an array via resize
# over-allocating and shrinking the array later may be faster but is
# probably not relevant compared to the cost of actually reading and
# converting the data
X = None
- for x in read_data(_loadtxt_chunksize):
+ while True:
+ chunk = []
+ for lineno, words in itertools.islice(
+ lineno_words_iter, _loadtxt_chunksize):
+ if usecols_getter is not None:
+ words = usecols_getter(words)
+ elif len(words) != ncols:
+ raise ValueError(
+ f"Wrong number of columns at line {lineno}")
+ # Convert each value according to its column, then pack it
+ # according to the dtype's nesting, and store it.
+ chunk.append(packer(convert_row(words)))
+ if not chunk: # The islice is empty, i.e. we're done.
+ break
+
if X is None:
- X = np.array(x, dtype)
+ X = np.array(chunk, dtype)
else:
nshape = list(X.shape)
pos = nshape[0]
- nshape[0] += len(x)
+ nshape[0] += len(chunk)
X.resize(nshape, refcheck=False)
- X[pos:, ...] = x
- finally:
- if fown:
- fh.close()
+ X[pos:, ...] = chunk
if X is None:
X = np.array([], dtype)
@@ -1475,8 +1474,11 @@ def fromregex(file, regexp, dtype, encoding=None):
Parameters
----------
- file : str or file
+ file : path or file
Filename or file object to read.
+
+ .. versionchanged:: 1.22.0
+ Now accepts `os.PathLike` implementations.
regexp : str or regexp
Regular expression used to parse the file.
Groups in the regular expression correspond to fields in the dtype.
@@ -1526,6 +1528,7 @@ def fromregex(file, regexp, dtype, encoding=None):
"""
own_fh = False
if not hasattr(file, "read"):
+ file = os.fspath(file)
file = np.lib._datasource.open(file, 'rt', encoding=encoding)
own_fh = True
@@ -1534,9 +1537,9 @@ def fromregex(file, regexp, dtype, encoding=None):
dtype = np.dtype(dtype)
content = file.read()
- if isinstance(content, bytes) and isinstance(regexp, np.compat.unicode):
+ if isinstance(content, bytes) and isinstance(regexp, str):
regexp = asbytes(regexp)
- elif isinstance(content, np.compat.unicode) and isinstance(regexp, bytes):
+ elif isinstance(content, str) and isinstance(regexp, bytes):
regexp = asstr(regexp)
if not hasattr(regexp, 'match'):
@@ -2307,62 +2310,6 @@ _genfromtxt_with_like = array_function_dispatch(
)(genfromtxt)
-def ndfromtxt(fname, **kwargs):
- """
- Load ASCII data stored in a file and return it as a single array.
-
- .. deprecated:: 1.17
- ndfromtxt` is a deprecated alias of `genfromtxt` which
- overwrites the ``usemask`` argument with `False` even when
- explicitly called as ``ndfromtxt(..., usemask=True)``.
- Use `genfromtxt` instead.
-
- Parameters
- ----------
- fname, kwargs : For a description of input parameters, see `genfromtxt`.
-
- See Also
- --------
- numpy.genfromtxt : generic function.
-
- """
- kwargs['usemask'] = False
- # Numpy 1.17
- warnings.warn(
- "np.ndfromtxt is a deprecated alias of np.genfromtxt, "
- "prefer the latter.",
- DeprecationWarning, stacklevel=2)
- return genfromtxt(fname, **kwargs)
-
-
-def mafromtxt(fname, **kwargs):
- """
- Load ASCII data stored in a text file and return a masked array.
-
- .. deprecated:: 1.17
- np.mafromtxt is a deprecated alias of `genfromtxt` which
- overwrites the ``usemask`` argument with `True` even when
- explicitly called as ``mafromtxt(..., usemask=False)``.
- Use `genfromtxt` instead.
-
- Parameters
- ----------
- fname, kwargs : For a description of input parameters, see `genfromtxt`.
-
- See Also
- --------
- numpy.genfromtxt : generic function to load ASCII data.
-
- """
- kwargs['usemask'] = True
- # Numpy 1.17
- warnings.warn(
- "np.mafromtxt is a deprecated alias of np.genfromtxt, "
- "prefer the latter.",
- DeprecationWarning, stacklevel=2)
- return genfromtxt(fname, **kwargs)
-
-
def recfromtxt(fname, **kwargs):
"""
Load ASCII data from a file and return it in a record array.
diff --git a/numpy/lib/npyio.pyi b/numpy/lib/npyio.pyi
index 508357927..4841e9e71 100644
--- a/numpy/lib/npyio.pyi
+++ b/numpy/lib/npyio.pyi
@@ -1,104 +1,265 @@
-from typing import Mapping, List, Any
+import os
+import sys
+import zipfile
+import types
+from typing import (
+ Literal as L,
+ Any,
+ Mapping,
+ TypeVar,
+ Generic,
+ List,
+ Type,
+ Iterator,
+ Union,
+ IO,
+ overload,
+ Sequence,
+ Callable,
+ Pattern,
+ Protocol,
+ Iterable,
+)
from numpy import (
DataSource as DataSource,
+ ndarray,
+ recarray,
+ dtype,
+ generic,
+ float64,
+ void,
)
+from numpy.ma.mrecords import MaskedRecords
+from numpy.typing import ArrayLike, DTypeLike, NDArray, _SupportsDType
+
from numpy.core.multiarray import (
packbits as packbits,
unpackbits as unpackbits,
)
+_T = TypeVar("_T")
+_T_contra = TypeVar("_T_contra", contravariant=True)
+_T_co = TypeVar("_T_co", covariant=True)
+_SCT = TypeVar("_SCT", bound=generic)
+_CharType_co = TypeVar("_CharType_co", str, bytes, covariant=True)
+_CharType_contra = TypeVar("_CharType_contra", str, bytes, contravariant=True)
+
+_DTypeLike = Union[
+ Type[_SCT],
+ dtype[_SCT],
+ _SupportsDType[dtype[_SCT]],
+]
+
+class _SupportsGetItem(Protocol[_T_contra, _T_co]):
+ def __getitem__(self, key: _T_contra, /) -> _T_co: ...
+
+class _SupportsRead(Protocol[_CharType_co]):
+ def read(self) -> _CharType_co: ...
+
+class _SupportsReadSeek(Protocol[_CharType_co]):
+ def read(self, n: int, /) -> _CharType_co: ...
+ def seek(self, offset: int, whence: int, /) -> object: ...
+
+class _SupportsWrite(Protocol[_CharType_contra]):
+ def write(self, s: _CharType_contra, /) -> object: ...
+
__all__: List[str]
-def loads(*args, **kwargs): ...
-
-class BagObj:
- def __init__(self, obj): ...
- def __getattribute__(self, key): ...
- def __dir__(self): ...
-
-def zipfile_factory(file, *args, **kwargs): ...
-
-class NpzFile(Mapping[Any, Any]):
- zip: Any
- fid: Any
- files: Any
- allow_pickle: Any
- pickle_kwargs: Any
- f: Any
- def __init__(self, fid, own_fid=..., allow_pickle=..., pickle_kwargs=...): ...
- def __enter__(self): ...
- def __exit__(self, exc_type, exc_value, traceback): ...
- def close(self): ...
- def __del__(self): ...
- def __iter__(self): ...
- def __len__(self): ...
- def __getitem__(self, key): ...
- def iteritems(self): ...
- def iterkeys(self): ...
-
-def load(file, mmap_mode=..., allow_pickle=..., fix_imports=..., encoding=...): ...
-def save(file, arr, allow_pickle=..., fix_imports=...): ...
-def savez(file, *args, **kwds): ...
-def savez_compressed(file, *args, **kwds): ...
+class BagObj(Generic[_T_co]):
+ def __init__(self, obj: _SupportsGetItem[str, _T_co]) -> None: ...
+ def __getattribute__(self, key: str) -> _T_co: ...
+ def __dir__(self) -> List[str]: ...
+
+class NpzFile(Mapping[str, NDArray[Any]]):
+ zip: zipfile.ZipFile
+ fid: None | IO[str]
+ files: List[str]
+ allow_pickle: bool
+ pickle_kwargs: None | Mapping[str, Any]
+ # Represent `f` as a mutable property so we can access the type of `self`
+ @property
+ def f(self: _T) -> BagObj[_T]: ...
+ @f.setter
+ def f(self: _T, value: BagObj[_T]) -> None: ...
+ def __init__(
+ self,
+ fid: IO[str],
+ own_fid: bool = ...,
+ allow_pickle: bool = ...,
+ pickle_kwargs: None | Mapping[str, Any] = ...,
+ ) -> None: ...
+ def __enter__(self: _T) -> _T: ...
+ def __exit__(
+ self,
+ exc_type: None | Type[BaseException],
+ exc_value: None | BaseException,
+ traceback: None | types.TracebackType,
+ /,
+ ) -> None: ...
+ def close(self) -> None: ...
+ def __del__(self) -> None: ...
+ def __iter__(self) -> Iterator[str]: ...
+ def __len__(self) -> int: ...
+ def __getitem__(self, key: str) -> NDArray[Any]: ...
+
+# NOTE: Returns a `NpzFile` if file is a zip file;
+# returns an `ndarray`/`memmap` otherwise
+def load(
+ file: str | bytes | os.PathLike[Any] | _SupportsReadSeek[bytes],
+ mmap_mode: L[None, "r+", "r", "w+", "c"] = ...,
+ allow_pickle: bool = ...,
+ fix_imports: bool = ...,
+ encoding: L["ASCII", "latin1", "bytes"] = ...,
+) -> Any: ...
+
+def save(
+ file: str | os.PathLike[str] | _SupportsWrite[bytes],
+ arr: ArrayLike,
+ allow_pickle: bool = ...,
+ fix_imports: bool = ...,
+) -> None: ...
+
+def savez(
+ file: str | os.PathLike[str] | _SupportsWrite[bytes],
+ *args: ArrayLike,
+ **kwds: ArrayLike,
+) -> None: ...
+
+def savez_compressed(
+ file: str | os.PathLike[str] | _SupportsWrite[bytes],
+ *args: ArrayLike,
+ **kwds: ArrayLike,
+) -> None: ...
+
+# File-like objects only have to implement `__iter__` and,
+# optionally, `encoding`
+@overload
def loadtxt(
- fname,
- dtype=...,
- comments=...,
- delimiter=...,
- converters=...,
- skiprows=...,
- usecols=...,
- unpack=...,
- ndmin=...,
- encoding=...,
- max_rows=...,
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
+ dtype: None = ...,
+ comments: str | Sequence[str] = ...,
+ delimiter: None | str = ...,
+ converters: None | Mapping[int | str, Callable[[str], Any]] = ...,
+ skiprows: int = ...,
+ usecols: int | Sequence[int] = ...,
+ unpack: bool = ...,
+ ndmin: L[0, 1, 2] = ...,
+ encoding: None | str = ...,
+ max_rows: None | int = ...,
*,
- like=...,
-): ...
+ like: None | ArrayLike = ...
+) -> NDArray[float64]: ...
+@overload
+def loadtxt(
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
+ dtype: _DTypeLike[_SCT],
+ comments: str | Sequence[str] = ...,
+ delimiter: None | str = ...,
+ converters: None | Mapping[int | str, Callable[[str], Any]] = ...,
+ skiprows: int = ...,
+ usecols: int | Sequence[int] = ...,
+ unpack: bool = ...,
+ ndmin: L[0, 1, 2] = ...,
+ encoding: None | str = ...,
+ max_rows: None | int = ...,
+ *,
+ like: None | ArrayLike = ...
+) -> NDArray[_SCT]: ...
+@overload
+def loadtxt(
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
+ dtype: DTypeLike,
+ comments: str | Sequence[str] = ...,
+ delimiter: None | str = ...,
+ converters: None | Mapping[int | str, Callable[[str], Any]] = ...,
+ skiprows: int = ...,
+ usecols: int | Sequence[int] = ...,
+ unpack: bool = ...,
+ ndmin: L[0, 1, 2] = ...,
+ encoding: None | str = ...,
+ max_rows: None | int = ...,
+ *,
+ like: None | ArrayLike = ...
+) -> NDArray[Any]: ...
+
def savetxt(
- fname,
- X,
- fmt=...,
- delimiter=...,
- newline=...,
- header=...,
- footer=...,
- comments=...,
- encoding=...,
-): ...
-def fromregex(file, regexp, dtype, encoding=...): ...
+ fname: str | os.PathLike[str] | _SupportsWrite[str] | _SupportsWrite[bytes],
+ X: ArrayLike,
+ fmt: str | Sequence[str] = ...,
+ delimiter: str = ...,
+ newline: str = ...,
+ header: str = ...,
+ footer: str = ...,
+ comments: str = ...,
+ encoding: None | str = ...,
+) -> None: ...
+
+@overload
+def fromregex(
+ file: str | os.PathLike[str] | _SupportsRead[str] | _SupportsRead[bytes],
+ regexp: str | bytes | Pattern[Any],
+ dtype: _DTypeLike[_SCT],
+ encoding: None | str = ...
+) -> NDArray[_SCT]: ...
+@overload
+def fromregex(
+ file: str | os.PathLike[str] | _SupportsRead[str] | _SupportsRead[bytes],
+ regexp: str | bytes | Pattern[Any],
+ dtype: DTypeLike,
+ encoding: None | str = ...
+) -> NDArray[Any]: ...
+
+# TODO: Sort out arguments
+@overload
def genfromtxt(
- fname,
- dtype=...,
- comments=...,
- delimiter=...,
- skip_header=...,
- skip_footer=...,
- converters=...,
- missing_values=...,
- filling_values=...,
- usecols=...,
- names=...,
- excludelist=...,
- deletechars=...,
- replace_space=...,
- autostrip=...,
- case_sensitive=...,
- defaultfmt=...,
- unpack=...,
- usemask=...,
- loose=...,
- invalid_raise=...,
- max_rows=...,
- encoding=...,
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
+ dtype: None = ...,
+ *args: Any,
+ **kwargs: Any,
+) -> NDArray[float64]: ...
+@overload
+def genfromtxt(
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
+ dtype: _DTypeLike[_SCT],
+ *args: Any,
+ **kwargs: Any,
+) -> NDArray[_SCT]: ...
+@overload
+def genfromtxt(
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
+ dtype: DTypeLike,
+ *args: Any,
+ **kwargs: Any,
+) -> NDArray[Any]: ...
+
+@overload
+def recfromtxt(
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
+ *,
+ usemask: L[False] = ...,
+ **kwargs: Any,
+) -> recarray[Any, dtype[void]]: ...
+@overload
+def recfromtxt(
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
+ *,
+ usemask: L[True],
+ **kwargs: Any,
+) -> MaskedRecords[Any, dtype[void]]: ...
+
+@overload
+def recfromcsv(
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
+ *,
+ usemask: L[False] = ...,
+ **kwargs: Any,
+) -> recarray[Any, dtype[void]]: ...
+@overload
+def recfromcsv(
+ fname: str | os.PathLike[str] | Iterable[str] | Iterable[bytes],
*,
- like=...,
-): ...
-def recfromtxt(fname, **kwargs): ...
-def recfromcsv(fname, **kwargs): ...
-
-# NOTE: Deprecated
-# def ndfromtxt(fname, **kwargs): ...
-# def mafromtxt(fname, **kwargs): ...
+ usemask: L[True],
+ **kwargs: Any,
+) -> MaskedRecords[Any, dtype[void]]: ...
diff --git a/numpy/lib/polynomial.py b/numpy/lib/polynomial.py
index 23021cafa..c40e50a57 100644
--- a/numpy/lib/polynomial.py
+++ b/numpy/lib/polynomial.py
@@ -152,9 +152,8 @@ def poly(seq_of_zeros):
return 1.0
dt = seq_of_zeros.dtype
a = ones((1,), dtype=dt)
- for k in range(len(seq_of_zeros)):
- a = NX.convolve(a, array([1, -seq_of_zeros[k]], dtype=dt),
- mode='full')
+ for zero in seq_of_zeros:
+ a = NX.convolve(a, array([1, -zero], dtype=dt), mode='full')
if issubclass(a.dtype.type, NX.complexfloating):
# if complex roots are all complex conjugates, the roots are real.
@@ -770,8 +769,8 @@ def polyval(p, x):
else:
x = NX.asanyarray(x)
y = NX.zeros_like(x)
- for i in range(len(p)):
- y = y * x + p[i]
+ for pv in p:
+ y = y * x + pv
return y
@@ -1273,14 +1272,14 @@ class poly1d:
s = s[:-5]
return s
- for k in range(len(coeffs)):
- if not iscomplex(coeffs[k]):
- coefstr = fmt_float(real(coeffs[k]))
- elif real(coeffs[k]) == 0:
- coefstr = '%sj' % fmt_float(imag(coeffs[k]))
+ for k, coeff in enumerate(coeffs):
+ if not iscomplex(coeff):
+ coefstr = fmt_float(real(coeff))
+ elif real(coeff) == 0:
+ coefstr = '%sj' % fmt_float(imag(coeff))
else:
- coefstr = '(%s + %sj)' % (fmt_float(real(coeffs[k])),
- fmt_float(imag(coeffs[k])))
+ coefstr = '(%s + %sj)' % (fmt_float(real(coeff)),
+ fmt_float(imag(coeff)))
power = (N-k)
if power == 0:
diff --git a/numpy/lib/shape_base.pyi b/numpy/lib/shape_base.pyi
index cfb3040b7..1598dc36c 100644
--- a/numpy/lib/shape_base.pyi
+++ b/numpy/lib/shape_base.pyi
@@ -1,5 +1,4 @@
-from typing import List, TypeVar, Callable, Sequence, Any, overload, Tuple
-from typing_extensions import SupportsIndex, Protocol
+from typing import List, TypeVar, Callable, Sequence, Any, overload, Tuple, SupportsIndex, Protocol
from numpy import (
generic,
@@ -39,15 +38,17 @@ _ArrayLike = _NestedSequence[_SupportsDType[dtype[_SCT]]]
class _ArrayWrap(Protocol):
def __call__(
self,
- __array: NDArray[Any],
- __context: None | Tuple[ufunc, Tuple[Any, ...], int] = ...,
+ array: NDArray[Any],
+ context: None | Tuple[ufunc, Tuple[Any, ...], int] = ...,
+ /,
) -> Any: ...
class _ArrayPrepare(Protocol):
def __call__(
self,
- __array: NDArray[Any],
- __context: None | Tuple[ufunc, Tuple[Any, ...], int] = ...,
+ array: NDArray[Any],
+ context: None | Tuple[ufunc, Tuple[Any, ...], int] = ...,
+ /,
) -> Any: ...
class _SupportsArrayWrap(Protocol):
diff --git a/numpy/lib/stride_tricks.pyi b/numpy/lib/stride_tricks.pyi
index d2e744b5a..bafc46e9c 100644
--- a/numpy/lib/stride_tricks.pyi
+++ b/numpy/lib/stride_tricks.pyi
@@ -1,16 +1,81 @@
-from typing import Any, List
+from typing import Any, List, Dict, Iterable, TypeVar, overload, SupportsIndex
-from numpy.typing import _ShapeLike, _Shape
+from numpy import dtype, generic
+from numpy.typing import (
+ NDArray,
+ ArrayLike,
+ _ShapeLike,
+ _Shape,
+ _NestedSequence,
+ _SupportsArray,
+)
+
+_SCT = TypeVar("_SCT", bound=generic)
+_ArrayLike = _NestedSequence[_SupportsArray[dtype[_SCT]]]
__all__: List[str]
class DummyArray:
- __array_interface__: Any
- base: Any
- def __init__(self, interface, base=...): ...
+ __array_interface__: Dict[str, Any]
+ base: None | NDArray[Any]
+ def __init__(
+ self,
+ interface: Dict[str, Any],
+ base: None | NDArray[Any] = ...,
+ ) -> None: ...
+
+@overload
+def as_strided(
+ x: _ArrayLike[_SCT],
+ shape: None | Iterable[int] = ...,
+ strides: None | Iterable[int] = ...,
+ subok: bool = ...,
+ writeable: bool = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def as_strided(
+ x: ArrayLike,
+ shape: None | Iterable[int] = ...,
+ strides: None | Iterable[int] = ...,
+ subok: bool = ...,
+ writeable: bool = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def sliding_window_view(
+ x: _ArrayLike[_SCT],
+ window_shape: int | Iterable[int],
+ axis: None | SupportsIndex = ...,
+ *,
+ subok: bool = ...,
+ writeable: bool = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def sliding_window_view(
+ x: ArrayLike,
+ window_shape: int | Iterable[int],
+ axis: None | SupportsIndex = ...,
+ *,
+ subok: bool = ...,
+ writeable: bool = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def broadcast_to(
+ array: _ArrayLike[_SCT],
+ shape: int | Iterable[int],
+ subok: bool = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def broadcast_to(
+ array: ArrayLike,
+ shape: int | Iterable[int],
+ subok: bool = ...,
+) -> NDArray[Any]: ...
-def as_strided(x, shape=..., strides=..., subok=..., writeable=...): ...
-def sliding_window_view(x, window_shape, axis=..., *, subok=..., writeable=...): ...
-def broadcast_to(array, shape, subok=...): ...
def broadcast_shapes(*args: _ShapeLike) -> _Shape: ...
-def broadcast_arrays(*args, subok=...): ...
+
+def broadcast_arrays(
+ *args: ArrayLike,
+ subok: bool = ...,
+) -> List[NDArray[Any]]: ...
diff --git a/numpy/lib/tests/test__datasource.py b/numpy/lib/tests/test__datasource.py
index 1ed7815d9..2738d41c4 100644
--- a/numpy/lib/tests/test__datasource.py
+++ b/numpy/lib/tests/test__datasource.py
@@ -102,10 +102,10 @@ class TestDataSourceOpen:
def test_InvalidHTTP(self):
url = invalid_httpurl()
- assert_raises(IOError, self.ds.open, url)
+ assert_raises(OSError, self.ds.open, url)
try:
self.ds.open(url)
- except IOError as e:
+ except OSError as e:
# Regression test for bug fixed in r4342.
assert_(e.errno is None)
@@ -120,7 +120,7 @@ class TestDataSourceOpen:
def test_InvalidFile(self):
invalid_file = invalid_textfile(self.tmpdir)
- assert_raises(IOError, self.ds.open, invalid_file)
+ assert_raises(OSError, self.ds.open, invalid_file)
def test_ValidGzipFile(self):
try:
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
index e1b615223..829691b1c 100644
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -1528,6 +1528,21 @@ class TestVectorize:
([('x',)], [('y',), ()]))
assert_equal(nfb._parse_gufunc_signature('(),(a,b,c),(d)->(d,e)'),
([(), ('a', 'b', 'c'), ('d',)], [('d', 'e')]))
+
+ # Tests to check if whitespaces are ignored
+ assert_equal(nfb._parse_gufunc_signature('(x )->()'), ([('x',)], [()]))
+ assert_equal(nfb._parse_gufunc_signature('( x , y )->( )'),
+ ([('x', 'y')], [()]))
+ assert_equal(nfb._parse_gufunc_signature('(x),( y) ->()'),
+ ([('x',), ('y',)], [()]))
+ assert_equal(nfb._parse_gufunc_signature('( x)-> (y ) '),
+ ([('x',)], [('y',)]))
+ assert_equal(nfb._parse_gufunc_signature(' (x)->( y),( )'),
+ ([('x',)], [('y',), ()]))
+ assert_equal(nfb._parse_gufunc_signature(
+ '( ), ( a, b,c ) ,( d) -> (d , e)'),
+ ([(), ('a', 'b', 'c'), ('d',)], [('d', 'e')]))
+
with assert_raises(ValueError):
nfb._parse_gufunc_signature('(x)(y)->()')
with assert_raises(ValueError):
@@ -2757,11 +2772,6 @@ class TestInterp:
assert_almost_equal(np.interp(x, xp, fp, period=360), y)
-def compare_results(res, desired):
- for i in range(len(desired)):
- assert_array_equal(res[i], desired[i])
-
-
class TestPercentile:
def test_basic(self):
diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py
index d97ad76df..11f2b7d4d 100644
--- a/numpy/lib/tests/test_io.py
+++ b/numpy/lib/tests/test_io.py
@@ -1229,9 +1229,11 @@ class Testfromregex:
a = np.array([(1312,), (1534,), (4444,)], dtype=dt)
assert_array_equal(x, a)
- def test_record_unicode(self):
+ @pytest.mark.parametrize("path_type", [str, Path])
+ def test_record_unicode(self, path_type):
utf8 = b'\xcf\x96'
- with temppath() as path:
+ with temppath() as str_path:
+ path = path_type(str_path)
with open(path, 'wb') as f:
f.write(b'1.312 foo' + utf8 + b' \n1.534 bar\n4.444 qux')
@@ -2503,28 +2505,6 @@ class TestPathUsage:
data = np.genfromtxt(path)
assert_array_equal(a, data)
- def test_ndfromtxt(self):
- # Test outputting a standard ndarray
- with temppath(suffix='.txt') as path:
- path = Path(path)
- with path.open('w') as f:
- f.write(u'1 2\n3 4')
-
- control = np.array([[1, 2], [3, 4]], dtype=int)
- test = np.genfromtxt(path, dtype=int)
- assert_array_equal(test, control)
-
- def test_mafromtxt(self):
- # From `test_fancy_dtype_alt` above
- with temppath(suffix='.txt') as path:
- path = Path(path)
- with path.open('w') as f:
- f.write(u'1,2,3.0\n4,5,6.0\n')
-
- test = np.genfromtxt(path, delimiter=',', usemask=True)
- control = ma.array([(1.0, 2.0, 3.0), (4.0, 5.0, 6.0)])
- assert_equal(test, control)
-
def test_recfromtxt(self):
with temppath(suffix='.txt') as path:
path = Path(path)
diff --git a/numpy/lib/tests/test_shape_base.py b/numpy/lib/tests/test_shape_base.py
index fb7ba7874..a148e53da 100644
--- a/numpy/lib/tests/test_shape_base.py
+++ b/numpy/lib/tests/test_shape_base.py
@@ -392,7 +392,7 @@ class TestArraySplit:
assert_(a.dtype.type is res[-1].dtype.type)
# Same thing for manual splits:
- res = array_split(a, [0, 1, 2], axis=0)
+ res = array_split(a, [0, 1], axis=0)
tgt = [np.zeros((0, 10)), np.array([np.arange(10)]),
np.array([np.arange(10)])]
compare_results(res, tgt)
@@ -713,5 +713,9 @@ class TestMayShareMemory:
# Utility
def compare_results(res, desired):
- for i in range(len(desired)):
- assert_array_equal(res[i], desired[i])
+ """Compare lists of arrays."""
+ if len(res) != len(desired):
+ raise ValueError("Iterables have different lengths")
+ # See also PEP 618 for Python 3.10
+ for x, y in zip(res, desired):
+ assert_array_equal(x, y)
diff --git a/numpy/lib/tests/test_utils.py b/numpy/lib/tests/test_utils.py
index 8a877ae69..72c91836f 100644
--- a/numpy/lib/tests/test_utils.py
+++ b/numpy/lib/tests/test_utils.py
@@ -11,6 +11,10 @@ from io import StringIO
@pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO")
+@pytest.mark.skipif(
+ sys.version_info == (3, 10, 0, "candidate", 1),
+ reason="Broken as of bpo-44524",
+)
def test_lookfor():
out = StringIO()
utils.lookfor('eigenvalue', module='numpy', output=out,
@@ -160,7 +164,7 @@ def test_info_method_heading():
class WithPublicMethods:
def first_method():
pass
-
+
def _has_method_heading(cls):
out = StringIO()
utils.info(cls, output=out)
diff --git a/numpy/lib/type_check.pyi b/numpy/lib/type_check.pyi
index fbe325858..5eb0e62d2 100644
--- a/numpy/lib/type_check.pyi
+++ b/numpy/lib/type_check.pyi
@@ -1,5 +1,5 @@
-import sys
from typing import (
+ Literal as L,
Any,
Container,
Iterable,
@@ -7,6 +7,7 @@ from typing import (
overload,
Type,
TypeVar,
+ Protocol,
)
from numpy import (
@@ -32,11 +33,6 @@ from numpy.typing import (
_DTypeLikeComplex,
)
-if sys.version_info >= (3, 8):
- from typing import Protocol, Literal as L
-else:
- from typing_extensions import Protocol, Literal as L
-
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
_SCT = TypeVar("_SCT", bound=generic)
diff --git a/numpy/lib/utils.py b/numpy/lib/utils.py
index b1a916d4a..1f2cb66fa 100644
--- a/numpy/lib/utils.py
+++ b/numpy/lib/utils.py
@@ -351,8 +351,7 @@ def who(vardict=None):
maxshape = 0
maxbyte = 0
totalbytes = 0
- for k in range(len(sta)):
- val = sta[k]
+ for val in sta:
if maxname < len(val[0]):
maxname = len(val[0])
if maxshape < len(val[1]):
@@ -369,8 +368,7 @@ def who(vardict=None):
prval = "Name %s Shape %s Bytes %s Type" % (sp1*' ', sp2*' ', sp3*' ')
print(prval + "\n" + "="*(len(prval)+5) + "\n")
- for k in range(len(sta)):
- val = sta[k]
+ for val in sta:
print("%s %s %s %s %s %s %s" % (val[0], ' '*(sp1-len(val[0])+4),
val[1], ' '*(sp2-len(val[1])+5),
val[2], ' '*(sp3-len(val[2])+5),
diff --git a/numpy/lib/utils.pyi b/numpy/lib/utils.pyi
index 0518655c6..f0a8797ad 100644
--- a/numpy/lib/utils.pyi
+++ b/numpy/lib/utils.pyi
@@ -1,4 +1,3 @@
-import sys
from ast import AST
from typing import (
Any,
@@ -11,6 +10,7 @@ from typing import (
Tuple,
TypeVar,
Union,
+ Protocol,
)
from numpy import ndarray, generic
@@ -21,17 +21,12 @@ from numpy.core.numerictypes import (
issubsctype as issubsctype,
)
-if sys.version_info >= (3, 8):
- from typing import Protocol
-else:
- from typing_extensions import Protocol
-
_T_contra = TypeVar("_T_contra", contravariant=True)
_FuncType = TypeVar("_FuncType", bound=Callable[..., Any])
# A file-like object opened in `w` mode
class _SupportsWrite(Protocol[_T_contra]):
- def write(self, __s: _T_contra) -> Any: ...
+ def write(self, s: _T_contra, /) -> Any: ...
__all__: List[str]
@@ -60,7 +55,8 @@ def deprecate(
) -> _Deprecate: ...
@overload
def deprecate(
- __func: _FuncType,
+ func: _FuncType,
+ /,
old_name: Optional[str] = ...,
new_name: Optional[str] = ...,
message: Optional[str] = ...,