Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Lib/test/test_capi/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,11 @@ def expect_bool_not(value):
for value in new_values:
expected, expect_flag = expect_func(value)

old_flags = sys.flags
config_set(name, value)
self.assertEqual(config_get(name), expected)
self.assertEqual(getattr(sys.flags, sys_flag), expect_flag)
self.assertIsNot(sys.flags, old_flags)
if name == "write_bytecode":
self.assertEqual(getattr(sys, "dont_write_bytecode"),
expect_flag)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:c:func:`PyConfig_Set()` and :func:`sys.set_int_max_str_digits` now replace
:data:`sys.flags`, instead of modifying :data:`sys.flags` in-place. Patch by
Victor Stinner.
80 changes: 63 additions & 17 deletions Python/sysmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1874,7 +1874,8 @@ sys_get_int_max_str_digits_impl(PyObject *module)
/*[clinic end generated code: output=0042f5e8ae0e8631 input=77fb74e987ba7ecb]*/
{
PyInterpreterState *interp = _PyInterpreterState_GET();
return PyLong_FromLong(interp->long_state.max_str_digits);
int maxdigits = _Py_atomic_load_int(&interp->long_state.max_str_digits);
return PyLong_FromLong(maxdigits);
}


Expand Down Expand Up @@ -3490,14 +3491,50 @@ sys_set_flag(PyObject *flags, Py_ssize_t pos, PyObject *value)
int
_PySys_SetFlagObj(Py_ssize_t pos, PyObject *value)
{
PyObject *flags = PySys_GetAttrString("flags");
if (flags == NULL) {
return -1;
PyObject *old_flags = NULL;
PyObject *new_flags = NULL;
PyObject *flags_str = NULL;

flags_str = PyUnicode_FromString("flags");
if (flags_str == NULL) {
goto error;
}

sys_set_flag(flags, pos, value);
Py_DECREF(flags);
return 0;
old_flags = PySys_GetAttr(flags_str);
if (old_flags == NULL) {
goto error;
}

new_flags = PyStructSequence_New(&FlagsType);
if (new_flags == NULL) {
goto error;
}

for (Py_ssize_t i=0; i < (Py_ssize_t)(Py_ARRAY_LENGTH(flags_fields) - 1); i++) {
if (i != pos) {
PyObject *old_value;
old_value = PyStructSequence_GET_ITEM(old_flags, i); // borrowed ref
if (old_value == NULL) {
goto error;
}
sys_set_flag(new_flags, i, old_value);
}
else {
sys_set_flag(new_flags, pos, value);
}
}

int res = _PySys_SetAttr(flags_str, new_flags);
Py_DECREF(flags_str);
Py_DECREF(old_flags);
Py_DECREF(new_flags);
return res;

error:
Py_DECREF(flags_str);
Py_DECREF(old_flags);
Py_DECREF(new_flags);
return -1;
}


Expand All @@ -3521,8 +3558,6 @@ set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
const PyPreConfig *preconfig = &interp->runtime->preconfig;
const PyConfig *config = _PyInterpreterState_GetConfig(interp);

// _PySys_UpdateConfig() modifies sys.flags in-place:
// Py_XDECREF() is needed in this case.
Py_ssize_t pos = 0;
#define SetFlagObj(expr) \
do { \
Expand Down Expand Up @@ -4153,16 +4188,27 @@ _PySys_UpdateConfig(PyThreadState *tstate)
#undef COPY_LIST
#undef COPY_WSTR

// sys.flags
PyObject *flags = PySys_GetAttrString("flags");
if (flags == NULL) {
// replace sys.flags
PyObject *new_flags = PyStructSequence_New(&FlagsType);
if (new_flags == NULL) {
return -1;
}
if (set_flags_from_config(interp, flags) < 0) {
Py_DECREF(flags);
if (set_flags_from_config(interp, new_flags) < 0) {
Py_DECREF(new_flags);
return -1;
}

PyObject *flags_str = PyUnicode_FromString("flags");
if (flags_str == NULL) {
Py_DECREF(new_flags);
return -1;
}
res = _PySys_SetAttr(flags_str, new_flags);
Py_DECREF(new_flags);
Py_DECREF(flags_str);
if (res < 0) {
return -1;
}
Py_DECREF(flags);

SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode));

Expand Down Expand Up @@ -4675,7 +4721,7 @@ _PySys_SetIntMaxStrDigits(int maxdigits)
// Set PyInterpreterState.long_state.max_str_digits
// and PyInterpreterState.config.int_max_str_digits.
PyInterpreterState *interp = _PyInterpreterState_GET();
interp->long_state.max_str_digits = maxdigits;
interp->config.int_max_str_digits = maxdigits;
_Py_atomic_store_int(&interp->long_state.max_str_digits, maxdigits);
_Py_atomic_store_int(&interp->config.int_max_str_digits, maxdigits);
return 0;
}
Loading