Rev 4465: Rough fix for bug#385453. in file:///home/vila/src/bzr/bugs/385453-make-pyrex/

Vincent Ladeuil v.ladeuil+lp at free.fr
Tue Jun 23 17:34:48 BST 2009


At file:///home/vila/src/bzr/bugs/385453-make-pyrex/

------------------------------------------------------------
revno: 4465
revision-id: v.ladeuil+lp at free.fr-20090623163448-9kjrstq8vf7vdp7u
parent: v.ladeuil+lp at free.fr-20090623125803-vrrrs2n9zsgd4ce1
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 385453-make-pyrex
timestamp: Tue 2009-06-23 18:34:48 +0200
message:
  Rough fix for bug#385453.
  
  * setup.py: 
  Some cleanup and exit early if pyrex generated C files are not
  available.
  
  * bzrlib/tests/test_setup.py:
  (TestSetup.setUp): CleanupBetter protect the build dir.
  (TestSetupBuild): Start adding tests for the build step.
  (TestSetupInstall): Separate install step tests.
  
  * bzrlib/tests/__init__.py:
  (PyrexFeature): Most extensions use pyrex.
-------------- next part --------------
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2009-06-10 18:58:02 +0000
+++ b/bzrlib/tests/__init__.py	2009-06-23 16:34:48 +0000
@@ -3986,3 +3986,20 @@
             return result
 except ImportError:
     pass
+
+
+class _PyrexFeature(Feature):
+
+    def _probe(self):
+        try:
+            import Pyrex
+            return True
+        except ImportError:
+            return False
+
+    def feature_name(self):
+        return 'pyrex'
+
+PyrexFeature = _PyrexFeature()
+
+

=== modified file 'bzrlib/tests/test_setup.py'
--- a/bzrlib/tests/test_setup.py	2009-06-23 12:58:03 +0000
+++ b/bzrlib/tests/test_setup.py	2009-06-23 16:34:48 +0000
@@ -54,8 +54,34 @@
             self.addCleanup(os.rmdir, tmp_dir)
             tmp_build_dir = os.path.join(tmp_dir, 'build')
             os.rename(self.build_dir, tmp_build_dir)
-            # And restore it after the test
+            # And restore the original after the test...
             self.addCleanup(os.rename, tmp_build_dir, self.build_dir)
+        # Create a pristine build dir for the test
+        os.mkdir(self.build_dir)
+        self.addCleanup(self.rmtree, self.build_dir)
+
+    def run_setup(self, args, retcode=0):
+        args = [sys.executable, './setup.py', ] + args
+        self.log('source base directory: %s', self.source_dir)
+        self.log('args: %r', args)
+        p = subprocess.Popen(args,
+                             cwd=self.source_dir,
+                             stdout=self._log_file,
+                             stderr=self._log_file,
+                             )
+        s = p.communicate()
+        self.assertEqual(retcode, p.returncode,
+                         'invocation of %r failed' % args)
+
+    def rmtree(self, dir):
+        """Wrap osutils.rmtre
+
+        osutils.rmtree is lazy loaded and can't be used directly in cleanp hooks
+        """
+        osutils.rmtree(dir)
+
+
+class TestSetupInstall(TestSetup):
 
     def test_build_and_install(self):
         """ test cmd `python setup.py build`
@@ -63,6 +89,7 @@
         This tests that the build process and man generator run correctly.
         It also can catch new subdirectories that weren't added to setup.py.
         """
+        self.requireFeature(tests.PyrexFeature)
         if not os.path.isfile('setup.py'):
             raise TestSkipped('There is no setup.py file in current directory')
         try:
@@ -78,14 +105,7 @@
                               ' "python-dev"')
         self.log('test_build_and_install running in %s' % os.getcwd())
         install_dir = osutils.mkdtemp()
-        def rmtree(dir):
-            """Wrap osutils.rmtre
-            osutils.rmtree is lazy loaded and can't be used directly in cleanp
-            hooks
-            """
-            osutils.rmtree(dir)
-        self.addCleanup(rmtree, install_dir)
-        self.addCleanup(rmtree, self.build_dir)
+        self.addCleanup(self.rmtree, install_dir)
 
         self.run_setup(['clean'])
         # build is implied by install
@@ -93,15 +113,16 @@
         self.run_setup(['install', '--prefix', install_dir])
         self.run_setup(['clean'])
 
-    def run_setup(self, args):
-        args = [sys.executable, './setup.py', ] + args
-        self.log('source base directory: %s', self.source_dir)
-        self.log('args: %r', args)
-        p = subprocess.Popen(args,
-                             cwd=self.source_dir,
-                             stdout=self._log_file,
-                             stderr=self._log_file,
-                             )
-        s = p.communicate()
-        self.assertEqual(0, p.returncode,
-                         'invocation of %r failed' % args)
+
+class TestSetupBuild(TestSetup):
+
+    def test_with_pyrex(self):
+        self.requireFeature(tests.PyrexFeature)
+        self.run_setup(['build_ext'])
+
+    def test_without_pyrex(self):
+        if tests.PyrexFeature.available():
+            raise tests.TestSkipped('pyrex *is* installed')
+        self.run_setup(['build_ext'], retcode=1)
+
+

=== modified file 'setup.py'
--- a/setup.py	2009-06-22 12:52:39 +0000
+++ b/setup.py	2009-06-23 16:34:48 +0000
@@ -161,22 +161,27 @@
 from distutils import log
 from distutils.errors import CCompilerError, DistutilsPlatformError
 from distutils.extension import Extension
+
 ext_modules = []
+
 try:
     from Pyrex.Distutils import build_ext
 except ImportError:
     have_pyrex = False
-    # try to build the extension from the prior generated source.
+    # We will try to build the extension from the generated source.
+    from distutils.command.build_ext import build_ext
+else:
+    have_pyrex = True
+    from Pyrex.Compiler.Version import version as pyrex_version
+
+
+if not have_pyrex:
     print
     print ("The python package 'Pyrex' is not available."
            " If the .c files are available,")
     print ("they will be built,"
            " but modifying the .pyx files will not rebuild them.")
     print
-    from distutils.command.build_ext import build_ext
-else:
-    have_pyrex = True
-    from Pyrex.Compiler.Version import version as pyrex_version
 
 
 class build_ext_if_possible(build_ext):
@@ -221,15 +226,16 @@
 
 # Override the build_ext if we have Pyrex available
 command_classes['build_ext'] = build_ext_if_possible
-unavailable_files = []
+missing_pyrex_generated_files = []
 
 
 def add_pyrex_extension(module_name, libraries=None, extra_source=[]):
     """Add a pyrex module to build.
 
     This will use Pyrex to auto-generate the .c file if it is available.
-    Otherwise it will fall back on the .c file. If the .c file is not
-    available, it will warn, and not add anything.
+    Otherwise it will fall back on using the existing .c file. If the .c file
+    is not available, it will not add the extension and setup will abort
+    (whatever command is used).
 
     You can pass any extra options to Extension through kwargs. One example is
     'libraries = []'.
@@ -250,13 +256,14 @@
         source = [pyrex_name]
     else:
         if not os.path.isfile(c_name):
-            unavailable_files.append(c_name)
+            missing_pyrex_generated_files.append(c_name)
             return
         else:
             source = [c_name]
     source.extend(extra_source)
     ext_modules.append(Extension(module_name, source,
-        define_macros=define_macros, libraries=libraries))
+                                 define_macros=define_macros,
+                                 libraries=libraries))
 
 
 add_pyrex_extension('bzrlib._bencode_pyx')
@@ -292,12 +299,11 @@
                              ['bzrlib/_patiencediff_c.c']))
 
 
-if unavailable_files:
+if missing_pyrex_generated_files:
     print 'C extension(s) not found:'
-    print '   %s' % ('\n  '.join(unavailable_files),)
-    print 'The python versions will be used instead.'
+    print '  %s' % ('\n  '.join(missing_pyrex_generated_files),)
     print
-
+    exit(1)
 
 def get_tbzr_py2exe_info(includes, excludes, packages, console_targets,
                          gui_targets, data_files):



More information about the bazaar-commits mailing list