Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 19 additions & 0 deletions Lib/test/test_os/test_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -1996,6 +1996,11 @@ def test_setpgroup(self):
)
support.wait_process(pid, exitcode=0)

def test_setpgroup_allow_none(self):
path, args = self.NOOP_PROGRAM[0], self.NOOP_PROGRAM
pid = self.spawn_func(path, args, os.environ, setpgroup=None)
support.wait_process(pid, exitcode=0)

def test_setpgroup_wrong_type(self):
with self.assertRaises(TypeError):
self.spawn_func(sys.executable,
Expand Down Expand Up @@ -2096,6 +2101,20 @@ def test_setsigdef_wrong_type(self):
[sys.executable, "-c", "pass"],
os.environ, setsigdef=[signal.NSIG, signal.NSIG+1])

def test_scheduler_allow_none(self):
path, args = self.NOOP_PROGRAM[0], self.NOOP_PROGRAM
pid = self.spawn_func(path, args, os.environ, scheduler=None)
support.wait_process(pid, exitcode=0)

@support.subTests("scheduler", [object(), 1, [1, 2]])
def test_scheduler_wrong_type(self, scheduler):
path, args = self.NOOP_PROGRAM[0], self.NOOP_PROGRAM
with self.assertRaisesRegex(
TypeError,
"scheduler must be a tuple or None",
):
self.spawn_func(path, args, os.environ, scheduler=scheduler)

@requires_sched
@unittest.skipIf(sys.platform.startswith(('freebsd', 'netbsd')),
"bpo-34685: test can fail on BSD")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Raise :exc:`TypeError` instead of :exc:`SystemError` when the *scheduler*
in :func:`os.posix_spawn` or :func:`os.posix_spawnp` is not a tuple.
Patch by Bénédikt Tran.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Allow *scheduler* and *setpgroup* arguments to be explicitly :const:`None`
when calling :func:`os.posix_spawn` or :func:`os.posix_spawnp`. Patch by
Bénédikt Tran.
10 changes: 5 additions & 5 deletions Modules/clinic/posixmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 15 additions & 8 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -7611,6 +7611,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
PyObject *setsigdef, PyObject *scheduler,
posix_spawnattr_t *attrp)
{
assert(scheduler == NULL || scheduler == Py_None || PyTuple_Check(scheduler));
long all_flags = 0;

errno = posix_spawnattr_init(attrp);
Expand All @@ -7619,7 +7620,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
return -1;
}

if (setpgroup) {
if (setpgroup && setpgroup != Py_None) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to support None?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs use setpgroup=None as a default. So either we rewrite all signatures or we support None.

pid_t pgid = PyLong_AsPid(setpgroup);
if (pgid == (pid_t)-1 && PyErr_Occurred()) {
goto fail;
Expand Down Expand Up @@ -7692,7 +7693,7 @@ parse_posix_spawn_flags(PyObject *module, const char *func_name, PyObject *setpg
}
#endif

if (scheduler) {
if (scheduler && scheduler != Py_None) {
#ifdef POSIX_SPAWN_SETSCHEDULER
PyObject *py_schedpolicy;
PyObject *schedparam_obj;
Expand Down Expand Up @@ -7917,6 +7918,12 @@ py_posix_spawn(int use_posix_spawnp, PyObject *module, path_t *path, PyObject *a
goto exit;
}

if (scheduler && !PyTuple_Check(scheduler) && scheduler != Py_None) {
PyErr_Format(PyExc_TypeError,
"%s: scheduler must be a tuple or None", func_name);
goto exit;
}

argvlist = parse_arglist(argv, &argc);
if (argvlist == NULL) {
goto exit;
Expand Down Expand Up @@ -8028,7 +8035,7 @@ os.posix_spawn
*
file_actions: object(c_default='NULL') = ()
A sequence of file action tuples.
setpgroup: object = NULL
setpgroup: object(c_default='NULL') = None
The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
resetids: bool = False
If the value is `true` the POSIX_SPAWN_RESETIDS will be activated.
Expand All @@ -8038,7 +8045,7 @@ os.posix_spawn
The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
setsigdef: object(c_default='NULL') = ()
The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
scheduler: object = NULL
scheduler: object(c_default='NULL') = None
A tuple with the scheduler policy (optional) and parameters.

Execute the program specified by path in a new process.
Expand All @@ -8050,7 +8057,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv,
PyObject *setpgroup, int resetids, int setsid,
PyObject *setsigmask, PyObject *setsigdef,
PyObject *scheduler)
/*[clinic end generated code: output=14a1098c566bc675 input=808aed1090d84e33]*/
/*[clinic end generated code: output=14a1098c566bc675 input=69e7c9ebbdcf94a5]*/
{
return py_posix_spawn(0, module, path, argv, env, file_actions,
setpgroup, resetids, setsid, setsigmask, setsigdef,
Expand All @@ -8074,7 +8081,7 @@ os.posix_spawnp
*
file_actions: object(c_default='NULL') = ()
A sequence of file action tuples.
setpgroup: object = NULL
setpgroup: object(c_default='NULL') = None
The pgroup to use with the POSIX_SPAWN_SETPGROUP flag.
resetids: bool = False
If the value is `True` the POSIX_SPAWN_RESETIDS will be activated.
Expand All @@ -8084,7 +8091,7 @@ os.posix_spawnp
The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag.
setsigdef: object(c_default='NULL') = ()
The sigmask to use with the POSIX_SPAWN_SETSIGDEF flag.
scheduler: object = NULL
scheduler: object(c_default='NULL') = None
A tuple with the scheduler policy (optional) and parameters.

Execute the program specified by path in a new process.
Expand All @@ -8096,7 +8103,7 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv,
PyObject *setpgroup, int resetids, int setsid,
PyObject *setsigmask, PyObject *setsigdef,
PyObject *scheduler)
/*[clinic end generated code: output=7b9aaefe3031238d input=9e89e616116752a1]*/
/*[clinic end generated code: output=7b9aaefe3031238d input=a5c057527c6881a5]*/
{
return py_posix_spawn(1, module, path, argv, env, file_actions,
setpgroup, resetids, setsid, setsigmask, setsigdef,
Expand Down
Loading