forcing future re-import from with an imported module

W

_wolf

following problem: i have a module importer_1 that first imports
importer_2, then importee. importer_2 also imports importee. as we all
know, follow-up imports are dealt out from the cache by python’s
import mechanism, meaning the importee file gets only cached once. i
can force module-level code in importee to be re-executed e.g. by
deleting importee from sys.modules. but in this case, code of shich
below, that does not work: if you delete importee from sys.modules
*from within importee*, you get a nasty "ImportError: Loaded module
importee not found in sys.modules" instead. but, the same line `import
sys; del sys.modules[ 'importee' ]` does what it says on the tin.

how can i say, approximately, "re-import the present module when it is
imported the next time, don’t use the cache" in a simple way? i do not
want to "reload" the module, that doesn’t help.

greets

_wolf



#------------------------------------------
# importer_1.py
#------------------------------------------

print 'this is importer 1'
import importer_2
# import sys; del sys.modules[ 'importee' ]
import importee
print 'importer 1 finished'

#------------------------------------------
# importer_2.py
#------------------------------------------

print 'this is importer 2'
import importee
print 'importer 2 finished'

#------------------------------------------
# importee.py
#------------------------------------------

print 'this is importee'
import sys; del sys.modules[ 'importee' ]
print 'importee finished'

#------------------------------------------
# Output
#------------------------------------------
this is importer 1
this is importer 2
this is importee
importee finished
Traceback (most recent call last):
File "C:\temp\active_imports\importer_1.py", line 2, in <module>
import importer_2
File "C:\temp\active_imports\importer_2.py", line 2, in <module>
import importee
ImportError: Loaded module importee not found in sys.modules
 
G

Gabriel Genellina

how can i say, approximately, "re-import the present module when it is
imported the next time, don’t use the cache" in a simple way? i do not
want to "reload" the module, that doesn’t help.

I'd say you're using modules the wrong way then. The code inside a module
is executed *once*, and that's by design. If you want to execute something
more than once, put that code inside a function, and call it as many times
as you want.
 
W

_wolf

I'd say you're using modules the wrong way then. The code inside a module
is executed *once*, and that's by design. If you want to execute something
more than once, put that code inside a function, and call it as many times
as you want.

thanks for your answer. i am aware that imports are not designed to
have side-effects, but this is exactly what i want: to trigger an
action with `import foo`. you get foo, and doing this can have a side-
effect for the module, in roughly the way that a `from __future__
import with_statement` changes the interpretation of the current
module (of course, i do not intend to effect syntactic changes---my
idea is to look into the module namespace and modify it). think of it
as ‘metamodule programming’ (à la metaclass programming).

maybe import hooks are the way to go? somtimes it would be good if
there was a signalling system that broadcasts all kinds of system
state change.

cheers & ~flow

ok so the question is: how to make it so each import of a given module
has a side-effect, even repeated imports?
 
R

rdmurray

thanks for your answer. i am aware that imports are not designed to
have side-effects, but this is exactly what i want: to trigger an
action with `import foo`. you get foo, and doing this can have a side-
effect for the module, in roughly the way that a `from __future__
import with_statement` changes the interpretation of the current
module (of course, i do not intend to effect syntactic changes---my
idea is to look into the module namespace and modify it). think of it
as ‘metamodule programming’ (à la metaclass programming).

maybe import hooks are the way to go? somtimes it would be good if
there was a signalling system that broadcasts all kinds of system
state change.

cheers & ~flow

ok so the question is: how to make it so each import of a given module
has a side-effect, even repeated imports?

Why can't you have the code that is doing the import subsequently
call a function from the module to produce whatever side effect it
is you want? Explicit is better than implicit. A python
programmer is going to expect that importing a module is idempotent,
and breaking that assumption strikes me as a bad idea.

Maybe you should give us more details about what problem it is
you are trying to solve. There might be a good pythonic way to
solve it.

--RDM
 
W

_wolf

"Why can't you have the code that is doing the import [...]
call a function [...] to produce [the] side effect [...]?
Explicit is better than implicit. A python programmer is
going to expect that importing a module is idempotent"

you’re completely right that `import foo` with side effects may break
some expectations, but so do all `from __future__` imports. you’re
also right that another solution would be to come in from the other
side and explicitly call a function from the importing module. all of
this does not answer one question tho: why does deleting a module work
most of the time, but not in the case outlined in my first post,
above? why do we get to see this slightly strange error message there
complaining about ‘not finding’ a module ‘in sys.modules’—well, most
of the time, when a module is not in that cache, it will be imported,
but not in this case. why?

cheers & ~flow
 
G

Gabriel Genellina

"Why can't you have the code that is doing the import [...]
call a function [...] to produce [the] side effect [...]?
Explicit is better than implicit. A python programmer is
going to expect that importing a module is idempotent"

you’re completely right that `import foo` with side effects may break
some expectations, but so do all `from __future__` imports. you’re
also right that another solution would be to come in from the other
side and explicitly call a function from the importing module. all of
this does not answer one question tho: why does deleting a module work
most of the time, but not in the case outlined in my first post,
above? why do we get to see this slightly strange error message there
complaining about ‘not finding’ a module ‘in sys.modules’—well, most
of the time, when a module is not in that cache, it will be imported,
but not in this case. why?

The import system can be customised in many ways (the various import
hooks, special entries in sys.path, meta_path, path_hooks, __import__,
etc.), even could be completely reimplemented. There are safety checks in
the interpreter, to validate some minimal pre and postconditions that
should always hold.
By example, checking that sys.path contains a list of directories. Or the
one you broke: after successfully executing "import foo", there must be an
entry named "foo" in sys.modules. If not, it is asumed that something in
the import machinery went wrong.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top