-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
py/builtinimport.c: Allow built-in modules to be packages (v2) #5701
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
Conversation
4b6aaa0
to
2a874dc
Compare
py/objmodule.c
Outdated
#if MICROPY_MODULE_WEAK_LINKS | ||
// Same as mp_module_get, but prefixes | ||
mp_obj_t mp_module_get_builtin_umodule(qstr module_name) { | ||
char buf[MICROPY_ALLOC_PATH_MAX]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid this stack allocation (which can be large) it might be better to pass in a buffer from the caller. Eg the VSTR_FIXED(path, MICROPY_ALLOC_PATH_MAX)
(not sure if that's allowed to be clobbered tho at the point of calling this function).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or even pass in the vstr itself and use vstr functions here to construct the u-module name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reused the path vstr. I'd prefer to do this while the path is empty (i.e. two lines higher) but then you end up creating a new "umodule" QSTR for every import.
py/objmodule.c
Outdated
|
||
// Returns an already-loaded module, a newly-initialised built-in, or MP_OBJ_NULL otherwise. | ||
mp_obj_t mp_module_get(qstr module_name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To decrease code size it might be possible to combine mp_module_get()
and mp_module_get_loaded()
in to 1 function, with an argument bool search_builtins
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out with some more refactoring I don't need both -- can always use the "include builtins" version.
I dug into this much further got the code size down, and made an effort to make the import code a lot easier to follow. Overall PR is now -80 bytes on PYBV11. (i.e. -152 for the first commit, +72 for this feature).
Clear up the code path for importing: - already-loaded modules - built-in modules - built-in umodules (formerly weak links) - filesystem modules - (...and in the future, built-in packages) Also only enables the -m behavior with a (unix-only) flag. Code size reduction of XX.
Allows a built-in module to add a sub-module as a member of its globals dict, and allow importing it as "import foo.bar" (or any other variation on the import statement). Note: This does give the slightly surprising behavior that "import foo" followed by "foo.bar.x" will also work. +56 bytes on PYBV11.
Thanks @jimmo - this has been useful. In case someone else is using this PR as a patch, some findings:
|
Closing this in favour of #8010 for now (which just simplifies the code but retains the existing behavior). We can revisit the built-in package stuff later. |
Fetch tools/adabot submodule for website build
This is a rework of #4731 based on adafruit#2657
The idea is that a built-in module can add another module as a member of its globals dict (whereas the previous approach was to allow for built-in modules with dots in their name).
I think the main surprise with this approach is that
will work, without foo.bar ever being explicitly imported, however there's nothing stopping a regular Python package from doing this either via its
__init__.py
. That said, ifMICROPY_MODULE_BUILTIN_INIT
is enabled, then foo.bar's init will not be called in the above example.The net code size change for this PR is -44 bytes on PYBV11 (but this feature itself, i.e. the final commit, is +56 bytes).
@tannewt @v923z