Skip to content

Commit 844d908

Browse files
[3.12] gh-126303: Fix pickling and copying of os.sched_param objects (GH-126336) (GH-126424)
(cherry picked from commit d384050)
1 parent 94423b6 commit 844d908

File tree

5 files changed

+41
-0
lines changed

5 files changed

+41
-0
lines changed

Include/internal/pycore_typeobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ PyAPI_DATA(PyTypeObject) _PyBufferWrapper_Type;
143143
PyObject *
144144
_PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, PyObject *name, int *meth_found);
145145

146+
extern int _PyType_AddMethod(PyTypeObject *, PyMethodDef *);
147+
146148
#ifdef __cplusplus
147149
}
148150
#endif

Lib/test/test_posix.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
from test.support import warnings_helper
77
from test.support.script_helper import assert_python_ok
88

9+
import copy
910
import errno
1011
import sys
1112
import signal
1213
import time
1314
import os
1415
import platform
16+
import pickle
1517
import stat
1618
import tempfile
1719
import unittest
@@ -1308,6 +1310,19 @@ def test_get_and_set_scheduler_and_param(self):
13081310
param = posix.sched_param(sched_priority=-large)
13091311
self.assertRaises(OverflowError, posix.sched_setparam, 0, param)
13101312

1313+
@requires_sched
1314+
def test_sched_param(self):
1315+
param = posix.sched_param(1)
1316+
for proto in range(pickle.HIGHEST_PROTOCOL+1):
1317+
newparam = pickle.loads(pickle.dumps(param, proto))
1318+
self.assertEqual(newparam, param)
1319+
newparam = copy.copy(param)
1320+
self.assertIsNot(newparam, param)
1321+
self.assertEqual(newparam, param)
1322+
newparam = copy.deepcopy(param)
1323+
self.assertIsNot(newparam, param)
1324+
self.assertEqual(newparam, param)
1325+
13111326
@unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
13121327
def test_sched_rr_get_interval(self):
13131328
try:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix pickling and copying of :class:`os.sched_param` objects.

Modules/posixmodule.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "pycore_object.h" // _PyObject_LookupSpecial()
2525
#include "pycore_pystate.h" // _PyInterpreterState_GET()
2626
#include "pycore_signal.h" // Py_NSIG
27+
#include "pycore_typeobject.h" // _PyType_AddMethod()
2728

2829
#ifdef MS_WINDOWS
2930
# include <windows.h>
@@ -7866,6 +7867,16 @@ os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
78667867
return res;
78677868
}
78687869

7870+
static PyObject *
7871+
os_sched_param_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
7872+
{
7873+
return Py_BuildValue("(O(N))", Py_TYPE(self), PyStructSequence_GetItem(self, 0));
7874+
}
7875+
7876+
static PyMethodDef os_sched_param_reduce_method = {
7877+
"__reduce__", (PyCFunction)os_sched_param_reduce, METH_NOARGS|METH_COEXIST, NULL,
7878+
};
7879+
78697880
PyDoc_VAR(os_sched_param__doc__);
78707881

78717882
static PyStructSequence_Field sched_param_fields[] = {
@@ -17001,6 +17012,12 @@ posixmodule_exec(PyObject *m)
1700117012
return -1;
1700217013
}
1700317014
((PyTypeObject *)state->SchedParamType)->tp_new = os_sched_param;
17015+
if (_PyType_AddMethod((PyTypeObject *)state->SchedParamType,
17016+
&os_sched_param_reduce_method) < 0)
17017+
{
17018+
return -1;
17019+
}
17020+
PyType_Modified((PyTypeObject *)state->SchedParamType);
1700417021
#endif
1700517022

1700617023
/* initialize TerminalSize_info */

Objects/typeobject.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6645,6 +6645,12 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth)
66456645
return 0;
66466646
}
66476647

6648+
int
6649+
_PyType_AddMethod(PyTypeObject *type, PyMethodDef *meth)
6650+
{
6651+
return type_add_method(type, meth);
6652+
}
6653+
66486654

66496655
/* Add the methods from tp_methods to the __dict__ in a type object */
66506656
static int

0 commit comments

Comments
 (0)