Skip to content

Commit a659a0c

Browse files
committed
Make stringdtype parametric on na_object again
1 parent faf1153 commit a659a0c

File tree

10 files changed

+260
-473
lines changed

10 files changed

+260
-473
lines changed

stringdtype/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ per-file-ignores = {"__init__.py" = ["F401"]}
3535

3636
[tool.meson-python.args]
3737
dist = []
38-
setup = ["-Dbuildtype=debug"]
38+
setup = ["-Dbuildtype=debug", "-Db_ndebug=false"]
3939
compile = []
4040
install = []

stringdtype/stringdtype/__init__.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,12 @@
33
"""
44

55
from .missing import NA # isort: skip
6-
from .scalar import StringScalar, PandasStringScalar # isort: skip
6+
from .scalar import StringScalar # isort: skip
77
from ._main import StringDType, _memory_usage
88

9-
try:
10-
from ._main import PandasStringDType
11-
except ImportError:
12-
PandasStringDType = None
13-
149
__all__ = [
1510
"NA",
1611
"StringDType",
1712
"StringScalar",
1813
"_memory_usage",
1914
]
20-
21-
# this happens when pandas isn't importable
22-
if PandasStringDType is None:
23-
del PandasStringDType
24-
else:
25-
__all__.extend("PandasStringDType")

stringdtype/stringdtype/scalar.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,3 @@
33

44
class StringScalar(str):
55
pass
6-
7-
8-
class PandasStringScalar(str):
9-
pass

stringdtype/stringdtype/src/casts.c

Lines changed: 51 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,30 @@ gil_error(PyObject *type, const char *msg)
1212
PyGILState_Release(gstate);
1313
}
1414

15-
#define ANY_TO_STRING_RESOLVE_DESCRIPTORS(safety) \
16-
static NPY_CASTING any_to_string_##safety##_resolve_descriptors( \
17-
PyObject *NPY_UNUSED(self), PyArray_DTypeMeta *dtypes[2], \
18-
PyArray_Descr *given_descrs[2], PyArray_Descr *loop_descrs[2], \
19-
npy_intp *NPY_UNUSED(view_offset)) \
20-
{ \
21-
if (given_descrs[1] == NULL) { \
22-
PyArray_Descr *new = (PyArray_Descr *)new_stringdtype_instance( \
23-
(PyTypeObject *)dtypes[1]); \
24-
if (new == NULL) { \
25-
return (NPY_CASTING)-1; \
26-
} \
27-
loop_descrs[1] = new; \
28-
} \
29-
else { \
30-
Py_INCREF(given_descrs[1]); \
31-
loop_descrs[1] = given_descrs[1]; \
32-
} \
33-
\
34-
Py_INCREF(given_descrs[0]); \
35-
loop_descrs[0] = given_descrs[0]; \
36-
\
37-
return NPY_##safety##_CASTING; \
15+
#define ANY_TO_STRING_RESOLVE_DESCRIPTORS(safety) \
16+
static NPY_CASTING any_to_string_##safety##_resolve_descriptors( \
17+
PyObject *NPY_UNUSED(self), \
18+
PyArray_DTypeMeta *NPY_UNUSED(dtypes[2]), \
19+
PyArray_Descr *given_descrs[2], PyArray_Descr *loop_descrs[2], \
20+
npy_intp *NPY_UNUSED(view_offset)) \
21+
{ \
22+
if (given_descrs[1] == NULL) { \
23+
PyArray_Descr *new = \
24+
(PyArray_Descr *)new_stringdtype_instance(NA_OBJ); \
25+
if (new == NULL) { \
26+
return (NPY_CASTING)-1; \
27+
} \
28+
loop_descrs[1] = new; \
29+
} \
30+
else { \
31+
Py_INCREF(given_descrs[1]); \
32+
loop_descrs[1] = given_descrs[1]; \
33+
} \
34+
\
35+
Py_INCREF(given_descrs[0]); \
36+
loop_descrs[0] = given_descrs[0]; \
37+
\
38+
return NPY_##safety##_CASTING; \
3839
}
3940

4041
ANY_TO_STRING_RESOLVE_DESCRIPTORS(SAFE)
@@ -83,10 +84,12 @@ string_to_string(PyArrayMethod_Context *NPY_UNUSED(context),
8384
while (N--) {
8485
s = (ss *)in;
8586
os = (ss *)out;
86-
ssfree(os);
87-
if (ssdup(s, os) < 0) {
88-
gil_error(PyExc_MemoryError, "ssdup failed");
89-
return -1;
87+
if (in != out) {
88+
ssfree(os);
89+
if (ssdup(s, os) < 0) {
90+
gil_error(PyExc_MemoryError, "ssdup failed");
91+
return -1;
92+
}
9093
}
9194

9295
in += in_stride;
@@ -103,9 +106,6 @@ static PyType_Slot s2s_slots[] = {
103106
{0, NULL}};
104107

105108
static char *s2s_name = "cast_StringDType_to_StringDType";
106-
static char *p2p_name = "cast_PandasStringDType_to_PandasStringDType";
107-
static char *s2p_name = "cast_StringDType_to_PandasStringDType";
108-
static char *p2s_name = "cast_PandasStringDType_to_StringDType";
109109

110110
// unicode to string
111111

@@ -535,6 +535,9 @@ static npy_longlong
535535
string_to_int(char *in, npy_longlong *value)
536536
{
537537
PyObject *pylong_value = string_to_pylong(in);
538+
if (pylong_value == NULL) {
539+
return -1;
540+
}
538541
*value = PyLong_AsLongLong(pylong_value);
539542
if (*value == -1 && PyErr_Occurred()) {
540543
Py_DECREF(pylong_value);
@@ -683,16 +686,16 @@ uint_to_string(unsigned long long in, char *out)
683686
static char *shortname##2s_name = "cast_" #typename "_to_StringDType";
684687

685688
#define DTYPES_AND_CAST_SPEC(shortname, typename) \
686-
PyArray_DTypeMeta **s2##shortname##_dtypes = \
687-
get_dtypes(this, &PyArray_##typename##DType); \
689+
PyArray_DTypeMeta **s2##shortname##_dtypes = get_dtypes( \
690+
(PyArray_DTypeMeta *)&StringDType, &PyArray_##typename##DType); \
688691
\
689692
PyArrayMethod_Spec *StringTo##typename##CastSpec = \
690693
get_cast_spec(s2##shortname##_name, NPY_UNSAFE_CASTING, \
691694
NPY_METH_REQUIRES_PYAPI, s2##shortname##_dtypes, \
692695
s2##shortname##_slots); \
693696
\
694-
PyArray_DTypeMeta **shortname##2s_dtypes = \
695-
get_dtypes(&PyArray_##typename##DType, this); \
697+
PyArray_DTypeMeta **shortname##2s_dtypes = get_dtypes( \
698+
&PyArray_##typename##DType, (PyArray_DTypeMeta *)&StringDType); \
696699
\
697700
PyArrayMethod_Spec *typename##ToStringCastSpec = get_cast_spec( \
698701
shortname##2s_name, NPY_UNSAFE_CASTING, NPY_METH_REQUIRES_PYAPI, \
@@ -946,28 +949,18 @@ get_dtypes(PyArray_DTypeMeta *dt1, PyArray_DTypeMeta *dt2)
946949
}
947950

948951
PyArrayMethod_Spec **
949-
get_casts(PyArray_DTypeMeta *this, PyArray_DTypeMeta *other)
952+
get_casts()
950953
{
951-
char *t2t_name = NULL;
954+
char *t2t_name = s2s_name;
952955

953-
if (this == (PyArray_DTypeMeta *)&StringDType) {
954-
t2t_name = s2s_name;
955-
}
956-
else {
957-
t2t_name = p2p_name;
958-
}
959-
960-
PyArray_DTypeMeta **t2t_dtypes = get_dtypes(this, this);
956+
PyArray_DTypeMeta **t2t_dtypes =
957+
get_dtypes((PyArray_DTypeMeta *)&StringDType,
958+
(PyArray_DTypeMeta *)&StringDType);
961959

962960
PyArrayMethod_Spec *ThisToThisCastSpec =
963961
get_cast_spec(t2t_name, NPY_NO_CASTING,
964962
NPY_METH_SUPPORTS_UNALIGNED, t2t_dtypes, s2s_slots);
965963

966-
PyArrayMethod_Spec *ThisToOtherCastSpec = NULL;
967-
PyArrayMethod_Spec *OtherToThisCastSpec = NULL;
968-
969-
int is_pandas = (this == (PyArray_DTypeMeta *)&PandasStringDType);
970-
971964
int num_casts = 27;
972965

973966
#if NPY_SIZEOF_BYTE == NPY_SIZEOF_SHORT
@@ -983,41 +976,29 @@ get_casts(PyArray_DTypeMeta *this, PyArray_DTypeMeta *other)
983976
num_casts += 4;
984977
#endif
985978

986-
if (is_pandas) {
987-
num_casts += 2;
988-
989-
PyArray_DTypeMeta **t2o_dtypes = get_dtypes(this, other);
990-
991-
ThisToOtherCastSpec = get_cast_spec(p2s_name, NPY_NO_CASTING,
992-
NPY_METH_SUPPORTS_UNALIGNED,
993-
t2o_dtypes, s2s_slots);
994-
995-
PyArray_DTypeMeta **o2t_dtypes = get_dtypes(other, this);
996-
997-
OtherToThisCastSpec = get_cast_spec(s2p_name, NPY_NO_CASTING,
998-
NPY_METH_SUPPORTS_UNALIGNED,
999-
o2t_dtypes, s2s_slots);
1000-
}
1001-
1002-
PyArray_DTypeMeta **u2s_dtypes = get_dtypes(&PyArray_UnicodeDType, this);
979+
PyArray_DTypeMeta **u2s_dtypes = get_dtypes(
980+
&PyArray_UnicodeDType, (PyArray_DTypeMeta *)&StringDType);
1003981

1004982
PyArrayMethod_Spec *UnicodeToStringCastSpec = get_cast_spec(
1005983
u2s_name, NPY_SAFE_CASTING, NPY_METH_NO_FLOATINGPOINT_ERRORS,
1006984
u2s_dtypes, u2s_slots);
1007985

1008-
PyArray_DTypeMeta **s2u_dtypes = get_dtypes(this, &PyArray_UnicodeDType);
986+
PyArray_DTypeMeta **s2u_dtypes = get_dtypes(
987+
(PyArray_DTypeMeta *)&StringDType, &PyArray_UnicodeDType);
1009988

1010989
PyArrayMethod_Spec *StringToUnicodeCastSpec = get_cast_spec(
1011990
s2u_name, NPY_SAFE_CASTING, NPY_METH_NO_FLOATINGPOINT_ERRORS,
1012991
s2u_dtypes, s2u_slots);
1013992

1014-
PyArray_DTypeMeta **s2b_dtypes = get_dtypes(this, &PyArray_BoolDType);
993+
PyArray_DTypeMeta **s2b_dtypes =
994+
get_dtypes((PyArray_DTypeMeta *)&StringDType, &PyArray_BoolDType);
1015995

1016996
PyArrayMethod_Spec *StringToBoolCastSpec = get_cast_spec(
1017997
s2b_name, NPY_UNSAFE_CASTING, NPY_METH_NO_FLOATINGPOINT_ERRORS,
1018998
s2b_dtypes, s2b_slots);
1019999

1020-
PyArray_DTypeMeta **b2s_dtypes = get_dtypes(&PyArray_BoolDType, this);
1000+
PyArray_DTypeMeta **b2s_dtypes =
1001+
get_dtypes(&PyArray_BoolDType, (PyArray_DTypeMeta *)&StringDType);
10211002

10221003
PyArrayMethod_Spec *BoolToStringCastSpec = get_cast_spec(
10231004
b2s_name, NPY_SAFE_CASTING, NPY_METH_NO_FLOATINGPOINT_ERRORS,
@@ -1108,14 +1089,7 @@ get_casts(PyArray_DTypeMeta *this, PyArray_DTypeMeta *other)
11081089
casts[cast_i++] = FloatToStringCastSpec;
11091090
casts[cast_i++] = StringToHalfCastSpec;
11101091
casts[cast_i++] = HalfToStringCastSpec;
1111-
if (is_pandas) {
1112-
casts[cast_i++] = ThisToOtherCastSpec;
1113-
casts[cast_i++] = OtherToThisCastSpec;
1114-
casts[cast_i++] = NULL;
1115-
}
1116-
else {
1117-
casts[cast_i++] = NULL;
1118-
}
1092+
casts[cast_i++] = NULL;
11191093

11201094
assert(casts[num_casts] == NULL);
11211095
assert(cast_i == num_casts + 1);

stringdtype/stringdtype/src/casts.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "numpy/ndarraytypes.h"
1313

1414
PyArrayMethod_Spec **
15-
get_casts(PyArray_DTypeMeta *this_dtype, PyArray_DTypeMeta *other_dtype);
15+
get_casts();
1616

1717
size_t
1818
utf8_char_to_ucs4_code(unsigned char *, Py_UCS4 *);

0 commit comments

Comments
 (0)