diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2013-08-01 19:04:50 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2013-08-01 19:04:50 (GMT) |
commit | 932ff8368289b53c4ca37167747bb71d146fc6ea (patch) | |
tree | 31f508a77d07676df88535e20bfe555eb662f0a2 /Modules/_io | |
parent | 2d350fd8af29eada0c3f264a91df6ab4af4a05fd (diff) | |
download | cpython-932ff8368289b53c4ca37167747bb71d146fc6ea.zip cpython-932ff8368289b53c4ca37167747bb71d146fc6ea.tar.gz cpython-932ff8368289b53c4ca37167747bb71d146fc6ea.tar.bz2 |
Issue #18608: Avoid keeping a strong reference to the locale module inside the _io module.
Diffstat (limited to 'Modules/_io')
-rw-r--r-- | Modules/_io/_iomodule.c | 25 | ||||
-rw-r--r-- | Modules/_io/_iomodule.h | 2 | ||||
-rw-r--r-- | Modules/_io/textio.c | 48 |
3 files changed, 48 insertions, 27 deletions
diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 4a7e758..14457e8 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -533,6 +533,31 @@ _PyIO_ConvertSsize_t(PyObject *obj, void *result) { } +PyObject * +_PyIO_get_locale_module(_PyIO_State *state) +{ + PyObject *mod; + if (state->locale_module != NULL) { + assert(PyWeakref_CheckRef(state->locale_module)); + mod = PyWeakref_GET_OBJECT(state->locale_module); + if (mod != Py_None) { + Py_INCREF(mod); + return mod; + } + Py_CLEAR(state->locale_module); + } + mod = PyImport_ImportModule("locale"); + if (mod == NULL) + return NULL; + state->locale_module = PyWeakref_NewRef(mod, NULL); + if (state->locale_module == NULL) { + Py_DECREF(mod); + return NULL; + } + return mod; +} + + static int iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { _PyIO_State *state = IO_MOD_STATE(mod); diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index ad1faa8..b90a658 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -137,6 +137,8 @@ typedef struct { #define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) #define IO_STATE IO_MOD_STATE(PyState_FindModule(&_PyIO_Module)) +extern PyObject *_PyIO_get_locale_module(_PyIO_State *); + extern PyObject *_PyIO_str_close; extern PyObject *_PyIO_str_closed; extern PyObject *_PyIO_str_decode; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 5d2438d..7b8de90 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -917,35 +917,29 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) } } if (encoding == NULL && self->encoding == NULL) { - if (state->locale_module == NULL) { - state->locale_module = PyImport_ImportModule("locale"); - if (state->locale_module == NULL) - goto catch_ImportError; - else - goto use_locale; - } - else { - use_locale: - self->encoding = _PyObject_CallMethodId( - state->locale_module, &PyId_getpreferredencoding, "O", Py_False); - if (self->encoding == NULL) { - catch_ImportError: - /* - Importing locale can raise a ImportError because of - _functools, and locale.getpreferredencoding can raise a - ImportError if _locale is not available. These will happen - during module building. - */ - if (PyErr_ExceptionMatches(PyExc_ImportError)) { - PyErr_Clear(); - self->encoding = PyUnicode_FromString("ascii"); - } - else - goto error; + PyObject *locale_module = _PyIO_get_locale_module(state); + if (locale_module == NULL) + goto catch_ImportError; + self->encoding = _PyObject_CallMethodId( + locale_module, &PyId_getpreferredencoding, "O", Py_False); + Py_DECREF(locale_module); + if (self->encoding == NULL) { + catch_ImportError: + /* + Importing locale can raise a ImportError because of + _functools, and locale.getpreferredencoding can raise a + ImportError if _locale is not available. These will happen + during module building. + */ + if (PyErr_ExceptionMatches(PyExc_ImportError)) { + PyErr_Clear(); + self->encoding = PyUnicode_FromString("ascii"); } - else if (!PyUnicode_Check(self->encoding)) - Py_CLEAR(self->encoding); + else + goto error; } + else if (!PyUnicode_Check(self->encoding)) + Py_CLEAR(self->encoding); } if (self->encoding != NULL) { encoding = _PyUnicode_AsString(self->encoding); |