Skip to content

Commit 662dfea

Browse files
committed
gh-158140: Resolve lazily imported sibling submodules independently
1 parent ad34fae commit 662dfea

8 files changed

Lines changed: 1404 additions & 54 deletions

File tree

‎Include/internal/pycore_import.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ PyAPI_FUNC(PyObject *) _PyImport_LoadLazyImportTstate(
4040
// Bind a pending child on module before removing its registration. Return a
4141
// new reference, NULL without an exception if absent, or NULL on error.
4242
// Set recheck_dict if a concurrent lookup may have already bound the child.
43+
extern PyObject *_PyImport_LoadLazySubmodule(PyThreadState *tstate, PyObject *name);
44+
extern PyObject *_PyImport_GetLazySubmodules(PyThreadState *, PyObject *);
45+
extern int _PyImport_ClearLazySubmodules(PyThreadState *, PyObject *);
4346
extern PyObject * _PyImport_TryLoadLazySubmodule(
4447
PyObject *module, PyObject *attr_name, int *recheck_dict);
4548
extern PyObject * _PyImport_LazyImportModuleLevelObject(

‎Include/internal/pycore_interp_structs.h‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,12 @@ struct _import_state {
356356
// lazily imported. This value is only for debugging/introspection
357357
// purposes and is not used by the runtime.
358358
PyObject *lazy_modules;
359-
// A dict mapping package names to a set of submodule names that
360-
// may need to be imported when an attribute is missing on the package.
359+
// A dict mapping package names to dicts of pending child names.
360+
// Values are declarations, True for completed imports, or False for
361+
// optional from-import attributes.
361362
PyObject *lazy_pending_submodules;
363+
// Cached imports may need to replace a published lazy binding.
364+
int has_lazy_submodules;
362365
#ifdef Py_GIL_DISABLED
363366
PyMutex lazy_mutex;
364367
#endif

‎Include/internal/pycore_lazyimportobject.h‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ PyAPI_FUNC(PyObject *) _PyLazyImport_New(
1818
struct _PyInterpreterFrame *frame, PyObject *builtins,
1919
PyObject *name, PyObject *fromlist);
2020

21+
extern int _PyLazyImport_IsSubmodule(PyObject *op);
22+
extern int _PyLazyImport_IsStrictSubmodule(PyObject *op);
23+
2124
extern int _PyLazyImport_IsResolving(PyThreadState *tstate, PyObject *op);
2225

2326
// Resolve a placeholder and replace its binding if it is unchanged or holds
@@ -27,6 +30,11 @@ PyAPI_FUNC(PyObject *) _PyLazyImport_Reify(
2730
PyThreadState *tstate, PyObject *placeholder,
2831
PyObject *name, PyObject *ns);
2932

33+
// Optional module lookups preserve from-import and __getattr__ fallbacks.
34+
extern PyObject *_PyLazyImport_ReifyOptional(
35+
PyThreadState *tstate, PyObject *placeholder,
36+
PyObject *name, PyObject *ns);
37+
3038
#ifdef __cplusplus
3139
}
3240
#endif

0 commit comments

Comments
 (0)