summaryrefslogtreecommitdiffhomepage
path: root/src/python
diff options
context:
space:
mode:
authorKonstantin Pavlov <thresh@nginx.com>2023-02-28 10:30:50 -0800
committerKonstantin Pavlov <thresh@nginx.com>2023-02-28 10:30:50 -0800
commit2cc95374dee1fba712a8520c03b72a763ea0b40b (patch)
tree9cf241d0cd7e191466e91156c99429f9491c76ac /src/python
parentcae4a4e4185503725d412d52d880189f46b76ef5 (diff)
parent0af1253c17161b19a5c61a0bbb262f6cd2e515ed (diff)
downloadunit-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.c36
-rw-r--r--src/python/nxt_python_asgi.c76
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++) {