+
+#include "config_common.h"
+
+
+static const char *
+gil_flag_to_str(int flag)
+{
+ switch (flag) {
+ case PyInterpreterConfig_DEFAULT_GIL:
+ return "default";
+ case PyInterpreterConfig_SHARED_GIL:
+ return "shared";
+ case PyInterpreterConfig_OWN_GIL:
+ return "own";
+ default:
+ PyErr_SetString(PyExc_SystemError,
+ "invalid interpreter config 'gil' value");
+ return NULL;
+ }
+}
+
+static int
+gil_flag_from_str(const char *str, int *p_flag)
+{
+ int flag;
+ if (str == NULL) {
+ flag = PyInterpreterConfig_DEFAULT_GIL;
+ }
+ else if (strcmp(str, "default") == 0) {
+ flag = PyInterpreterConfig_DEFAULT_GIL;
+ }
+ else if (strcmp(str, "shared") == 0) {
+ flag = PyInterpreterConfig_SHARED_GIL;
+ }
+ else if (strcmp(str, "own") == 0) {
+ flag = PyInterpreterConfig_OWN_GIL;
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "unsupported interpreter config .gil value '%s'", str);
+ return -1;
+ }
+ *p_flag = flag;
+ return 0;
+}
+
+PyObject *
+_PyInterpreterConfig_AsDict(PyInterpreterConfig *config)
+{
+ PyObject *dict = PyDict_New();
+ if (dict == NULL) {
+ return NULL;
+ }
+
+#define ADD(NAME, OBJ) \
+ do { \
+ int res = PyDict_SetItemString(dict, NAME, (OBJ)); \
+ Py_DECREF(OBJ); \
+ if (res < 0) { \
+ goto error; \
+ } \
+ } while (0)
+#define ADD_BOOL(FIELD) \
+ ADD(#FIELD, Py_NewRef(config->FIELD ? Py_True : Py_False))
+#define ADD_STR(FIELD, STR) \
+ do { \
+ if (STR == NULL) { \
+ goto error; \
+ } \
+ PyObject *obj = PyUnicode_FromString(STR); \
+ if (obj == NULL) { \
+ goto error; \
+ } \
+ ADD(#FIELD, obj); \
+ } while (0)
+
+ ADD_BOOL(use_main_obmalloc);
+ ADD_BOOL(allow_fork);
+ ADD_BOOL(allow_exec);
+ ADD_BOOL(allow_threads);
+ ADD_BOOL(allow_daemon_threads);
+ ADD_BOOL(check_multi_interp_extensions);
+
+ ADD_STR(gil, gil_flag_to_str(config->gil));
+
+#undef ADD_STR
+#undef ADD_BOOL
+#undef ADD
+
+ return dict;
+
+error:
+ Py_DECREF(dict);
+ return NULL;
+}
+
+static int
+_config_dict_get_bool(PyObject *dict, const char *name, int *p_flag)
+{
+ PyObject *item;
+ if (_config_dict_get(dict, name, &item) < 0) {
+ return -1;
+ }
+ // For now we keep things strict, rather than using PyObject_IsTrue().
+ int flag = item == Py_True;
+ if (!flag && item != Py_False) {
+ Py_DECREF(item);
+ config_dict_invalid_type(name);
+ return -1;
+ }
+ Py_DECREF(item);
+ *p_flag = flag;
+ return 0;
+}
+
+static int
+_config_dict_copy_str(PyObject *dict, const char *name,
+ char *buf, size_t bufsize)
+{
+ PyObject *item;
+ if (_config_dict_get(dict, name, &item) < 0) {
+ return -1;
+ }
+ if (!PyUnicode_Check(item)) {
+ Py_DECREF(item);
+ config_dict_invalid_type(name);
+ return -1;
+ }
+ strncpy(buf, PyUnicode_AsUTF8(item), bufsize-1);
+ buf[bufsize-1] = '\0';
+ Py_DECREF(item);
+ return 0;
+}
+
+static int
+interp_config_from_dict(PyObject *origdict, PyInterpreterConfig *config,
+ bool missing_allowed)
+{
+ PyObject *dict = PyDict_New();
+ if (dict == NULL) {
+ return -1;
+ }
+ if (PyDict_Update(dict, origdict) < 0) {
+ goto error;
+ }
+
+#define CHECK(NAME) \
+ do { \
+ if (PyErr_Occurred()) { \
+ goto error; \
+ } \
+ else { \
+ if (!missing_allowed) { \
+ (void)config_dict_get(dict, NAME); \
+ assert(PyErr_Occurred()); \
+ goto error; \
+ } \
+ } \
+ } while (0)
+#define COPY_BOOL(FIELD) \
+ do { \
+ int flag; \
+ if (_config_dict_get_bool(dict, #FIELD, &flag) < 0) { \
+ CHECK(#FIELD); \
+ } \
+ else { \
+ config->FIELD = flag; \
+ (void)PyDict_PopString(dict, #FIELD, NULL); \
+ } \
+ } while (0)
+
+ COPY_BOOL(use_main_obmalloc);
+ COPY_BOOL(allow_fork);
+ COPY_BOOL(allow_exec);
+ COPY_BOOL(allow_threads);
+ COPY_BOOL(allow_daemon_threads);
+ COPY_BOOL(check_multi_interp_extensions);
+
+ // PyInterpreterConfig.gil
+ char buf[20];
+ if (_config_dict_copy_str(dict, "gil", buf, 20) < 0) {
+ CHECK("gil");
+ }
+ else {
+ int flag;
+ if (gil_flag_from_str(buf, &flag) < 0) {
+ goto error;
+ }
+ config->gil = flag;
+ (void)PyDict_PopString(dict, "gil", NULL);
+ }
+
+#undef COPY_BOOL
+#undef CHECK
+
+ Py_ssize_t unused = PyDict_GET_SIZE(dict);
+ if (unused == 1) {
+ PyErr_Format(PyExc_ValueError,
+ "config dict has 1 extra item (%R)", dict);
+ goto error;
+ }
+ else if (unused > 0) {
+ PyErr_Format(PyExc_ValueError,
+ "config dict has %d extra items (%R)", unused, dict);
+ goto error;
+ }
+ return 0;
+
+error:
+ Py_DECREF(dict);
+ return -1;
+}
+
+int
+_PyInterpreterConfig_InitFromDict(PyInterpreterConfig *config, PyObject *dict)
+{
+ if (!PyDict_Check(dict)) {
+ PyErr_SetString(PyExc_TypeError, "dict expected");
+ return -1;
+ }
+ if (interp_config_from_dict(dict, config, false) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+_PyInterpreterConfig_UpdateFromDict(PyInterpreterConfig *config, PyObject *dict)
+{
+ if (!PyDict_Check(dict)) {
+ PyErr_SetString(PyExc_TypeError, "dict expected");
+ return -1;
+ }
+ if (interp_config_from_dict(dict, config, true) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+int
+_PyInterpreterConfig_InitFromState(PyInterpreterConfig *config,
+ PyInterpreterState *interp)
+{
+ // Populate the config by re-constructing the values from the interpreter.
+ *config = (PyInterpreterConfig){
+#define FLAG(flag) \
+ (interp->feature_flags & Py_RTFLAGS_ ## flag)
+ .use_main_obmalloc = FLAG(USE_MAIN_OBMALLOC),
+ .allow_fork = FLAG(FORK),
+ .allow_exec = FLAG(EXEC),
+ .allow_threads = FLAG(THREADS),
+ .allow_daemon_threads = FLAG(DAEMON_THREADS),
+ .check_multi_interp_extensions = FLAG(MULTI_INTERP_EXTENSIONS),
+#undef FLAG
+ .gil = interp->ceval.own_gil
+ ? PyInterpreterConfig_OWN_GIL
+ : PyInterpreterConfig_SHARED_GIL,
+ };
+ return 0;
+}
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy