summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2018-09-22 11:03:42 -0500
committerGitHub <noreply@github.com>2018-09-22 11:03:42 -0500
commit1c0ebd808ede34d384a44ed19093afc109ba0cd8 (patch)
tree06509c60528c1a5fde3653b41878c2c6940ae8ed
parent611bd6c082c7030027a3e4772739f257dc4a5941 (diff)
parent776e68b8d32958d700712741eb7e66598faa27ba (diff)
downloadnumpy-1c0ebd808ede34d384a44ed19093afc109ba0cd8.tar.gz
Merge pull request #12012 from eric-wieser/_type_aliases
MAINT: Extract the crazy number of type aliases to their own file
-rw-r--r--numpy/core/_type_aliases.py312
-rw-r--r--numpy/core/numerictypes.py292
2 files changed, 325 insertions, 279 deletions
diff --git a/numpy/core/_type_aliases.py b/numpy/core/_type_aliases.py
new file mode 100644
index 000000000..2c1c5c933
--- /dev/null
+++ b/numpy/core/_type_aliases.py
@@ -0,0 +1,312 @@
+"""
+Due to compatibility, numpy has a very large number of different naming
+conventions for the scalar types (those subclassing from `numpy.generic`).
+This file produces a convoluted set of dictionaries mapping names to types,
+and sometimes other mappings too.
+
+.. data:: allTypes
+ A dictionary of names to types that will be exposed as attributes through
+ ``np.core.numerictypes.*``
+
+.. 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
+import sys
+
+from numpy.compat import unicode
+from numpy._globals import VisibleDeprecationWarning
+from numpy.core._string_helpers import english_lower, english_capitalize
+from numpy.core.multiarray import typeinfo, dtype
+
+
+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
+
+
+# separate the actual type info from the abtract base classes
+_abstract_types = {}
+_concrete_typeinfo = {}
+for k, v in typeinfo.items():
+ # make all the keys lowercase too
+ k = english_lower(k)
+ if isinstance(v, type):
+ _abstract_types[k] = v
+ else:
+ _concrete_typeinfo[k] = v
+
+
+_kind_to_stem = {
+ 'u': 'uint',
+ 'i': 'int',
+ 'c': 'complex',
+ 'f': 'float',
+ 'b': 'bool',
+ 'V': 'void',
+ 'O': 'object',
+ 'M': 'datetime',
+ 'm': 'timedelta'
+}
+if sys.version_info[0] >= 3:
+ _kind_to_stem.update({
+ 'S': 'bytes',
+ 'U': 'str'
+ })
+else:
+ _kind_to_stem.update({
+ 'S': 'string',
+ 'U': 'unicode'
+ })
+
+
+def _bits_of(obj):
+ try:
+ info = next(v for v in _concrete_typeinfo.values() if v.type is obj)
+ except StopIteration:
+ if obj in _abstract_types.values():
+ raise ValueError("Cannot count the bits of an abstract type")
+
+ # some third-party type - make a best-guess
+ return dtype(obj).itemsize * 8
+ else:
+ return info.bits
+
+
+def bitname(obj):
+ """Return a bit-width name for a given type object"""
+ bits = _bits_of(obj)
+ char = dtype(obj).kind
+ base = _kind_to_stem[char]
+
+ if base == 'object':
+ bits = 0
+
+ if bits != 0:
+ char = "%s%d" % (char, bits // 8)
+
+ return base, bits, char
+
+
+def _add_types():
+ for name, info in _concrete_typeinfo.items():
+ # define C-name and insert typenum and typechar references also
+ allTypes[name] = info.type
+ sctypeDict[name] = info.type
+ sctypeDict[info.char] = info.type
+ sctypeDict[info.num] = info.type
+
+ for name, cls in _abstract_types.items():
+ allTypes[name] = cls
+_add_types()
+
+# This is the priority order used to assign the bit-sized NPY_INTxx names, which
+# must match the order in npy_common.h in order for NPY_INTxx and np.intxx to be
+# consistent.
+# If two C types have the same size, then the earliest one in this list is used
+# as the sized name.
+_int_ctypes = ['long', 'longlong', 'int', 'short', 'byte']
+_uint_ctypes = list('u' + t for t in _int_ctypes)
+
+def _add_aliases():
+ for name, info in _concrete_typeinfo.items():
+ # these are handled by _add_integer_aliases
+ if name in _int_ctypes or name in _uint_ctypes:
+ continue
+
+ # insert bit-width version for this class (if relevant)
+ base, bit, char = bitname(info.type)
+
+ myname = "%s%d" % (base, bit)
+
+ # ensure that (c)longdouble does not overwrite the aliases assigned to
+ # (c)double
+ 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_aliases()
+
+def _add_integer_aliases():
+ seen_bits = set()
+ for i_ctype, u_ctype in zip(_int_ctypes, _uint_ctypes):
+ i_info = _concrete_typeinfo[i_ctype]
+ 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)]:
+ 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)
+
+_add_integer_aliases()
+
+# We use these later
+void = allTypes['void']
+
+#
+# Rework the Python names (so that float and complex and int are consistent
+# with Python usage)
+#
+def _set_up_aliases():
+ type_pairs = [('complex_', 'cdouble'),
+ ('int0', 'intp'),
+ ('uint0', 'uintp'),
+ ('single', 'float'),
+ ('csingle', 'cfloat'),
+ ('singlecomplex', 'cfloat'),
+ ('float_', 'double'),
+ ('intc', 'int'),
+ ('uintc', 'uint'),
+ ('int_', 'long'),
+ ('uint', 'ulong'),
+ ('cfloat', 'cdouble'),
+ ('longfloat', 'longdouble'),
+ ('clongfloat', 'clongdouble'),
+ ('longcomplex', 'clongdouble'),
+ ('bool_', 'bool'),
+ ('bytes_', 'string'),
+ ('string_', 'string'),
+ ('unicode_', 'unicode'),
+ ('object_', 'object')]
+ if sys.version_info[0] >= 3:
+ type_pairs.extend([('str_', 'unicode')])
+ else:
+ type_pairs.extend([('str_', 'string')])
+ for alias, t in type_pairs:
+ allTypes[alias] = allTypes[t]
+ sctypeDict[alias] = sctypeDict[t]
+ # Remove aliases overriding python types and modules
+ to_remove = ['ulong', 'object', 'unicode', 'int', 'long', 'float',
+ 'complex', 'bool', 'string', 'datetime', 'timedelta']
+ if sys.version_info[0] >= 3:
+ # Py3K
+ to_remove.append('bytes')
+ to_remove.append('str')
+ to_remove.remove('unicode')
+ to_remove.remove('long')
+ for t in to_remove:
+ try:
+ del allTypes[t]
+ del sctypeDict[t]
+ except KeyError:
+ pass
+_set_up_aliases()
+
+# Now, construct dictionary to lookup character codes from types
+_sctype2char_dict = {}
+def _construct_char_code_lookup():
+ for name, info in _concrete_typeinfo.items():
+ if info.char not in ['p', 'P']:
+ _sctype2char_dict[info.type] = info.char
+_construct_char_code_lookup()
+
+
+sctypes = {'int': [],
+ 'uint':[],
+ 'float':[],
+ 'complex':[],
+ 'others':[bool, object, bytes, unicode, void]}
+
+def _add_array_type(typename, bits):
+ try:
+ t = allTypes['%s%d' % (typename, bits)]
+ except KeyError:
+ pass
+ else:
+ sctypes[typename].append(t)
+
+def _set_array_types():
+ ibytes = [1, 2, 4, 8, 16, 32, 64]
+ fbytes = [2, 4, 8, 10, 12, 16, 32, 64]
+ for bytes in ibytes:
+ bits = 8*bytes
+ _add_array_type('int', bits)
+ _add_array_type('uint', bits)
+ for bytes in fbytes:
+ bits = 8*bytes
+ _add_array_type('float', bits)
+ _add_array_type('complex', 2*bits)
+ _gi = dtype('p')
+ if _gi.type not in sctypes['int']:
+ indx = 0
+ sz = _gi.itemsize
+ _lst = sctypes['int']
+ while (indx < len(_lst) and sz >= _lst[indx](0).itemsize):
+ indx += 1
+ sctypes['int'].insert(indx, _gi.type)
+ sctypes['uint'].insert(indx, dtype('P').type)
+_set_array_types()
+
+
+# Add additional strings to the sctypeDict
+if sys.version_info[0] >= 3:
+ _toadd = ['int', 'float', 'complex', 'bool', 'object',
+ 'str', 'bytes', 'object', ('a', allTypes['bytes_'])]
+else:
+ _toadd = ['int', 'float', 'complex', 'bool', 'object', 'string',
+ ('str', allTypes['string_']),
+ 'unicode', 'object', ('a', allTypes['string_'])]
+
+for name in _toadd:
+ if isinstance(name, tuple):
+ sctypeDict[name[0]] = name[1]
+ else:
+ sctypeDict[name] = allTypes['%s_' % name]
+
+del _toadd, name
diff --git a/numpy/core/numerictypes.py b/numpy/core/numerictypes.py
index f0cd8ec74..25bf185cb 100644
--- a/numpy/core/numerictypes.py
+++ b/numpy/core/numerictypes.py
@@ -92,7 +92,6 @@ from numpy.core.multiarray import (
datetime_as_string, busday_offset, busday_count, is_busday,
busdaycalendar
)
-from numpy._globals import VisibleDeprecationWarning
# we add more at the bottom
__all__ = ['sctypeDict', 'sctypeNA', 'typeDict', 'typeNA', 'sctypes',
@@ -108,6 +107,18 @@ from ._string_helpers import (
english_lower, english_upper, english_capitalize, LOWER_TABLE, UPPER_TABLE
)
+from ._type_aliases import (
+ sctypeDict,
+ sctypeNA,
+ allTypes,
+ bitname,
+ sctypes,
+ _sctype2char_dict,
+ _concrete_typeinfo,
+ _bits_of,
+ _kind_to_stem,
+)
+
# we don't export these for import *, but we do want them accessible
# as numerictypes.bool, etc.
if sys.version_info[0] >= 3:
@@ -117,270 +128,9 @@ else:
from __builtin__ import bool, int, float, complex, object, unicode, str
-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 here
-
-
-# separate the actual type info from the abtract base classes
-_abstract_types = {}
-_concrete_typeinfo = {}
-for k, v in typeinfo.items():
- # make all the keys lowercase too
- k = english_lower(k)
- if isinstance(v, type):
- _abstract_types[k] = v
- else:
- _concrete_typeinfo[k] = v
-
-
-_kind_to_stem = {
- 'u': 'uint',
- 'i': 'int',
- 'c': 'complex',
- 'f': 'float',
- 'b': 'bool',
- 'V': 'void',
- 'O': 'object',
- 'M': 'datetime',
- 'm': 'timedelta'
-}
-if sys.version_info[0] >= 3:
- _kind_to_stem.update({
- 'S': 'bytes',
- 'U': 'str'
- })
-else:
- _kind_to_stem.update({
- 'S': 'string',
- 'U': 'unicode'
- })
-
-
-def _bits_of(obj):
- try:
- info = next(v for v in _concrete_typeinfo.values() if v.type is obj)
- except StopIteration:
- if obj in _abstract_types.values():
- raise ValueError("Cannot count the bits of an abstract type")
-
- # some third-party type - make a best-guess
- return dtype(obj).itemsize * 8
- else:
- return info.bits
-
-
-def bitname(obj):
- """Return a bit-width name for a given type object"""
- bits = _bits_of(obj)
- char = dtype(obj).kind
- base = _kind_to_stem[char]
-
- if base == 'object':
- bits = 0
-
- if bits != 0:
- char = "%s%d" % (char, bits // 8)
-
- return base, bits, char
-
-
-def _add_types():
- for name, info in _concrete_typeinfo.items():
- # define C-name and insert typenum and typechar references also
- allTypes[name] = info.type
- sctypeDict[name] = info.type
- sctypeDict[info.char] = info.type
- sctypeDict[info.num] = info.type
-
- for name, cls in _abstract_types.items():
- allTypes[name] = cls
-_add_types()
-
-# This is the priority order used to assign the bit-sized NPY_INTxx names, which
-# must match the order in npy_common.h in order for NPY_INTxx and np.intxx to be
-# consistent.
-# If two C types have the same size, then the earliest one in this list is used
-# as the sized name.
-_int_ctypes = ['long', 'longlong', 'int', 'short', 'byte']
-_uint_ctypes = list('u' + t for t in _int_ctypes)
-
-def _add_aliases():
- for name, info in _concrete_typeinfo.items():
- # these are handled by _add_integer_aliases
- if name in _int_ctypes or name in _uint_ctypes:
- continue
-
- # insert bit-width version for this class (if relevant)
- base, bit, char = bitname(info.type)
-
- myname = "%s%d" % (base, bit)
-
- # ensure that (c)longdouble does not overwrite the aliases assigned to
- # (c)double
- 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_aliases()
-
-def _add_integer_aliases():
- seen_bits = set()
- for i_ctype, u_ctype in zip(_int_ctypes, _uint_ctypes):
- i_info = _concrete_typeinfo[i_ctype]
- 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)]:
- 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)
-
-_add_integer_aliases()
-
-# We use these later
-void = allTypes['void']
+# We use this later
generic = allTypes['generic']
-#
-# Rework the Python names (so that float and complex and int are consistent
-# with Python usage)
-#
-def _set_up_aliases():
- type_pairs = [('complex_', 'cdouble'),
- ('int0', 'intp'),
- ('uint0', 'uintp'),
- ('single', 'float'),
- ('csingle', 'cfloat'),
- ('singlecomplex', 'cfloat'),
- ('float_', 'double'),
- ('intc', 'int'),
- ('uintc', 'uint'),
- ('int_', 'long'),
- ('uint', 'ulong'),
- ('cfloat', 'cdouble'),
- ('longfloat', 'longdouble'),
- ('clongfloat', 'clongdouble'),
- ('longcomplex', 'clongdouble'),
- ('bool_', 'bool'),
- ('bytes_', 'string'),
- ('string_', 'string'),
- ('unicode_', 'unicode'),
- ('object_', 'object')]
- if sys.version_info[0] >= 3:
- type_pairs.extend([('str_', 'unicode')])
- else:
- type_pairs.extend([('str_', 'string')])
- for alias, t in type_pairs:
- allTypes[alias] = allTypes[t]
- sctypeDict[alias] = sctypeDict[t]
- # Remove aliases overriding python types and modules
- to_remove = ['ulong', 'object', 'unicode', 'int', 'long', 'float',
- 'complex', 'bool', 'string', 'datetime', 'timedelta']
- if sys.version_info[0] >= 3:
- # Py3K
- to_remove.append('bytes')
- to_remove.append('str')
- to_remove.remove('unicode')
- to_remove.remove('long')
- for t in to_remove:
- try:
- del allTypes[t]
- del sctypeDict[t]
- except KeyError:
- pass
-_set_up_aliases()
-
-# Now, construct dictionary to lookup character codes from types
-_sctype2char_dict = {}
-def _construct_char_code_lookup():
- for name, info in _concrete_typeinfo.items():
- if info.char not in ['p', 'P']:
- _sctype2char_dict[info.type] = info.char
-_construct_char_code_lookup()
-
-
-sctypes = {'int': [],
- 'uint':[],
- 'float':[],
- 'complex':[],
- 'others':[bool, object, bytes, unicode, void]}
-
-def _add_array_type(typename, bits):
- try:
- t = allTypes['%s%d' % (typename, bits)]
- except KeyError:
- pass
- else:
- sctypes[typename].append(t)
-
-def _set_array_types():
- ibytes = [1, 2, 4, 8, 16, 32, 64]
- fbytes = [2, 4, 8, 10, 12, 16, 32, 64]
- for bytes in ibytes:
- bits = 8*bytes
- _add_array_type('int', bits)
- _add_array_type('uint', bits)
- for bytes in fbytes:
- bits = 8*bytes
- _add_array_type('float', bits)
- _add_array_type('complex', 2*bits)
- _gi = dtype('p')
- if _gi.type not in sctypes['int']:
- indx = 0
- sz = _gi.itemsize
- _lst = sctypes['int']
- while (indx < len(_lst) and sz >= _lst[indx](0).itemsize):
- indx += 1
- sctypes['int'].insert(indx, _gi.type)
- sctypes['uint'].insert(indx, dtype('P').type)
-_set_array_types()
-
-
genericTypeRank = ['bool', 'int8', 'uint8', 'int16', 'uint16',
'int32', 'uint32', 'int64', 'uint64', 'int128',
'uint128', 'float16',
@@ -761,22 +511,6 @@ except AttributeError:
ScalarType.extend(_sctype2char_dict.keys())
ScalarType = tuple(ScalarType)
-# Add additional strings to the sctypeDict
-if sys.version_info[0] >= 3:
- _toadd = ['int', 'float', 'complex', 'bool', 'object',
- 'str', 'bytes', 'object', ('a', allTypes['bytes_'])]
-else:
- _toadd = ['int', 'float', 'complex', 'bool', 'object', 'string',
- ('str', allTypes['string_']),
- 'unicode', 'object', ('a', allTypes['string_'])]
-
-for name in _toadd:
- if isinstance(name, tuple):
- sctypeDict[name[0]] = name[1]
- else:
- sctypeDict[name] = allTypes['%s_' % name]
-
-del _toadd, name
# Now add the types we've determined to this module
for key in allTypes: