Skip to content

gh-126303: Fix pickling and copying of os.sched_param objects #126336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Include/internal/pycore_typeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,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.
Expand Down
21 changes: 21 additions & 0 deletions Lib/test/test_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix pickling and copying of :class:`os.sched_param` objects.
17 changes: 17 additions & 0 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -8210,6 +8211,16 @@ os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
return res;
}

static PyObject *
os_sched_param_reduce(PyObject *self, PyObject *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[] = {
Expand Down Expand Up @@ -18033,6 +18044,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 */
Expand Down
6 changes: 6 additions & 0 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -7656,6 +7656,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
Expand Down
Loading