Skip to content
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

Merged
merged 23 commits into from
May 1, 2024

Conversation

ericsnowcurrently
Copy link
Member

@ericsnowcurrently ericsnowcurrently commented Apr 24, 2024

I've pulled this out of #118116.

This change will make some later changes simpler.

@ericsnowcurrently
Copy link
Member Author

@encukou, aside from the other things this PR does, it should also take care of the problem with is_singlephase() you described in #117953 (comment).

Copy link
Member

@encukou encukou left a 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)
Copy link
Member

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.

Copy link
Member Author

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
Comment on lines 1264 to 1266
// 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);
Copy link
Member

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.

Suggested change
// 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);

Copy link
Member Author

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.

Copy link
Member Author

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);
Copy link
Member

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.

Suggested change
assert(!PyErr_Occurred() && res.err == NULL);
assert(!PyErr_Occurred());
assert(res.err == NULL);

Copy link
Member Author

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
Comment on lines 1426 to 1427

// XXX __file__ doesn't get set!
Copy link
Member

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.

Suggested change
// XXX __file__ doesn't get set!

Copy link
Member Author

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. 😄

Copy link
Member Author

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);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
assert(!PyErr_Occurred() && res.err == NULL);
assert(!PyErr_Occurred());
assert(res.err == NULL);

Copy link
Member Author

Choose a reason for hiding this comment

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

done

}

if (err->exc != NULL) {
PyErr_SetRaisedException(err->exc);
Copy link
Member

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:

Suggested change
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).

Copy link
Member Author

Choose a reason for hiding this comment

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

done

goto error;
}
}

assert(!PyErr_Occurred());
assert(!PyErr_Occurred() && res.err == NULL);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
assert(!PyErr_Occurred() && res.err == NULL);
assert(!PyErr_Occurred());
aeesrt(res.err == NULL);

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@ericsnowcurrently ericsnowcurrently merged commit 526ca4c into python:main May 1, 2024
34 checks passed
@ericsnowcurrently ericsnowcurrently deleted the extension-kinds branch May 1, 2024 23:40
SonicField pushed a commit to SonicField/cpython that referenced this pull request May 8, 2024
…ort Machinery (pythongh-118205)

This change will make some later changes simpler.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants