1"""
2numerictypes: Define the numeric type objects
3
4This module is designed so "from numerictypes import \\*" is safe.
5Exported symbols include:
6
7 Dictionary with all registered number types (including aliases):
8 sctypeDict
9
10 Type objects (not all will be available, depends on platform):
11 see variable sctypes for which ones you have
12
13 Bit-width names
14
15 int8 int16 int32 int64 int128
16 uint8 uint16 uint32 uint64 uint128
17 float16 float32 float64 float96 float128 float256
18 complex32 complex64 complex128 complex192 complex256 complex512
19 datetime64 timedelta64
20
21 c-based names
22
23 bool_
24
25 object_
26
27 void, str_, unicode_
28
29 byte, ubyte,
30 short, ushort
31 intc, uintc,
32 intp, uintp,
33 int_, uint,
34 longlong, ulonglong,
35
36 single, csingle,
37 float_, complex_,
38 longfloat, clongfloat,
39
40 As part of the type-hierarchy: xx -- is bit-width
41
42 generic
43 +-> bool_ (kind=b)
44 +-> number
45 | +-> integer
46 | | +-> signedinteger (intxx) (kind=i)
47 | | | byte
48 | | | short
49 | | | intc
50 | | | intp
51 | | | int_
52 | | | longlong
53 | | \\-> unsignedinteger (uintxx) (kind=u)
54 | | ubyte
55 | | ushort
56 | | uintc
57 | | uintp
58 | | uint_
59 | | ulonglong
60 | +-> inexact
61 | +-> floating (floatxx) (kind=f)
62 | | half
63 | | single
64 | | float_ (double)
65 | | longfloat
66 | \\-> complexfloating (complexxx) (kind=c)
67 | csingle (singlecomplex)
68 | complex_ (cfloat, cdouble)
69 | clongfloat (longcomplex)
70 +-> flexible
71 | +-> character
72 | | str_ (string_, bytes_) (kind=S) [Python 2]
73 | | unicode_ (kind=U) [Python 2]
74 | |
75 | | bytes_ (string_) (kind=S) [Python 3]
76 | | str_ (unicode_) (kind=U) [Python 3]
77 | |
78 | \\-> void (kind=V)
79 \\-> object_ (not used much) (kind=O)
80
81"""
82import numbers
83
84from numpy.core.multiarray import (
85 ndarray, array, dtype, datetime_data, datetime_as_string,
86 busday_offset, busday_count, is_busday, busdaycalendar
87 )
88from numpy.core.overrides import set_module
89
90# we add more at the bottom
91__all__ = ['sctypeDict', 'sctypes',
92 'ScalarType', 'obj2sctype', 'cast', 'nbytes', 'sctype2char',
93 'maximum_sctype', 'issctype', 'typecodes', 'find_common_type',
94 'issubdtype', 'datetime_data', 'datetime_as_string',
95 'busday_offset', 'busday_count', 'is_busday', 'busdaycalendar',
96 ]
97
98# we don't need all these imports, but we need to keep them for compatibility
99# for users using np.core.numerictypes.UPPER_TABLE
100from ._string_helpers import (
101 english_lower, english_upper, english_capitalize, LOWER_TABLE, UPPER_TABLE
102)
103
104from ._type_aliases import (
105 sctypeDict,
106 allTypes,
107 bitname,
108 sctypes,
109 _concrete_types,
110 _concrete_typeinfo,
111 _bits_of,
112)
113from ._dtype import _kind_name
114
115# we don't export these for import *, but we do want them accessible
116# as numerictypes.bool, etc.
117from builtins import bool, int, float, complex, object, str, bytes
118from numpy.compat import long, unicode
119
120
121# We use this later
122generic = allTypes['generic']
123
124genericTypeRank = ['bool', 'int8', 'uint8', 'int16', 'uint16',
125 'int32', 'uint32', 'int64', 'uint64', 'int128',
126 'uint128', 'float16',
127 'float32', 'float64', 'float80', 'float96', 'float128',
128 'float256',
129 'complex32', 'complex64', 'complex128', 'complex160',
130 'complex192', 'complex256', 'complex512', 'object']
131
132@set_module('numpy')
133def maximum_sctype(t):
134 """
135 Return the scalar type of highest precision of the same kind as the input.
136
137 Parameters
138 ----------
139 t : dtype or dtype specifier
140 The input data type. This can be a `dtype` object or an object that
141 is convertible to a `dtype`.
142
143 Returns
144 -------
145 out : dtype
146 The highest precision data type of the same kind (`dtype.kind`) as `t`.
147
148 See Also
149 --------
150 obj2sctype, mintypecode, sctype2char
151 dtype
152
153 Examples
154 --------
155 >>> np.maximum_sctype(int)
156 <class 'numpy.int64'>
157 >>> np.maximum_sctype(np.uint8)
158 <class 'numpy.uint64'>
159 >>> np.maximum_sctype(complex)
160 <class 'numpy.complex256'> # may vary
161
162 >>> np.maximum_sctype(str)
163 <class 'numpy.str_'>
164
165 >>> np.maximum_sctype('i2')
166 <class 'numpy.int64'>
167 >>> np.maximum_sctype('f4')
168 <class 'numpy.float128'> # may vary
169
170 """
171 g = obj2sctype(t)
172 if g is None:
173 return t
174 t = g
175 base = _kind_name(dtype(t))
176 if base in sctypes:
177 return sctypes[base][-1]
178 else:
179 return t
180
181
182@set_module('numpy')
183def issctype(rep):
184 """
185 Determines whether the given object represents a scalar data-type.
186
187 Parameters
188 ----------
189 rep : any
190 If `rep` is an instance of a scalar dtype, True is returned. If not,
191 False is returned.
192
193 Returns
194 -------
195 out : bool
196 Boolean result of check whether `rep` is a scalar dtype.
197
198 See Also
199 --------
200 issubsctype, issubdtype, obj2sctype, sctype2char
201
202 Examples
203 --------
204 >>> np.issctype(np.int32)
205 True
206 >>> np.issctype(list)
207 False
208 >>> np.issctype(1.1)
209 False
210
211 Strings are also a scalar type:
212
213 >>> np.issctype(np.dtype('str'))
214 True
215
216 """
217 if not isinstance(rep, (type, dtype)):
218 return False
219 try:
220 res = obj2sctype(rep)
221 if res and res != object_:
222 return True
223 return False
224 except Exception:
225 return False
226
227
228@set_module('numpy')
229def obj2sctype(rep, default=None):
230 """
231 Return the scalar dtype or NumPy equivalent of Python type of an object.
232
233 Parameters
234 ----------
235 rep : any
236 The object of which the type is returned.
237 default : any, optional
238 If given, this is returned for objects whose types can not be
239 determined. If not given, None is returned for those objects.
240
241 Returns
242 -------
243 dtype : dtype or Python type
244 The data type of `rep`.
245
246 See Also
247 --------
248 sctype2char, issctype, issubsctype, issubdtype, maximum_sctype
249
250 Examples
251 --------
252 >>> np.obj2sctype(np.int32)
253 <class 'numpy.int32'>
254 >>> np.obj2sctype(np.array([1., 2.]))
255 <class 'numpy.float64'>
256 >>> np.obj2sctype(np.array([1.j]))
257 <class 'numpy.complex128'>
258
259 >>> np.obj2sctype(dict)
260 <class 'numpy.object_'>
261 >>> np.obj2sctype('string')
262
263 >>> np.obj2sctype(1, default=list)
264 <class 'list'>
265
266 """
267 # prevent abstract classes being upcast
268 if isinstance(rep, type) and issubclass(rep, generic):
269 return rep
270 # extract dtype from arrays
271 if isinstance(rep, ndarray):
272 return rep.dtype.type
273 # fall back on dtype to convert
274 try:
275 res = dtype(rep)
276 except Exception:
277 return default
278 else:
279 return res.type
280
281
282@set_module('numpy')
283def issubclass_(arg1, arg2):
284 """
285 Determine if a class is a subclass of a second class.
286
287 `issubclass_` is equivalent to the Python built-in ``issubclass``,
288 except that it returns False instead of raising a TypeError if one
289 of the arguments is not a class.
290
291 Parameters
292 ----------
293 arg1 : class
294 Input class. True is returned if `arg1` is a subclass of `arg2`.
295 arg2 : class or tuple of classes.
296 Input class. If a tuple of classes, True is returned if `arg1` is a
297 subclass of any of the tuple elements.
298
299 Returns
300 -------
301 out : bool
302 Whether `arg1` is a subclass of `arg2` or not.
303
304 See Also
305 --------
306 issubsctype, issubdtype, issctype
307
308 Examples
309 --------
310 >>> np.issubclass_(np.int32, int)
311 False
312 >>> np.issubclass_(np.int32, float)
313 False
314 >>> np.issubclass_(np.float64, float)
315 True
316
317 """
318 try:
319 return issubclass(arg1, arg2)
320 except TypeError:
321 return False
322
323
324@set_module('numpy')
325def issubsctype(arg1, arg2):
326 """
327 Determine if the first argument is a subclass of the second argument.
328
329 Parameters
330 ----------
331 arg1, arg2 : dtype or dtype specifier
332 Data-types.
333
334 Returns
335 -------
336 out : bool
337 The result.
338
339 See Also
340 --------
341 issctype, issubdtype, obj2sctype
342
343 Examples
344 --------
345 >>> np.issubsctype('S8', str)
346 False
347 >>> np.issubsctype(np.array([1]), int)
348 True
349 >>> np.issubsctype(np.array([1]), float)
350 False
351
352 """
353 return issubclass(obj2sctype(arg1), obj2sctype(arg2))
354
355
356@set_module('numpy')
357def issubdtype(arg1, arg2):
358 r"""
359 Returns True if first argument is a typecode lower/equal in type hierarchy.
360
361 This is like the builtin :func:`issubclass`, but for `dtype`\ s.
362
363 Parameters
364 ----------
365 arg1, arg2 : dtype_like
366 `dtype` or object coercible to one
367
368 Returns
369 -------
370 out : bool
371
372 See Also
373 --------
374 :ref:`arrays.scalars` : Overview of the numpy type hierarchy.
375 issubsctype, issubclass_
376
377 Examples
378 --------
379 `issubdtype` can be used to check the type of arrays:
380
381 >>> ints = np.array([1, 2, 3], dtype=np.int32)
382 >>> np.issubdtype(ints.dtype, np.integer)
383 True
384 >>> np.issubdtype(ints.dtype, np.floating)
385 False
386
387 >>> floats = np.array([1, 2, 3], dtype=np.float32)
388 >>> np.issubdtype(floats.dtype, np.integer)
389 False
390 >>> np.issubdtype(floats.dtype, np.floating)
391 True
392
393 Similar types of different sizes are not subdtypes of each other:
394
395 >>> np.issubdtype(np.float64, np.float32)
396 False
397 >>> np.issubdtype(np.float32, np.float64)
398 False
399
400 but both are subtypes of `floating`:
401
402 >>> np.issubdtype(np.float64, np.floating)
403 True
404 >>> np.issubdtype(np.float32, np.floating)
405 True
406
407 For convenience, dtype-like objects are allowed too:
408
409 >>> np.issubdtype('S1', np.string_)
410 True
411 >>> np.issubdtype('i4', np.signedinteger)
412 True
413
414 """
415 if not issubclass_(arg1, generic):
416 arg1 = dtype(arg1).type
417 if not issubclass_(arg2, generic):
418 arg2 = dtype(arg2).type
419
420 return issubclass(arg1, arg2)
421
422
423# This dictionary allows look up based on any alias for an array data-type
424class _typedict(dict):
425 """
426 Base object for a dictionary for look-up with any alias for an array dtype.
427
428 Instances of `_typedict` can not be used as dictionaries directly,
429 first they have to be populated.
430
431 """
432
433 def __getitem__(self, obj):
434 return dict.__getitem__(self, obj2sctype(obj))
435
436nbytes = _typedict()
437_alignment = _typedict()
438_maxvals = _typedict()
439_minvals = _typedict()
440def _construct_lookups():
441 for name, info in _concrete_typeinfo.items():
442 obj = info.type
443 nbytes[obj] = info.bits // 8
444 _alignment[obj] = info.alignment
445 if len(info) > 5:
446 _maxvals[obj] = info.max
447 _minvals[obj] = info.min
448 else:
449 _maxvals[obj] = None
450 _minvals[obj] = None
451
452_construct_lookups()
453
454
455@set_module('numpy')
456def sctype2char(sctype):
457 """
458 Return the string representation of a scalar dtype.
459
460 Parameters
461 ----------
462 sctype : scalar dtype or object
463 If a scalar dtype, the corresponding string character is
464 returned. If an object, `sctype2char` tries to infer its scalar type
465 and then return the corresponding string character.
466
467 Returns
468 -------
469 typechar : str
470 The string character corresponding to the scalar type.
471
472 Raises
473 ------
474 ValueError
475 If `sctype` is an object for which the type can not be inferred.
476
477 See Also
478 --------
479 obj2sctype, issctype, issubsctype, mintypecode
480
481 Examples
482 --------
483 >>> for sctype in [np.int32, np.double, np.complex_, np.string_, np.ndarray]:
484 ... print(np.sctype2char(sctype))
485 l # may vary
486 d
487 D
488 S
489 O
490
491 >>> x = np.array([1., 2-1.j])
492 >>> np.sctype2char(x)
493 'D'
494 >>> np.sctype2char(list)
495 'O'
496
497 """
498 sctype = obj2sctype(sctype)
499 if sctype is None:
500 raise ValueError("unrecognized type")
501 if sctype not in _concrete_types:
502 # for compatibility
503 raise KeyError(sctype)
504 return dtype(sctype).char
505
506# Create dictionary of casting functions that wrap sequences
507# indexed by type or type character
508cast = _typedict()
509for key in _concrete_types:
510 cast[key] = lambda x, k=key: array(x, copy=False).astype(k)
511
512
513def _scalar_type_key(typ):
514 """A ``key`` function for `sorted`."""
515 dt = dtype(typ)
516 return (dt.kind.lower(), dt.itemsize)
517
518
519ScalarType = [int, float, complex, bool, bytes, str, memoryview]
520ScalarType += sorted(_concrete_types, key=_scalar_type_key)
521ScalarType = tuple(ScalarType)
522
523
524# Now add the types we've determined to this module
525for key in allTypes:
526 globals()[key] = allTypes[key]
527 __all__.append(key)
528
529del key
530
531typecodes = {'Character':'c',
532 'Integer':'bhilqp',
533 'UnsignedInteger':'BHILQP',
534 'Float':'efdg',
535 'Complex':'FDG',
536 'AllInteger':'bBhHiIlLqQpP',
537 'AllFloat':'efdgFDG',
538 'Datetime': 'Mm',
539 'All':'?bhilqpBHILQPefdgFDGSUVOMm'}
540
541# backwards compatibility --- deprecated name
542# Formal deprecation: Numpy 1.20.0, 2020-10-19 (see numpy/__init__.py)
543typeDict = sctypeDict
544
545# b -> boolean
546# u -> unsigned integer
547# i -> signed integer
548# f -> floating point
549# c -> complex
550# M -> datetime
551# m -> timedelta
552# S -> string
553# U -> Unicode string
554# V -> record
555# O -> Python object
556_kind_list = ['b', 'u', 'i', 'f', 'c', 'S', 'U', 'V', 'O', 'M', 'm']
557
558__test_types = '?'+typecodes['AllInteger'][:-2]+typecodes['AllFloat']+'O'
559__len_test_types = len(__test_types)
560
561# Keep incrementing until a common type both can be coerced to
562# is found. Otherwise, return None
563def _find_common_coerce(a, b):
564 if a > b:
565 return a
566 try:
567 thisind = __test_types.index(a.char)
568 except ValueError:
569 return None
570 return _can_coerce_all([a, b], start=thisind)
571
572# Find a data-type that all data-types in a list can be coerced to
573def _can_coerce_all(dtypelist, start=0):
574 N = len(dtypelist)
575 if N == 0:
576 return None
577 if N == 1:
578 return dtypelist[0]
579 thisind = start
580 while thisind < __len_test_types:
581 newdtype = dtype(__test_types[thisind])
582 numcoerce = len([x for x in dtypelist if newdtype >= x])
583 if numcoerce == N:
584 return newdtype
585 thisind += 1
586 return None
587
588def _register_types():
589 numbers.Integral.register(integer)
590 numbers.Complex.register(inexact)
591 numbers.Real.register(floating)
592 numbers.Number.register(number)
593
594_register_types()
595
596
597@set_module('numpy')
598def find_common_type(array_types, scalar_types):
599 """
600 Determine common type following standard coercion rules.
601
602 Parameters
603 ----------
604 array_types : sequence
605 A list of dtypes or dtype convertible objects representing arrays.
606 scalar_types : sequence
607 A list of dtypes or dtype convertible objects representing scalars.
608
609 Returns
610 -------
611 datatype : dtype
612 The common data type, which is the maximum of `array_types` ignoring
613 `scalar_types`, unless the maximum of `scalar_types` is of a
614 different kind (`dtype.kind`). If the kind is not understood, then
615 None is returned.
616
617 See Also
618 --------
619 dtype, common_type, can_cast, mintypecode
620
621 Examples
622 --------
623 >>> np.find_common_type([], [np.int64, np.float32, complex])
624 dtype('complex128')
625 >>> np.find_common_type([np.int64, np.float32], [])
626 dtype('float64')
627
628 The standard casting rules ensure that a scalar cannot up-cast an
629 array unless the scalar is of a fundamentally different kind of data
630 (i.e. under a different hierarchy in the data type hierarchy) then
631 the array:
632
633 >>> np.find_common_type([np.float32], [np.int64, np.float64])
634 dtype('float32')
635
636 Complex is of a different type, so it up-casts the float in the
637 `array_types` argument:
638
639 >>> np.find_common_type([np.float32], [complex])
640 dtype('complex128')
641
642 Type specifier strings are convertible to dtypes and can therefore
643 be used instead of dtypes:
644
645 >>> np.find_common_type(['f4', 'f4', 'i4'], ['c8'])
646 dtype('complex128')
647
648 """
649 array_types = [dtype(x) for x in array_types]
650 scalar_types = [dtype(x) for x in scalar_types]
651
652 maxa = _can_coerce_all(array_types)
653 maxsc = _can_coerce_all(scalar_types)
654
655 if maxa is None:
656 return maxsc
657
658 if maxsc is None:
659 return maxa
660
661 try:
662 index_a = _kind_list.index(maxa.kind)
663 index_sc = _kind_list.index(maxsc.kind)
664 except ValueError:
665 return None
666
667 if index_sc > index_a:
668 return _find_common_coerce(maxsc, maxa)
669 else:
670 return maxa