summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2020-01-06 18:18:57 +0200
committerGitHub <noreply@github.com>2020-01-06 18:18:57 +0200
commit682177360bff78786d8d45bb9203839c4ad44357 (patch)
tree7bcb6186447565adff24837cc6529b74564b4520 /numpy/core
parentb66864cfcaf0875f80bf68ccbd0cbbaaabc94f85 (diff)
parentb6379539924568dad725f2ecc820477685f8d938 (diff)
downloadnumpy-682177360bff78786d8d45bb9203839c4ad44357.tar.gz
Merge pull request #15256 from eric-wieser/use-keyword-only-arguments
MAINT: Implement keyword-only arguments as syntax
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/_ufunc_config.py4
-rw-r--r--numpy/core/arrayprint.py59
-rw-r--r--numpy/core/code_generators/generate_umath.py6
-rw-r--r--numpy/core/einsumfunc.py62
-rw-r--r--numpy/core/getlimits.py12
-rw-r--r--numpy/core/numeric.py3
-rw-r--r--numpy/core/tests/test_umath.py4
7 files changed, 61 insertions, 89 deletions
diff --git a/numpy/core/_ufunc_config.py b/numpy/core/_ufunc_config.py
index cc8d2bcb0..4872a5385 100644
--- a/numpy/core/_ufunc_config.py
+++ b/numpy/core/_ufunc_config.py
@@ -430,8 +430,8 @@ class errstate(contextlib.ContextDecorator):
"""
- def __init__(self, **kwargs):
- self.call = kwargs.pop('call', _Unspecified)
+ def __init__(self, *, call=_Unspecified, **kwargs):
+ self.call = call
self.kwargs = kwargs
def __enter__(self):
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
index 136b9ecff..918da4a72 100644
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -98,7 +98,7 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None,
@set_module('numpy')
def set_printoptions(precision=None, threshold=None, edgeitems=None,
linewidth=None, suppress=None, nanstr=None, infstr=None,
- formatter=None, sign=None, floatmode=None, **kwarg):
+ formatter=None, sign=None, floatmode=None, *, legacy=None):
"""
Set printing options.
@@ -247,11 +247,6 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ])
"""
- legacy = kwarg.pop('legacy', None)
- if kwarg:
- msg = "set_printoptions() got unexpected keyword argument '{}'"
- raise TypeError(msg.format(kwarg.popitem()[0]))
-
opt = _make_options_dict(precision, threshold, edgeitems, linewidth,
suppress, nanstr, infstr, sign, formatter,
floatmode, legacy)
@@ -367,23 +362,22 @@ def repr_format(x):
def str_format(x):
return str(x)
-def _get_formatdict(data, **opt):
- prec, fmode = opt['precision'], opt['floatmode']
- supp, sign = opt['suppress'], opt['sign']
- legacy = opt['legacy']
+def _get_formatdict(data, *, precision, floatmode, suppress, sign, legacy,
+ formatter, **kwargs):
+ # note: extra arguments in kwargs are ignored
# wrapped in lambdas to avoid taking a code path with the wrong type of data
formatdict = {
'bool': lambda: BoolFormat(data),
'int': lambda: IntegerFormat(data),
- 'float': lambda:
- FloatingFormat(data, prec, fmode, supp, sign, legacy=legacy),
- 'longfloat': lambda:
- FloatingFormat(data, prec, fmode, supp, sign, legacy=legacy),
- 'complexfloat': lambda:
- ComplexFloatingFormat(data, prec, fmode, supp, sign, legacy=legacy),
- 'longcomplexfloat': lambda:
- ComplexFloatingFormat(data, prec, fmode, supp, sign, legacy=legacy),
+ 'float': lambda: FloatingFormat(
+ data, precision, floatmode, suppress, sign, legacy=legacy),
+ 'longfloat': lambda: FloatingFormat(
+ data, precision, floatmode, suppress, sign, legacy=legacy),
+ 'complexfloat': lambda: ComplexFloatingFormat(
+ data, precision, floatmode, suppress, sign, legacy=legacy),
+ 'longcomplexfloat': lambda: ComplexFloatingFormat(
+ data, precision, floatmode, suppress, sign, legacy=legacy),
'datetime': lambda: DatetimeFormat(data, legacy=legacy),
'timedelta': lambda: TimedeltaFormat(data),
'object': lambda: _object_format,
@@ -396,7 +390,6 @@ def _get_formatdict(data, **opt):
def indirect(x):
return lambda: x
- formatter = opt['formatter']
if formatter is not None:
fkeys = [k for k in formatter.keys() if formatter[k] is not None]
if 'all' in fkeys:
@@ -523,7 +516,7 @@ def _array2string_dispatcher(
suppress_small=None, separator=None, prefix=None,
style=None, formatter=None, threshold=None,
edgeitems=None, sign=None, floatmode=None, suffix=None,
- **kwarg):
+ *, legacy=None):
return (a,)
@@ -532,7 +525,7 @@ def array2string(a, max_line_width=None, precision=None,
suppress_small=None, separator=' ', prefix="",
style=np._NoValue, formatter=None, threshold=None,
edgeitems=None, sign=None, floatmode=None, suffix="",
- **kwarg):
+ *, legacy=None):
"""
Return a string representation of an array.
@@ -677,10 +670,6 @@ def array2string(a, max_line_width=None, precision=None,
'[0x0 0x1 0x2]'
"""
- legacy = kwarg.pop('legacy', None)
- if kwarg:
- msg = "array2string() got unexpected keyword argument '{}'"
- raise TypeError(msg.format(kwarg.popitem()[0]))
overrides = _make_options_dict(precision, threshold, edgeitems,
max_line_width, suppress_small, None, None,
@@ -852,12 +841,12 @@ def _none_or_positive_arg(x, name):
class FloatingFormat:
""" Formatter for subtypes of np.floating """
def __init__(self, data, precision, floatmode, suppress_small, sign=False,
- **kwarg):
+ *, legacy=None):
# for backcompatibility, accept bools
if isinstance(sign, bool):
sign = '+' if sign else '-'
- self._legacy = kwarg.get('legacy', False)
+ self._legacy = legacy
if self._legacy == '1.13':
# when not 0d, legacy does not support '-'
if data.shape != () and sign == '-':
@@ -1164,20 +1153,24 @@ class BoolFormat:
class ComplexFloatingFormat:
""" Formatter for subtypes of np.complexfloating """
def __init__(self, x, precision, floatmode, suppress_small,
- sign=False, **kwarg):
+ sign=False, *, legacy=None):
# for backcompatibility, accept bools
if isinstance(sign, bool):
sign = '+' if sign else '-'
floatmode_real = floatmode_imag = floatmode
- if kwarg.get('legacy', False) == '1.13':
+ if legacy == '1.13':
floatmode_real = 'maxprec_equal'
floatmode_imag = 'maxprec'
- self.real_format = FloatingFormat(x.real, precision, floatmode_real,
- suppress_small, sign=sign, **kwarg)
- self.imag_format = FloatingFormat(x.imag, precision, floatmode_imag,
- suppress_small, sign='+', **kwarg)
+ self.real_format = FloatingFormat(
+ x.real, precision, floatmode_real, suppress_small,
+ sign=sign, legacy=legacy
+ )
+ self.imag_format = FloatingFormat(
+ x.imag, precision, floatmode_imag, suppress_small,
+ sign='+', legacy=legacy
+ )
def __call__(self, x):
r = self.real_format(x.real)
diff --git a/numpy/core/code_generators/generate_umath.py b/numpy/core/code_generators/generate_umath.py
index c517248de..6f18d5aa9 100644
--- a/numpy/core/code_generators/generate_umath.py
+++ b/numpy/core/code_generators/generate_umath.py
@@ -130,7 +130,7 @@ class Ufunc:
type_descriptions : list of TypeDescription objects
"""
def __init__(self, nin, nout, identity, docstring, typereso,
- *type_descriptions, **kwargs):
+ *type_descriptions, signature=None):
self.nin = nin
self.nout = nout
if identity is None:
@@ -139,13 +139,11 @@ class Ufunc:
self.docstring = docstring
self.typereso = typereso
self.type_descriptions = []
- self.signature = kwargs.pop('signature', None)
+ self.signature = signature
for td in type_descriptions:
self.type_descriptions.extend(td)
for td in self.type_descriptions:
td.finish_signature(self.nin, self.nout)
- if kwargs:
- raise ValueError('unknown kwargs %r' % str(kwargs))
# String-handling utilities to avoid locale-dependence.
diff --git a/numpy/core/einsumfunc.py b/numpy/core/einsumfunc.py
index 8ae14ce30..ec3eb19d2 100644
--- a/numpy/core/einsumfunc.py
+++ b/numpy/core/einsumfunc.py
@@ -689,7 +689,7 @@ def _parse_einsum_input(operands):
return (input_subscripts, output_subscript, operands)
-def _einsum_path_dispatcher(*operands, **kwargs):
+def _einsum_path_dispatcher(*operands, optimize=None, einsum_call=None):
# NOTE: technically, we should only dispatch on array-like arguments, not
# subscripts (given as strings). But separating operands into
# arrays/subscripts is a little tricky/slow (given einsum's two supported
@@ -700,7 +700,7 @@ def _einsum_path_dispatcher(*operands, **kwargs):
@array_function_dispatch(_einsum_path_dispatcher, module='numpy')
-def einsum_path(*operands, **kwargs):
+def einsum_path(*operands, optimize='greedy', einsum_call=False):
"""
einsum_path(subscripts, *operands, optimize='greedy')
@@ -810,16 +810,8 @@ def einsum_path(*operands, **kwargs):
5 defg,hd->efgh efgh->efgh
"""
- # Make sure all keywords are valid
- valid_contract_kwargs = ['optimize', 'einsum_call']
- unknown_kwargs = [k for (k, v) in kwargs.items() if k
- not in valid_contract_kwargs]
- if len(unknown_kwargs):
- raise TypeError("Did not understand the following kwargs:"
- " %s" % unknown_kwargs)
-
# Figure out what the path really is
- path_type = kwargs.pop('optimize', True)
+ path_type = optimize
if path_type is True:
path_type = 'greedy'
if path_type is None:
@@ -845,7 +837,7 @@ def einsum_path(*operands, **kwargs):
raise TypeError("Did not understand the path: %s" % str(path_type))
# Hidden option, only einsum should call this
- einsum_call_arg = kwargs.pop("einsum_call", False)
+ einsum_call_arg = einsum_call
# Python side parsing
input_subscripts, output_subscript, operands = _parse_einsum_input(operands)
@@ -990,17 +982,17 @@ def einsum_path(*operands, **kwargs):
return (path, path_print)
-def _einsum_dispatcher(*operands, **kwargs):
+def _einsum_dispatcher(*operands, out=None, optimize=None, **kwargs):
# Arguably we dispatch on more arguments that we really should; see note in
# _einsum_path_dispatcher for why.
for op in operands:
yield op
- yield kwargs.get('out')
+ yield out
# Rewrite einsum to handle different cases
@array_function_dispatch(_einsum_dispatcher, module='numpy')
-def einsum(*operands, **kwargs):
+def einsum(*operands, out=None, optimize=False, **kwargs):
"""
einsum(subscripts, *operands, out=None, dtype=None, order='K',
casting='safe', optimize=False)
@@ -1345,39 +1337,29 @@ def einsum(*operands, **kwargs):
... _ = np.einsum('ijk,ilm,njm,nlk,abc->',a,a,a,a,a, optimize=path)
"""
-
- # Grab non-einsum kwargs; do not optimize by default.
- optimize_arg = kwargs.pop('optimize', False)
+ # Special handling if out is specified
+ specified_out = out is not None
# If no optimization, run pure einsum
- if optimize_arg is False:
+ if optimize is False:
+ if specified_out:
+ kwargs['out'] = out
return c_einsum(*operands, **kwargs)
- valid_einsum_kwargs = ['out', 'dtype', 'order', 'casting']
- einsum_kwargs = {k: v for (k, v) in kwargs.items() if
- k in valid_einsum_kwargs}
-
- # Make sure all keywords are valid
- valid_contract_kwargs = ['optimize'] + valid_einsum_kwargs
+ # Check the kwargs to avoid a more cryptic error later, without having to
+ # repeat default values here
+ valid_einsum_kwargs = ['dtype', 'order', 'casting']
unknown_kwargs = [k for (k, v) in kwargs.items() if
- k not in valid_contract_kwargs]
-
+ k not in valid_einsum_kwargs]
if len(unknown_kwargs):
raise TypeError("Did not understand the following kwargs: %s"
% unknown_kwargs)
- # Special handeling if out is specified
- specified_out = False
- out_array = einsum_kwargs.pop('out', None)
- if out_array is not None:
- specified_out = True
# Build the contraction list and operand
- operands, contraction_list = einsum_path(*operands, optimize=optimize_arg,
+ operands, contraction_list = einsum_path(*operands, optimize=optimize,
einsum_call=True)
- handle_out = False
-
# Start contraction loop
for num, contraction in enumerate(contraction_list):
inds, idx_rm, einsum_str, remaining, blas = contraction
@@ -1408,23 +1390,23 @@ def einsum(*operands, **kwargs):
# Build a new view if needed
if (tensor_result != results_index) or handle_out:
if handle_out:
- einsum_kwargs["out"] = out_array
- new_view = c_einsum(tensor_result + '->' + results_index, new_view, **einsum_kwargs)
+ kwargs["out"] = out
+ new_view = c_einsum(tensor_result + '->' + results_index, new_view, **kwargs)
# Call einsum
else:
# If out was specified
if handle_out:
- einsum_kwargs["out"] = out_array
+ kwargs["out"] = out
# Do the contraction
- new_view = c_einsum(einsum_str, *tmp_operands, **einsum_kwargs)
+ new_view = c_einsum(einsum_str, *tmp_operands, **kwargs)
# Append new items and dereference what we can
operands.append(new_view)
del tmp_operands, new_view
if specified_out:
- return out_array
+ return out
else:
return operands[0]
diff --git a/numpy/core/getlimits.py b/numpy/core/getlimits.py
index a80db1c81..b00ef64bd 100644
--- a/numpy/core/getlimits.py
+++ b/numpy/core/getlimits.py
@@ -34,7 +34,7 @@ class MachArLike:
def __init__(self,
ftype,
- **kwargs):
+ *, eps, epsneg, huge, tiny, ibeta, **kwargs):
params = _MACHAR_PARAMS[ftype]
float_conv = lambda v: array([v], ftype)
float_to_float = lambda v : _fr1(float_conv(v))
@@ -42,11 +42,11 @@ class MachArLike:
self.title = params['title']
# Parameter types same as for discovered MachAr object.
- self.epsilon = self.eps = float_to_float(kwargs.pop('eps'))
- self.epsneg = float_to_float(kwargs.pop('epsneg'))
- self.xmax = self.huge = float_to_float(kwargs.pop('huge'))
- self.xmin = self.tiny = float_to_float(kwargs.pop('tiny'))
- self.ibeta = params['itype'](kwargs.pop('ibeta'))
+ self.epsilon = self.eps = float_to_float(eps)
+ self.epsneg = float_to_float(epsneg)
+ self.xmax = self.huge = float_to_float(huge)
+ self.xmin = self.tiny = float_to_float(tiny)
+ self.ibeta = params['itype'](ibeta)
self.__dict__.update(kwargs)
self.precision = int(-log10(self.eps))
self.resolution = float_to_float(float_conv(10) ** (-self.precision))
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index 505218a2e..f18ab6336 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -1716,7 +1716,7 @@ def indices(dimensions, dtype=int, sparse=False):
@set_module('numpy')
-def fromfunction(function, shape, **kwargs):
+def fromfunction(function, shape, *, dtype=float, **kwargs):
"""
Construct an array by executing a function over each coordinate.
@@ -1767,7 +1767,6 @@ def fromfunction(function, shape, **kwargs):
[2, 3, 4]])
"""
- dtype = kwargs.pop('dtype', float)
args = indices(shape, dtype=dtype)
return function(*args, **kwargs)
diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index 2913b1c4d..e966eebf0 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -2353,7 +2353,7 @@ class TestSpecialMethods:
# NOTE: this class is given as an example in doc/subclassing.py;
# if you make any changes here, do update it there too.
class A(np.ndarray):
- def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
+ def __array_ufunc__(self, ufunc, method, *inputs, out=None, **kwargs):
args = []
in_no = []
for i, input_ in enumerate(inputs):
@@ -2363,7 +2363,7 @@ class TestSpecialMethods:
else:
args.append(input_)
- outputs = kwargs.pop('out', None)
+ outputs = out
out_no = []
if outputs:
out_args = []