[Python-checkins] r72585 - in python/trunk: Lib/distutils/command/build_ext.py Lib/distutils/tests/test_build_ext.py Misc/NEWS

tarek.ziade python-checkins at python.org
Tue May 12 19:07:15 CEST 2009


Author: tarek.ziade
Date: Tue May 12 19:07:14 2009
New Revision: 72585

Log:
fixed #5977: distutils build_ext.get_outputs was not using the inplace option

Modified:
   python/trunk/Lib/distutils/command/build_ext.py
   python/trunk/Lib/distutils/tests/test_build_ext.py
   python/trunk/Misc/NEWS

Modified: python/trunk/Lib/distutils/command/build_ext.py
==============================================================================
--- python/trunk/Lib/distutils/command/build_ext.py	(original)
+++ python/trunk/Lib/distutils/command/build_ext.py	Tue May 12 19:07:14 2009
@@ -311,38 +311,38 @@
 
         # Setup the CCompiler object that we'll use to do all the
         # compiling and linking
-        self.compiler = new_compiler(compiler=self.compiler,
+        self._compiler = new_compiler(compiler=self.compiler,
                                      verbose=self.verbose,
                                      dry_run=self.dry_run,
                                      force=self.force)
-        customize_compiler(self.compiler)
+        customize_compiler(self._compiler)
         # If we are cross-compiling, init the compiler now (if we are not
         # cross-compiling, init would not hurt, but people may rely on
         # late initialization of compiler even if they shouldn't...)
         if os.name == 'nt' and self.plat_name != get_platform():
-            self.compiler.initialize(self.plat_name)
+            self._compiler.initialize(self.plat_name)
 
         # And make sure that any compile/link-related options (which might
         # come from the command-line or from the setup script) are set in
         # that CCompiler object -- that way, they automatically apply to
         # all compiling and linking done here.
         if self.include_dirs is not None:
-            self.compiler.set_include_dirs(self.include_dirs)
+            self._compiler.set_include_dirs(self.include_dirs)
         if self.define is not None:
             # 'define' option is a list of (name,value) tuples
             for (name, value) in self.define:
-                self.compiler.define_macro(name, value)
+                self._compiler.define_macro(name, value)
         if self.undef is not None:
             for macro in self.undef:
-                self.compiler.undefine_macro(macro)
+                self._compiler.undefine_macro(macro)
         if self.libraries is not None:
-            self.compiler.set_libraries(self.libraries)
+            self._compiler.set_libraries(self.libraries)
         if self.library_dirs is not None:
-            self.compiler.set_library_dirs(self.library_dirs)
+            self._compiler.set_library_dirs(self.library_dirs)
         if self.rpath is not None:
-            self.compiler.set_runtime_library_dirs(self.rpath)
+            self._compiler.set_runtime_library_dirs(self.rpath)
         if self.link_objects is not None:
-            self.compiler.set_link_objects(self.link_objects)
+            self._compiler.set_link_objects(self.link_objects)
 
         # Now actually compile and link everything.
         self.build_extensions()
@@ -446,9 +446,7 @@
         # "build" tree.
         outputs = []
         for ext in self.extensions:
-            fullname = self.get_ext_fullname(ext.name)
-            outputs.append(os.path.join(self.build_lib,
-                                        self.get_ext_filename(fullname)))
+            outputs.append(self.get_ext_fullpath(ext.name))
         return outputs
 
     def build_extensions(self):
@@ -473,24 +471,9 @@
                    "a list of source filenames") % ext.name
         sources = list(sources)
 
-        fullname = self.get_ext_fullname(ext.name)
-        if self.inplace:
-            # ignore build-lib -- put the compiled extension into
-            # the source tree along with pure Python modules
-
-            modpath = string.split(fullname, '.')
-            package = string.join(modpath[0:-1], '.')
-            base = modpath[-1]
-
-            build_py = self.get_finalized_command('build_py')
-            package_dir = build_py.get_package_dir(package)
-            ext_filename = os.path.join(package_dir,
-                                        self.get_ext_filename(base))
-        else:
-            ext_filename = os.path.join(self.build_lib,
-                                        self.get_ext_filename(fullname))
+        ext_path = self.get_ext_fullpath(ext.name)
         depends = sources + ext.depends
-        if not (self.force or newer_group(depends, ext_filename, 'newer')):
+        if not (self.force or newer_group(depends, ext_path, 'newer')):
             log.debug("skipping '%s' extension (up-to-date)", ext.name)
             return
         else:
@@ -521,13 +504,13 @@
         for undef in ext.undef_macros:
             macros.append((undef,))
 
-        objects = self.compiler.compile(sources,
-                                        output_dir=self.build_temp,
-                                        macros=macros,
-                                        include_dirs=ext.include_dirs,
-                                        debug=self.debug,
-                                        extra_postargs=extra_args,
-                                        depends=ext.depends)
+        objects = self._compiler.compile(sources,
+                                         output_dir=self.build_temp,
+                                         macros=macros,
+                                         include_dirs=ext.include_dirs,
+                                         debug=self.debug,
+                                         extra_postargs=extra_args,
+                                         depends=ext.depends)
 
         # XXX -- this is a Vile HACK!
         #
@@ -548,10 +531,10 @@
         extra_args = ext.extra_link_args or []
 
         # Detect target language, if not provided
-        language = ext.language or self.compiler.detect_language(sources)
+        language = ext.language or self._compiler.detect_language(sources)
 
-        self.compiler.link_shared_object(
-            objects, ext_filename,
+        self._compiler.link_shared_object(
+            objects, ext_path,
             libraries=self.get_libraries(ext),
             library_dirs=ext.library_dirs,
             runtime_library_dirs=ext.runtime_library_dirs,
@@ -653,8 +636,28 @@
 
     # -- Name generators -----------------------------------------------
     # (extension names, filenames, whatever)
+    def get_ext_fullpath(self, ext_name):
+        """Returns the path of the filename for a given extension.
+
+        The file is located in `build_lib` or directly in the package
+        (inplace option).
+        """
+        if self.inplace:
+            fullname = self.get_ext_fullname(ext_name)
+            modpath = fullname.split('.')
+            package = '.'.join(modpath[0:-1])
+            base = modpath[-1]
+            build_py = self.get_finalized_command('build_py')
+            package_dir = os.path.abspath(build_py.get_package_dir(package))
+            return os.path.join(package_dir, base)
+        else:
+            filename = self.get_ext_filename(ext_name)
+            return os.path.join(self.build_lib, filename)
+
+    def get_ext_fullname(self, ext_name):
+        """Returns the fullname of a given extension name.
 
-    def get_ext_fullname (self, ext_name):
+        Adds the `package.` prefix"""
         if self.package is None:
             return ext_name
         else:
@@ -701,7 +704,7 @@
         # Append '_d' to the python import library on debug builds.
         if sys.platform == "win32":
             from distutils.msvccompiler import MSVCCompiler
-            if not isinstance(self.compiler, MSVCCompiler):
+            if not isinstance(self._compiler, MSVCCompiler):
                 template = "python%d%d"
                 if self.debug:
                     template = template + '_d'

Modified: python/trunk/Lib/distutils/tests/test_build_ext.py
==============================================================================
--- python/trunk/Lib/distutils/tests/test_build_ext.py	(original)
+++ python/trunk/Lib/distutils/tests/test_build_ext.py	Tue May 12 19:07:14 2009
@@ -113,7 +113,7 @@
             else:
                 _config_vars['Py_ENABLE_SHARED'] = old_var
 
-        # make sur we get some lobrary dirs under solaris
+        # make sure we get some library dirs under solaris
         self.assert_(len(cmd.library_dirs) > 0)
 
     def test_user_site(self):
@@ -282,13 +282,50 @@
         cmd.ensure_finalized()
         self.assertEquals(cmd.get_source_files(), ['xxx'])
 
+    def test_compiler_option(self):
+        # cmd.compiler is an option and
+        # should not be overriden by a compiler instance
+        # when the command is run
+        dist = Distribution()
+        cmd = build_ext(dist)
+        cmd.compiler = 'unix'
+        cmd.ensure_finalized()
+        cmd.run()
+        self.assertEquals(cmd.compiler, 'unix')
+
     def test_get_outputs(self):
-        modules = [Extension('foo', ['xxx'], optional=False)]
-        dist = Distribution({'name': 'xx', 'ext_modules': modules})
+        tmp_dir = self.mkdtemp()
+        c_file = os.path.join(tmp_dir, 'foo.c')
+        self.write_file(c_file, '')
+        ext = Extension('foo', [c_file], optional=False)
+        dist = Distribution({'name': 'xx',
+                             'ext_modules': [ext]})
         cmd = build_ext(dist)
         cmd.ensure_finalized()
         self.assertEquals(len(cmd.get_outputs()), 1)
 
+        if os.name == "nt":
+            cmd.debug = sys.executable.endswith("_d.exe")
+
+        cmd.build_lib = os.path.join(self.tmp_dir, 'build')
+        cmd.build_temp = os.path.join(self.tmp_dir, 'tempt')
+
+        # issue #5977 : distutils build_ext.get_outputs
+        # returns wrong result with --inplace
+        cmd.inplace = 1
+        cmd.run()
+        so_file = cmd.get_outputs()[0]
+        self.assert_(os.path.exists(so_file))
+        so_dir = os.path.dirname(so_file)
+        self.assertEquals(so_dir, os.getcwd())
+
+        cmd.inplace = 0
+        cmd.run()
+        so_file = cmd.get_outputs()[0]
+        self.assert_(os.path.exists(so_file))
+        so_dir = os.path.dirname(so_file)
+        self.assertEquals(so_dir, cmd.build_lib)
+
 def test_suite():
     src = _get_source_filename()
     if not os.path.exists(src):

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Tue May 12 19:07:14 2009
@@ -291,6 +291,9 @@
 Library
 -------
 
+- Issue #5977: distutils build_ext.get_outputs was not taking into account the
+  inplace option. Initial patch by kxroberto.
+
 - Issue #5984: distutils.command.build_ext.check_extensions_list checks were broken
   for old-style extensions.
 


More information about the Python-checkins mailing list