util.pxd 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. from cpython.object cimport PyTypeObject
  2. cdef extern from "Python.h":
  3. # Note: importing extern-style allows us to declare these as nogil
  4. # functions, whereas `from cpython cimport` does not.
  5. bint PyBool_Check(object obj) nogil
  6. bint PyFloat_Check(object obj) nogil
  7. bint PyComplex_Check(object obj) nogil
  8. bint PyObject_TypeCheck(object obj, PyTypeObject* type) nogil
  9. # Note that following functions can potentially raise an exception,
  10. # thus they cannot be declared 'nogil'. Also PyUnicode_AsUTF8AndSize() can
  11. # potentially allocate memory inside in unlikely case of when underlying
  12. # unicode object was stored as non-utf8 and utf8 wasn't requested before.
  13. const char* PyUnicode_AsUTF8AndSize(object obj,
  14. Py_ssize_t* length) except NULL
  15. object PyUnicode_EncodeLocale(object obj, const char *errors) nogil
  16. object PyUnicode_DecodeLocale(const char *str, const char *errors) nogil
  17. from numpy cimport (
  18. float64_t,
  19. int64_t,
  20. )
  21. cdef extern from "numpy/arrayobject.h":
  22. PyTypeObject PyFloatingArrType_Type
  23. cdef extern from "numpy/ndarrayobject.h":
  24. PyTypeObject PyTimedeltaArrType_Type
  25. PyTypeObject PyDatetimeArrType_Type
  26. PyTypeObject PyComplexFloatingArrType_Type
  27. PyTypeObject PyBoolArrType_Type
  28. bint PyArray_IsIntegerScalar(obj) nogil
  29. bint PyArray_Check(obj) nogil
  30. cdef extern from "numpy/npy_common.h":
  31. int64_t NPY_MIN_INT64
  32. cdef inline int64_t get_nat():
  33. return NPY_MIN_INT64
  34. # --------------------------------------------------------------------
  35. # Type Checking
  36. cdef inline bint is_integer_object(object obj) nogil:
  37. """
  38. Cython equivalent of
  39. `isinstance(val, (int, long, np.integer)) and not isinstance(val, bool)`
  40. Parameters
  41. ----------
  42. val : object
  43. Returns
  44. -------
  45. is_integer : bool
  46. Notes
  47. -----
  48. This counts np.timedelta64 objects as integers.
  49. """
  50. return (not PyBool_Check(obj) and PyArray_IsIntegerScalar(obj)
  51. and not is_timedelta64_object(obj))
  52. cdef inline bint is_float_object(object obj) nogil:
  53. """
  54. Cython equivalent of `isinstance(val, (float, np.float_))`
  55. Parameters
  56. ----------
  57. val : object
  58. Returns
  59. -------
  60. is_float : bool
  61. """
  62. return (PyFloat_Check(obj) or
  63. (PyObject_TypeCheck(obj, &PyFloatingArrType_Type)))
  64. cdef inline bint is_complex_object(object obj) nogil:
  65. """
  66. Cython equivalent of `isinstance(val, (complex, np.complex_))`
  67. Parameters
  68. ----------
  69. val : object
  70. Returns
  71. -------
  72. is_complex : bool
  73. """
  74. return (PyComplex_Check(obj) or
  75. PyObject_TypeCheck(obj, &PyComplexFloatingArrType_Type))
  76. cdef inline bint is_bool_object(object obj) nogil:
  77. """
  78. Cython equivalent of `isinstance(val, (bool, np.bool_))`
  79. Parameters
  80. ----------
  81. val : object
  82. Returns
  83. -------
  84. is_bool : bool
  85. """
  86. return (PyBool_Check(obj) or
  87. PyObject_TypeCheck(obj, &PyBoolArrType_Type))
  88. cdef inline bint is_real_number_object(object obj) nogil:
  89. return is_bool_object(obj) or is_integer_object(obj) or is_float_object(obj)
  90. cdef inline bint is_timedelta64_object(object obj) nogil:
  91. """
  92. Cython equivalent of `isinstance(val, np.timedelta64)`
  93. Parameters
  94. ----------
  95. val : object
  96. Returns
  97. -------
  98. is_timedelta64 : bool
  99. """
  100. return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type)
  101. cdef inline bint is_datetime64_object(object obj) nogil:
  102. """
  103. Cython equivalent of `isinstance(val, np.datetime64)`
  104. Parameters
  105. ----------
  106. val : object
  107. Returns
  108. -------
  109. is_datetime64 : bool
  110. """
  111. return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type)
  112. cdef inline bint is_array(object val):
  113. """
  114. Cython equivalent of `isinstance(val, np.ndarray)`
  115. Parameters
  116. ----------
  117. val : object
  118. Returns
  119. -------
  120. is_ndarray : bool
  121. """
  122. return PyArray_Check(val)
  123. cdef inline bint is_nan(object val):
  124. """
  125. Check if val is a Not-A-Number float or complex, including
  126. float('NaN') and np.nan.
  127. Parameters
  128. ----------
  129. val : object
  130. Returns
  131. -------
  132. is_nan : bool
  133. """
  134. cdef float64_t fval
  135. if is_float_object(val):
  136. fval = val
  137. return fval != fval
  138. return is_complex_object(val) and val != val
  139. cdef inline const char* get_c_string_buf_and_size(str py_string,
  140. Py_ssize_t *length) except NULL:
  141. """
  142. Extract internal char* buffer of unicode or bytes object `py_string` with
  143. getting length of this internal buffer saved in `length`.
  144. Notes
  145. -----
  146. Python object owns memory, thus returned char* must not be freed.
  147. `length` can be NULL if getting buffer length is not needed.
  148. Parameters
  149. ----------
  150. py_string : str
  151. length : Py_ssize_t*
  152. Returns
  153. -------
  154. buf : const char*
  155. """
  156. return PyUnicode_AsUTF8AndSize(py_string, length)
  157. cdef inline const char* get_c_string(str py_string) except NULL:
  158. return get_c_string_buf_and_size(py_string, NULL)
  159. cdef inline bytes string_encode_locale(str py_string):
  160. """As opposed to PyUnicode_Encode, use current system locale to encode."""
  161. return PyUnicode_EncodeLocale(py_string, NULL)
  162. cdef inline object char_to_string_locale(const char* data):
  163. """As opposed to PyUnicode_FromString, use current system locale to decode."""
  164. return PyUnicode_DecodeLocale(data, NULL)