Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2Due to compatibility, numpy has a very large number of different naming 

3conventions for the scalar types (those subclassing from `numpy.generic`). 

4This file produces a convoluted set of dictionaries mapping names to types, 

5and sometimes other mappings too. 

6 

7.. data:: allTypes 

8 A dictionary of names to types that will be exposed as attributes through 

9 ``np.core.numerictypes.*`` 

10 

11.. data:: sctypeDict 

12 Similar to `allTypes`, but maps a broader set of aliases to their types. 

13 

14.. data:: sctypeNA 

15 NumArray-compatible names for the scalar types. Contains not only 

16 ``name: type`` mappings, but ``char: name`` mappings too. 

17 

18 .. deprecated:: 1.16 

19 

20.. data:: sctypes 

21 A dictionary keyed by a "type group" string, providing a list of types 

22 under that group. 

23 

24""" 

25import warnings 

26 

27from numpy.compat import unicode 

28from numpy._globals import VisibleDeprecationWarning 

29from numpy.core._string_helpers import english_lower, english_capitalize 

30from numpy.core.multiarray import typeinfo, dtype 

31from numpy.core._dtype import _kind_name 

32 

33 

34sctypeDict = {} # Contains all leaf-node scalar types with aliases 

35class TypeNADict(dict): 

36 def __getitem__(self, key): 

37 # 2018-06-24, 1.16 

38 warnings.warn('sctypeNA and typeNA will be removed in v1.18 ' 

39 'of numpy', VisibleDeprecationWarning, stacklevel=2) 

40 return dict.__getitem__(self, key) 

41 def get(self, key, default=None): 

42 # 2018-06-24, 1.16 

43 warnings.warn('sctypeNA and typeNA will be removed in v1.18 ' 

44 'of numpy', VisibleDeprecationWarning, stacklevel=2) 

45 return dict.get(self, key, default) 

46 

47sctypeNA = TypeNADict() # Contails all leaf-node types -> numarray type equivalences 

48allTypes = {} # Collect the types we will add to the module 

49 

50 

51# separate the actual type info from the abstract base classes 

52_abstract_types = {} 

53_concrete_typeinfo = {} 

54for k, v in typeinfo.items(): 

55 # make all the keys lowercase too 

56 k = english_lower(k) 

57 if isinstance(v, type): 

58 _abstract_types[k] = v 

59 else: 

60 _concrete_typeinfo[k] = v 

61 

62_concrete_types = {v.type for k, v in _concrete_typeinfo.items()} 

63 

64 

65def _bits_of(obj): 

66 try: 

67 info = next(v for v in _concrete_typeinfo.values() if v.type is obj) 

68 except StopIteration: 

69 if obj in _abstract_types.values(): 

70 raise ValueError("Cannot count the bits of an abstract type") 

71 

72 # some third-party type - make a best-guess 

73 return dtype(obj).itemsize * 8 

74 else: 

75 return info.bits 

76 

77 

78def bitname(obj): 

79 """Return a bit-width name for a given type object""" 

80 bits = _bits_of(obj) 

81 dt = dtype(obj) 

82 char = dt.kind 

83 base = _kind_name(dt) 

84 

85 if base == 'object': 

86 bits = 0 

87 

88 if bits != 0: 

89 char = "%s%d" % (char, bits // 8) 

90 

91 return base, bits, char 

92 

93 

94def _add_types(): 

95 for name, info in _concrete_typeinfo.items(): 

96 # define C-name and insert typenum and typechar references also 

97 allTypes[name] = info.type 

98 sctypeDict[name] = info.type 

99 sctypeDict[info.char] = info.type 

100 sctypeDict[info.num] = info.type 

101 

102 for name, cls in _abstract_types.items(): 

103 allTypes[name] = cls 

104_add_types() 

105 

106# This is the priority order used to assign the bit-sized NPY_INTxx names, which 

107# must match the order in npy_common.h in order for NPY_INTxx and np.intxx to be 

108# consistent. 

109# If two C types have the same size, then the earliest one in this list is used 

110# as the sized name. 

111_int_ctypes = ['long', 'longlong', 'int', 'short', 'byte'] 

112_uint_ctypes = list('u' + t for t in _int_ctypes) 

113 

114def _add_aliases(): 

115 for name, info in _concrete_typeinfo.items(): 

116 # these are handled by _add_integer_aliases 

117 if name in _int_ctypes or name in _uint_ctypes: 

118 continue 

119 

120 # insert bit-width version for this class (if relevant) 

121 base, bit, char = bitname(info.type) 

122 

123 myname = "%s%d" % (base, bit) 

124 

125 # ensure that (c)longdouble does not overwrite the aliases assigned to 

126 # (c)double 

127 if name in ('longdouble', 'clongdouble') and myname in allTypes: 

128 continue 

129 

130 base_capitalize = english_capitalize(base) 

131 if base == 'complex': 

132 na_name = '%s%d' % (base_capitalize, bit//2) 

133 elif base == 'bool': 

134 na_name = base_capitalize 

135 else: 

136 na_name = "%s%d" % (base_capitalize, bit) 

137 

138 allTypes[myname] = info.type 

139 

140 # add mapping for both the bit name and the numarray name 

141 sctypeDict[myname] = info.type 

142 sctypeDict[na_name] = info.type 

143 

144 # add forward, reverse, and string mapping to numarray 

145 sctypeNA[na_name] = info.type 

146 sctypeNA[info.type] = na_name 

147 sctypeNA[info.char] = na_name 

148 

149 sctypeDict[char] = info.type 

150 sctypeNA[char] = na_name 

151_add_aliases() 

152 

153def _add_integer_aliases(): 

154 seen_bits = set() 

155 for i_ctype, u_ctype in zip(_int_ctypes, _uint_ctypes): 

156 i_info = _concrete_typeinfo[i_ctype] 

157 u_info = _concrete_typeinfo[u_ctype] 

158 bits = i_info.bits # same for both 

159 

160 for info, charname, intname, Intname in [ 

161 (i_info,'i%d' % (bits//8,), 'int%d' % bits, 'Int%d' % bits), 

162 (u_info,'u%d' % (bits//8,), 'uint%d' % bits, 'UInt%d' % bits)]: 

163 if bits not in seen_bits: 

164 # sometimes two different types have the same number of bits 

165 # if so, the one iterated over first takes precedence 

166 allTypes[intname] = info.type 

167 sctypeDict[intname] = info.type 

168 sctypeDict[Intname] = info.type 

169 sctypeDict[charname] = info.type 

170 sctypeNA[Intname] = info.type 

171 sctypeNA[charname] = info.type 

172 sctypeNA[info.type] = Intname 

173 sctypeNA[info.char] = Intname 

174 

175 seen_bits.add(bits) 

176 

177_add_integer_aliases() 

178 

179# We use these later 

180void = allTypes['void'] 

181 

182# 

183# Rework the Python names (so that float and complex and int are consistent 

184# with Python usage) 

185# 

186def _set_up_aliases(): 

187 type_pairs = [('complex_', 'cdouble'), 

188 ('int0', 'intp'), 

189 ('uint0', 'uintp'), 

190 ('single', 'float'), 

191 ('csingle', 'cfloat'), 

192 ('singlecomplex', 'cfloat'), 

193 ('float_', 'double'), 

194 ('intc', 'int'), 

195 ('uintc', 'uint'), 

196 ('int_', 'long'), 

197 ('uint', 'ulong'), 

198 ('cfloat', 'cdouble'), 

199 ('longfloat', 'longdouble'), 

200 ('clongfloat', 'clongdouble'), 

201 ('longcomplex', 'clongdouble'), 

202 ('bool_', 'bool'), 

203 ('bytes_', 'string'), 

204 ('string_', 'string'), 

205 ('str_', 'unicode'), 

206 ('unicode_', 'unicode'), 

207 ('object_', 'object')] 

208 for alias, t in type_pairs: 

209 allTypes[alias] = allTypes[t] 

210 sctypeDict[alias] = sctypeDict[t] 

211 # Remove aliases overriding python types and modules 

212 to_remove = ['ulong', 'object', 'int', 'float', 

213 'complex', 'bool', 'string', 'datetime', 'timedelta', 

214 'bytes', 'str'] 

215 

216 for t in to_remove: 

217 try: 

218 del allTypes[t] 

219 del sctypeDict[t] 

220 except KeyError: 

221 pass 

222_set_up_aliases() 

223 

224 

225sctypes = {'int': [], 

226 'uint':[], 

227 'float':[], 

228 'complex':[], 

229 'others':[bool, object, bytes, unicode, void]} 

230 

231def _add_array_type(typename, bits): 

232 try: 

233 t = allTypes['%s%d' % (typename, bits)] 

234 except KeyError: 

235 pass 

236 else: 

237 sctypes[typename].append(t) 

238 

239def _set_array_types(): 

240 ibytes = [1, 2, 4, 8, 16, 32, 64] 

241 fbytes = [2, 4, 8, 10, 12, 16, 32, 64] 

242 for bytes in ibytes: 

243 bits = 8*bytes 

244 _add_array_type('int', bits) 

245 _add_array_type('uint', bits) 

246 for bytes in fbytes: 

247 bits = 8*bytes 

248 _add_array_type('float', bits) 

249 _add_array_type('complex', 2*bits) 

250 _gi = dtype('p') 

251 if _gi.type not in sctypes['int']: 

252 indx = 0 

253 sz = _gi.itemsize 

254 _lst = sctypes['int'] 

255 while (indx < len(_lst) and sz >= _lst[indx](0).itemsize): 

256 indx += 1 

257 sctypes['int'].insert(indx, _gi.type) 

258 sctypes['uint'].insert(indx, dtype('P').type) 

259_set_array_types() 

260 

261 

262# Add additional strings to the sctypeDict 

263_toadd = ['int', 'float', 'complex', 'bool', 'object', 

264 'str', 'bytes', ('a', 'bytes_')] 

265 

266for name in _toadd: 

267 if isinstance(name, tuple): 

268 sctypeDict[name[0]] = allTypes[name[1]] 

269 else: 

270 sctypeDict[name] = allTypes['%s_' % name] 

271 

272del _toadd, name