Frozen modules and search order

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
User avatar
tuupola
Posts: 54
Joined: Sun Sep 17, 2017 12:10 am
Contact:

Frozen modules and search order

Post by tuupola » Fri Mar 02, 2018 10:48 am

Do i understand correctly frozen modules are always the first in the search order when doing an import?

For example let's assume I have a frozen module called foo. I made some changes to it and would like to test the changes so I upload foo.py to the flash. However when I do import foo it always seems to import the frozen module.

Do I have any other options than flashing a new firmware without the frozen module?

cefn
Posts: 225
Joined: Tue Aug 09, 2016 10:58 am

Re: Frozen modules and search order

Post by cefn » Fri Mar 02, 2018 3:14 pm

I wonder if you could import a randomname module, then system.modules['modulename'] = randomname before importing anything else at startup.

User avatar
pythoncoder
Posts: 3607
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Frozen modules and search order

Post by pythoncoder » Sat Mar 03, 2018 7:45 am

Frozen modules are found first. This has caught me out more than once :oops:

@cefn I'm afraid I don't follow your solution, perhaps you can clarify? The value of the sys.modules dict is a module instance rather than a module name. But perhaps I'm missing your point here.
Peter Hinch

cefn
Posts: 225
Joined: Tue Aug 09, 2016 10:58 am

Re: Frozen modules and search order

Post by cefn » Sat Mar 03, 2018 9:22 am

Sorry for the last post. Was rushing the post in on a phone, autocorrect messed things up and wasn't able to put together a proper code example. I was referring to the strategy shared by @stijn in viewtopic.php?f=2&t=4449&p=25753&hilit=monkey#p25753

After putting a file myfrozenmodule123123.mpy in the filesystem, you might do...

Code: Select all

# make sure this happens before anything else
import myfrozenmodule123123
sys.modules['myfrozenmodule']=myfrozenmodule123123
# start loading modules which import myfrozenmodule now, and they should end up receiving the substitute module
However, I don't now if the strategy might not work with frozen modules for some reason.

User avatar
pythoncoder
Posts: 3607
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Frozen modules and search order

Post by pythoncoder » Sun Mar 04, 2018 7:51 am

A quick test suggests that this does work. A useful technique.
Peter Hinch

User avatar
dhylands
Posts: 3228
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Frozen modules and search order

Post by dhylands » Sun Mar 18, 2018 11:59 pm

tuupola wrote:
Fri Mar 02, 2018 10:48 am
Do i understand correctly frozen modules are always the first in the search order when doing an import?

For example let's assume I have a frozen module called foo. I made some changes to it and would like to test the changes so I upload foo.py to the flash. However when I do import foo it always seems to import the frozen module.

Do I have any other options than flashing a new firmware without the frozen module?
If you examine sys.path, then you'll see that there is often an empty string shown in the array. When micropython encounters this empty string, this is where it looks for frozen modules. By default, sys.path looks like this:

Code: Select all

>>> import sys
>>> sys.path
['', '/flash', '/flash/lib']
so in this scenario, frozen modules will be located before modules in /flash. If you were to modify sys.path:

Code: Select all

>>> del sys.path[0]
>>> sys.path.append('')
>>> sys.path
['/flash', '/flash/lib', '']
then modules in /flash will override the frozen ones.

I was able to confirm this on my pyboard. By default there is an lcd160cr.py module which is frozen. I created a /flash/lcd160cr.py file which contained this:

Code: Select all

print('Custom lcd160cr.py loaded')
As expected if you import lcd160cr, then nothing is printed.

Code: Select all

>>> import lcd160cr
>>> 
If you enter Control-D and do this instead:

Code: Select all

>>> import sys
>>> sys.path
['', '/flash', '/flash/lib']
>>> del sys.path[0]
>>> sys.path.append('')
>>> sys.path
['/flash', '/flash/lib', '']
>>> import lcd160cr
Custom lcd160cr.py loaded
>>> 
then we see that the import lcd160cr imported the file from /flash instead.

User avatar
pythoncoder
Posts: 3607
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Frozen modules and search order

Post by pythoncoder » Mon Mar 19, 2018 6:59 am

Ingenious :idea:
Peter Hinch

User avatar
tuupola
Posts: 54
Joined: Sun Sep 17, 2017 12:10 am
Contact:

Re: Frozen modules and search order

Post by tuupola » Wed Mar 28, 2018 3:16 pm

Awesome. Thanks!

Post Reply