Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

BUG: fix refcounting for dtypemeta aliases #25329

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 1 commit into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 5 additions & 0 deletions 5 numpy/_core/include/numpy/_dtype_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,5 +444,10 @@ typedef PyObject *(getitemfunction)(PyArray_Descr *, char *);
*/
#define NPY_DTYPE(descr) ((PyArray_DTypeMeta *)Py_TYPE(descr))

static inline PyArray_DTypeMeta *
NPY_DT_NewRef(PyArray_DTypeMeta *o) {
Py_INCREF(o);
return o;
}

#endif /* NUMPY_CORE_INCLUDE_NUMPY___DTYPE_API_H_ */
12 changes: 3 additions & 9 deletions 12 numpy/_core/src/multiarray/abstractdtypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ int_common_dtype(PyArray_DTypeMeta *NPY_UNUSED(cls), PyArray_DTypeMeta *other)
if (NPY_DT_is_legacy(other) && other->type_num < NPY_NTYPES) {
if (other->type_num == NPY_BOOL) {
/* Use the default integer for bools: */
return &PyArray_IntpDType;
return NPY_DT_NewRef(&PyArray_IntpDType);
}
}
else if (NPY_DT_is_legacy(other)) {
Expand All @@ -174,7 +174,6 @@ int_common_dtype(PyArray_DTypeMeta *NPY_UNUSED(cls), PyArray_DTypeMeta *other)
/* Try again with `int8`, an error may have been set, though */
PyArray_DTypeMeta *int8_dt = &PyArray_Int8DType;
res = NPY_DT_CALL_common_dtype(other, int8_dt);
Py_DECREF(int8_dt);
if (res == NULL) {
PyErr_Clear();
}
Expand All @@ -187,7 +186,6 @@ int_common_dtype(PyArray_DTypeMeta *NPY_UNUSED(cls), PyArray_DTypeMeta *other)
/* And finally, we will try the default integer, just for sports... */
PyArray_DTypeMeta *default_int = &PyArray_IntpDType;
res = NPY_DT_CALL_common_dtype(other, default_int);
Py_DECREF(default_int);
if (res == NULL) {
PyErr_Clear();
}
Expand All @@ -204,7 +202,7 @@ float_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
if (NPY_DT_is_legacy(other) && other->type_num < NPY_NTYPES) {
if (other->type_num == NPY_BOOL || PyTypeNum_ISINTEGER(other->type_num)) {
/* Use the default integer for bools and ints: */
return &PyArray_DoubleDType;
return NPY_DT_NewRef(&PyArray_DoubleDType);
}
}
else if (other == &PyArray_PyIntAbstractDType) {
Expand All @@ -215,7 +213,6 @@ float_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
/* This is a back-compat fallback to usually do the right thing... */
PyArray_DTypeMeta *half_dt = &PyArray_HalfDType;
PyArray_DTypeMeta *res = NPY_DT_CALL_common_dtype(other, half_dt);
Py_DECREF(half_dt);
if (res == NULL) {
PyErr_Clear();
}
Expand All @@ -228,7 +225,6 @@ float_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
/* Retry with double (the default float) */
PyArray_DTypeMeta *double_dt = &PyArray_DoubleDType;
res = NPY_DT_CALL_common_dtype(other, double_dt);
Py_DECREF(double_dt);
return res;
}
Py_INCREF(Py_NotImplemented);
Expand All @@ -243,14 +239,13 @@ complex_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
if (other->type_num == NPY_BOOL ||
PyTypeNum_ISINTEGER(other->type_num)) {
/* Use the default integer for bools and ints: */
return &PyArray_CDoubleDType;
return NPY_DT_NewRef(&PyArray_CDoubleDType);
}
}
else if (NPY_DT_is_legacy(other)) {
/* This is a back-compat fallback to usually do the right thing... */
PyArray_DTypeMeta *cfloat_dt = &PyArray_CFloatDType;
PyArray_DTypeMeta *res = NPY_DT_CALL_common_dtype(other, cfloat_dt);
Py_DECREF(cfloat_dt);
if (res == NULL) {
PyErr_Clear();
}
Expand All @@ -263,7 +258,6 @@ complex_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
/* Retry with cdouble (the default complex) */
PyArray_DTypeMeta *cdouble_dt = &PyArray_CDoubleDType;
res = NPY_DT_CALL_common_dtype(other, cdouble_dt);
Py_DECREF(cdouble_dt);
return res;

}
Expand Down
4 changes: 0 additions & 4 deletions 4 numpy/_core/src/multiarray/convert_datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -3049,8 +3049,6 @@ PyArray_InitializeStringCasts(void)

result = 0;
finish:
Py_DECREF(string);
Py_DECREF(unicode);
Py_XDECREF(other_dt);
return result;
}
Expand Down Expand Up @@ -3733,7 +3731,6 @@ PyArray_InitializeVoidToVoidCast(void)
};

int res = PyArray_AddCastingImplementation_FromSpec(&spec, 1);
Py_DECREF(Void);
return res;
}

Expand Down Expand Up @@ -3915,7 +3912,6 @@ PyArray_InitializeObjectToObjectCast(void)
};

int res = PyArray_AddCastingImplementation_FromSpec(&spec, 1);
Py_DECREF(Object);
return res;
}

Expand Down
4 changes: 0 additions & 4 deletions 4 numpy/_core/src/multiarray/datetime.c
Original file line number Diff line number Diff line change
Expand Up @@ -4281,10 +4281,6 @@ PyArray_InitializeDatetimeCasts()

result = 0;
fail:
Py_DECREF(datetime);
Py_DECREF(timedelta);
Py_DECREF(string);
Py_DECREF(unicode);
Py_XDECREF(tmp);
return result;
}
Expand Down
6 changes: 3 additions & 3 deletions 6 numpy/_core/src/multiarray/dtypemeta.c
Original file line number Diff line number Diff line change
Expand Up @@ -919,13 +919,13 @@ default_builtin_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
return cls;
}
else if (cls->type_num == NPY_HALF || cls->type_num == NPY_FLOAT) {
return &PyArray_CFloatDType;
return NPY_DT_NewRef(&PyArray_CFloatDType);
}
else if (cls->type_num == NPY_DOUBLE) {
return &PyArray_CDoubleDType;
return NPY_DT_NewRef(&PyArray_CDoubleDType);
}
else if (cls->type_num == NPY_LONGDOUBLE) {
return &PyArray_CLongDoubleDType;
return NPY_DT_NewRef(&PyArray_CLongDoubleDType);
}
}
else if (other == &PyArray_PyFloatAbstractDType) {
Expand Down
4 changes: 0 additions & 4 deletions 4 numpy/_core/src/umath/_scaled_float_dtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,6 @@ sfloat_init_casts(void)
/* Technically, it is just a copy currently so this is fine: */
spec.flags = NPY_METH_NO_FLOATINGPOINT_ERRORS;
PyArray_DTypeMeta *double_DType = &PyArray_DoubleDType;
Py_DECREF(double_DType); /* immortal anyway */
dtypes[0] = double_DType;

slots[0].slot = NPY_METH_resolve_descriptors;
Expand Down Expand Up @@ -519,7 +518,6 @@ sfloat_init_casts(void)
spec.name = "sfloat_to_bool_cast";
dtypes[0] = &PyArray_SFloatDType;
dtypes[1] = &PyArray_BoolDType;
Py_DECREF(dtypes[1]); /* immortal anyway */

if (PyArray_AddCastingImplementation_FromSpec(&spec, 0)) {
return -1;
Expand Down Expand Up @@ -762,7 +760,6 @@ sfloat_add_wrapping_loop(const char *ufunc_name, PyArray_DTypeMeta *dtypes[3])
ufunc, dtypes, wrapped_dtypes, &translate_given_descrs_to_double,
&translate_loop_descrs);
Py_DECREF(ufunc);
Py_DECREF(double_dt);

return res;
}
Expand Down Expand Up @@ -849,7 +846,6 @@ sfloat_init_ufuncs(void) {
* Add a promoter for both directions of multiply with double.
*/
PyArray_DTypeMeta *double_DType = &PyArray_DoubleDType;
Py_DECREF(double_DType); /* immortal anyway */

PyArray_DTypeMeta *promoter_dtypes[3] = {
&PyArray_SFloatDType, double_DType, NULL};
Expand Down
5 changes: 3 additions & 2 deletions 5 numpy/_core/src/umath/dispatching.c
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,7 @@ object_only_ufunc_promoter(PyUFuncObject *ufunc,
new_op_dtypes[i] = object_DType;
}
}
Py_DECREF(object_DType);

return 0;
}

Expand Down Expand Up @@ -1196,6 +1196,7 @@ logical_ufunc_promoter(PyUFuncObject *NPY_UNUSED(ufunc),
else {
/* Always override to boolean */
item = &PyArray_BoolDType;
Py_INCREF(item);
if (op_dtypes[i] != NULL && op_dtypes[i]->type_num == NPY_OBJECT) {
force_object = 1;
}
Expand All @@ -1219,7 +1220,7 @@ logical_ufunc_promoter(PyUFuncObject *NPY_UNUSED(ufunc),
if (signature[i] != NULL) {
continue;
}
Py_SETREF(new_op_dtypes[i], &PyArray_ObjectDType);
Py_SETREF(new_op_dtypes[i], NPY_DT_NewRef(&PyArray_ObjectDType));
}
return 0;
}
Expand Down
7 changes: 3 additions & 4 deletions 7 numpy/_core/src/umath/special_integer_comparisons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ pyint_comparison_promoter(PyUFuncObject *NPY_UNUSED(ufunc),
PyArray_DTypeMeta *op_dtypes[], PyArray_DTypeMeta *signature[],
PyArray_DTypeMeta *new_op_dtypes[])
{
new_op_dtypes[0] = &PyArray_ObjectDType;
new_op_dtypes[1] = &PyArray_ObjectDType;
new_op_dtypes[2] = &PyArray_BoolDType;
new_op_dtypes[0] = NPY_DT_NewRef(&PyArray_ObjectDType);
new_op_dtypes[1] = NPY_DT_NewRef(&PyArray_ObjectDType);
new_op_dtypes[2] = NPY_DT_NewRef(&PyArray_BoolDType);
return 0;
}

Expand Down Expand Up @@ -468,6 +468,5 @@ init_special_int_comparisons(PyObject *umath)
finish:

Py_XDECREF(info);
Py_DECREF(Bool);
return res;
}
17 changes: 7 additions & 10 deletions 17 numpy/_core/src/umath/string_ufuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1100,8 +1100,8 @@ string_find_rfind_count_promoter(PyUFuncObject *NPY_UNUSED(ufunc),
new_op_dtypes[0] = op_dtypes[0];
Py_INCREF(op_dtypes[1]);
new_op_dtypes[1] = op_dtypes[1];
new_op_dtypes[2] = &PyArray_Int64DType;
new_op_dtypes[3] = &PyArray_Int64DType;
new_op_dtypes[2] = NPY_DT_NewRef(&PyArray_Int64DType);
new_op_dtypes[3] = NPY_DT_NewRef(&PyArray_Int64DType);
new_op_dtypes[4] = PyArray_DTypeFromTypeNum(NPY_DEFAULT_INT);
return 0;
}
Expand All @@ -1116,9 +1116,9 @@ string_startswith_endswith_promoter(PyUFuncObject *NPY_UNUSED(ufunc),
new_op_dtypes[0] = op_dtypes[0];
Py_INCREF(op_dtypes[1]);
new_op_dtypes[1] = op_dtypes[1];
new_op_dtypes[2] = &PyArray_Int64DType;
new_op_dtypes[3] = &PyArray_Int64DType;
new_op_dtypes[4] = &PyArray_BoolDType;
new_op_dtypes[2] = NPY_DT_NewRef(&PyArray_Int64DType);
new_op_dtypes[3] = NPY_DT_NewRef(&PyArray_Int64DType);
new_op_dtypes[4] = NPY_DT_NewRef(&PyArray_BoolDType);
return 0;
}

Expand Down Expand Up @@ -1240,9 +1240,6 @@ init_comparison(PyObject *umath)

res = 0;
finish:
Py_DECREF(String);
Py_DECREF(Unicode);
Py_DECREF(Bool);
return res;
}

Expand Down Expand Up @@ -1297,10 +1294,10 @@ init_ufunc(PyObject *umath, const char *name, const char *specname, int nin, int

for (int i = 0; i < nin+nout; i++) {
if (typenums[i] == NPY_OBJECT && enc == ENCODING::UTF32) {
dtypes[i] = &PyArray_UnicodeDType;
dtypes[i] = NPY_DT_NewRef(&PyArray_UnicodeDType);
}
else if (typenums[i] == NPY_OBJECT && enc == ENCODING::ASCII) {
dtypes[i] = &PyArray_BytesDType;
dtypes[i] = NPY_DT_NewRef(&PyArray_BytesDType);
}
else {
dtypes[i] = PyArray_DTypeFromTypeNum(typenums[i]);
Expand Down
5 changes: 5 additions & 0 deletions 5 numpy/_core/tests/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -2573,3 +2573,8 @@ def test__array_namespace__(self):
"is not supported."
):
arr.__array_namespace__(api_version="2023.12")

def test_isin_refcnt_bug(self):
# gh-25295
for _ in range(1000):
np.isclose(np.int64(2), np.int64(2), atol=1e-15, rtol=1e-300)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.