Coverage for /opt/homebrew/lib/python3.11/site-packages/numpy/core/_type_aliases.py: 89%

124 statements  

« prev     ^ index     » next       coverage.py v7.2.3, created at 2023-05-04 13:14 +0700

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:: sctypes 

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

16 under that group. 

17 

18""" 

19 

20from numpy.compat import unicode 

21from numpy.core._string_helpers import english_lower 

22from numpy.core.multiarray import typeinfo, dtype 

23from numpy.core._dtype import _kind_name 

24 

25 

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

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

28 

29 

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

31_abstract_types = {} 

32_concrete_typeinfo = {} 

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

34 # make all the keys lowercase too 

35 k = english_lower(k) 

36 if isinstance(v, type): 

37 _abstract_types[k] = v 

38 else: 

39 _concrete_typeinfo[k] = v 

40 

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

42 

43 

44def _bits_of(obj): 

45 try: 

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

47 except StopIteration: 

48 if obj in _abstract_types.values(): 

49 msg = "Cannot count the bits of an abstract type" 

50 raise ValueError(msg) from None 

51 

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

53 return dtype(obj).itemsize * 8 

54 else: 

55 return info.bits 

56 

57 

58def bitname(obj): 

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

60 bits = _bits_of(obj) 

61 dt = dtype(obj) 

62 char = dt.kind 

63 base = _kind_name(dt) 

64 

65 if base == 'object': 

66 bits = 0 

67 

68 if bits != 0: 

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

70 

71 return base, bits, char 

72 

73 

74def _add_types(): 

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

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

77 allTypes[name] = info.type 

78 sctypeDict[name] = info.type 

79 sctypeDict[info.char] = info.type 

80 sctypeDict[info.num] = info.type 

81 

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

83 allTypes[name] = cls 

84_add_types() 

85 

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

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

88# consistent. 

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

90# as the sized name. 

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

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

93 

94def _add_aliases(): 

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

96 # these are handled by _add_integer_aliases 

97 if name in _int_ctypes or name in _uint_ctypes: 

98 continue 

99 

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

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

102 

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

104 

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

106 # (c)double 

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

108 continue 

109 

110 # Add to the main namespace if desired: 

111 if bit != 0 and base != "bool": 

112 allTypes[myname] = info.type 

113 

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

115 sctypeDict[char] = info.type 

116 

117 # add mapping for both the bit name 

118 sctypeDict[myname] = info.type 

119 

120 

121_add_aliases() 

122 

123def _add_integer_aliases(): 

124 seen_bits = set() 

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

126 i_info = _concrete_typeinfo[i_ctype] 

127 u_info = _concrete_typeinfo[u_ctype] 

128 bits = i_info.bits # same for both 

129 

130 for info, charname, intname in [ 

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

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

133 if bits not in seen_bits: 

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

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

136 allTypes[intname] = info.type 

137 sctypeDict[intname] = info.type 

138 sctypeDict[charname] = info.type 

139 

140 seen_bits.add(bits) 

141 

142_add_integer_aliases() 

143 

144# We use these later 

145void = allTypes['void'] 

146 

147# 

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

149# with Python usage) 

150# 

151def _set_up_aliases(): 

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

153 ('single', 'float'), 

154 ('csingle', 'cfloat'), 

155 ('singlecomplex', 'cfloat'), 

156 ('float_', 'double'), 

157 ('intc', 'int'), 

158 ('uintc', 'uint'), 

159 ('int_', 'long'), 

160 ('uint', 'ulong'), 

161 ('cfloat', 'cdouble'), 

162 ('longfloat', 'longdouble'), 

163 ('clongfloat', 'clongdouble'), 

164 ('longcomplex', 'clongdouble'), 

165 ('bool_', 'bool'), 

166 ('bytes_', 'string'), 

167 ('string_', 'string'), 

168 ('str_', 'unicode'), 

169 ('unicode_', 'unicode'), 

170 ('object_', 'object')] 

171 for alias, t in type_pairs: 

172 allTypes[alias] = allTypes[t] 

173 sctypeDict[alias] = sctypeDict[t] 

174 # Remove aliases overriding python types and modules 

175 to_remove = ['object', 'int', 'float', 

176 'complex', 'bool', 'string', 'datetime', 'timedelta', 

177 'bytes', 'str'] 

178 

179 for t in to_remove: 

180 try: 

181 del allTypes[t] 

182 del sctypeDict[t] 

183 except KeyError: 

184 pass 

185 

186 # Additional aliases in sctypeDict that should not be exposed as attributes 

187 attrs_to_remove = ['ulong'] 

188 

189 for t in attrs_to_remove: 

190 try: 

191 del allTypes[t] 

192 except KeyError: 

193 pass 

194_set_up_aliases() 

195 

196 

197sctypes = {'int': [], 

198 'uint':[], 

199 'float':[], 

200 'complex':[], 

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

202 

203def _add_array_type(typename, bits): 

204 try: 

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

206 except KeyError: 

207 pass 

208 else: 

209 sctypes[typename].append(t) 

210 

211def _set_array_types(): 

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

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

214 for bytes in ibytes: 

215 bits = 8*bytes 

216 _add_array_type('int', bits) 

217 _add_array_type('uint', bits) 

218 for bytes in fbytes: 

219 bits = 8*bytes 

220 _add_array_type('float', bits) 

221 _add_array_type('complex', 2*bits) 

222 _gi = dtype('p') 

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

224 indx = 0 

225 sz = _gi.itemsize 

226 _lst = sctypes['int'] 

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

228 indx += 1 

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

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

231_set_array_types() 

232 

233 

234# Add additional strings to the sctypeDict 

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

236 'str', 'bytes', ('a', 'bytes_'), 

237 ('int0', 'intp'), ('uint0', 'uintp')] 

238 

239for name in _toadd: 

240 if isinstance(name, tuple): 

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

242 else: 

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

244 

245del _toadd, name