Re: [Zope] Refreshing modules imported into external methods
Thanks for the responses to my question.
Have you tried this? Go to its manage page and hit 'Save changes'. Running Zope in debug mode (-D) may help too but I'm not sure.
Unfortunately, neither of those things worked.
create a refreshing External Method that uses Python's "reload" to reload modules
This worked. It seems strange from a Python perspective, since there's no need to use "reload" inside ordinary programs; Python automatically re-imports any code that has changed. The "reload" function is ordinarily only useful when working interactively with the interpreter. But it works beautifully in this case. Returning to my previous example: external method file foo.py (located in /path_to_Zope/Extensions): import bar def foo(): reload(bar) # Reload module 'bar' as per Dieter's suggestion. return 'foo' + bar.baz() Python module bar.py (located on my PYTHONPATH): def baz(): return 'bar' Now changes to bar.py are reflected immediately in calls to foo(), without restarting Zope. Thanks again, Michael ===== Michael Hartl http://www.michaelhartl.com/ __________________________________ Do you Yahoo!? New Yahoo! Photos - easier uploading and sharing. http://photos.yahoo.com/
Michael Hartl wrote at 2003-12-17 10:29 -0800:
...
create a refreshing External Method that uses Python's "reload" to reload modules
This worked. It seems strange from a Python perspective, since there's no need to use "reload" inside ordinary programs; Python automatically re-imports any code that has changed.
In fact, Python does not care at all when you change a module after it has been imported. Especially, it does *not* reload modules in ordinary programs. When you see automatic reloading then this is a feature of something outside Python (e.g. Zope or the IDE). -- Dieter
--- Dieter Maurer <dieter@handshake.de> wrote:
This worked. It seems strange from a Python perspective, since there's no need to use "reload" inside ordinary programs; Python automatically re-imports any code that has changed.
In fact, Python does not care at all when you change a module after it has been imported. Especially, it does *not* reload modules in ordinary programs.
When you see automatic reloading then this is a feature of something outside Python (e.g. Zope or the IDE).
Perhaps you mean that the Python interpreter doesn't automatically reload modified modules when run interactively; I certainly agree with that. On the other hand, when a module is included in another program, any changes to the module are automatically reflected in the program when it is run at the Linux command line. (Essentially the same thing happens under Windows when a Python file is run as a script by double-clicking on it.) I'm sure Dieter already knows about this, but let me elaborate for the sake of those on the list without extensive Python experience. Consider the following two files: foo.py: import bar print bar.baz() bar.py: def baz(): return 'This is an unmodified module.' Running foo.py at the command line produces the following: $ python foo.py This is an unmodified module. Running foo.py also causes the creation of a bytecode version of bar.py (namely, bar.pyc). If we now edit bar.py so that it reads def baz(): return 'This is a modified module.' and then run foo.py at the command line again, we have $ python foo.py This is a modified module. Here Python recognizes that bar.py is newer than its bytecode counterpart bar.pyc, so it produces a new bar.pyc bytecode file, and then uses the modified version of bar.baz() inside foo.py. In other words, even though we have not explicitly reloaded bar.py (with the reload(bar) command), its changes nevertheless show up when we run foo.py. Moreover, if bar.py itself imports a module called quux, then any changes to quux.py will propagate all the way up to foo.py, and so on. The result is that at no point does the programmer need to pay attention to the modification status of any imported modules; Python handles all of it for you. Because of the behavior of Python programs in the file system, I expected the same behavior for external methods called from Zope, since external methods live in files on the file system. This expectation was not met; an explicit call to reload() is necessary for any changes in external modules to be reflected in the methods that import them. Michael ===== Michael Hartl http://www.michaelhartl.com/ __________________________________ Do you Yahoo!? New Yahoo! Photos - easier uploading and sharing. http://photos.yahoo.com/
Michael Hartl said:
On the other hand, when a module is included in another program, any changes to the module are automatically reflected in the program when it is run at the Linux command line. (Essentially the same thing happens under Windows when a Python file is run as a script by double-clicking on it.)
This is irrelevant to how a long-running program works. If you reloaded Zope every time you executed a request, you'd see the same behavior... eventually. :-) For non-trivial software, Python's "ordinary" behavior is the opposite of what you described. FWIW, Dylan
This is irrelevant to how a long-running program works. If you reloaded Zope every time you executed a request, you'd see the same behavior... eventually. :-)
For non-trivial software, Python's "ordinary" behavior is the opposite of what you described.
I guess it depends on what you consider "trivial" software or "ordinary" behavior. As an example, suppose you were to replicate all the standard Unix utilities as Python programs (wc.py, grep.py, head.py, tail.py, awk.py, etc.), so that, e.g., 'wc.py file' would count the words in a file. Then modules imported into any of these programs would be updated automatically just as I described. Surely the entire corpus of Unix utilities cannot be said to consist only of "trivial" programs! In fact, any Python program that follows the "do something, then return to the shell" paradigm will behave exactly as I described. This is probably the most common Linux/Unix paradigm, and includes many highly nontrivial programs such as gcc, make, and (La)TeX. I agree that a program running persistently (i.e., what you call a "long-running program") won't behave in the way I described, but there are many nontrivial programs that don't fit this model. One might argue that Zope is precisely such a long-running (persistent) program, so its behavior should be expected. The reason that Zope's behavior surprised me is that changes to the external method file *were* immediately reflected in my Zope pages (i.e., without restarting Zope or even clicking on 'Save Changes' in the external method's properties). This means that Zope must be reparsing the external method's file, much as invoking a program from the command line forces a file reparsing. In the command line case, when a file is parsed all included modules are checked for updates and re-imported if necessary. In light of this, my expectation for Zope's behavior, though incorrect, doesn't seem unreasonable to me. Michael ===== Michael Hartl http://www.michaelhartl.com/ __________________________________ Do you Yahoo!? New Yahoo! Photos - easier uploading and sharing. http://photos.yahoo.com/
Michael Hartl said:
This is irrelevant to how a long-running program works. If you reloaded Zope every time you executed a request, you'd see the same behavior... eventually. :-)
For non-trivial software, Python's "ordinary" behavior is the opposite of what you described.
I guess it depends on what you consider "trivial" software or "ordinary" behavior.
Maybe so. In any event, several people have now made it clear how Zope handles this issue and I'm going to pass on the opportunity to discuss whether or not "wc" is a trivial program. Dylan
participants (3)
-
Dieter Maurer -
Dylan Reinhardt -
Michael Hartl