diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2018-09-11 10:03:24 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-11 10:03:24 -0500 |
commit | b1187f667a2bb5d7a0c519192440a5116a948180 (patch) | |
tree | 783159011a0b4b82f06aa887fb1b0fc43a8ba01b | |
parent | 6598d0144d819330daa73d9a99120b2a525c19bd (diff) | |
parent | dfead64385e5ffb95b3053d5f955117fd81d4705 (diff) | |
download | numpy-b1187f667a2bb5d7a0c519192440a5116a948180.tar.gz |
Merge pull request #11921 from eric-wieser/fix-bitname
MAINT: Don't rely on `__name__` in bitname - use the information directly from the typeinfo.
-rw-r--r-- | numpy/core/numerictypes.py | 113 | ||||
-rw-r--r-- | numpy/core/tests/test_numerictypes.py | 5 |
2 files changed, 51 insertions, 67 deletions
diff --git a/numpy/core/numerictypes.py b/numpy/core/numerictypes.py index 817af4c7b..259aef2c6 100644 --- a/numpy/core/numerictypes.py +++ b/numpy/core/numerictypes.py @@ -238,71 +238,53 @@ for k, v in typeinfo.items(): _concrete_typeinfo[k] = v -def _evalname(name): - k = 0 - for ch in name: - if ch in '0123456789': - break - k += 1 - try: - bits = int(name[k:]) - except ValueError: - bits = 0 - base = name[:k] - return base, bits +_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 bitname(obj): - """Return a bit-width name for a given type object""" - name = obj.__name__ - base = '' - char = '' + +def _bits_of(obj): try: - if name[-1] == '_': - newname = name[:-1] - else: - newname = name - info = _concrete_typeinfo[english_lower(newname)] - assert(info.type == obj) # sanity check - bits = info.bits - - except KeyError: # bit-width name - base, bits = _evalname(name) - char = base[0] - - if name == 'bool_': - char = 'b' - base = 'bool' - elif name == 'void': - char = 'V' - base = 'void' - elif name == 'object_': - char = 'O' - base = 'object' - bits = 0 - elif name == 'datetime64': - char = 'M' - elif name == 'timedelta64': - char = 'm' + 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") - if sys.version_info[0] >= 3: - if name == 'bytes_': - char = 'S' - base = 'bytes' - elif name == 'str_': - char = 'U' - base = 'str' + # some third-party type - make a best-guess + return dtype(obj).itemsize * 8 else: - if name == 'string_': - char = 'S' - base = 'string' - elif name == 'unicode_': - char = 'U' - base = 'unicode' + return info.bits - bytes = bits // 8 - if char != '' and bytes != 0: - char = "%s%d" % (char, bytes) +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 @@ -336,7 +318,6 @@ def _add_aliases(): # insert bit-width version for this class (if relevant) base, bit, char = bitname(info.type) - assert base != '' myname = "%s%d" % (base, bit) # ensure that (c)longdouble does not overwrite the aliases assigned to @@ -363,7 +344,6 @@ def _add_aliases(): sctypeNA[info.type] = na_name sctypeNA[info.char] = na_name - assert char != '' sctypeDict[char] = info.type sctypeNA[char] = na_name _add_aliases() @@ -543,13 +523,12 @@ def maximum_sctype(t): if g is None: return t t = g - name = t.__name__ - base, bits = _evalname(name) - if bits == 0: - return t - else: + bits = _bits_of(t) + base = _kind_to_stem[dtype(t).kind] + if base in sctypes: return sctypes[base][-1] - + else: + return t def issctype(rep): """ diff --git a/numpy/core/tests/test_numerictypes.py b/numpy/core/tests/test_numerictypes.py index 72da9933c..0eae9e059 100644 --- a/numpy/core/tests/test_numerictypes.py +++ b/numpy/core/tests/test_numerictypes.py @@ -415,6 +415,11 @@ class TestSctypeDict(object): assert_(np.sctypeDict['c16'] is not np.clongdouble) +class TestBitName(object): + def test_abstract(self): + assert_raises(ValueError, np.core.numerictypes.bitname, np.floating) + + class TestMaximumSctype(object): # note that parametrizing with sctype['int'] and similar would skip types |