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

Commit 932ff83

Browse filesBrowse files
committed
Issue #18608: Avoid keeping a strong reference to the locale module inside the _io module.
1 parent 2d350fd commit 932ff83
Copy full SHA for 932ff83

File tree

4 files changed

+51
-27
lines changed
Filter options

4 files changed

+51
-27
lines changed

‎Misc/NEWS

Copy file name to clipboardExpand all lines: Misc/NEWS
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ Core and Builtins
179179
Library
180180
-------
181181

182+
- Issue #18608: Avoid keeping a strong reference to the locale module
183+
inside the _io module.
184+
182185
- Issue #18619: Fix atexit leaking callbacks registered from sub-interpreters,
183186
and make it GC-aware.
184187

‎Modules/_io/_iomodule.c

Copy file name to clipboardExpand all lines: Modules/_io/_iomodule.c
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,31 @@ _PyIO_ConvertSsize_t(PyObject *obj, void *result) {
533533
}
534534

535535

536+
PyObject *
537+
_PyIO_get_locale_module(_PyIO_State *state)
538+
{
539+
PyObject *mod;
540+
if (state->locale_module != NULL) {
541+
assert(PyWeakref_CheckRef(state->locale_module));
542+
mod = PyWeakref_GET_OBJECT(state->locale_module);
543+
if (mod != Py_None) {
544+
Py_INCREF(mod);
545+
return mod;
546+
}
547+
Py_CLEAR(state->locale_module);
548+
}
549+
mod = PyImport_ImportModule("locale");
550+
if (mod == NULL)
551+
return NULL;
552+
state->locale_module = PyWeakref_NewRef(mod, NULL);
553+
if (state->locale_module == NULL) {
554+
Py_DECREF(mod);
555+
return NULL;
556+
}
557+
return mod;
558+
}
559+
560+
536561
static int
537562
iomodule_traverse(PyObject *mod, visitproc visit, void *arg) {
538563
_PyIO_State *state = IO_MOD_STATE(mod);

‎Modules/_io/_iomodule.h

Copy file name to clipboardExpand all lines: Modules/_io/_iomodule.h
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ typedef struct {
137137
#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod))
138138
#define IO_STATE IO_MOD_STATE(PyState_FindModule(&_PyIO_Module))
139139

140+
extern PyObject *_PyIO_get_locale_module(_PyIO_State *);
141+
140142
extern PyObject *_PyIO_str_close;
141143
extern PyObject *_PyIO_str_closed;
142144
extern PyObject *_PyIO_str_decode;

‎Modules/_io/textio.c

Copy file name to clipboardExpand all lines: Modules/_io/textio.c
+21-27Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -917,35 +917,29 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
917917
}
918918
}
919919
if (encoding == NULL && self->encoding == NULL) {
920-
if (state->locale_module == NULL) {
921-
state->locale_module = PyImport_ImportModule("locale");
922-
if (state->locale_module == NULL)
923-
goto catch_ImportError;
924-
else
925-
goto use_locale;
926-
}
927-
else {
928-
use_locale:
929-
self->encoding = _PyObject_CallMethodId(
930-
state->locale_module, &PyId_getpreferredencoding, "O", Py_False);
931-
if (self->encoding == NULL) {
932-
catch_ImportError:
933-
/*
934-
Importing locale can raise a ImportError because of
935-
_functools, and locale.getpreferredencoding can raise a
936-
ImportError if _locale is not available. These will happen
937-
during module building.
938-
*/
939-
if (PyErr_ExceptionMatches(PyExc_ImportError)) {
940-
PyErr_Clear();
941-
self->encoding = PyUnicode_FromString("ascii");
942-
}
943-
else
944-
goto error;
920+
PyObject *locale_module = _PyIO_get_locale_module(state);
921+
if (locale_module == NULL)
922+
goto catch_ImportError;
923+
self->encoding = _PyObject_CallMethodId(
924+
locale_module, &PyId_getpreferredencoding, "O", Py_False);
925+
Py_DECREF(locale_module);
926+
if (self->encoding == NULL) {
927+
catch_ImportError:
928+
/*
929+
Importing locale can raise a ImportError because of
930+
_functools, and locale.getpreferredencoding can raise a
931+
ImportError if _locale is not available. These will happen
932+
during module building.
933+
*/
934+
if (PyErr_ExceptionMatches(PyExc_ImportError)) {
935+
PyErr_Clear();
936+
self->encoding = PyUnicode_FromString("ascii");
945937
}
946-
else if (!PyUnicode_Check(self->encoding))
947-
Py_CLEAR(self->encoding);
938+
else
939+
goto error;
948940
}
941+
else if (!PyUnicode_Check(self->encoding))
942+
Py_CLEAR(self->encoding);
949943
}
950944
if (self->encoding != NULL) {
951945
encoding = _PyUnicode_AsString(self->encoding);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.