From c4e4f2588862b9b3e86c2ff5a3805d74dbb9deb8 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Tue, 5 Dec 2017 18:15:07 -0800 Subject: [PATCH 1/2] remove datetime.pxd --- pandas/_libs/hashing.pyx | 3 +- pandas/_libs/src/datetime.pxd | 64 ----------------------------- pandas/_libs/tslib.pyx | 3 +- pandas/_libs/tslibs/conversion.pyx | 3 +- pandas/_libs/tslibs/np_datetime.pxd | 7 ++++ pandas/_libs/tslibs/np_datetime.pyx | 26 +++++++++++- setup.py | 3 +- 7 files changed, 37 insertions(+), 72 deletions(-) delete mode 100644 pandas/_libs/src/datetime.pxd 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 7f3cc0a7e81dd..fde52b78313e7 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..6bfe8123d7ced 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,21 @@ 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 = parse_iso_8601_datetime(tmp, len(val), + dts, out_local, out_tzoffset) + + if result == -1: + raise ValueError('Unable to parse %s' % str(val)) + 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 [] From 9a8abda3f1c5d23816b240c3923ad92c59d69e7d Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Wed, 6 Dec 2017 08:24:06 -0800 Subject: [PATCH 2/2] re-insert extra layer to fix python3 error --- pandas/_libs/tslibs/np_datetime.pyx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/tslibs/np_datetime.pyx b/pandas/_libs/tslibs/np_datetime.pyx index 6bfe8123d7ced..7f861a50f03b8 100644 --- a/pandas/_libs/tslibs/np_datetime.pyx +++ b/pandas/_libs/tslibs/np_datetime.pyx @@ -179,9 +179,23 @@ cdef inline int _string_to_dts(object val, pandas_datetimestruct* dts, val = PyUnicode_AsASCIIString(val) tmp = val - result = parse_iso_8601_datetime(tmp, len(val), - dts, out_local, out_tzoffset) + 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