Skip to content

Conversation

@pablogsal
Copy link
Member

@pablogsal pablogsal commented Dec 6, 2025

⚠️ Dear reviewers, to avoid collapsing the GitHub API with a lot of comments, please open PRs against the base branch with any suggestions or fixes if you are sure are not controversial ⚠️


📚 Documentation preview 📚: https://cpython-previews--142351.org.readthedocs.build/

DinoV and others added 30 commits October 2, 2025 13:22
Highlight lazy imports in the new REPL
@picnixz
Copy link
Member

picnixz commented Dec 6, 2025

@pablogsal PTAL LazyImportsCabal#25

@picnixz
Copy link
Member

picnixz commented Dec 6, 2025

I'll be doing small reviews because I'm not on my dev session and it takes too long for creating a PR :') I promise I won't be too nitpicky!

@pablogsal pablogsal requested a review from willingc as a code owner December 6, 2025 18:34
pair: name; binding
pair: keyword; from
pair: keyword; as
pair: keyword; lazy
Copy link
Member

Choose a reason for hiding this comment

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

I suggest you move this to the below section on lazy specifically.

Copy link
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

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

I'll review more tomorrow when I'm on my dev session, it'll be easier. But here are a few comments and questions about import.c

PyImport_GetLazyImportsFilter(void)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
return Py_XNewRef(FT_ATOMIC_LOAD_PTR_RELAXED(LAZY_IMPORTS_FILTER(interp)));
Copy link
Member

Choose a reason for hiding this comment

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

If the import filter is not set, this may return NULL without an exception set. So either you want it to be documented or you want to return None instead.

PyObject *old = _Py_atomic_exchange_ptr(&LAZY_IMPORTS_FILTER(interp), Py_XNewRef(filter));
Py_XDECREF(old);
#else
Py_XSETREF(LAZY_IMPORTS_FILTER(interp), Py_XNewRef(filter));
Copy link
Member

Choose a reason for hiding this comment

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

This makes me wondeer whether we couldn't have a FT helper for this. It's probably not the only place that will need this in the future.

Comment on lines 4350 to 4354
if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &modname) < 0) {
return NULL;
} else if (modname == NULL) {
modname = Py_None;
}
Copy link
Member

Choose a reason for hiding this comment

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

This should be two separate ifs right? because you might have modname == NULL if the name doesn't exist.

if (filter != NULL) {
PyObject *modname;
if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &modname) < 0) {
return NULL;
Copy link
Member

Choose a reason for hiding this comment

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

You need to decref abs_name here (you can also have a goto error maybe?)

Python/import.c Outdated
Comment on lines 4368 to 4370
if (!PyObject_IsTrue(res)) {
Py_DECREF(abs_name);
return PyImport_ImportModuleLevelObject(
Copy link
Member

@picnixz picnixz Dec 6, 2025

Choose a reason for hiding this comment

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

Just me thinking aloud but is it possible to have a UAF here because filter is an arbitrary callable (so, we could alter fromlist)?


// Add the module name to sys.lazy_modules set (PEP 810)
PyObject *lazy_modules_set = interp->imports.lazy_modules_set;
if (lazy_modules_set != NULL) {
Copy link
Member

Choose a reason for hiding this comment

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

When is it possible to have lazy_modules_set NULL?

}

child_dict = get_mod_dict(child_module);
if (child_dict == NULL || !PyDict_CheckExact(child_dict)) {
Copy link
Member

Choose a reason for hiding this comment

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

child_dict can be NULL and we must go to error here

Comment on lines +906 to +907

lazy import json
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
lazy import json
lazy import json
lazy import sys

For 'json' in sys.modules to run.

@pablogsal
Copy link
Member Author

@DinoV @colesbury I haven't paid attention to FT when I updated the draft implementation so please take a special look at that

@pablogsal
Copy link
Member Author

pablogsal commented Dec 6, 2025

@DinoV @colesbury I haven't paid attention to FT when I updated the draft implementation so please take a special look at that

In particular ./python -m test test_import.test_lazy_imports -v shows some tsan problems.

I think I got them in 470b9e4 but not sure if that's the best way to fix this.

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.

6 participants