1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

""" 

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 

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 

 

 

# separate the actual type info from the abstract 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 

 

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

 

 

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) 

dt = dtype(obj) 

char = dt.kind 

base = _kind_name(dt) 

 

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', 'int', 'float', 

'complex', 'bool', 'string', 'datetime', 'timedelta'] 

if sys.version_info[0] >= 3: 

to_remove.extend(['bytes', 'str']) 

else: 

to_remove.extend(['unicode', 'long']) 

 

for t in to_remove: 

try: 

del allTypes[t] 

del sctypeDict[t] 

except KeyError: 

pass 

_set_up_aliases() 

 

 

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 

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

if sys.version_info[0] >= 3: 

_toadd.extend(['str', 'bytes', ('a', 'bytes_')]) 

else: 

_toadd.extend(['string', ('str', 'string_'), 'unicode', ('a', 'string_')]) 

 

for name in _toadd: 

if isinstance(name, tuple): 

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

else: 

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

 

del _toadd, name