Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/release/upcoming_changes/16554.compatibility.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Numeric-style type names have been removed from type dictionaries
-----------------------------------------------------------------

To stay in sync with the deprecation for ``np.dtype("Complex64")``
and other numeric-style (capital case) types. These were removed
from ``np.sctypeDict`` and ``np.typeDict``. You should use
the lower case versions instead. Note that ``"Complex64"``
corresponds to ``"complex128"`` and ``"Complex32"`` corresponds
to ``"complex64"``. The numpy style (new) versions, denote the full
size and not the size of the real/imaginary part.
8 changes: 8 additions & 0 deletions doc/release/upcoming_changes/16554.deprecation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Further Numeric Style types Deprecated
--------------------------------------

The remaining numeric-style type codes ``Bytes0``, ``Str0``,
``Uint32``, ``Uint64``, and ``Datetime64``
have been deprecated. The lower-case variants should be used
instead. For bytes and string ``"S"`` and ``"U"``
are further alternatives.
5 changes: 5 additions & 0 deletions doc/release/upcoming_changes/16554.expired.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* The deprecation of numeric style type-codes ``np.dtype("Complex64")``
(with upper case spelling), is expired. ``"Complex64"`` corresponded to
``"complex128"`` and ``"Complex32"`` corresponded to ``"complex64"``.
* The deprecation of ``np.sctypeNA`` and ``np.typeNA`` is expired. Both
have been removed from the public API. Use ``np.typeDict`` instead.
59 changes: 15 additions & 44 deletions numpy/core/_type_aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,19 @@
.. data:: sctypeDict
Similar to `allTypes`, but maps a broader set of aliases to their types.

.. data:: sctypeNA
NumArray-compatible names for the scalar types. Contains not only
``name: type`` mappings, but ``char: name`` mappings too.

.. deprecated:: 1.16

.. data:: sctypes
A dictionary keyed by a "type group" string, providing a list of types
under that group.

"""
import warnings

from numpy.compat import unicode
from numpy._globals import VisibleDeprecationWarning
from numpy.core._string_helpers import english_lower, english_capitalize
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is english_capitalize used any more?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I hardcoded the few exceptions...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point is, can its definition be removed too?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being unclear, yes it can be, there are no more usages in this file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eric-wieser one quick question to be sure. Uin32 was never defined on windows? Because otherwise I have to check for (and add it) here... (or remove both)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uint32 was defined on 32-bit windows only.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, its a 32bit thing... In any case, will fix this up then.

Cool about gh-14882 seems there is consensus on moving forward with it, so I will definitely review and put that in soon!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being unclear, yes it can be, there are no more usages in this file.

Ping on this - we may as well remove it from _string_helpers if it has no other callers.

from numpy.core._string_helpers import english_lower
from numpy.core.multiarray import typeinfo, dtype
from numpy.core._dtype import _kind_name


sctypeDict = {} # Contains all leaf-node scalar types with aliases
class TypeNADict(dict):
def __getitem__(self, key):
# 2018-06-24, 1.16
warnings.warn('sctypeNA and typeNA will be removed in v1.18 '
'of numpy', VisibleDeprecationWarning, stacklevel=2)
return dict.__getitem__(self, key)
def get(self, key, default=None):
# 2018-06-24, 1.16
warnings.warn('sctypeNA and typeNA will be removed in v1.18 '
'of numpy', VisibleDeprecationWarning, stacklevel=2)
return dict.get(self, key, default)

sctypeNA = TypeNADict() # Contails all leaf-node types -> numarray type equivalences
allTypes = {} # Collect the types we will add to the module


Expand Down Expand Up @@ -127,27 +106,24 @@ def _add_aliases():
if name in ('longdouble', 'clongdouble') and myname in allTypes:
continue

base_capitalize = english_capitalize(base)
if base == 'complex':
na_name = '%s%d' % (base_capitalize, bit//2)
elif base == 'bool':
na_name = base_capitalize
else:
na_name = "%s%d" % (base_capitalize, bit)

allTypes[myname] = info.type

# add mapping for both the bit name and the numarray name
sctypeDict[myname] = info.type
sctypeDict[na_name] = info.type

# add forward, reverse, and string mapping to numarray
sctypeNA[na_name] = info.type
sctypeNA[info.type] = na_name
sctypeNA[info.char] = na_name

sctypeDict[char] = info.type
sctypeNA[char] = na_name

# Add deprecated numeric-style type aliases manually, at some point
# we may want to deprecate the lower case "bytes0" version as well.
for name in ["Bytes0", "Datetime64", "Str0", "Uint32", "Uint64"]:
if english_lower(name) not in allTypes:
# Only one of Uint32 or Uint64, aliases of `np.uintp`, was (and is) defined, note that this
# is not UInt32/UInt64 (capital i), which is removed.
continue
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if is weird, but it failed tests and I think it is correct... if anyone has a 32bit linux or maybe windows to see that Uint64 was never included in np.typeDict on old versions, that would be good.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It now passes tests, is this comment outdated?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I worked around it. But, I now realized on windows we probably had a stray Uint32 and that will be missing now...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np.typeDict has UInt64 on 1.16, windows 32 bit:

>>> sys.version
'2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:19:08) [MSC v.1500 32 bit (Intel)]'
>>> np.typeDict['UInt64']
<type 'numpy.uint64'>
>>> np.__version__
1.16.6
>>>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note the 'I' in 'UInt64'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The capitalized UInt form has already been deprecated - it's just the weird Uint form that isn't.

It looks to me like I added this type accidentally as part of giving [np.cint, np.int_, np.longlong] unique names. On numpy 1.11.0 (and python 2.7) the name isn't there at all:

>>> numpy.__version__
'1.11.0'
>>> sorted(k for k in numpy.typeDict.keys() if isinstance(k, str) and k[0].isupper() and len(k) > 2)
['Bool', 'Complex128', 'Complex32', 'Complex64', 'Datetime64', 'Float128', 'Float16', 'Float32', 'Float64', 'Int16', 'Int32', 'Int64', 'Int8', 'Object0', 'String0', 'Timedelta64', 'UInt16', 'UInt32', 'UInt64', 'UInt8', 'Unicode0', 'Void0']

So I think we can just remove this special case?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that makes it more recent. I think we could just remove it, but if we want to get rid of Datetime64 as well, I also don't see a real downside to just including it here...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for reference - the Uint64 name comes from uintp, due to these lines (97a2950#r39808190) in 1.16.

So on 32-bit platforms, there will be a Uint32 instead.

Let's either deprecate both or remove both.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I included Uint32, I think if the tests all pass things should be fine.

allTypes[name] = allTypes[english_lower(name)]
sctypeDict[name] = sctypeDict[english_lower(name)]

_add_aliases()

def _add_integer_aliases():
Expand All @@ -157,20 +133,15 @@ def _add_integer_aliases():
u_info = _concrete_typeinfo[u_ctype]
bits = i_info.bits # same for both

for info, charname, intname, Intname in [
(i_info,'i%d' % (bits//8,), 'int%d' % bits, 'Int%d' % bits),
(u_info,'u%d' % (bits//8,), 'uint%d' % bits, 'UInt%d' % bits)]:
for info, charname, intname in [
(i_info,'i%d' % (bits//8,), 'int%d' % bits),
(u_info,'u%d' % (bits//8,), 'uint%d' % bits)]:
if bits not in seen_bits:
# sometimes two different types have the same number of bits
# if so, the one iterated over first takes precedence
allTypes[intname] = info.type
sctypeDict[intname] = info.type
sctypeDict[Intname] = info.type
sctypeDict[charname] = info.type
sctypeNA[Intname] = info.type
sctypeNA[charname] = info.type
sctypeNA[info.type] = Intname
sctypeNA[info.char] = Intname

seen_bits.add(bits)

Expand Down
4 changes: 1 addition & 3 deletions numpy/core/numerictypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
from numpy.core.overrides import set_module

# we add more at the bottom
__all__ = ['sctypeDict', 'sctypeNA', 'typeDict', 'typeNA', 'sctypes',
__all__ = ['sctypeDict', 'typeDict', 'sctypes',
'ScalarType', 'obj2sctype', 'cast', 'nbytes', 'sctype2char',
'maximum_sctype', 'issctype', 'typecodes', 'find_common_type',
'issubdtype', 'datetime_data', 'datetime_as_string',
Expand All @@ -106,7 +106,6 @@

from ._type_aliases import (
sctypeDict,
sctypeNA,
allTypes,
bitname,
sctypes,
Expand Down Expand Up @@ -512,7 +511,6 @@ def sctype2char(sctype):

# backwards compatibility --- deprecated name
typeDict = sctypeDict
typeNA = sctypeNA

# b -> boolean
# u -> unsigned integer
Expand Down
6 changes: 3 additions & 3 deletions numpy/core/src/multiarray/descriptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -1678,14 +1678,14 @@ _convert_from_str(PyObject *obj, int align)
}

/* Check for a deprecated Numeric-style typecode */
char *dep_tps[] = {"Bool", "Complex", "Float", "Int",
"Object0", "String0", "Timedelta64",
"Unicode0", "UInt", "Void0"};
/* `Uint` has deliberately weird uppercasing */
char *dep_tps[] = {"Bytes", "Datetime64", "Str", "Uint"};
int ndep_tps = sizeof(dep_tps) / sizeof(dep_tps[0]);
for (int i = 0; i < ndep_tps; ++i) {
char *dep_tp = dep_tps[i];

if (strncmp(type, dep_tp, strlen(dep_tp)) == 0) {
/* Deprecated 2020-06-09, NumPy 1.20 */
if (DEPRECATE("Numeric-style type codes are "
"deprecated and will result in "
"an error in the future.") < 0) {
Expand Down
25 changes: 6 additions & 19 deletions numpy/core/tests/test_deprecations.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,19 +313,14 @@ def test_insufficient_width_negative(self):

class TestNumericStyleTypecodes(_DeprecationTestCase):
"""
Deprecate the old numeric-style dtypes, which are especially
confusing for complex types, e.g. Complex32 -> complex64. When the
deprecation cycle is complete, the check for the strings should be
removed from PyArray_DescrConverter in descriptor.c, and the
deprecated keys should not be added as capitalized aliases in
_add_aliases in numerictypes.py.
Most numeric style typecodes were previously deprecated (and removed)
in 1.20. This also deprecates the remaining ones.
"""
# 2020-06-09, NumPy 1.20
def test_all_dtypes(self):
deprecated_types = [
'Bool', 'Complex32', 'Complex64', 'Float16', 'Float32', 'Float64',
'Int8', 'Int16', 'Int32', 'Int64', 'Object0', 'Timedelta64',
'UInt8', 'UInt16', 'UInt32', 'UInt64', 'Void0'
]
deprecated_types = ['Bytes0', 'Datetime64', 'Str0']
# Depending on intp size, either Uint32 or Uint64 is defined:
deprecated_types.append(f"U{np.dtype(np.intp).name}")
Copy link
Copy Markdown
Member

@eric-wieser eric-wieser Jun 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or

Suggested change
deprecated_types.append(f"U{np.dtype(np.intp).name}")
deprecated_types.append(np.dtype(np.uintp).name.title())

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks nicer, I am a bit uncertain about locales here since the other code used english_upper everywere?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, safer to leave it as is.

for dt in deprecated_types:
self.assert_deprecated(np.dtype, exceptions=(TypeError,),
args=(dt,))
Expand Down Expand Up @@ -438,14 +433,6 @@ def test_generator_sum(self):
self.assert_deprecated(np.sum, args=((i for i in range(5)),))


class TestSctypeNA(_VisibleDeprecationTestCase):
# 2018-06-24, 1.16
def test_sctypeNA(self):
self.assert_deprecated(lambda: np.sctypeNA['?'])
self.assert_deprecated(lambda: np.typeNA['?'])
self.assert_deprecated(lambda: np.typeNA.get('?'))


class TestPositiveOnNonNumerical(_DeprecationTestCase):
# 2018-06-28, 1.16.0
def test_positive_on_non_number(self):
Expand Down
9 changes: 9 additions & 0 deletions numpy/core/tests/test_dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ def test_invalid_types(self):
assert_raises(TypeError, np.dtype, 'q8')
assert_raises(TypeError, np.dtype, 'Q8')

@pytest.mark.parametrize("dtype",
['Bool', 'Complex32', 'Complex64', 'Float16', 'Float32', 'Float64',
'Int8', 'Int16', 'Int32', 'Int64', 'Object0', 'Timedelta64',
'UInt8', 'UInt16', 'UInt32', 'UInt64', 'Void0',
"Float128", "Complex128"])
def test_numeric_style_types_are_invalid(self, dtype):
with assert_raises(TypeError):
np.dtype(dtype)

@pytest.mark.parametrize(
'value',
['m8', 'M8', 'datetime64', 'timedelta64',
Expand Down
7 changes: 0 additions & 7 deletions numpy/core/tests/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,6 @@ def test_pickle_transposed(self):
b = pickle.load(f)
assert_array_equal(a, b)

def test_typeNA(self):
# Issue gh-515
with suppress_warnings() as sup:
sup.filter(np.VisibleDeprecationWarning)
assert_equal(np.typeNA[np.int64], 'Int64')
assert_equal(np.typeNA[np.uint64], 'UInt64')

def test_dtype_names(self):
# Ticket #35
# Should succeed
Expand Down