From: Serhiy Storchaka Date: Tue, 5 Nov 2024 06:52:51 +0000 (+0200) Subject: [3.12] gh-126303: Fix pickling and copying of os.sched_param objects (GH-126336)... X-Git-Tag: v3.12.8~111 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=844d908adb0cd5cfe07e229c614b98f7c2e7a810;p=thirdparty%2FPython%2Fcpython.git [3.12] gh-126303: Fix pickling and copying of os.sched_param objects (GH-126336) (GH-126424) (cherry picked from commit d3840503b0f590ee574fbdf3c96626ff8b3c45f6) --- diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index 63f76fc55c9b..4fdbc91a1ba4 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -143,6 +143,8 @@ PyAPI_DATA(PyTypeObject) _PyBufferWrapper_Type; PyObject * _PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, PyObject *name, int *meth_found); +extern int _PyType_AddMethod(PyTypeObject *, PyMethodDef *); + #ifdef __cplusplus } #endif diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index aa811326e4cc..e225b8919d13 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -6,12 +6,14 @@ from test.support import os_helper from test.support import warnings_helper from test.support.script_helper import assert_python_ok +import copy import errno import sys import signal import time import os import platform +import pickle import stat import tempfile import unittest @@ -1308,6 +1310,19 @@ class PosixTester(unittest.TestCase): param = posix.sched_param(sched_priority=-large) self.assertRaises(OverflowError, posix.sched_setparam, 0, param) + @requires_sched + def test_sched_param(self): + param = posix.sched_param(1) + for proto in range(pickle.HIGHEST_PROTOCOL+1): + newparam = pickle.loads(pickle.dumps(param, proto)) + self.assertEqual(newparam, param) + newparam = copy.copy(param) + self.assertIsNot(newparam, param) + self.assertEqual(newparam, param) + newparam = copy.deepcopy(param) + self.assertIsNot(newparam, param) + self.assertEqual(newparam, param) + @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function") def test_sched_rr_get_interval(self): try: diff --git a/Misc/NEWS.d/next/Library/2024-11-02-19-20-44.gh-issue-126303.yVvyWB.rst b/Misc/NEWS.d/next/Library/2024-11-02-19-20-44.gh-issue-126303.yVvyWB.rst new file mode 100644 index 000000000000..0072c97338c2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-02-19-20-44.gh-issue-126303.yVvyWB.rst @@ -0,0 +1 @@ +Fix pickling and copying of :class:`os.sched_param` objects. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index b8558cc2265a..d5298519b588 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -24,6 +24,7 @@ #include "pycore_object.h" // _PyObject_LookupSpecial() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_signal.h" // Py_NSIG +#include "pycore_typeobject.h" // _PyType_AddMethod() #ifdef MS_WINDOWS # include @@ -7866,6 +7867,16 @@ os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) return res; } +static PyObject * +os_sched_param_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return Py_BuildValue("(O(N))", Py_TYPE(self), PyStructSequence_GetItem(self, 0)); +} + +static PyMethodDef os_sched_param_reduce_method = { + "__reduce__", (PyCFunction)os_sched_param_reduce, METH_NOARGS|METH_COEXIST, NULL, +}; + PyDoc_VAR(os_sched_param__doc__); static PyStructSequence_Field sched_param_fields[] = { @@ -17001,6 +17012,12 @@ posixmodule_exec(PyObject *m) return -1; } ((PyTypeObject *)state->SchedParamType)->tp_new = os_sched_param; + if (_PyType_AddMethod((PyTypeObject *)state->SchedParamType, + &os_sched_param_reduce_method) < 0) + { + return -1; + } + PyType_Modified((PyTypeObject *)state->SchedParamType); #endif /* initialize TerminalSize_info */ diff --git a/Objects/typeobject.c b/Objects/typeobject.c index a262ce073358..7c678907ed56 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6645,6 +6645,12 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth) return 0; } +int +_PyType_AddMethod(PyTypeObject *type, PyMethodDef *meth) +{ + return type_add_method(type, meth); +} + /* Add the methods from tp_methods to the __dict__ in a type object */ static int