← index #16684PR #5701
Related · medium · value 0.301
QUERY · ISSUE

Suggestion: add the ability to modify builtin modules (conforming to the standard C-Python implementation)

openby xuancong84opened 2025-02-02updated 2025-02-04
enhancement

Description

The standard C-Python allows modification of built-in modules. With that capability, we can create genuine global variables across all imported modules in the following way:

import os
os.g_abc = "Hello world"

Using this technique, inside any imported module, you can access os.g_abc after importing os module.

However, this is not allowed in Micropython, giving the following error:

AttributeError: 'module' object has no attribute 'g_abc'

FYI, this is the only way to create genuine global variables if your level of python profession believes that globals() can solve the problem. No. That is because globals() is only global w.r.t. the module that it is located in, not w.r.t. the global runtime. For example,

### moduleA.py

def test():
 globals()['g_abc'] = 'hello'

def mainA():
 print(g_abc)
### moduleB.py

import moduleA
moduleA.test()

moduleA.mainA()   # this works fine
print(globals()['g_abc']). # this will crash, because the global variable is only defined within moduleA context, not in moduleB or elsewhere

Code Size

No response

Implementation

I hope the MicroPython maintainers or community will implement this feature

Code of Conduct

Yes, I agree

CANDIDATE · PULL REQUEST

py/builtinimport.c: Allow built-in modules to be packages (v2)

closedby jimmoopened 2020-02-26updated 2021-12-01
py-core

This is a rework of #4731 based on https://github.com/adafruit/circuitpython/pull/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

import foo
foo.bar.baz()

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, if MICROPY_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

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied