Skip to content

Commit 66e4afd

Browse files
authored
Merge pull request #10951 from tannewt/fix-issue-10614
Import: .py module wins over namespace-package dir (#10614)
2 parents 02a3fc6 + 2fd4bce commit 66e4afd

4 files changed

Lines changed: 28 additions & 1 deletion

File tree

py/builtinimport.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,26 @@ static mp_import_stat_t stat_module(vstr_t *path) {
105105
mp_import_stat_t stat = stat_path(path);
106106
DEBUG_printf("stat %s: %d\n", vstr_str(path), stat);
107107
if (stat == MP_IMPORT_STAT_DIR) {
108-
return stat;
108+
// CIRCUITPY-CHANGE: match CPython import precedence. A regular
109+
// package (directory with __init__.py/.mpy) takes precedence, then a
110+
// sibling .py/.mpy module, and only then a namespace package
111+
// (directory without __init__). See
112+
// https://docs.python.org/3/reference/import.html#regular-packages
113+
size_t orig_len = path->len;
114+
vstr_add_str(path, PATH_SEP_CHAR "__init__.py");
115+
mp_import_stat_t init_stat = stat_file_py_or_mpy(path);
116+
path->len = orig_len;
117+
if (init_stat == MP_IMPORT_STAT_FILE) {
118+
return MP_IMPORT_STAT_DIR;
119+
}
120+
121+
vstr_add_str(path, ".py");
122+
mp_import_stat_t file_stat = stat_file_py_or_mpy(path);
123+
if (file_stat == MP_IMPORT_STAT_FILE) {
124+
return file_stat;
125+
}
126+
path->len = orig_len;
127+
return MP_IMPORT_STAT_DIR;
109128
}
110129

111130
// Not a directory, add .py and try as a file.

tests/import/import_shared_name.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# https://github.com/adafruit/circuitpython/issues/10614
2+
# When a directory `shared_name/` (no __init__.py) and a module `shared_name.py`
3+
# share a name, `import shared_name` must pick the .py module per PEP 420
4+
# precedence: regular package > module > namespace package.
5+
import shared_name
6+
7+
print("done")

tests/import/shared_name.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print("hello shared_name.py")

tests/import/shared_name/spritesheet.bmp

Whitespace-only changes.

0 commit comments

Comments
 (0)