From 4da857ae94d9ee9ebeeb67e83858ad31bc3c1838 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Sat, 22 Aug 2020 11:23:55 -0600 Subject: MAINT: Make arrayprint str and repr the ndarray defaults. This removes the old default routines in 'strfunc.c' that were never used and looked to have unicode/byte problems. The functions now self initialize when called, so the explicit initialization when the arrayprint module is loaded is no longer needed. --- numpy/core/arrayprint.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 5d9642ea8..ad1530419 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -1628,6 +1628,3 @@ def set_string_function(f, repr=True): return multiarray.set_string_function(_default_array_str, 0) else: return multiarray.set_string_function(f, repr) - -set_string_function(_default_array_str, False) -set_string_function(_default_array_repr, True) -- cgit v1.2.1 From 76336f1cddc0f62d4ad952785877cd2f4c413911 Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Fri, 18 Dec 2020 12:39:11 +0100 Subject: DOC: Clarify that `np.array2string` can only take an `ndarray` --- numpy/core/arrayprint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index ad1530419..51bad18de 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -524,7 +524,7 @@ def array2string(a, max_line_width=None, precision=None, Parameters ---------- - a : array_like + a : ndarray Input array. max_line_width : int, optional Inserts newlines if text is longer than `max_line_width`. -- cgit v1.2.1 From 82e5747dd40cbbde9c728452f21fa4716492c81d Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Sat, 19 Dec 2020 15:41:38 +0100 Subject: MAINT: Remove any mention of `formatter["str"]` It's been non-functional for the past 8 years (xref https://github.com/numpy/numpy/pull/459) --- numpy/core/arrayprint.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 51bad18de..94ec8ed34 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -146,7 +146,6 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None, - 'longcomplexfloat' : composed of two 128-bit floats - 'numpystr' : types `numpy.string_` and `numpy.unicode_` - 'object' : `np.object_` arrays - - 'str' : all other strings Other keys that can be used to set a group of types at once are: @@ -154,7 +153,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None, - 'int_kind' : sets 'int' - 'float_kind' : sets 'float' and 'longfloat' - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat' - - 'str_kind' : sets 'str' and 'numpystr' + - 'str_kind' : sets 'numpystr' floatmode : str, optional Controls the interpretation of the `precision` option for floating-point types. Can take the following values @@ -375,8 +374,7 @@ def _get_formatdict(data, *, precision, floatmode, suppress, sign, legacy, 'timedelta': lambda: TimedeltaFormat(data), 'object': lambda: _object_format, 'void': lambda: str_format, - 'numpystr': lambda: repr_format, - 'str': lambda: str} + 'numpystr': lambda: repr_format} # we need to wrap values in `formatter` in a lambda, so that the interface # is the same as the above values. @@ -398,8 +396,7 @@ def _get_formatdict(data, *, precision, floatmode, suppress, sign, legacy, for key in ['complexfloat', 'longcomplexfloat']: formatdict[key] = indirect(formatter['complex_kind']) if 'str_kind' in fkeys: - for key in ['numpystr', 'str']: - formatdict[key] = indirect(formatter['str_kind']) + formatdict['numpystr'] = indirect(formatter['str_kind']) for key in formatdict.keys(): if key in fkeys: formatdict[key] = indirect(formatter[key]) @@ -572,7 +569,6 @@ def array2string(a, max_line_width=None, precision=None, - 'longcomplexfloat' : composed of two 128-bit floats - 'void' : type `numpy.void` - 'numpystr' : types `numpy.string_` and `numpy.unicode_` - - 'str' : all other strings Other keys that can be used to set a group of types at once are: @@ -580,7 +576,7 @@ def array2string(a, max_line_width=None, precision=None, - 'int_kind' : sets 'int' - 'float_kind' : sets 'float' and 'longfloat' - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat' - - 'str_kind' : sets 'str' and 'numpystr' + - 'str_kind' : sets 'numpystr' threshold : int, optional Total number of array elements which trigger summarization rather than full repr. -- cgit v1.2.1 From f305d5962614e98eea5d10a2140eee7e16ab9aca Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Wed, 27 Jan 2021 17:43:33 -0800 Subject: DOC: Misc numpydoc format fixes Via prototype docstring autoreformatter; and cherry-picked to mostly include spacing issues around colons in parameters and see also. When no space is present numpydoc tend to miss-parse those sections A couple of typos are fixed as well. --- numpy/core/arrayprint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 94ec8ed34..3fade4824 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -538,7 +538,7 @@ def array2string(a, max_line_width=None, precision=None, separator : str, optional Inserted between elements. prefix : str, optional - suffix: str, optional + suffix : str, optional The length of the prefix and suffix strings are used to respectively align and wrap the output. An array is typically printed as:: -- cgit v1.2.1 From ef639359f4862762d97c215990f86a7a622c0f0d Mon Sep 17 00:00:00 2001 From: Mitchell Faas Date: Sun, 31 Jan 2021 00:51:28 +0100 Subject: ENH: Added sanity check to printoptions See issue #18254 --- numpy/core/arrayprint.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 3fade4824..2d772c778 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -78,6 +78,7 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None, if legacy not in [None, False, '1.13']: warnings.warn("legacy printing option can currently only be '1.13' or " "`False`", stacklevel=3) + if threshold is not None: # forbid the bad threshold arg suggested by stack overflow, gh-12351 if not isinstance(threshold, numbers.Number): @@ -85,6 +86,12 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None, if np.isnan(threshold): raise ValueError("threshold must be non-NAN, try " "sys.maxsize for untruncated representation") + + if precision is not None: + # forbid the bad precision arg as suggested by issue #18254 + if not isinstance(precision, int): + raise TypeError('precision must be an integer') + return options -- cgit v1.2.1 From da39ec1322f93732b7a80402e3a1f1d0ddcf3a7b Mon Sep 17 00:00:00 2001 From: Mitchell Faas Date: Sun, 31 Jan 2021 16:21:47 +0100 Subject: BUG: Now allows for all integer types Fixed a bug where precision couldn't be a non-native integer. See comments on pull request #18263 for more info. --- numpy/core/arrayprint.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 2d772c778..ffcddd9b2 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -41,6 +41,7 @@ from .numeric import concatenate, asarray, errstate from .numerictypes import (longlong, intc, int_, float_, complex_, bool_, flexible) from .overrides import array_function_dispatch, set_module +from operator import index import warnings import contextlib @@ -89,7 +90,9 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None, if precision is not None: # forbid the bad precision arg as suggested by issue #18254 - if not isinstance(precision, int): + try: + options['precision'] = index(precision) + except TypeError: raise TypeError('precision must be an integer') return options -- cgit v1.2.1 From c47ddc18e490ae0b1a8422b2ce6e2b7b5781f87e Mon Sep 17 00:00:00 2001 From: Mitchell-Faas <35742861+Mitchell-Faas@users.noreply.github.com> Date: Sun, 31 Jan 2021 16:28:47 +0100 Subject: ENH: Improved error traceback in set_printoptions Co-authored-by: Eric Wieser --- numpy/core/arrayprint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index ffcddd9b2..7c43d6f75 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -92,8 +92,8 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None, # forbid the bad precision arg as suggested by issue #18254 try: options['precision'] = index(precision) - except TypeError: - raise TypeError('precision must be an integer') + except TypeError as e: + raise TypeError('precision must be an integer') from e return options -- cgit v1.2.1 From 3e285e43b4e430b29711e53cded86eab00f85db2 Mon Sep 17 00:00:00 2001 From: Mitchell Faas Date: Sun, 31 Jan 2021 17:06:57 +0100 Subject: MAINT: import refactor --- numpy/core/arrayprint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 7c43d6f75..5c1d6cb63 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -41,7 +41,7 @@ from .numeric import concatenate, asarray, errstate from .numerictypes import (longlong, intc, int_, float_, complex_, bool_, flexible) from .overrides import array_function_dispatch, set_module -from operator import index +import operator import warnings import contextlib @@ -91,7 +91,7 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None, if precision is not None: # forbid the bad precision arg as suggested by issue #18254 try: - options['precision'] = index(precision) + options['precision'] = operator.index(precision) except TypeError as e: raise TypeError('precision must be an integer') from e -- cgit v1.2.1 From 75bb1a80d104561c7a1870c86e6e5f0972cde5df Mon Sep 17 00:00:00 2001 From: Allan Haldane Date: Mon, 15 Mar 2021 08:27:59 -0400 Subject: BUG/ENH: fix array2string rounding bug by adding min_digits option Fixes #18609 --- numpy/core/arrayprint.py | 64 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 20 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 5c1d6cb63..523820c33 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -914,6 +914,7 @@ class FloatingFormat: self.trim = '.' self.exp_size = -1 self.unique = True + self.min_digits = None elif self.exp_format: trim, unique = '.', True if self.floatmode == 'fixed' or self._legacy == '1.13': @@ -927,6 +928,8 @@ class FloatingFormat: self.trim = 'k' self.precision = max(len(s) for s in frac_part) + self.min_digits = self.precision + self.unique = unique # for back-compat with np 1.13, use 2 spaces & sign and full prec if self._legacy == '1.13': @@ -936,10 +939,7 @@ class FloatingFormat: self.pad_left = max(len(s) for s in int_part) # pad_right is only needed for nan length calculation self.pad_right = self.exp_size + 2 + self.precision - - self.unique = False else: - # first pass printing to determine sizes trim, unique = '.', True if self.floatmode == 'fixed': trim, unique = 'k', False @@ -955,14 +955,14 @@ class FloatingFormat: self.pad_left = max(len(s) for s in int_part) self.pad_right = max(len(s) for s in frac_part) self.exp_size = -1 + self.unique = unique if self.floatmode in ['fixed', 'maxprec_equal']: - self.precision = self.pad_right - self.unique = False + self.precision = self.min_digits = self.pad_right self.trim = 'k' else: - self.unique = True self.trim = '.' + self.min_digits = 0 if self._legacy != '1.13': # account for sign = ' ' by adding one to pad_left @@ -991,6 +991,7 @@ class FloatingFormat: if self.exp_format: return dragon4_scientific(x, precision=self.precision, + min_digits=self.min_digits, unique=self.unique, trim=self.trim, sign=self.sign == '+', @@ -999,6 +1000,7 @@ class FloatingFormat: else: return dragon4_positional(x, precision=self.precision, + min_digits=self.min_digits, unique=self.unique, fractional=True, trim=self.trim, @@ -1009,7 +1011,8 @@ class FloatingFormat: @set_module('numpy') def format_float_scientific(x, precision=None, unique=True, trim='k', - sign=False, pad_left=None, exp_digits=None): + sign=False, pad_left=None, exp_digits=None, + min_digits=None): """ Format a floating-point scalar as a decimal string in scientific notation. @@ -1027,11 +1030,12 @@ def format_float_scientific(x, precision=None, unique=True, trim='k', If `True`, use a digit-generation strategy which gives the shortest representation which uniquely identifies the floating-point number from other values of the same type, by judicious rounding. If `precision` - was omitted, print all necessary digits, otherwise digit generation is - cut off after `precision` digits and the remaining value is rounded. + is given fewer digits than necessary can be printed, or if `min_digits` + is given more can be printed, in which cases the last digit is rounded + with unbiased rounding. If `False`, digits are generated as if printing an infinite-precision value and stopping after `precision` digits, rounding the remaining - value. + value with unbiased rounding trim : one of 'k', '.', '0', '-', optional Controls post-processing trimming of trailing digits, as follows: @@ -1048,6 +1052,10 @@ def format_float_scientific(x, precision=None, unique=True, trim='k', exp_digits : non-negative integer, optional Pad the exponent with zeros until it contains at least this many digits. If omitted, the exponent will be at least 2 digits. + min_digits : non-negative integer or None, optional + Minimum number of digits to print. Only has an effect if `unique=True` + in which case additional digits past those necessary to uniquely + identify the value may be printed, rounding the last additional digit. Returns ------- @@ -1071,15 +1079,18 @@ def format_float_scientific(x, precision=None, unique=True, trim='k', precision = _none_or_positive_arg(precision, 'precision') pad_left = _none_or_positive_arg(pad_left, 'pad_left') exp_digits = _none_or_positive_arg(exp_digits, 'exp_digits') + min_digits = _none_or_positive_arg(min_digits, 'min_digits') + if min_digits > 0 and precision > 0 and min_digits > precision: + raise ValueError("min_digits must be less than or equal to precision") return dragon4_scientific(x, precision=precision, unique=unique, trim=trim, sign=sign, pad_left=pad_left, - exp_digits=exp_digits) + exp_digits=exp_digits, min_digits=min_digits) @set_module('numpy') def format_float_positional(x, precision=None, unique=True, fractional=True, trim='k', sign=False, - pad_left=None, pad_right=None): + pad_left=None, pad_right=None, min_digits=None): """ Format a floating-point scalar as a decimal string in positional notation. @@ -1097,16 +1108,19 @@ def format_float_positional(x, precision=None, unique=True, If `True`, use a digit-generation strategy which gives the shortest representation which uniquely identifies the floating-point number from other values of the same type, by judicious rounding. If `precision` - was omitted, print out all necessary digits, otherwise digit generation - is cut off after `precision` digits and the remaining value is rounded. + is given fewer digits than necessary can be printed, or if `min_digits` + is given more can be printed, in which cases the last digit is rounded + with unbiased rounding. If `False`, digits are generated as if printing an infinite-precision value and stopping after `precision` digits, rounding the remaining - value. + value with unbiased rounding fractional : boolean, optional - If `True`, the cutoff of `precision` digits refers to the total number - of digits after the decimal point, including leading zeros. - If `False`, `precision` refers to the total number of significant - digits, before or after the decimal point, ignoring leading zeros. + If `True`, the cutoffs of `precision` and `min_digits` refer to the + total number of digits after the decimal point, including leading + zeros. + If `False`, `precision` and `min_digits` refer to the total number of + significant digits, before or after the decimal point, ignoring leading + zeros. trim : one of 'k', '.', '0', '-', optional Controls post-processing trimming of trailing digits, as follows: @@ -1123,6 +1137,10 @@ def format_float_positional(x, precision=None, unique=True, pad_right : non-negative integer, optional Pad the right side of the string with whitespace until at least that many characters are to the right of the decimal point. + min_digits : non-negative integer or None, optional + Minimum number of digits to print. Only has an effect if `unique=True` + in which case additional digits past those necessary to uniquely + identify the value may be printed, rounding the last additional digit. Returns ------- @@ -1147,10 +1165,16 @@ def format_float_positional(x, precision=None, unique=True, precision = _none_or_positive_arg(precision, 'precision') pad_left = _none_or_positive_arg(pad_left, 'pad_left') pad_right = _none_or_positive_arg(pad_right, 'pad_right') + min_digits = _none_or_positive_arg(min_digits, 'min_digits') + if not fractional and precision == 0: + raise ValueError("precision must be greater than 0 if " + "fractional=False") + if min_digits > 0 and precision > 0 and min_digits > precision: + raise ValueError("min_digits must be less than or equal to precision") return dragon4_positional(x, precision=precision, unique=unique, fractional=fractional, trim=trim, sign=sign, pad_left=pad_left, - pad_right=pad_right) + pad_right=pad_right, min_digits=min_digits) class IntegerFormat: -- cgit v1.2.1 From c1aa1af62f6e9fcdda92d6d0991b15051a565814 Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Fri, 19 Mar 2021 22:03:06 +1300 Subject: MAINT: use super() as described by PEP 3135 --- numpy/core/arrayprint.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 5c1d6cb63..3251c51e3 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -1253,12 +1253,12 @@ class DatetimeFormat(_TimelikeFormat): self.legacy = legacy # must be called after the above are configured - super(DatetimeFormat, self).__init__(x) + super().__init__(x) def __call__(self, x): if self.legacy == '1.13': return self._format_non_nat(x) - return super(DatetimeFormat, self).__call__(x) + return super().__call__(x) def _format_non_nat(self, x): return "'%s'" % datetime_as_string(x, -- cgit v1.2.1 From f14a028404e0457b7ca049fdd4968675cbc9cf54 Mon Sep 17 00:00:00 2001 From: Allan Haldane Date: Fri, 19 Mar 2021 12:42:57 -0400 Subject: Update numpy/core/arrayprint.py Co-authored-by: Sebastian Berg --- numpy/core/arrayprint.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 523820c33..e86986518 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -1053,9 +1053,9 @@ def format_float_scientific(x, precision=None, unique=True, trim='k', Pad the exponent with zeros until it contains at least this many digits. If omitted, the exponent will be at least 2 digits. min_digits : non-negative integer or None, optional - Minimum number of digits to print. Only has an effect if `unique=True` - in which case additional digits past those necessary to uniquely - identify the value may be printed, rounding the last additional digit. + Minimum number of digits to print. This only has an effect for `unique=True`. + In that case more digits than necessary to uniquely identify the value may + be printed. The last additional digit is rounded unbiased. Returns ------- -- cgit v1.2.1 From 5abc3946bd951211df4d0b492bd1781394dddcde Mon Sep 17 00:00:00 2001 From: Allan Haldane Date: Fri, 19 Mar 2021 12:45:28 -0400 Subject: Update numpy/core/arrayprint.py Co-authored-by: Sebastian Berg --- numpy/core/arrayprint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index e86986518..8a93705ca 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -1030,7 +1030,7 @@ def format_float_scientific(x, precision=None, unique=True, trim='k', If `True`, use a digit-generation strategy which gives the shortest representation which uniquely identifies the floating-point number from other values of the same type, by judicious rounding. If `precision` - is given fewer digits than necessary can be printed, or if `min_digits` + is given fewer digits than necessary can be printed. If `min_digits` is given more can be printed, in which cases the last digit is rounded with unbiased rounding. If `False`, digits are generated as if printing an infinite-precision -- cgit v1.2.1 From d177382065ca135b921175b94a79119c61a1dbd5 Mon Sep 17 00:00:00 2001 From: Allan Haldane Date: Fri, 19 Mar 2021 12:58:15 -0400 Subject: Update arrayprint.py --- numpy/core/arrayprint.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 8a93705ca..d9d2dbe68 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -1053,9 +1053,10 @@ def format_float_scientific(x, precision=None, unique=True, trim='k', Pad the exponent with zeros until it contains at least this many digits. If omitted, the exponent will be at least 2 digits. min_digits : non-negative integer or None, optional - Minimum number of digits to print. This only has an effect for `unique=True`. - In that case more digits than necessary to uniquely identify the value may - be printed. The last additional digit is rounded unbiased. + Minimum number of digits to print. This only has an effect for + `unique=True`. In that case more digits than necessary to uniquely + identify the value may be printed and rounded unbiased. + Returns ------- -- cgit v1.2.1 From 179d62bc18174378e220c6babf3806b838f02229 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Wed, 31 Mar 2021 10:14:34 -0600 Subject: DOC: Add versionadded for new min_digits argument. --- numpy/core/arrayprint.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index d9d2dbe68..73d276463 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -1057,7 +1057,8 @@ def format_float_scientific(x, precision=None, unique=True, trim='k', `unique=True`. In that case more digits than necessary to uniquely identify the value may be printed and rounded unbiased. - + -- versionadded:: 1.21.0 + Returns ------- rep : string @@ -1142,6 +1143,8 @@ def format_float_positional(x, precision=None, unique=True, Minimum number of digits to print. Only has an effect if `unique=True` in which case additional digits past those necessary to uniquely identify the value may be printed, rounding the last additional digit. + + -- versionadded:: 1.21.0 Returns ------- -- cgit v1.2.1 From 13c313c107e5a85d3d1ce8eff37af5c4022f8cba Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Tue, 20 Jul 2021 20:47:20 -0500 Subject: TST: Add C-side "Scaled float" example This adds a C-side scaled float (actually double), that is available as: SF = np.core._multiarray_umath._get_sfloat_dtype() It supports different scaling factors: a = np.arange(10.).astype(SF(2.)) b = np.arange(10.).astype(SF(0.5)) and casting from double (used there). This commit makes tiny changes in NumPy to support correct printing. --- numpy/core/arrayprint.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index f16bcfd39..2a4bef669 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -420,7 +420,9 @@ def _get_format_function(data, **options): dtype_ = data.dtype dtypeobj = dtype_.type formatdict = _get_formatdict(data, **options) - if issubclass(dtypeobj, _nt.bool_): + if dtypeobj is None: + return formatdict["numpystr"]() + elif issubclass(dtypeobj, _nt.bool_): return formatdict['bool']() elif issubclass(dtypeobj, _nt.integer): if issubclass(dtypeobj, _nt.timedelta64): @@ -1408,6 +1410,9 @@ def dtype_short_repr(dtype): >>> dt = np.int64([1, 2]).dtype >>> assert eval(dtype_short_repr(dt)) == dt """ + if type(dtype).__repr__ != np.dtype.__repr__: + # TODO: Custom repr for user DTypes, logic should likely move. + return repr(dtype) if dtype.names is not None: # structured dtypes give a list or tuple repr return str(dtype) -- cgit v1.2.1 From a6f7d14e60e3d56fe1c0073730a06e23cf696c5a Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Wed, 29 Sep 2021 20:09:32 +0200 Subject: ENH: Add spaces after punctuation in dtype repr/str. (#19686) Before: ``` In [1]: np.dtype({"names": ["a"], "formats": [int], "offsets": [2]}) Out[1]: dtype({'names':['a'], 'formats':[' 113: options['linewidth'] -= len(suffix) # treat as a null array if any of shape elements == 0 @@ -702,7 +738,7 @@ def array2string(a, max_line_width=None, precision=None, def _extendLine(s, line, word, line_width, next_line_prefix, legacy): needs_wrap = len(line) + len(word) > line_width - if legacy != '1.13': + if legacy > 113: # don't wrap lines if it won't help if len(line) <= len(next_line_prefix): needs_wrap = False @@ -719,7 +755,7 @@ def _extendLine_pretty(s, line, word, line_width, next_line_prefix, legacy): Extends line with nicely formatted (possibly multi-line) string ``word``. """ words = word.splitlines() - if len(words) == 1 or legacy == '1.13': + if len(words) == 1 or legacy <= 113: return _extendLine(s, line, word, line_width, next_line_prefix, legacy) max_word_length = max(len(word) for word in words) @@ -765,7 +801,7 @@ def _formatArray(a, format_function, line_width, next_line_prefix, # when recursing, add a space to align with the [ added, and reduce the # length of the line by 1 next_hanging_indent = hanging_indent + ' ' - if legacy == '1.13': + if legacy <= 113: next_width = curr_width else: next_width = curr_width - len(']') @@ -785,7 +821,7 @@ def _formatArray(a, format_function, line_width, next_line_prefix, # last axis (rows) - wrap elements if they would not fit on one line if axes_left == 1: # the length up until the beginning of the separator / bracket - if legacy == '1.13': + if legacy <= 113: elem_width = curr_width - len(separator.rstrip()) else: elem_width = curr_width - max(len(separator.rstrip()), len(']')) @@ -800,7 +836,7 @@ def _formatArray(a, format_function, line_width, next_line_prefix, if show_summary: s, line = _extendLine( s, line, summary_insert, elem_width, hanging_indent, legacy) - if legacy == '1.13': + if legacy <= 113: line += ", " else: line += separator @@ -811,7 +847,7 @@ def _formatArray(a, format_function, line_width, next_line_prefix, s, line, word, elem_width, hanging_indent, legacy) line += separator - if legacy == '1.13': + if legacy <= 113: # width of the separator is not considered on 1.13 elem_width = curr_width word = recurser(index + (-1,), next_hanging_indent, next_width) @@ -830,7 +866,7 @@ def _formatArray(a, format_function, line_width, next_line_prefix, s += hanging_indent + nested + line_sep if show_summary: - if legacy == '1.13': + if legacy <= 113: # trailing space, fixed nbr of newlines, and fixed separator s += hanging_indent + summary_insert + ", \n" else: @@ -875,7 +911,7 @@ class FloatingFormat: sign = '+' if sign else '-' self._legacy = legacy - if self._legacy == '1.13': + if self._legacy <= 113: # when not 0d, legacy does not support '-' if data.shape != () and sign == '-': sign = ' ' @@ -919,7 +955,7 @@ class FloatingFormat: self.min_digits = None elif self.exp_format: trim, unique = '.', True - if self.floatmode == 'fixed' or self._legacy == '1.13': + if self.floatmode == 'fixed' or self._legacy <= 113: trim, unique = 'k', False strs = (dragon4_scientific(x, precision=self.precision, unique=unique, trim=trim, sign=self.sign == '+') @@ -934,7 +970,7 @@ class FloatingFormat: self.unique = unique # for back-compat with np 1.13, use 2 spaces & sign and full prec - if self._legacy == '1.13': + if self._legacy <= 113: self.pad_left = 3 else: # this should be only 1 or 2. Can be calculated from sign. @@ -951,7 +987,7 @@ class FloatingFormat: sign=self.sign == '+') for x in finite_vals) int_part, frac_part = zip(*(s.split('.') for s in strs)) - if self._legacy == '1.13': + if self._legacy <= 113: self.pad_left = 1 + max(len(s.lstrip('-+')) for s in int_part) else: self.pad_left = max(len(s) for s in int_part) @@ -966,7 +1002,7 @@ class FloatingFormat: self.trim = '.' self.min_digits = 0 - if self._legacy != '1.13': + if self._legacy > 113: # account for sign = ' ' by adding one to pad_left if self.sign == ' ' and not any(np.signbit(finite_vals)): self.pad_left += 1 @@ -1215,7 +1251,7 @@ class ComplexFloatingFormat: sign = '+' if sign else '-' floatmode_real = floatmode_imag = floatmode - if legacy == '1.13': + if legacy <= 113: floatmode_real = 'maxprec_equal' floatmode_imag = 'maxprec' @@ -1286,7 +1322,7 @@ class DatetimeFormat(_TimelikeFormat): super().__init__(x) def __call__(self, x): - if self.legacy == '1.13': + if self.legacy <= 113: return self._format_non_nat(x) return super().__call__(x) @@ -1390,7 +1426,7 @@ def dtype_is_implied(dtype): array([1, 2, 3], dtype=int8) """ dtype = np.dtype(dtype) - if _format_options['legacy'] == '1.13' and dtype.type == bool_: + if _format_options['legacy'] <= 113 and dtype.type == bool_: return False # not just void types can be structured, and names are not part of the repr @@ -1445,7 +1481,7 @@ def _array_repr_implementation( prefix = class_name + "(" suffix = ")" if skipdtype else "," - if (_format_options['legacy'] == '1.13' and + if (_format_options['legacy'] <= 113 and arr.shape == () and not arr.dtype.names): lst = repr(arr.item()) elif arr.size > 0 or arr.shape == (0,): @@ -1466,7 +1502,7 @@ def _array_repr_implementation( # Note: This line gives the correct result even when rfind returns -1. last_line_len = len(arr_str) - (arr_str.rfind('\n') + 1) spacer = " " - if _format_options['legacy'] == '1.13': + if _format_options['legacy'] <= 113: if issubclass(arr.dtype.type, flexible): spacer = '\n' + ' '*len(class_name + "(") elif last_line_len + len(dtype_str) + 1 > max_line_width: @@ -1540,7 +1576,7 @@ def _array_str_implementation( a, max_line_width=None, precision=None, suppress_small=None, array2string=array2string): """Internal version of array_str() that allows overriding array2string.""" - if (_format_options['legacy'] == '1.13' and + if (_format_options['legacy'] <= 113 and a.shape == () and not a.dtype.names): return str(a.item()) -- cgit v1.2.1 From d66bb7c8872a8f7c2373506262de9163892d6bee Mon Sep 17 00:00:00 2001 From: Ross Barnowski Date: Sun, 13 Nov 2022 21:16:39 -0800 Subject: MAINT: Rm unnecessary checks in determining typeless data. The issubclass should always be false in Python3, so this change should not change behavior. --- numpy/core/arrayprint.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index d7e9bf795..957cecf1c 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -1394,10 +1394,6 @@ def _void_scalar_repr(x): _typelessdata = [int_, float_, complex_, bool_] -if issubclass(intc, int): - _typelessdata.append(intc) -if issubclass(longlong, int): - _typelessdata.append(longlong) def dtype_is_implied(dtype): -- cgit v1.2.1 From 3f00488871ac169b1fd2f40495ad85cb581cc02b Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Mon, 16 Jan 2023 14:13:21 +0100 Subject: MAINT: Fix stacklevels for the new C dispatcher not adding one --- numpy/core/arrayprint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index 957cecf1c..e0d8ab5c7 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -724,7 +724,7 @@ def array2string(a, max_line_width=None, precision=None, # Deprecation 11-9-2017 v1.14 warnings.warn("'style' argument is deprecated and no longer functional" " except in 1.13 'legacy' mode", - DeprecationWarning, stacklevel=3) + DeprecationWarning, stacklevel=2) if options['legacy'] > 113: options['linewidth'] -= len(suffix) -- cgit v1.2.1 From 75af40548eb85cfa25cb4074e9e4ebc5d5196b4e Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Thu, 7 Oct 2021 14:29:40 +0200 Subject: =?UTF-8?q?MAINT,=20DOC:=20string=5F=20=E2=86=92=20bytes=5F=20and?= =?UTF-8?q?=20unicode=5F=20=E2=86=92=20str=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- numpy/core/arrayprint.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index e0d8ab5c7..a243366b7 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -169,7 +169,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None, - 'longfloat' : 128-bit floats - 'complexfloat' - 'longcomplexfloat' : composed of two 128-bit floats - - 'numpystr' : types `numpy.string_` and `numpy.unicode_` + - 'numpystr' : types `numpy.bytes_` and `numpy.str_` - 'object' : `np.object_` arrays Other keys that can be used to set a group of types at once are: @@ -475,7 +475,7 @@ def _get_format_function(data, **options): return formatdict['longcomplexfloat']() else: return formatdict['complexfloat']() - elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)): + elif issubclass(dtypeobj, (_nt.str_, _nt.bytes_)): return formatdict['numpystr']() elif issubclass(dtypeobj, _nt.datetime64): return formatdict['datetime']() @@ -616,7 +616,7 @@ def array2string(a, max_line_width=None, precision=None, - 'complexfloat' - 'longcomplexfloat' : composed of two 128-bit floats - 'void' : type `numpy.void` - - 'numpystr' : types `numpy.string_` and `numpy.unicode_` + - 'numpystr' : types `numpy.bytes_` and `numpy.str_` Other keys that can be used to set a group of types at once are: -- cgit v1.2.1 From 071388f957c13c1a4f03bc811e3d128335ac686e Mon Sep 17 00:00:00 2001 From: molsonkiko <46202915+molsonkiko@users.noreply.github.com> Date: Tue, 14 Mar 2023 05:57:27 -0700 Subject: ENH: show dtype in array repr when endianness is non-native (#23295) Fx problem where, for example, np.array([1], dtype='>u2') and np.array([1], dtype=' Date: Mon, 20 Feb 2023 21:50:20 -0500 Subject: ENH: Use threshold also inside SubArrayFormat. Previously, for structured arrays that contain a lot of elements, those are always all shown, independent of the threshold print option. This PR ensures that threshold and edgeitems are respected. Note that multidimensional items are typeset without line breaks, to avoid breaking up the structure. Hence, this does not solve the issue that structured array elements can easily overfill a line on the console. --- numpy/core/arrayprint.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'numpy/core/arrayprint.py') diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index dcfb6e6a8..62cd52707 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -1096,7 +1096,7 @@ def format_float_scientific(x, precision=None, unique=True, trim='k', identify the value may be printed and rounded unbiased. -- versionadded:: 1.21.0 - + Returns ------- rep : string @@ -1181,7 +1181,7 @@ def format_float_positional(x, precision=None, unique=True, Minimum number of digits to print. Only has an effect if `unique=True` in which case additional digits past those necessary to uniquely identify the value may be printed, rounding the last additional digit. - + -- versionadded:: 1.21.0 Returns @@ -1339,13 +1339,29 @@ class TimedeltaFormat(_TimelikeFormat): class SubArrayFormat: - def __init__(self, format_function): + def __init__(self, format_function, **options): self.format_function = format_function + self.threshold = options['threshold'] + self.edge_items = options['edgeitems'] + + def __call__(self, a): + self.summary_insert = "..." if a.size > self.threshold else "" + return self.format_array(a) + + def format_array(self, a): + if np.ndim(a) == 0: + return self.format_function(a) + + if self.summary_insert and a.shape[0] > 2*self.edge_items: + formatted = ( + [self.format_array(a_) for a_ in a[:self.edge_items]] + + [self.summary_insert] + + [self.format_array(a_) for a_ in a[-self.edge_items:]] + ) + else: + formatted = [self.format_array(a_) for a_ in a] - def __call__(self, arr): - if arr.ndim <= 1: - return "[" + ", ".join(self.format_function(a) for a in arr) + "]" - return "[" + ", ".join(self.__call__(a) for a in arr) + "]" + return "[" + ", ".join(formatted) + "]" class StructuredVoidFormat: @@ -1369,7 +1385,7 @@ class StructuredVoidFormat: for field_name in data.dtype.names: format_function = _get_format_function(data[field_name], **options) if data.dtype[field_name].shape != (): - format_function = SubArrayFormat(format_function) + format_function = SubArrayFormat(format_function, **options) format_functions.append(format_function) return cls(format_functions) @@ -1428,7 +1444,7 @@ def dtype_is_implied(dtype): # not just void types can be structured, and names are not part of the repr if dtype.names is not None: return False - + # should care about endianness *unless size is 1* (e.g., int8, bool) if not dtype.isnative: return False -- cgit v1.2.1