diff options
author | Konstantin Pavlov <thresh@nginx.com> | 2023-02-28 10:30:50 -0800 |
---|---|---|
committer | Konstantin Pavlov <thresh@nginx.com> | 2023-02-28 10:30:50 -0800 |
commit | 2cc95374dee1fba712a8520c03b72a763ea0b40b (patch) | |
tree | 9cf241d0cd7e191466e91156c99429f9491c76ac /src/python | |
parent | cae4a4e4185503725d412d52d880189f46b76ef5 (diff) | |
parent | 0af1253c17161b19a5c61a0bbb262f6cd2e515ed (diff) | |
download | unit-2cc95374dee1fba712a8520c03b72a763ea0b40b.tar.gz unit-2cc95374dee1fba712a8520c03b72a763ea0b40b.tar.bz2 |
Merged with the 1.29 branch.
Diffstat (limited to 'src/python')
-rw-r--r-- | src/python/nxt_python.c | 36 | ||||
-rw-r--r-- | src/python/nxt_python_asgi.c | 76 |
2 files changed, 82 insertions, 30 deletions
diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c index bdb04579..7c059649 100644 --- a/src/python/nxt_python.c +++ b/src/python/nxt_python.c @@ -75,8 +75,25 @@ static nxt_python_proto_t nxt_py_proto; static nxt_int_t nxt_python3_init_config(nxt_int_t pep405) { - PyStatus status; - PyConfig config; + PyConfig config; + PyStatus status; + nxt_int_t ret; + PyPreConfig preconfig; + + ret = NXT_ERROR; + + PyPreConfig_InitIsolatedConfig(&preconfig); + /* + * Determine whether to use UTF-8 mode or not, UTF-8 + * will be enabled if LC_CTYPE is C, POSIX or some + * specific UTF-8 locale. + */ + preconfig.utf8_mode = -1; + + status = Py_PreInitialize(&preconfig); + if (PyStatus_Exception(status)) { + return ret; + } PyConfig_InitIsolatedConfig(&config); @@ -84,29 +101,28 @@ nxt_python3_init_config(nxt_int_t pep405) status = PyConfig_SetString(&config, &config.program_name, nxt_py_home); if (PyStatus_Exception(status)) { - goto pyinit_exception; + goto out_config_clear; } } else { - status =PyConfig_SetString(&config, &config.home, nxt_py_home); + status = PyConfig_SetString(&config, &config.home, nxt_py_home); if (PyStatus_Exception(status)) { - goto pyinit_exception; + goto out_config_clear; } } status = Py_InitializeFromConfig(&config); if (PyStatus_Exception(status)) { - goto pyinit_exception; + goto out_config_clear; } - PyConfig_Clear(&config); - return NXT_OK; + ret = NXT_OK; -pyinit_exception: +out_config_clear: PyConfig_Clear(&config); - return NXT_ERROR; + return ret; } #elif PY_MAJOR_VERSION == 3 diff --git a/src/python/nxt_python_asgi.c b/src/python/nxt_python_asgi.c index 587a17cf..adf03e2b 100644 --- a/src/python/nxt_python_asgi.c +++ b/src/python/nxt_python_asgi.c @@ -17,6 +17,8 @@ static PyObject *nxt_python_asgi_get_func(PyObject *obj); +static PyObject *nxt_python_asgi_get_event_loop(PyObject *asyncio, + const char *event_loop_func); static int nxt_python_asgi_ctx_data_alloc(void **pdata, int main); static void nxt_python_asgi_ctx_data_free(void *data); static int nxt_python_asgi_startup(void *data); @@ -201,14 +203,53 @@ nxt_python_asgi_init(nxt_unit_init_t *init, nxt_python_proto_t *proto) } +static PyObject * +nxt_python_asgi_get_event_loop(PyObject *asyncio, const char *event_loop_func) +{ + PyObject *event_loop, *loop; + + event_loop = PyDict_GetItemString(PyModule_GetDict(asyncio), + event_loop_func); + if (nxt_slow_path(event_loop == NULL)) { + nxt_unit_alert(NULL, "Python failed to get '%s' from module 'asyncio'", + event_loop_func); + return NULL; + } + + if (nxt_slow_path(PyCallable_Check(event_loop) == 0)) { + nxt_unit_alert(NULL, "'asyncio.%s' is not a callable object", + event_loop_func); + return NULL; + } + + loop = PyObject_CallObject(event_loop, NULL); + if (nxt_slow_path(loop == NULL)) { + if (strcmp(event_loop_func, "get_running_loop") != 0) { + nxt_unit_alert(NULL, "Python failed to call 'asyncio.%s'", + event_loop_func); + } + + return NULL; + } + + return loop; +} + + static int nxt_python_asgi_ctx_data_alloc(void **pdata, int main) { uint32_t i; - PyObject *asyncio, *loop, *event_loop, *obj; + PyObject *asyncio, *loop, *obj; const char *event_loop_func; nxt_py_asgi_ctx_data_t *ctx_data; +#if PY_VERSION_HEX < NXT_PYTHON_VER(3, 7) + static const char *main_event_loop_func = "get_event_loop"; +#else + static const char *main_event_loop_func = "get_running_loop"; +#endif + ctx_data = nxt_unit_malloc(NULL, sizeof(nxt_py_asgi_ctx_data_t)); if (nxt_slow_path(ctx_data == NULL)) { nxt_unit_alert(NULL, "Failed to allocate context data"); @@ -241,29 +282,24 @@ nxt_python_asgi_ctx_data_alloc(void **pdata, int main) goto fail; } - event_loop_func = main ? "get_event_loop" : "new_event_loop"; + event_loop_func = main ? main_event_loop_func : "new_event_loop"; - event_loop = PyDict_GetItemString(PyModule_GetDict(asyncio), - event_loop_func); - if (nxt_slow_path(event_loop == NULL)) { - nxt_unit_alert(NULL, - "Python failed to get '%s' from module 'asyncio'", - event_loop_func); + loop = nxt_python_asgi_get_event_loop(asyncio, event_loop_func); + if (loop == NULL) { +#if PY_VERSION_HEX < NXT_PYTHON_VER(3, 7) goto fail; - } +#else + if (!main) { + goto fail; + } - if (nxt_slow_path(PyCallable_Check(event_loop) == 0)) { - nxt_unit_alert(NULL, - "'asyncio.%s' is not a callable object", - event_loop_func); - goto fail; - } + PyErr_Clear(); - loop = PyObject_CallObject(event_loop, NULL); - if (nxt_slow_path(loop == NULL)) { - nxt_unit_alert(NULL, "Python failed to call 'asyncio.%s'", - event_loop_func); - goto fail; + loop = nxt_python_asgi_get_event_loop(asyncio, "new_event_loop"); + if (nxt_slow_path(loop == NULL)) { + goto fail; + } +#endif } for (i = 0; i < nxt_nitems(handlers); i++) { |