Hey all,
Been enjoying webpy, but stumbled on a bit of a gotcha with the reload
functionality. I have a workaround which has its own pitfalls, but
thought that if ever anyone finds themselves puzzled with global
variable misbehaving, this might save them some time, as it took a lot
of time in a debugger to figure out what was going on.
By default when using the builtin server (usually for developing)
there is the very nice functionality that when a file changes it
reloads it and any modules it depends on.
We had been creating a fairly complex application and hooking webpy
into it as a frontend. In the code we need to set an instance of a
client and attach it to the global environment for the application,
for various reasons.
If you have the debug flag on the reload functionality kicks in very
nicely, and reloads the module. However, the way it handles globals
is with this code:
mod = __import__(module_name)
mapping = getattr(mod, mapping_name, None)
if mapping:
self.fvars = mod.__dict__
The problem is that any variables that are not in the imported module
are lost this way. In our script the addition to globals() is done in
the
if __name__ == 'main':
...
section, so when loaded as a module this section is not executed, and
neither should it, because we only want one instance of this object
running per instance of the application.
I thought maybe it would be an idea to have the fvars (originally
globals() in most cases) only updated, rather than replaced, so any
new values are added and overwritten, but values that have no
replacement are left alone. This, of course, has other consequences
which might be considered worse, but I figure having fresh values for
things that should be there, with some extra crud possibly hanging
around in a development environment is not really a big problem, and
having variables go missing suddenly is more difficult to deal with,
esp. as it does it inconsistently.
This is what I came up with as a possible replacement, and I am
attaching the diff.
mod = __import__(module_name)
mapping = getattr(mod, mapping_name, None)
if mapping:
self.fvars.update(mod.__dict__)
The quick workaround once I figured out the problem was to disable
the reload mechanism, but thought this might be a cake and eat it
too solution.
Anyway, thought it might be worth thinking about. Thanks for all the
work on this excellent web app framework. It is nice to finally work
with a python framework where people have actually thought about the
useability of the api, and have some taste.
Thanks,
Rohan
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"web.py" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [email protected]
For more options, visit this group at http://groups.google.com/group/webpy?hl=en
-~----------~----~----~----~------~----~------~--~---
*** /usr/lib/site-packages/web.py-0.31-py2.5.egg/web/application.py 2009-02-11 11:53:43.000000000 +0100
--- .../lib/python2.5/site-packages/web.py-0.31-py2.5.egg/web/application.py 2009-02-25 15:33:59.462824630 +0100
***************
*** 73,79 ****
mod = __import__(module_name)
mapping = getattr(mod, mapping_name, None)
if mapping:
! self.fvars = mod.__dict__
self.mapping = mapping
self.add_processor(loadhook(Reloader()))
--- 73,79 ----
mod = __import__(module_name)
mapping = getattr(mod, mapping_name, None)
if mapping:
! self.fvars.update(mod.__dict__)
self.mapping = mapping
self.add_processor(loadhook(Reloader()))