Hello,
this patch (committed as r239) fixes ticket #32 (SQLObject failed to be
packaged under Windows). As explained in Python 2.4 release notes
(http://www.python.org/2.4.2/NEWS.html):
==================================================
When importing a module M raises an exception, Python no longer leaves M in
sys.modules. Before 2.4a2 it did, and a subsequent import of M would
succeed, picking up a module object from sys.modules reflecting as much of
the initialization of M as completed before the exception was raised.
Subsequent imports got no indication that M was in a partially- initialized
state, and the importers could get into arbitrarily bad trouble as a result
(the M they got was in an unintended state, arbitrarily far removed from M's
author's intent). Now subsequent imports of M will continue raising
exceptions (but if, for example, the source code for M is edited between
import attempts, then perhaps later attempts will succeed, or raise a
different exception).
This can break existing code, but in such cases the code was probably
working before by accident. In the Python source, the only case of breakage
discovered was in a test accidentally relying on a damaged module remaining
in sys.modules. Cases are also known where tests deliberately provoking
import errors remove damaged modules from sys.modules themselves, and such
tests will break now if they do an unconditional del sys.modules[M].
==================================================
When PYTHONCASEOK=1, SQLObject relied on this by accident to work. In fact,
SQLObject is broken with Python 2.3 when PYTHONCASEOK=1. The problem here is
that nobody in the world ever sets PYTHONCASEOK=1, but alas PyInstaller's
import hooks works exactly that way. This is alread documented as a bug in
ticket #1.
The fix here is to do the right thing and cleanup sys.modules. To be 100%
compatible, we do this only with Python 2.4 and above. I hope this is a good
enough stop-gap for now.
It looks like Ticket #1 is our main source of problems. I should have that
fixed ASAP.
--
Giovanni Bajo
Index: iu.py
===================================================================
--- iu.py (revision 227)
+++ iu.py (working copy)
@@ -28,6 +28,11 @@
import imp
import marshal
+try:
+ py_version = sys.version_info
+except AttributeError:
+ py_version = (1,5)
+
#=======================Owners==========================#
# An Owner does imports from a particular piece of turf
# That is, there's an Owner for each thing on sys.path
@@ -386,10 +391,22 @@
if hasattr(mod, '__co__'):
co = mod.__co__
del mod.__co__
- if reload:
- exec co in sys.modules[fqname].__dict__
- else:
- exec co in mod.__dict__
+ try:
+ if reload:
+ exec co in sys.modules[fqname].__dict__
+ else:
+ exec co in mod.__dict__
+ except:
+ # In Python 2.4 and above, sys.modules is left clean
+ # after a broken import. We need to do the same to
+ # achieve perfect compatibility (see ticket #32).
+ if py_version >= (2,4,0):
+ # FIXME: how can we recover from a broken reload()?
+ # Should we save the mod dict and restore it in case
+ # of failure?
+ if not reload:
+ del sys.modules[fqname]
+ raise
if fqname == 'thread' and not self.threaded:
## print "thread detected!"
self.setThreaded()
_______________________________________________
PyInstaller mailing list
[email protected]
http://lists.hpcf.upr.edu/mailman/listinfo/pyinstaller