]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-126303: Fix pickling and copying of os.sched_param objects (GH-126336)...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 5 Nov 2024 06:50:33 +0000 (07:50 +0100)
committerGitHub <noreply@github.com>
Tue, 5 Nov 2024 06:50:33 +0000 (06:50 +0000)
(cherry picked from commit d3840503b0f590ee574fbdf3c96626ff8b3c45f6)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
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 05f125f928ca680efc20b78d0158e943a755d29b..a6562f7f9ba74eba1bca0a21e199ba9cf87a82f3 100644 (file)
@@ -230,6 +230,7 @@ extern PyObject* _PyType_GetFullyQualifiedName(PyTypeObject *type, char sep);
 // self->tp_flags = (self->tp_flags & ~mask) | flags;
 extern void _PyType_SetFlags(PyTypeObject *self, unsigned long mask,
                              unsigned long flags);
+extern int _PyType_AddMethod(PyTypeObject *, PyMethodDef *);
 
 // Like _PyType_SetFlags(), but apply the operation to self and any of its
 // subclasses without Py_TPFLAGS_IMMUTABLETYPE set.
index 35016b83a477fc5c0589bbf6bc471c39d1adc67e..ef9d617f66feec34075b69401f5770eaf5a23b01 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
@@ -1317,6 +1319,25 @@ 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)
+        newparam = copy.replace(param)
+        self.assertIsNot(newparam, param)
+        self.assertEqual(newparam, param)
+        newparam = copy.replace(param, sched_priority=0)
+        self.assertNotEqual(newparam, param)
+        self.assertEqual(newparam.sched_priority, 0)
+
     @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 bb01957d5cc0afedceb51d5efce2dea2271bf19b..5edc9dcc7ff3e596367d92038a41a5cd17546ed6 100644 (file)
@@ -24,6 +24,7 @@
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
 #include "pycore_signal.h"        // Py_NSIG
 #include "pycore_time.h"          // _PyLong_FromTime_t()
+#include "pycore_typeobject.h"    // _PyType_AddMethod()
 
 #ifdef HAVE_UNISTD_H
 #  include <unistd.h>             // symlink()
@@ -8172,6 +8173,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[] = {
@@ -17980,6 +17991,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 128086429636401688bfff86a19d1b7b92c33318..82a4ea6267aaa0304024bcf1b54220fc95ea1109 100644 (file)
@@ -7332,6 +7332,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