-
-
Notifications
You must be signed in to change notification settings - Fork 33.3k
bpo-16500: Don't use string constants for os.register_at_fork() behavior #1834
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
Conversation
|
I'm not sure I like this. This is longer to type, and doesn't seem to bring anything over human-readable string constants (compare with, say, @1st1 ? |
|
I wouldn't expect My main complaint is the use of magic string values. Alternatives would be
|
|
Well, I would rather have constants than your two other suggestions :-) |
os.register_at_fork(before=prepare_for_launch,
after_parent=launch_cleanup,
after_child=reinitialize_stuff)Looks very readable to me. |
|
Why not. It's much better than having three separate functions, at least. |
Doc/library/os.rst
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is "if control is expected to return to the Python interpreter" related to other arguments? _posixsubprocess.fork_exec() doesn't call any of handlers if preexec_fn is None.
And the same question about the documentation of PyOS_AfterFork_Child() vs other functions.
Lib/test/test_posix.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not clear what argument triggered an error. Use three different invocations with three assertRaises.
Lib/test/test_posix.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same as above.
Modules/posixmodule.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Double backticks don't look nice in text output.
Modules/posixmodule.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means that os.register_at_fork(before=lambda:None, after_in_child=42, after_in_parent='spam') is successful.
I would change this condition to just (!(before || after_in_child || after_in_parent)) or (!before && !after_in_child && !after_in_parent) and add separate PyCallable_Check() checks for every non-NULL argument.
Since this case was not caught by tests, needed a new test for it.
Modules/posixmodule.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check for before != NULL can be moved into register_at_forker() together with a PyCallable_Check() check. Unless you want to produce more specific error messages.
Doc/c-api/sys.rst
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HAVE_FORK is internal CPython define. It is not a part of any API.
|
Having linters and IDEs helping you with the +1 to go with keyword arguments, instead of constants. os.register_at_fork(before=prepare_for_launch,
after_parent=launch_cleanup,
after_child=reinitialize_stuff) |
|
Thanks @serhiy-storchaka I believe I've addressed all of those suggestions. |
Adds the constants and updates all uses and documentation.
This switches from using str constants or os module constants on a warn parameter to using named keyword only arguments specifying the intent of the callable being passed in. It avoids the need for string literals or new os module constants and is generally more readable. This is more similar to how the libc pthread_atfork() API works.
We don't want to call PyOS_BeforeFork() or PyOS_AfterFork_Parent() if we never manage to make it to the fork() call it self, erroring out instead.
The statement about re-entering the interpreter applies to all three calls, not just after_in_child.
Modules/posixmodule.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message looks like:
'before' must be callable, not <class 'str'>
It is more common to include the type name rather than repr.
'before' must be callable, not str
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
%s and Py_TYPE(obj)->tp_name solves that. thanks.
Modules/posixmodule.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is more common to return either
- 1 on success, 0 on failure, or
- 0 on success, -1 on failure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it doesn't really matter. 0 on success and non-zero on failure is the real idiom. 1 and -1 are both non-zero and pass a truth test.
Modules/posixmodule.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This partially repeats descriptions of arguments ('before' is called before forking, etc).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed some of the redundancy in the docstring.
Modules/posixmodule.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"in the parent" perhaps is redundant.
And "Zero arg" may be redundant in the docstring. This detail can be explained in the module documentation. Shortened "arg" is a jargon word.
Modules/posixmodule.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Callables.
Doc/library/os.rst
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
os.fork() is not the only forking function. There are also os.fork1(), os.forkpty() and _posixsubprocess.fork_exec(). And third-party code can call fork().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is impossible and unmaintainable to list them all, I've generalized the wording.
|
I don't know why, but the diff now shows already merged changes, including unrelated to this issue. This makes reviewing hard. |
|
I don't know why git did that. I followed the https://cpython-devguide.readthedocs.io/gitbootcamp.html#syncing-with-upstream instructions to pull in recent changes so the tests would pass and I could update Lib/threading.py to use this API. :( |
9c9dbac to
22a40c9
Compare
|
Okay, I figured out how to do a proper rebasing and the diffs for this PR look sane again without including merged changes from others. (for reference, the git instructions I followed were based on https://www.digitalocean.com/community/tutorials/how-to-rebase-and-update-a-pull-request) |
Modules/clinic/posixmodule.c.h
Outdated
| "--\n" | ||
| "\n" | ||
| "Register a callable object to be called when forking.\n" | ||
| "Registers callables to be called when forking a new process.\n" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a style rule, CPython uses infinitives in documentation, not present tense.
|
btw, if you don't want to mess around with git rebases, |
I believe all comments have been addressed. Anything else can be addressed in follow up commits.
Add
osmodule constants and updates all uses and documentation instead of string literals.This allows for cleaner code with less chance of a typo in a string value showing up at runtime.
Linters and similar tools can flag incorrect constant names before run time.