Skip to content

CLN: Get rid of PyArray_GetCastFunc #56114

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 6 commits into from
Nov 26, 2023
Merged
Changes from 1 commit
Commits
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
19 changes: 11 additions & 8 deletions pandas/_libs/src/vendored/ujson/python/objToJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -1280,13 +1280,10 @@ char **NpyArr_encodeLabels(PyArrayObject *labels, PyObjectEncoder *enc,
NPY_DATETIMEUNIT dateUnit = NPY_FR_ns;
if (PyTypeNum_ISDATETIME(type_num)) {
is_datetimelike = 1;
PyArray_VectorUnaryFunc *castfunc =
PyArray_GetCastFunc(PyArray_DescrFromType(type_num), NPY_INT64);
if (!castfunc) {
PyErr_Format(PyExc_ValueError, "Cannot cast numpy dtype %d to long",
enc->npyType);
}
castfunc(dataptr, &i8date, 1, NULL, NULL);
PyObject *scalarItem = PyArray_ToScalar(dataptr, labels);
PyArray_CastScalarToCtype(scalarItem, &i8date,
PyArray_DescrFromType(NPY_INT64));
Py_DECREF(scalarItem);
Copy link
Contributor

@seberg seberg Nov 22, 2023

Choose a reason for hiding this comment

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

Here, you can just use:

memcpy(&i8date, dataptr, sizeof(i8data));

I think, since you know this is an int64, as datetimes are int64 (I am unsure about alignment, thus the memcpy).

Same below? (at last I would think so?)

Copy link
Member Author

Choose a reason for hiding this comment

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

Wow, this is even easier, thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, I just realized the cast function doesn't handle alignment, so even i8data = *(npy_int64 *)dataptr; should work.

dateUnit = get_datetime_metadata_from_dtype(dtype).base;
} else if (PyDate_Check(item) || PyDelta_Check(item)) {
is_datetimelike = 1;
Expand Down Expand Up @@ -1432,6 +1429,13 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
enc->npyType);
}
castfunc(enc->npyValue, &longVal, 1, NULL, NULL);

PyObject *scalar =
PyArray_ToScalar(enc->npyValue, enc->npyCtxtPassthru->array);
PyArray_Scalar(enc->npyValue, PyArray_DescrFromType(enc->npyType), NULL);
PyArray_CastScalarToCtype(scalar, &longVal,
PyArray_DescrFromType(NPY_INT64));
Py_DECREF(scalar);
if (longVal == get_nat()) {
tc->type = JT_NULL;
} else {
Expand Down Expand Up @@ -1532,7 +1536,6 @@ void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {

PyArray_Descr *outcode = PyArray_DescrFromType(NPY_INT64);
PyArray_CastScalarToCtype(obj, &longVal, outcode);
Py_DECREF(outcode);
Copy link
Member

Choose a reason for hiding this comment

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

Just confirming this was also an intentional cleanup?

Copy link
Contributor

Choose a reason for hiding this comment

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

No, this is an accident and shouldn't be included.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the catch.

I wonder if we're leaking references to PyArray_Descr elsewhere than.

The numpy docs don't seem too clear about whether we're borrowing references or owning it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, yeah the deleted code here used to leak them... One point is that array creation functions steal them, though.


if (enc->datetimeIso) {
GET_TC(tc)->longValue = longVal;
Expand Down