https://github.com/python/cpython/commit/ce1a1a6021a2f0a1af8160b866869e9678618dfc
commit: ce1a1a6021a2f0a1af8160b866869e9678618dfc
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2024-11-05T06:50:33Z
summary:

[3.13] gh-126303: Fix pickling and copying of os.sched_param objects 
(GH-126336) (GH-126423)

(cherry picked from commit d3840503b0f590ee574fbdf3c96626ff8b3c45f6)

Co-authored-by: Serhiy Storchaka <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-11-02-19-20-44.gh-issue-126303.yVvyWB.rst
M Include/internal/pycore_typeobject.h
M Lib/test/test_posix.py
M Modules/posixmodule.c
M Objects/typeobject.c

diff --git a/Include/internal/pycore_typeobject.h 
b/Include/internal/pycore_typeobject.h
index 05f125f928ca68..a6562f7f9ba74e 100644
--- a/Include/internal/pycore_typeobject.h
+++ b/Include/internal/pycore_typeobject.h
@@ -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.
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index 35016b83a477fc..ef9d617f66feec 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -6,12 +6,14 @@
 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 @@ def test_get_and_set_scheduler_and_param(self):
         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
index 00000000000000..0072c97338c251
--- /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 bb01957d5cc0af..5edc9dcc7ff3e5 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -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 */
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 12808642963640..82a4ea6267aaa0 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -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

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to