| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import sys | ||
| import unittest | ||
| from test.support import threading_helper | ||
|
|
||
|
|
||
| class SysModuleTest(unittest.TestCase): | ||
| def test_int_max_str_digits_thread(self): | ||
| # gh-151218: Check that it's safe to call get_int_max_str_digits() and | ||
| # set_int_max_str_digits() in parallel. Previously, this test triggered | ||
| # warnings in TSan on a free threaded build. | ||
|
|
||
| old_limit = sys.get_int_max_str_digits() | ||
| self.addCleanup(sys.set_int_max_str_digits, old_limit) | ||
|
|
||
| def worker(worker_id): | ||
| if not worker_id: | ||
| for i in range (20_000): | ||
| sys.get_int_max_str_digits() | ||
| else: | ||
| for i in range (20_000): | ||
| sys.set_int_max_str_digits(4300 + (i & 7)) | ||
|
|
||
| workers = [lambda: worker(i) for i in range(5)] | ||
| threading_helper.run_concurrently(workers) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() |
| 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` (create a new object), instead of modifying :data:`sys.flags` | ||
| in-place. Patch by Victor Stinner. |
| 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,39 @@ 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 *new_flags = NULL; | ||
| PyObject *flags_str = &_Py_ID(flags); // immortal ref | ||
|
|
||
| PyObject *old_flags = PySys_GetAttr(flags_str); | ||
| if (old_flags == NULL) { | ||
| goto error; | ||
| } | ||
|
|
||
| sys_set_flag(flags, pos, value); | ||
| Py_DECREF(flags); | ||
| return 0; | ||
| new_flags = PyStructSequence_New(&FlagsType); | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityAll this dance makes me wonder whether we need a PyStructSequence_Copy. Would be nicer to just copy the structure and alter one field.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI searched for PyStructSequence_New() and the only other place which creates a copy of an existing structseq is structseq_replace(): structseq.__replace__() method. I'm not sure that it's worth it to write a generic PyStructSequence_Copy() function. Example using structseq.__replace__() method: $ python >>> import sys, copy >>> copy.replace(sys.flags, verbose=3) sys.flags(..., verbose=3, ...)
Sorry, something went wrong.
All reactions
|
||
| 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 | ||
| 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(old_flags); | ||
| Py_DECREF(new_flags); | ||
| return res; | ||
|
|
||
| error: | ||
| Py_XDECREF(old_flags); | ||
| Py_XDECREF(new_flags); | ||
| return -1; | ||
| } | ||
|
|
||
|
|
||
| Expand All | @@ -3521,8 +3547,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 | @@ -4033,7 +4057,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) | |
| /* implementation */ | ||
| SET_SYS("implementation", make_impl_info(version_info)); | ||
|
|
||
| // sys.flags: updated in-place later by _PySys_UpdateConfig() | ||
| // sys.flags: updated later by _PySys_UpdateConfig() | ||
| ENSURE_INFO_TYPE(FlagsType, flags_desc); | ||
| SET_SYS("flags", make_flags(tstate->interp)); | ||
|
|
||
| Expand Down Expand Up | @@ -4153,16 +4177,21 @@ _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; | ||
| } | ||
|
|
||
| res = _PySys_SetAttr(&_Py_ID(flags), new_flags); | ||
| Py_DECREF(new_flags); | ||
| if (res < 0) { | ||
| return -1; | ||
| } | ||
| Py_DECREF(flags); | ||
|
|
||
| SET_SYS("dont_write_bytecode", PyBool_FromLong(!config->write_bytecode)); | ||
|
|
||
| Expand Down Expand Up | @@ -4675,7 +4704,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); | ||
|
Comment thread
picnixz marked this conversation as resolved.
|
||
| return 0; | ||
| } | ||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.