Skip to content

Use PyCapsule for internal datetime functions #51525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 40 commits into from
Mar 11, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
431495b
initial file setup and build
WillAyd Feb 18, 2023
c3dca72
Building standalone impl
WillAyd Feb 18, 2023
d77a2ed
more build
WillAyd Feb 18, 2023
4525e77
linting
WillAyd Feb 18, 2023
782b971
more updates
WillAyd Feb 18, 2023
69abccd
Capsule location change
WillAyd Feb 19, 2023
69460bd
working import
WillAyd Feb 20, 2023
776f0f5
working imports?
WillAyd Feb 20, 2023
c4a05b5
moved lots
WillAyd Feb 20, 2023
a995ee2
Working impl
WillAyd Feb 21, 2023
05e28ad
styling
WillAyd Feb 21, 2023
d938374
import cleanups
WillAyd Feb 21, 2023
df687b3
revert init change
WillAyd Feb 21, 2023
a26f312
cleanups
WillAyd Feb 21, 2023
96b6f96
isort fixups
WillAyd Feb 21, 2023
7b28333
api test fix
WillAyd Feb 21, 2023
ccea2b3
removed unneeded tokenizer add
WillAyd Feb 21, 2023
2bf7264
Hacked together parser capsule
WillAyd Feb 26, 2023
418910d
Symbol cleanups
WillAyd Feb 26, 2023
a4f7e1a
Resolved all undefined symbols in parsers.pyx
WillAyd Feb 26, 2023
ad1d149
IO callbacks restored
WillAyd Feb 26, 2023
5887254
Fix build and test failures
WillAyd Feb 26, 2023
138ea0d
Try relative imports for MSFT compat
WillAyd Feb 26, 2023
679d03d
try py_ssize_t_clean macro
WillAyd Feb 26, 2023
7c4e365
Removed double tokenizer include
WillAyd Feb 26, 2023
5aee18a
removed unneeded include path
WillAyd Feb 26, 2023
a0523be
more cleanups
WillAyd Feb 27, 2023
554d701
noexcept
WillAyd Feb 27, 2023
726d93d
signature cleanup
WillAyd Feb 27, 2023
d2fe542
simplify parser impl
WillAyd Feb 28, 2023
49a2739
retain np_datetime_string license
WillAyd Feb 28, 2023
3981ec2
retained old file structure where possible
WillAyd Feb 28, 2023
fb75100
Commited C file
WillAyd Feb 28, 2023
f51e7f4
Removed erroneous comments
WillAyd Mar 2, 2023
709bf6c
Merge branch 'main' into np-datetime-capsule
WillAyd Mar 2, 2023
f4dac4f
graft pd_parser.c
WillAyd Mar 6, 2023
7fd0a49
Merge branch 'main' into np-datetime-capsule
WillAyd Mar 6, 2023
12179c7
graft -> include
WillAyd Mar 6, 2023
67f5445
Merge remote-tracking branch 'upstream/main' into np-datetime-capsule
WillAyd Mar 9, 2023
9271ce3
Merge branch 'main' into np-datetime-capsule
WillAyd Mar 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pandas/_libs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
]


# Below import needs to happen first to ensure pandas top level
# module gets monkeypatched with the pandas_datetime_CAPI
# see pandas_datetime_exec in pd_datetime.c
import pandas._libs.pandas_datetime as pandas_datetime # noqa # isort: skip
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of this, but capsules currently cannot be attached to anything but a top level package. See python/cpython#6898 which I think would solve this, but for now this has to be attached to the top level namespace and really come before anything else to avoid circular import errors

from pandas._libs.interval import Interval
from pandas._libs.tslibs import (
NaT,
Expand Down
5 changes: 5 additions & 0 deletions pandas/_libs/index.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ from pandas._libs.tslibs.nattype cimport c_NaT as NaT
from pandas._libs.tslibs.np_datetime cimport (
NPY_DATETIMEUNIT,
get_unit_from_dtype,
import_pandas_datetime,
)

import_pandas_datetime()


from pandas._libs.tslibs.period cimport is_period_object
from pandas._libs.tslibs.timedeltas cimport _Timedelta
from pandas._libs.tslibs.timestamps cimport _Timestamp
Expand Down
3 changes: 3 additions & 0 deletions pandas/_libs/missing.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ from pandas._libs.tslibs.np_datetime cimport (
get_datetime64_unit,
get_datetime64_value,
get_timedelta64_value,
import_pandas_datetime
)

import_pandas_datetime()

from pandas._libs.ops_dispatch import maybe_dispatch_ufunc_to_dunder_op

cdef:
Expand Down
163 changes: 0 additions & 163 deletions pandas/_libs/src/ujson/python/date_conversions.c

This file was deleted.

39 changes: 0 additions & 39 deletions pandas/_libs/src/ujson/python/date_conversions.h

This file was deleted.

7 changes: 6 additions & 1 deletion pandas/_libs/src/ujson/python/objToJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ Numeric decoder derived from TCL library
#include <numpy/ndarraytypes.h>
#include <numpy/npy_math.h>
#include <ultrajson.h>
#include "date_conversions.h"
#include "datetime.h"
#include "pd_datetime.h"

npy_int64 get_nat(void) { return NPY_MIN_INT64; }

Expand Down Expand Up @@ -1977,6 +1977,11 @@ PyObject *objToJSON(PyObject *Py_UNUSED(self), PyObject *args,
return NULL;
}

PandasDateTime_IMPORT;
if (PandasDateTimeAPI == NULL) {
return NULL;
}

static char *kwlist[] = {"obj",
"ensure_ascii",
"double_precision",
Expand Down
6 changes: 6 additions & 0 deletions pandas/_libs/tslib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ from pandas._libs.tslibs.np_datetime cimport (
pandas_datetime_to_datetimestruct,
pydate_to_dt64,
string_to_dts,
import_pandas_datetime,
)


import_pandas_datetime()


from pandas._libs.tslibs.strptime cimport parse_today_now
from pandas._libs.util cimport (
is_datetime64_object,
Expand Down
5 changes: 4 additions & 1 deletion pandas/_libs/tslibs/conversion.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ from cpython.datetime cimport (
PyDate_Check,
PyDateTime_Check,
datetime,
import_datetime,
time,
timedelta,
tzinfo,
import_datetime,
)

import_datetime()
Expand All @@ -47,8 +47,11 @@ from pandas._libs.tslibs.np_datetime cimport (
pydatetime_to_dt64,
pydatetime_to_dtstruct,
string_to_dts,
import_pandas_datetime,
)

import_pandas_datetime()

from pandas._libs.tslibs.np_datetime import OutOfBoundsDatetime

from pandas._libs.tslibs.nattype cimport (
Expand Down
3 changes: 3 additions & 0 deletions pandas/_libs/tslibs/dtypes.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ from enum import Enum
from pandas._libs.tslibs.np_datetime cimport (
NPY_DATETIMEUNIT,
get_conversion_factor,
import_pandas_datetime
)

import_pandas_datetime()


cdef class PeriodDtypeBase:
"""
Expand Down
2 changes: 2 additions & 0 deletions pandas/_libs/tslibs/fields.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ from pandas._libs.tslibs.np_datetime cimport (
pandas_datetime_to_datetimestruct,
pandas_timedelta_to_timedeltastruct,
pandas_timedeltastruct,
import_pandas_datetime,
)

import_pandas_datetime()

@cython.wraparound(False)
@cython.boundscheck(False)
Expand Down
20 changes: 13 additions & 7 deletions pandas/_libs/tslibs/np_datetime.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ cdef extern from "numpy/ndarraytypes.h":

int64_t NPY_DATETIME_NAT # elswhere we call this NPY_NAT

cdef extern from "src/datetime/np_datetime.h":

cdef extern from "src/datetime/pd_datetime.h":
ctypedef struct pandas_timedeltastruct:
int64_t days
int32_t hrs, min, sec, ms, us, ns, seconds, microseconds, nanoseconds
Expand All @@ -71,6 +72,17 @@ cdef extern from "src/datetime/np_datetime.h":
pandas_timedeltastruct *result
) nogil

void PandasDateTime_IMPORT()

ctypedef enum FormatRequirement:
PARTIAL_MATCH
EXACT_MATCH
INFER_FORMAT

# You must call this before using the PandasDateTime CAPI functions
cdef inline void import_pandas_datetime():
PandasDateTime_IMPORT

cdef bint cmp_scalar(int64_t lhs, int64_t rhs, int op) except -1

cdef check_dts_bounds(npy_datetimestruct *dts, NPY_DATETIMEUNIT unit=?)
Expand Down Expand Up @@ -124,9 +136,3 @@ cdef int64_t convert_reso(
NPY_DATETIMEUNIT to_reso,
bint round_ok,
) except? -1

cdef extern from "src/datetime/np_datetime_strings.h":
ctypedef enum FormatRequirement:
PARTIAL_MATCH
EXACT_MATCH
INFER_FORMAT
5 changes: 2 additions & 3 deletions pandas/_libs/tslibs/np_datetime.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ from cpython.object cimport (
)

import_datetime()
PandasDateTime_IMPORT

import numpy as np

Expand All @@ -35,7 +36,7 @@ from numpy cimport (
from pandas._libs.tslibs.util cimport get_c_string_buf_and_size


cdef extern from "src/datetime/np_datetime.h":
cdef extern from "src/datetime/pd_datetime.h":
int cmp_npy_datetimestruct(npy_datetimestruct *a,
npy_datetimestruct *b)

Expand All @@ -48,15 +49,13 @@ cdef extern from "src/datetime/np_datetime.h":

PyArray_DatetimeMetaData get_datetime_metadata_from_dtype(cnp.PyArray_Descr *dtype)

cdef extern from "src/datetime/np_datetime_strings.h":
int parse_iso_8601_datetime(const char *str, int len, int want_exc,
npy_datetimestruct *out,
NPY_DATETIMEUNIT *out_bestunit,
int *out_local, int *out_tzoffset,
const char *format, int format_len,
FormatRequirement exact)


# ----------------------------------------------------------------------
# numpy object inspection

Expand Down
Loading