bpo-20104: Improve error handling and fix a reference leak in os.posix_spawn().#6332
Conversation
|
Should I close #6331 in favour of this one? |
gpshead
left a comment
There was a problem hiding this comment.
I made a couple of commits to fixup trivial issues.
| @@ -0,0 +1 @@ | |||
| Fixed numerous issues with :func:`os.posix_spawn()`. | |||
There was a problem hiding this comment.
This is not specific and meaningful to the reader. Explain what Python user visible changes were made that a reader would encounter. examples:
"Improved error handling in os.posix_spawn"
"Fixes a potential crash in the new os.posix_spawn implementation" (is that true?)
There was a problem hiding this comment.
I'd go with Improved error handling and fixed a reference leak in :func:`os.posix_spawn()`.
| like posix.environ. */ | ||
|
|
||
| if (!PySequence_Check(argv)) { | ||
| if (!PyList_Check(argv) && !PyTuple_Check(argv)) { |
There was a problem hiding this comment.
PySequence_Check was correct. There is no need to force this to be exactly a list or a tuple as parse_file_actions uses the sequence APIs.
There was a problem hiding this comment.
The docstring says that it should a tuple or a list, and other similar APIs accept only tuples and lists. If there is a need of supporting other sequences, it is better to implement this feature consistently for all APIs and in a separate issue.
Actually accepting arbitrary sequences can have negative consequences. str and bytes are sequences, and passing them by mistake will cause raising errors with unhelpful messages.
| goto fail; | ||
| } | ||
| int overflow; | ||
| long tag = PyLong_AsLongAndOverflow(PyTuple_GET_ITEM(file_action, 0), |
There was a problem hiding this comment.
You never use overflow. Just call PyLong_AsLong() as the original code did.
There was a problem hiding this comment.
I just don't like if different exceptions are raised for different incorrect values of the same type. But this is not critical.
Actually I think that it would be better to make POSIX_SPAWN_OPEN etc just singletons and test for identity instead of converting them to C long.
|
|
||
| for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { | ||
| file_action = PySequence_Fast_GET_ITEM(seq, i); | ||
| Py_INCREF(file_action); |
There was a problem hiding this comment.
Why are you INCREFing this? Borrowing the reference is the normal thing to do when looping over a sequence in C.
Get rid of the INCREF and you don't have to worry about the DECREFs.
There was a problem hiding this comment.
This is a borrowed reference. The code inside a loop can call an arbitrary Python code, and this can invalidate borrowed references.
|
When you're done making the requested changes, leave the comment: |
| @@ -0,0 +1 @@ | |||
| Fixed numerous issues with :func:`os.posix_spawn()`. | |||
There was a problem hiding this comment.
I'd go with Improved error handling and fixed a reference leak in :func:`os.posix_spawn()`.
serhiy-storchaka
left a comment
There was a problem hiding this comment.
Thank you for fixing these issues and for documenting the new function @gpshead.
But increfing a borrowed reference is neccessary, and supporting other sequences as argv can open a can of worms. It should be discussed separately if there is a need of this feature.
|
|
||
| for (int i = 0; i < PySequence_Fast_GET_SIZE(seq); ++i) { | ||
| file_action = PySequence_Fast_GET_ITEM(seq, i); | ||
| Py_INCREF(file_action); |
There was a problem hiding this comment.
This is a borrowed reference. The code inside a loop can call an arbitrary Python code, and this can invalidate borrowed references.
| like posix.environ. */ | ||
|
|
||
| if (!PySequence_Check(argv)) { | ||
| if (!PyList_Check(argv) && !PyTuple_Check(argv)) { |
There was a problem hiding this comment.
The docstring says that it should a tuple or a list, and other similar APIs accept only tuples and lists. If there is a need of supporting other sequences, it is better to implement this feature consistently for all APIs and in a separate issue.
Actually accepting arbitrary sequences can have negative consequences. str and bytes are sequences, and passing them by mistake will cause raising errors with unhelpful messages.
| goto fail; | ||
| } | ||
| int overflow; | ||
| long tag = PyLong_AsLongAndOverflow(PyTuple_GET_ITEM(file_action, 0), |
There was a problem hiding this comment.
I just don't like if different exceptions are raised for different incorrect values of the same type. But this is not critical.
Actually I think that it would be better to make POSIX_SPAWN_OPEN etc just singletons and test for identity instead of converting them to C long.
|
Added new tests (mainly inspired by tests for the third-party module https://github.com/projectcalico/posix_spawn) and improved the documentation. |
|
@gpshead: @serhiy-storchaka updated his PR and replied to your comments, would you mind to review it again? @serhiy-storchaka: Travis CI is unhappy. Did you check why? This PR fixes a reference leak which makes the Linux Refleaks buildbot red: https://bugs.python.org/issue33357 cc @pablogsal Note: I didn't review the PR. |
|
@serhiy-storchaka: Please replace |
|
Thanks @serhiy-storchaka for the PR 🌮🎉.. I'm working now to backport this PR to: 3.7. |
…x_spawn(). (pythonGH-6332) (cherry picked from commit ef34753) Co-authored-by: Serhiy Storchaka <[email protected]>
|
GH-6673 is a backport of this pull request to the 3.7 branch. |
…x_spawn(). (GH-6332) (cherry picked from commit ef34753) Co-authored-by: Serhiy Storchaka <[email protected]>
https://bugs.python.org/issue20104