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

This commit is contained in:
Serhiy Storchaka 2024-11-05 08:23:17 +02:00 committed by GitHub
parent d960226547
commit d3840503b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 46 additions and 0 deletions

View File

@ -243,6 +243,7 @@ extern PyObject* _PyType_GetFullyQualifiedName(PyTypeObject *type, char sep);
// self->tp_flags = (self->tp_flags & ~mask) | flags; // self->tp_flags = (self->tp_flags & ~mask) | flags;
extern void _PyType_SetFlags(PyTypeObject *self, unsigned long mask, extern void _PyType_SetFlags(PyTypeObject *self, unsigned long mask,
unsigned long flags); unsigned long flags);
extern int _PyType_AddMethod(PyTypeObject *, PyMethodDef *);
// Like _PyType_SetFlags(), but apply the operation to self and any of its // Like _PyType_SetFlags(), but apply the operation to self and any of its
// subclasses without Py_TPFLAGS_IMMUTABLETYPE set. // subclasses without Py_TPFLAGS_IMMUTABLETYPE set.

View File

@ -6,12 +6,14 @@ from test.support import os_helper
from test.support import warnings_helper from test.support import warnings_helper
from test.support.script_helper import assert_python_ok from test.support.script_helper import assert_python_ok
import copy
import errno import errno
import sys import sys
import signal import signal
import time import time
import os import os
import platform import platform
import pickle
import stat import stat
import tempfile import tempfile
import unittest import unittest
@ -1317,6 +1319,25 @@ class PosixTester(unittest.TestCase):
param = posix.sched_param(sched_priority=-large) param = posix.sched_param(sched_priority=-large)
self.assertRaises(OverflowError, posix.sched_setparam, 0, param) 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") @unittest.skipUnless(hasattr(posix, "sched_rr_get_interval"), "no function")
def test_sched_rr_get_interval(self): def test_sched_rr_get_interval(self):
try: try:

View File

@ -0,0 +1 @@
Fix pickling and copying of :class:`os.sched_param` objects.

View File

@ -24,6 +24,7 @@
#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_signal.h" // Py_NSIG #include "pycore_signal.h" // Py_NSIG
#include "pycore_time.h" // _PyLong_FromTime_t() #include "pycore_time.h" // _PyLong_FromTime_t()
#include "pycore_typeobject.h" // _PyType_AddMethod()
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> // symlink() # include <unistd.h> // symlink()
@ -8210,6 +8211,16 @@ os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
return res; 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__); PyDoc_VAR(os_sched_param__doc__);
static PyStructSequence_Field sched_param_fields[] = { static PyStructSequence_Field sched_param_fields[] = {
@ -18033,6 +18044,12 @@ posixmodule_exec(PyObject *m)
return -1; return -1;
} }
((PyTypeObject *)state->SchedParamType)->tp_new = os_sched_param; ((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 #endif
/* initialize TerminalSize_info */ /* initialize TerminalSize_info */

View File

@ -7656,6 +7656,12 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth)
return 0; 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 */ /* Add the methods from tp_methods to the __dict__ in a type object */
static int static int