-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
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
bpo-45256: Rationalize code around Python-to-Python calls a bit. #29235
Conversation
🤖 New build scheduled with the buildbot fleet by @pablogsal for commit 9cc3f1f 🤖 If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again. |
Python/ceval.c
Outdated
_PyFrame_Clear(frame, 1); | ||
return NULL; | ||
} | ||
return frame; | ||
fail: |
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.
Why this tag? There is only one place where you can reach the tag, no? Is also not future proof, because you are only raising PyErr_NoMemory
so I am not sure what is the advantage. Is for separating error handling from the logic?
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 just to keep the error handling out of the main block of code.
It is a quite common idiom in CPython to put the error handling at the end. Personally, I think early exits help readability, so I think it is worth doing even if there is only a single jump to the error handler.
I see you point about PyErr_NoMemory
though, I'll rename the label to fail_no_memory
for clarity.
_PyFrame_Clear(frame, 0); | ||
return NULL; | ||
} | ||
frame->previous = tstate->frame; | ||
tstate->frame = frame; | ||
return frame; | ||
fail: |
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.
Question: If the call succeeds, don't we need to do this work anyway in initialize_locals
? Not sure if is going to be more messy, but we could maybe share this path or part of this path for error and not error cases. For instance, remove these parts in initialize_locals
:
if (kwnames) {
Py_ssize_t kwcount = PyTuple_GET_SIZE(kwnames);
for (j = argcount; j < argcount+kwcount; j++) {
Py_DECREF(args[j]);
}
}
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 don't think so. If the call succeeds all the argument references are consumed by moving them into the local variable array.
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.
LGTM
steal_args
parameter. All code involved in frame initialization always consume the references to the arguments.In theory
CALL_PY_SIMPLE
should be a bit quicker, but that doesn't show up in the benchmark resultshttps://bugs.python.org/issue45256