[Checkins] SVN: zc.buildout/branches/gary-4/src/zc/buildout/ change the way that we identify namespace packages and better comment the code, per review.
Gary Poster
gary.poster at canonical.com
Mon Feb 22 18:12:27 EST 2010
Log message for revision 109331:
change the way that we identify namespace packages and better comment the code, per review.
Changed:
U zc.buildout/branches/gary-4/src/zc/buildout/easy_install.py
U zc.buildout/branches/gary-4/src/zc/buildout/tests.py
-=-
Modified: zc.buildout/branches/gary-4/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/branches/gary-4/src/zc/buildout/easy_install.py 2010-02-22 23:12:24 UTC (rev 109330)
+++ zc.buildout/branches/gary-4/src/zc/buildout/easy_install.py 2010-02-22 23:12:26 UTC (rev 109331)
@@ -163,24 +163,47 @@
#
# The namespace packages installed in site-packages with
# --single-version-externally-managed use a mechanism that cause them to
-# be processed when site.py is imported. Simply starting Python with -S
-# addresses the problem in Python 2.4 and 2.5, but Python 2.6's distutils
-# imports a value from the site module, so we unfortunately have to do more
-# drastic surgery in the _easy_install_cmd code below. The changes to
-# sys.modules specifically try to only remove namespace modules installed by
-# the --single-version-externally-managed code.
+# be processed when site.py is imported (see
+# http://mail.python.org/pipermail/distutils-sig/2009-May/011730.html
+# for another description of the problem). Simply starting Python with
+# -S addresses the problem in Python 2.4 and 2.5, but Python 2.6's
+# distutils imports a value from the site module, so we unfortunately
+# have to do more drastic surgery in the _easy_install_cmd code below.
+#
+# Here's an example of the .pth files created by setuptools when using that
+# flag:
+#
+# import sys,new,os;
+# p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('<NAMESPACE>',));
+# ie = os.path.exists(os.path.join(p,'__init__.py'));
+# m = not ie and sys.modules.setdefault('<NAMESPACE>',new.module('<NAMESPACE>'));
+# mp = (m or []) and m.__dict__.setdefault('__path__',[]);
+# (p not in mp) and mp.append(p)
+#
+# The code, below, then, runs under -S, indicating that site.py should
+# not be loaded initially. It gets the initial sys.path under these
+# circumstances, and then imports site (because Python 2.6's distutils
+# will want it, as mentioned above). It then reinstates the old sys.path
+# value. Then it removes namespace packages (created by the setuptools
+# code above) from sys.modules. It identifies namespace packages by
+# iterating over every loaded module. It first looks if there is a
+# __path__, so it is a package; and then it sees if that __path__ does
+# not have an __init__.py. (Note that PEP 382,
+# http://www.python.org/dev/peps/pep-0382, makes it possible to have a
+# namespace package that has an __init__.py, but also should make it
+# unnecessary for site.py to preprocess these packages, so it should be
+# fine, as far as can be guessed as of this writing.) Finally, it
+# imports easy_install and runs it.
_easy_install_cmd = _safe_arg('''\
-import sys; \
-p = sys.path[:]; \
-m = sys.modules.keys(); \
-import site; \
-sys.path[:] = p; \
-m_attrs = set(('__builtins__', '__file__', '__package__', '__path__')); \
-match = set(('__path__',)); \
+import sys,os;\
+p = sys.path[:];\
+import site;\
+sys.path[:] = p;\
[sys.modules.pop(k) for k, v in sys.modules.items()\
- if k not in m and v and m_attrs.intersection(dir(v)) == match]; \
-from setuptools.command.easy_install import main; \
+ if hasattr(v, '__path__') and len(v.__path__)==1 and\
+ not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))];\
+from setuptools.command.easy_install import main;\
main()''')
Modified: zc.buildout/branches/gary-4/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/branches/gary-4/src/zc/buildout/tests.py 2010-02-22 23:12:24 UTC (rev 109330)
+++ zc.buildout/branches/gary-4/src/zc/buildout/tests.py 2010-02-22 23:12:26 UTC (rev 109331)
@@ -1992,8 +1992,9 @@
We already have: tellmy.version 1.0
<BLANKLINE>
-The bugfix was simply to add Python's "-S" option when calling
-easyinstall (see zc.buildout.easy_install.Installer._call_easy_install).
+You can see the copiously commented fix for this in easy_install.py (see
+zc.buildout.easy_install.Installer._call_easy_install and particularly
+the comment leading up to zc.buildout.easy_install._easy_install_cmd).
Now the install works correctly, as seen here.
>>> print system(buildout)
More information about the checkins
mailing list