[Zope-Checkins] SVN: Zope/branches/five-integration/setup.py add setup for Five and Zope3 packages

Brian Lloyd brian at zope.com
Tue Mar 15 10:04:43 EST 2005


Log message for revision 29474:
  add setup for Five and Zope3 packages

Changed:
  U   Zope/branches/five-integration/setup.py

-=-
Modified: Zope/branches/five-integration/setup.py
===================================================================
--- Zope/branches/five-integration/setup.py	2005-03-15 15:03:40 UTC (rev 29473)
+++ Zope/branches/five-integration/setup.py	2005-03-15 15:04:42 UTC (rev 29474)
@@ -1081,6 +1081,243 @@
     )
 
 
+
+# Zope 3 / Five integration layer support. Note that in addition to the
+# Five package itself, we also pull in several modules from the Zope 3
+# heirarchy: zope, persistent, transaction. Most of this is ripped from
+# the Zope 3 setup.py.
+
+from distutils import dir_util
+from distutils.command.build import build as buildcmd
+from distutils.command.build_ext import build_ext
+from distutils.command.install_lib import install_lib as installcmd
+from distutils.core import setup
+from distutils.dist import Distribution
+from distutils.extension import Extension
+
+if sys.version_info < (2, 3):
+    _setup = setup
+    def setup(**kwargs):
+        if kwargs.has_key("classifiers"):
+            del kwargs["classifiers"]
+        _setup(**kwargs)
+
+
+# A hack to determine if Extension objects support the `depends' keyword arg,
+# which only exists in Python 2.3's distutils.
+if not "depends" in Extension.__init__.func_code.co_varnames:
+    # If it doesn't, create a local replacement that removes depends from the
+    # kwargs before calling the regular constructor.
+    _Extension = Extension
+    class Extension(_Extension):
+        def __init__(self, name, sources, **kwargs):
+            if "depends" in kwargs:
+                del kwargs["depends"]
+            _Extension.__init__(self, name, sources, **kwargs)
+
+
+# We have to snoop for file types that distutils doesn't copy correctly when
+# doing a non-build-in-place.
+EXTS = ['.conf', '.css', '.dtd', '.gif', '.jpg', '.html',
+        '.js',   '.mo',  '.png', '.pt', '.stx', '.ref',
+        '.txt',  '.xml', '.zcml', '.mar', '.in', '.sample',
+        ]
+
+
+# This class serves multiple purposes.  It walks the file system looking for
+# auxiliary files that distutils doesn't install properly, and it actually
+# copies those files (when hooked into by distutils).  It also walks the file
+# system looking for candidate packages for distutils to install as normal.
+# The key here is that the package must have an __init__.py file.
+class Finder:
+    def __init__(self, exts, prefix):
+        self._files = []
+        self._pkgs = {}
+        self._exts = exts
+        # We're finding packages in lib/python in the source dir, but we're
+        # copying them directly under build/lib.<plat>.  So we need to lop off
+        # the prefix when calculating the package names from the file names.
+        self._plen = len(prefix)
+
+    def visit(self, ignore, dir, files):
+        for file in files:
+            # First see if this is one of the packages we want to add, or if
+            # we're really skipping this package.
+            if '__init__.py' in files:
+                aspkg = dir[self._plen:].replace(os.sep, '.')
+                self._pkgs[aspkg] = True
+            # Add any extra files we're interested in
+            base, ext = os.path.splitext(file)
+            if ext in self._exts:
+                self._files.append(os.path.join(dir, file))
+
+    def copy_files(self, cmd, outputbase):
+        for file in self._files:
+            dest = os.path.join(outputbase, file[self._plen:])
+            # Make sure the destination directory exists
+            dir = os.path.dirname(dest)
+            if not os.path.exists(dir):
+                dir_util.mkpath(dir)
+            cmd.copy_file(file, dest)
+
+    def get_packages(self):
+        return self._pkgs.keys()
+
+def remove_stale_bytecode(arg, dirname, names):
+    names = map(os.path.normcase, names)
+    for name in names:
+        if name.endswith(".pyc") or name.endswith(".pyo"):
+            srcname = name[:-1]
+            if srcname not in names:
+                fullname = os.path.join(dirname, name)
+                print "Removing stale bytecode file", fullname
+                os.unlink(fullname)
+
+# This bit uses the finder to crawl through the zope3 packages we need
+# and Do The Right Thing to arrange for setup for sub-packages.
+z3_packages = ['zope']
+packages = []
+
+for name in z3_packages:
+    basedir = os.path.join(PACKAGES_ROOT, name)    
+    finder = Finder(EXTS, basedir)
+    os.path.walk(basedir, finder.visit, None)
+    packages.extend(finder.get_packages())
+
+# Distutils hook classes
+class MyBuilder(buildcmd):
+    def run(self):
+        os.path.walk(os.curdir, remove_stale_bytecode, None)
+        buildcmd.run(self)
+        finder.copy_files(self, self.build_lib)
+
+class MyExtBuilder(build_ext):
+    # Override the default build_ext to remove stale bytecodes.
+    # Technically, removing bytecode has nothing to do with
+    # building extensions, but Zope's the build_ext -i variant
+    # is used to build Zope in place.
+    def run(self):
+        os.path.walk(os.curdir, remove_stale_bytecode, None)
+        build_ext.run(self)
+
+class MyLibInstaller(installcmd):
+    def run(self):
+        installcmd.run(self)
+        finder.copy_files(self, self.install_dir)
+
+class MyDistribution(Distribution):
+    # To control the selection of MyLibInstaller and MyPyBuilder, we
+    # have to set it into the cmdclass instance variable, set in
+    # Distribution.__init__().
+    def __init__(self, *attrs):
+        Distribution.__init__(self, *attrs)
+        self.cmdclass['build'] = MyBuilder
+        self.cmdclass['build_ext'] = MyExtBuilder
+        self.cmdclass['install_lib'] = MyLibInstaller
+
+
+# All Zope3 extension modules must be listed here.
+ext_modules = [
+##     Extension(name = 'persistent.cPersistence',
+##               include_dirs = ['persistent'],
+##               sources= ['persistent/cPersistence.c',
+##                         'persistent/ring.c'],
+##               depends = ['persistent/cPersistence.h',
+##                          'persistent/ring.h',
+##                          'persistent/ring.c']
+##               ),
+##     Extension(name = 'persistent.cPickleCache',
+##               include_dirs = ['persistent'],
+##               sources= ['persistent/cPickleCache.c',
+##                         'persistent/ring.c'],
+##                depends = ['persistent/cPersistence.h',
+##                          'persistent/ring.h',
+##                          'persistent/ring.c']
+##               ),
+##     Extension(name = 'persistent.TimeStamp',
+##               sources= ['persistent/TimeStamp.c']
+##               ),
+
+##    Extension("zope.i18nmessageid._zope_i18nmessageid_message",
+##              ["zope/i18nmessageid/_zope_i18nmessageid_message.c"],
+##              ),
+
+    Extension("zope.proxy._zope_proxy_proxy",
+              ["zope/proxy/_zope_proxy_proxy.c"],
+              include_dirs = ["zope/proxy"],
+              depends = ["zope/proxy/proxy.h"]),
+
+    Extension("zope.security._proxy", ["zope/security/_proxy.c"],
+              include_dirs = ["zope/proxy"],
+              depends = ["zope/proxy/proxy.h"]),
+
+    Extension("zope.security._zope_security_checker",
+              ["zope/security/_zope_security_checker.c"],
+              include_dirs = [],
+              depends = []),
+
+    Extension("zope.interface._zope_interface_coptimizations",
+              ["zope/interface/_zope_interface_coptimizations.c"]),
+
+    Extension("zope.hookable._zope_hookable",
+              ["zope/hookable/_zope_hookable.c"]),
+
+    Extension("zope.thread._zope_thread",
+              ["zope/thread/_zope_thread.c"]),
+
+    Extension("zope.app.container._zope_app_container_contained",
+              ["zope/app/container/_zope_app_container_contained.c"],
+              include_dirs = ["persistent",
+                              "zope/proxy",
+                              "zope/app/container"],
+              depends = [
+                 "persistent/cPersistence.h",
+                 "zope/proxy/_zope_proxy_proxy.c",
+                 ]),
+    
+    ]
+
+# We're using the module docstring as the distutils descriptions.
+doclines = __doc__.split("\n")
+
+setup(name="zope",
+      version="X3.0",
+      maintainer="Zope Corporation",
+      maintainer_email="zope3-dev at zope.org",
+      url = "http://dev.zope.org/Zope3/",
+      ext_modules = ext_modules,
+      # This doesn't work right at all
+      headers = ["persistent/cPersistence.h",
+                 "zope/proxy/proxy.h"],
+      scripts = [],
+      license = "http://www.zope.org/Resources/ZPL",
+      platforms = ["any"],
+      description = doclines[0],
+      long_description = "\n".join(doclines[2:]),
+      packages = packages,
+      #package_dir = {'': 'src'},
+      distclass = MyDistribution,
+      )
+
+
+setup(
+    name='Five',
+    author='Martijn Faassen',
+
+    packages=['Products.Five'],
+    data_files=[['Products/Five', ['Products/Five/*']],
+                ['Products/Five/demo', ['Products/Five/demo/*']],
+                ['Products/Five/doc', ['Products/ZReST/doc/*']],
+                ['Products/Five/skel', ['Products/ZReST/skel/*']],
+                ['Products/Five/tests', ['Products/ZReST/tests/*']],
+                ],
+    )
+
+
+
+
+
+
 # Call distutils setup with all lib/python packages and modules, and
 # flush setup_info.  Wondering why we run py_modules separately?  So am I.
 # Distutils won't let us specify packages and py_modules in the same call.



More information about the Zope-Checkins mailing list