From 82d1fadebb6eafca23cf979f9fe7bf6e60ad9b7f Mon Sep 17 00:00:00 2001 From: MWR27 <64335495+MWR27@users.noreply.github.com> Date: Wed, 3 Jun 2026 12:32:11 -0400 Subject: [PATCH 1/2] Add warning for implicit relative imports --- Python/import.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Python/import.c b/Python/import.c index b79354b37a4064..1262a1c2b6c9f4 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2247,6 +2247,11 @@ import_module_level(char *name, PyObject *globals, PyObject *locals, Py_ssize_t buflen = 0; PyObject *parent, *head, *next, *tail; + char parentstr[MAXPATHLEN + 1]; /* maybe rename to pkgstr or pkgname? */ + char *orig_name = name; + int is_from_form; + int might_warn_implicit; + if (strchr(name, '/') != NULL #ifdef MS_WINDOWS || strchr(name, '\\') != NULL @@ -2265,6 +2270,13 @@ import_module_level(char *name, PyObject *globals, PyObject *locals, if (parent == NULL) goto error_exit; + might_warn_implicit = level < 0 && + parent != Py_None && + buflen + strlen(name) + 1 <= MAXPATHLEN; + if (might_warn_implicit) { + memcpy(parentstr, buf, buflen + 1); + } + Py_INCREF(parent); head = load_next(parent, level < 0 ? Py_None : parent, &name, buf, &buflen); @@ -2303,6 +2315,35 @@ import_module_level(char *name, PyObject *globals, PyObject *locals, } if (!b) fromlist = NULL; + is_from_form = b; + } + + if (might_warn_implicit) { + char potential_resolved[MAXPATHLEN + 2]; + sprintf(potential_resolved, "%s.%s", parentstr, orig_name); + + if (strcmp(potential_resolved, buf) == 0) { + char msg[524]; + char fix[260]; + if (is_from_form) { + sprintf(msg, + "implicit relative import from '%.200s' resolved to '%.200s'; " + "in 3.x imports are absolute by default, so this may resolve differently", + orig_name, buf); + sprintf(fix, + "use 'from %.200s import ...' if the parent package is intended", buf); + } else { + sprintf(msg, + "implicit relative import '%.200s' resolved to '%.200s'; " + "in 3.x imports are absolute by default, so this may resolve differently", + orig_name, buf); + sprintf(fix, + "use 'import %.200s' if the parent package is intended", buf); + } + if (PyErr_WarnPy3k_WithFix(msg, fix, 1) < 0) { + goto error_exit; + } + } } if (fromlist == NULL) { From 411eee548d121bb82476decd8377c33ad1f16fff Mon Sep 17 00:00:00 2001 From: MWR27 <64335495+MWR27@users.noreply.github.com> Date: Wed, 3 Jun 2026 13:09:33 -0400 Subject: [PATCH 2/2] Fix not recognizing submodules in multiple levels of subpackages --- Python/import.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/import.c b/Python/import.c index 1262a1c2b6c9f4..9b8759164d00cb 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2272,6 +2272,7 @@ import_module_level(char *name, PyObject *globals, PyObject *locals, might_warn_implicit = level < 0 && parent != Py_None && + strchr(name, '.') == NULL && buflen + strlen(name) + 1 <= MAXPATHLEN; if (might_warn_implicit) { memcpy(parentstr, buf, buflen + 1);