-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
gh-117953: Work Relative to Specific Extension Kinds in the Import Machinery #118205
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
gh-117953: Work Relative to Specific Extension Kinds in the Import Machinery #118205
Conversation
33af2db
to
3724e9e
Compare
3724e9e
to
4406192
Compare
@encukou, aside from the other things this PR does, it should also take care of the problem with |
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.
Thank you! I have a few comments of the nitpicky kind.
Python/import.c
Outdated
} | ||
|
||
static bool | ||
check_multiphase_preinit(PyModuleDef *def) |
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.
Nitpick: consider making these do the assert, and naming them assert_multiphase_preinit
& assert_singlephase
. “check” is ambigous (should it do the assert?), and there aren't really suitable for anything but asserts.
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.
done
Python/import.c
Outdated
// XXX Two modules should not share the same def->m_base. | ||
//assert(def->m_base.m_init == NULL | ||
// || def->m_base.m_init == singlephase->m_init); |
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.
Hm, I don't remember why this is here.
Let's have the tests find where this was needed? A debug-build assert probably is the best tool.
// XXX Two modules should not share the same def->m_base. | |
//assert(def->m_base.m_init == NULL | |
// || def->m_base.m_init == singlephase->m_init); | |
// The following assert used to be skipped if | |
// def->m_base.m_init == singlephase->m_init | |
// but two modules should not share the same def->m_base. | |
assert(def->m_base.m_init == NULL); |
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.
Yeah, that isn't very clear and the commented-out assert isn't helping matters. I'll clarify the comment and drop the rest.
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.
done
Python/import.c
Outdated
return NULL; | ||
} | ||
assert(!PyErr_Occurred()); | ||
assert(!PyErr_Occurred() && res.err == NULL); |
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.
Let this tell you which one went wrong.
assert(!PyErr_Occurred() && res.err == NULL); | |
assert(!PyErr_Occurred()); | |
assert(res.err == NULL); |
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.
done
Python/import.c
Outdated
|
||
// XXX __file__ doesn't get set! |
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 is now solved, file gets set elsewhere.
// XXX __file__ doesn't get set! |
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.
While the import machinery (in importlib._bootstrap
) does set __file__
, the only place it gets set for a single-phase init module via _imp.load_dynamic
(ergo ExtensionFileLoader.exec_module()
) is the first time it is loaded, in import_run_extension()
. In the above case, the module was found in the global cache and gets reloaded from the cached init function.
I was going to clarify the comment, but it would be just as easy to actually set __file__
and be done with it. 😄
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.
done
Python/import.c
Outdated
goto finally; | ||
} | ||
assert(!PyErr_Occurred()); | ||
assert(!PyErr_Occurred() && res.err == NULL); |
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.
assert(!PyErr_Occurred() && res.err == NULL); | |
assert(!PyErr_Occurred()); | |
assert(res.err == NULL); |
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.
done
Python/importdl.c
Outdated
} | ||
|
||
if (err->exc != NULL) { | ||
PyErr_SetRaisedException(err->exc); |
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.
Consider warning the reader about that function's quirk:
PyErr_SetRaisedException(err->exc); | |
PyErr_SetRaisedException(err->exc); | |
err->exc = NULL; /* SetRaisedException stole our reference */ |
Maybe it would be better to merge _Py_ext_module_loader_result_apply_error
and _Py_ext_module_loader_result_clear
? They're effectively always used together (with apply
skipped on success).
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.
done
Python/importdl.c
Outdated
goto error; | ||
} | ||
} | ||
|
||
assert(!PyErr_Occurred()); | ||
assert(!PyErr_Occurred() && res.err == NULL); |
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.
assert(!PyErr_Occurred() && res.err == NULL); | |
assert(!PyErr_Occurred()); | |
aeesrt(res.err == NULL); |
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.
done
…sult_apply_error().
…ort Machinery (pythongh-118205) This change will make some later changes simpler.
I've pulled this out of #118116.
This change will make some later changes simpler.