]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-126303: Fix pickling and copying of os.sched_param objects (GH-126336)...
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 5 Nov 2024 06:52:51 +0000 (08:52 +0200)
committerGitHub <noreply@github.com>
Tue, 5 Nov 2024 06:52:51 +0000 (06:52 +0000)
(cherry picked from commit d3840503b0f590ee574fbdf3c96626ff8b3c45f6)

Include/internal/pycore_typeobject.h
Lib/test/test_posix.py
Misc/NEWS.d/next/Library/2024-11-02-19-20-44.gh-issue-126303.yVvyWB.rst [new file with mode: 0644]
Modules/posixmodule.c
Objects/typeobject.c

index 63f76fc55c9b274a0c858630ad065c92a2e7a34c..4fdbc91a1ba4c665781e999b6e720d7492486942 100644 (file)
@@ -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
index aa811326e4ccf0f843b5b75219ea7c81e587e6ed..e225b8919d13957082c9ca3b0a8bed724ae0b077 100644 (file)
@@ -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 (file)
index 0000000..0072c97
--- /dev/null
@@ -0,0 +1 @@
+Fix pickling and copying of :class:`os.sched_param` objects.
index b8558cc2265a586dc9ae9e27fbcd9eff432aa7c5..d5298519b588463bf39a240c2cd9f2198cb21cb5 100644 (file)
@@ -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 <windows.h>
@@ -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 */
index a262ce073358257718083718112c23c288df3770..7c678907ed56026ccaa3b3ca2c92109920169340 100644 (file)
@@ -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