Skip to content

Commit 64ddb07

Browse files
WillAydjreback
authored andcommitted
Clean Up nogil Warning From Parsers (#30369)
1 parent 16c56d6 commit 64ddb07

File tree

3 files changed

+20
-32
lines changed

3 files changed

+20
-32
lines changed

pandas/_libs/parsers.pyx

+9-27
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,9 @@ cdef extern from "parser/tokenizer.h":
171171
int64_t skip_first_N_rows
172172
int64_t skipfooter
173173
# pick one, depending on whether the converter requires GIL
174-
float64_t (*double_converter_nogil)(const char *, char **,
175-
char, char, char,
176-
int, int *, int *) nogil
177-
float64_t (*double_converter_withgil)(const char *, char **,
178-
char, char, char,
179-
int, int *, int *)
174+
float64_t (*double_converter)(const char *, char **,
175+
char, char, char,
176+
int, int *, int *) nogil
180177

181178
# error handling
182179
char *warn_msg
@@ -469,16 +466,11 @@ cdef class TextReader:
469466

470467
if float_precision == "round_trip":
471468
# see gh-15140
472-
#
473-
# Our current roundtrip implementation requires the GIL.
474-
self.parser.double_converter_nogil = NULL
475-
self.parser.double_converter_withgil = round_trip
469+
self.parser.double_converter = round_trip
476470
elif float_precision == "high":
477-
self.parser.double_converter_withgil = NULL
478-
self.parser.double_converter_nogil = precise_xstrtod
471+
self.parser.double_converter = precise_xstrtod
479472
else:
480-
self.parser.double_converter_withgil = NULL
481-
self.parser.double_converter_nogil = xstrtod
473+
self.parser.double_converter = xstrtod
482474

483475
if isinstance(dtype, dict):
484476
dtype = {k: pandas_dtype(dtype[k])
@@ -1663,22 +1655,12 @@ cdef _try_double(parser_t *parser, int64_t col,
16631655
result = np.empty(lines, dtype=np.float64)
16641656
data = <float64_t *>result.data
16651657
na_fset = kset_float64_from_list(na_flist)
1666-
if parser.double_converter_nogil != NULL: # if it can run without the GIL
1667-
with nogil:
1668-
error = _try_double_nogil(parser, parser.double_converter_nogil,
1669-
col, line_start, line_end,
1670-
na_filter, na_hashset, use_na_flist,
1671-
na_fset, NA, data, &na_count)
1672-
else:
1673-
assert parser.double_converter_withgil != NULL
1674-
error = _try_double_nogil(parser,
1675-
<float64_t (*)(const char *, char **,
1676-
char, char, char,
1677-
int, int *, int *)
1678-
nogil>parser.double_converter_withgil,
1658+
with nogil:
1659+
error = _try_double_nogil(parser, parser.double_converter,
16791660
col, line_start, line_end,
16801661
na_filter, na_hashset, use_na_flist,
16811662
na_fset, NA, data, &na_count)
1663+
16821664
kh_destroy_float64(na_fset)
16831665
if error != 0:
16841666
return None, None

pandas/_libs/src/parser/tokenizer.c

+7
Original file line numberDiff line numberDiff line change
@@ -1774,11 +1774,18 @@ double precise_xstrtod(const char *str, char **endptr, char decimal,
17741774

17751775
double round_trip(const char *p, char **q, char decimal, char sci, char tsep,
17761776
int skip_trailing, int *error, int *maybe_int) {
1777+
// This is called from a nogil block in parsers.pyx
1778+
// so need to explicitly get GIL before Python calls
1779+
PyGILState_STATE gstate;
1780+
gstate = PyGILState_Ensure();
1781+
17771782
double r = PyOS_string_to_double(p, q, 0);
17781783
if (maybe_int != NULL) *maybe_int = 0;
17791784
if (PyErr_Occurred() != NULL) *error = -1;
17801785
else if (r == Py_HUGE_VAL) *error = (int)Py_HUGE_VAL;
17811786
PyErr_Clear();
1787+
1788+
PyGILState_Release(gstate);
17821789
return r;
17831790
}
17841791

pandas/_libs/src/parser/tokenizer.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,8 @@ typedef struct parser_t {
155155
PyObject *skipfunc;
156156
int64_t skip_first_N_rows;
157157
int64_t skip_footer;
158-
// pick one, depending on whether the converter requires GIL
159-
double (*double_converter_nogil)(const char *, char **,
160-
char, char, char, int, int *, int *);
161-
double (*double_converter_withgil)(const char *, char **,
162-
char, char, char, int, int *, int *);
158+
double (*double_converter)(const char *, char **,
159+
char, char, char, int, int *, int *);
163160

164161
// error handling
165162
char *warn_msg;
@@ -226,6 +223,8 @@ double xstrtod(const char *p, char **q, char decimal, char sci, char tsep,
226223
double precise_xstrtod(const char *p, char **q, char decimal,
227224
char sci, char tsep, int skip_trailing,
228225
int *error, int *maybe_int);
226+
227+
// GH-15140 - round_trip requires and acquires the GIL on its own
229228
double round_trip(const char *p, char **q, char decimal, char sci, char tsep,
230229
int skip_trailing, int *error, int *maybe_int);
231230
int to_boolean(const char *item, uint8_t *val);

0 commit comments

Comments
 (0)