diff --git a/pandas/_libs/hashing.pyx b/pandas/_libs/hashing.pyx index 4c4449fb3e291..aa7aa4b528194 100644 --- a/pandas/_libs/hashing.pyx +++ b/pandas/_libs/hashing.pyx @@ -42,7 +42,8 @@ def hash_object_array(ndarray[object] arr, object key, object encoding='utf8'): bytes data, k uint8_t *kb uint64_t *lens - char **vecs, *cdata + char **vecs + char *cdata object val k = key.encode(encoding) diff --git a/pandas/_libs/src/datetime.pxd b/pandas/_libs/src/datetime.pxd deleted file mode 100644 index d919fca09c006..0000000000000 --- a/pandas/_libs/src/datetime.pxd +++ /dev/null @@ -1,64 +0,0 @@ -# cython: profile=False -from numpy cimport int64_t, npy_int64, npy_int32 - -from cpython cimport PyUnicode_Check, PyUnicode_AsASCIIString - - -cdef extern from "numpy/ndarrayobject.h": - ctypedef int64_t npy_datetime - -cdef extern from "datetime/np_datetime.h": - ctypedef enum PANDAS_DATETIMEUNIT: - PANDAS_FR_Y - PANDAS_FR_M - PANDAS_FR_W - PANDAS_FR_D - PANDAS_FR_B - PANDAS_FR_h - PANDAS_FR_m - PANDAS_FR_s - PANDAS_FR_ms - PANDAS_FR_us - PANDAS_FR_ns - PANDAS_FR_ps - PANDAS_FR_fs - PANDAS_FR_as - - ctypedef struct pandas_datetimestruct: - npy_int64 year - npy_int32 month, day, hour, min, sec, us, ps, as - - void pandas_datetime_to_datetimestruct(npy_datetime val, - PANDAS_DATETIMEUNIT fr, - pandas_datetimestruct *result) nogil - - -cdef extern from "datetime/np_datetime_strings.h": - int parse_iso_8601_datetime(char *str, int len, - pandas_datetimestruct *out, - int *out_local, int *out_tzoffset) - -cdef inline int _string_to_dts(object val, pandas_datetimestruct* dts, - int* out_local, int* out_tzoffset) except? -1: - cdef int result - cdef char *tmp - - if PyUnicode_Check(val): - val = PyUnicode_AsASCIIString(val); - - tmp = val - result = _cstring_to_dts(tmp, len(val), dts, out_local, out_tzoffset) - - if result == -1: - raise ValueError('Unable to parse %s' % str(val)) - return result - -cdef inline int _cstring_to_dts(char *val, int length, - pandas_datetimestruct* dts, - int* out_local, int* out_tzoffset) except? -1: - cdef: - int result - - result = parse_iso_8601_datetime(val, length, - dts, out_local, out_tzoffset) - return result diff --git a/pandas/_libs/tslib.pyx b/pandas/_libs/tslib.pyx index 020ac812e1c20..5e08df7dfe27b 100644 --- a/pandas/_libs/tslib.pyx +++ b/pandas/_libs/tslib.pyx @@ -23,12 +23,11 @@ from cpython.datetime cimport (PyDateTime_Check, PyDate_Check, timedelta, datetime, date) # import datetime C API PyDateTime_IMPORT -# this is our datetime.pxd -from datetime cimport _string_to_dts from tslibs.np_datetime cimport (check_dts_bounds, pandas_datetimestruct, + _string_to_dts, dt64_to_dtstruct, dtstruct_to_dt64, pydatetime_to_dt64, pydate_to_dt64, get_datetime64_value, diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 0257d13157acc..4f6b2f52d4d24 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -20,14 +20,13 @@ PyDateTime_IMPORT from np_datetime cimport (check_dts_bounds, pandas_datetimestruct, + pandas_datetime_to_datetimestruct, _string_to_dts, PANDAS_DATETIMEUNIT, PANDAS_FR_ns, npy_datetime, dt64_to_dtstruct, dtstruct_to_dt64, get_datetime64_unit, get_datetime64_value, pydatetime_to_dt64) -from datetime cimport pandas_datetime_to_datetimestruct, _string_to_dts - from util cimport (is_string_object, is_datetime64_object, is_integer_object, is_float_object) diff --git a/pandas/_libs/tslibs/np_datetime.pxd b/pandas/_libs/tslibs/np_datetime.pxd index 8d9a812654ab0..33b8b32bcf2dc 100644 --- a/pandas/_libs/tslibs/np_datetime.pxd +++ b/pandas/_libs/tslibs/np_datetime.pxd @@ -50,6 +50,10 @@ cdef extern from "../src/datetime/np_datetime.h": PANDAS_FR_fs PANDAS_FR_as + void pandas_datetime_to_datetimestruct(npy_datetime val, + PANDAS_DATETIMEUNIT fr, + pandas_datetimestruct *result) nogil + int days_per_month_table[2][12] int dayofweek(int y, int m, int d) nogil int is_leapyear(int64_t year) nogil @@ -71,3 +75,6 @@ cdef int64_t pydate_to_dt64(date val, pandas_datetimestruct *dts) cdef npy_datetime get_datetime64_value(object obj) nogil cdef npy_timedelta get_timedelta64_value(object obj) nogil cdef PANDAS_DATETIMEUNIT get_datetime64_unit(object obj) nogil + +cdef int _string_to_dts(object val, pandas_datetimestruct* dts, + int* out_local, int* out_tzoffset) except? -1 diff --git a/pandas/_libs/tslibs/np_datetime.pyx b/pandas/_libs/tslibs/np_datetime.pyx index 72c028161a937..7f861a50f03b8 100644 --- a/pandas/_libs/tslibs/np_datetime.pyx +++ b/pandas/_libs/tslibs/np_datetime.pyx @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- # cython: profile=False -from cpython cimport Py_EQ, Py_NE, Py_GE, Py_GT, Py_LT, Py_LE +from cpython cimport (Py_EQ, Py_NE, Py_GE, Py_GT, Py_LT, Py_LE, + PyUnicode_Check, PyUnicode_AsASCIIString) from cpython.datetime cimport (datetime, date, PyDateTime_IMPORT, @@ -33,6 +34,11 @@ cdef extern from "../src/datetime/np_datetime.h": pandas_datetimestruct _NS_MIN_DTS, _NS_MAX_DTS +cdef extern from "../src/datetime/np_datetime_strings.h": + int parse_iso_8601_datetime(char *str, int len, + pandas_datetimestruct *out, + int *out_local, int *out_tzoffset) + # ---------------------------------------------------------------------- # numpy object inspection @@ -161,3 +167,35 @@ cdef inline int64_t pydate_to_dt64(date val, dts.hour = dts.min = dts.sec = dts.us = 0 dts.ps = dts.as = 0 return dtstruct_to_dt64(dts) + + +cdef inline int _string_to_dts(object val, pandas_datetimestruct* dts, + int* out_local, int* out_tzoffset) except? -1: + cdef: + int result + char *tmp + + if PyUnicode_Check(val): + val = PyUnicode_AsASCIIString(val) + + tmp = val + result = _cstring_to_dts(tmp, len(val), dts, out_local, out_tzoffset) + + if result == -1: + raise ValueError('Unable to parse %s' % str(val)) + return result + + +cdef inline int _cstring_to_dts(char *val, int length, + pandas_datetimestruct* dts, + int* out_local, int* out_tzoffset) except? -1: + # Note: without this "extra layer" between _string_to_dts + # and parse_iso_8601_datetime, calling _string_to_dts raises + # `SystemError: returned a result with an error set` + # in Python3 + cdef: + int result + + result = parse_iso_8601_datetime(val, length, + dts, out_local, out_tzoffset) + return result diff --git a/setup.py b/setup.py index 5820b0dd9933c..c58cc8ef99faf 100755 --- a/setup.py +++ b/setup.py @@ -453,8 +453,7 @@ def pxd(name): 'pandas/_libs/src/datetime/np_datetime_strings.h'] np_datetime_sources = ['pandas/_libs/src/datetime/np_datetime.c', 'pandas/_libs/src/datetime/np_datetime_strings.c'] -tseries_depends = np_datetime_headers + ['pandas/_libs/src/datetime.pxd', - 'pandas/_libs/tslibs/np_datetime.pxd'] +tseries_depends = np_datetime_headers + ['pandas/_libs/tslibs/np_datetime.pxd'] # some linux distros require it libraries = ['m'] if not is_platform_windows() else []