[Python-checkins] r54166 - in python/trunk: Misc/NEWS setup.py

skip.montanaro python-checkins at python.org
Tue Mar 6 16:41:43 CET 2007


Author: skip.montanaro
Date: Tue Mar  6 16:41:38 2007
New Revision: 54166

Modified:
   python/trunk/Misc/NEWS
   python/trunk/setup.py
Log:
patch 1673619 - identify extension modules which cannot be built

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Tue Mar  6 16:41:38 2007
@@ -141,6 +141,9 @@
 Library
 -------
 
+- Patch #1673619: setup.py identifies extension modules it doesn't know how
+  to build and those it knows how to build but that fail to build.
+
 - Patch #912410: Replace HTML entity references for attribute values 
   in HTMLParser.
 

Modified: python/trunk/setup.py
==============================================================================
--- python/trunk/setup.py	(original)
+++ python/trunk/setup.py	Tue Mar  6 16:41:38 2007
@@ -91,10 +91,14 @@
 
 class PyBuildExt(build_ext):
 
+    def __init__(self, dist):
+        build_ext.__init__(self, dist)
+        self.failed = []
+
     def build_extensions(self):
 
         # Detect which modules should be compiled
-        self.detect_modules()
+        missing = self.detect_modules()
 
         # Remove modules that are present on the disabled list
         self.extensions = [ext for ext in self.extensions
@@ -178,6 +182,31 @@
 
         build_ext.build_extensions(self)
 
+        longest = max([len(e.name) for e in self.extensions])
+        if self.failed:
+            longest = max(longest, max([len(name) for name in self.failed]))
+
+        def print_three_column(lst):
+            lst.sort(cmp=str.lower)
+            # guarantee zip() doesn't drop anything
+            while len(lst) % 3:
+                lst.append("")
+            for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]):
+                print "%-*s   %-*s   %-*s" % (longest, e, longest, f,
+                                              longest, g)
+            print
+
+        if missing:
+            print
+            print "Failed to find the necessary bits to build these modules:"
+            print_three_column(missing)
+
+        if self.failed:
+            failed = self.failed[:]
+            print
+            print "Failed to build these modules:"
+            print_three_column(failed)
+
     def build_extension(self, ext):
 
         if ext.name == '_ctypes':
@@ -189,6 +218,7 @@
         except (CCompilerError, DistutilsError), why:
             self.announce('WARNING: building of extension "%s" failed: %s' %
                           (ext.name, sys.exc_info()[1]))
+            self.failed.append(ext.name)
             return
         # Workaround for Mac OS X: The Carbon-based modules cannot be
         # reliably imported into a command-line Python
@@ -209,6 +239,7 @@
         try:
             imp.load_dynamic(ext.name, ext_filename)
         except ImportError, why:
+            self.failed.append(ext.name)
             self.announce('*** WARNING: renaming "%s" since importing it'
                           ' failed: %s' % (ext.name, why), level=3)
             assert not self.inplace
@@ -234,6 +265,7 @@
             self.announce('*** WARNING: importing extension "%s" '
                           'failed with %s: %s' % (ext.name, exc_type, why),
                           level=3)
+            self.failed.append(ext.name)
 
     def get_platform(self):
         # Get value of sys.platform
@@ -299,6 +331,7 @@
             ]
         inc_dirs = self.compiler.include_dirs + ['/usr/include']
         exts = []
+        missing = []
 
         config_h = sysconfig.get_config_h_filename()
         config_h_vars = sysconfig.parse_config_h(open(config_h))
@@ -387,6 +420,8 @@
         # static Unicode character database
         if have_unicode:
             exts.append( Extension('unicodedata', ['unicodedata.c']) )
+        else:
+            missing.append('unicodedata')
         # access to ISO C locale support
         data = open('pyconfig.h').read()
         m = re.search(r"#s*define\s+WITH_LIBINTL\s+1\s*", data)
@@ -419,6 +454,11 @@
             if (config_h_vars.get('HAVE_GETSPNAM', False) or
                     config_h_vars.get('HAVE_GETSPENT', False)):
                 exts.append( Extension('spwd', ['spwdmodule.c']) )
+            else:
+                missing.append('spwd')
+        else:
+            missing.extend(['pwd', 'grp', 'spwd'])
+
         # select(2); not on ancient System V
         exts.append( Extension('select', ['selectmodule.c']) )
 
@@ -435,11 +475,15 @@
         # Memory-mapped files (also works on Win32).
         if platform not in ['atheos', 'mac']:
             exts.append( Extension('mmap', ['mmapmodule.c']) )
+        else:
+            missing.append('mmap')
 
         # Lance Ellinghaus's syslog module
         if platform not in ['mac']:
             # syslog daemon interface
             exts.append( Extension('syslog', ['syslogmodule.c']) )
+        else:
+            missing.append('syslog')
 
         # George Neville-Neil's timing module:
         # Deprecated in PEP 4 http://www.python.org/peps/pep-0004.html
@@ -466,6 +510,8 @@
             exts.append( Extension('imageop', ['imageop.c']) )
             # Read SGI RGB image files (but coded portably)
             exts.append( Extension('rgbimg', ['rgbimgmodule.c']) )
+        else:
+            missing.extend(['imageop', 'rgbimg'])
 
         # readline
         do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
@@ -503,6 +549,9 @@
                                    library_dirs=['/usr/lib/termcap'],
                                    extra_link_args=readline_extra_link_args,
                                    libraries=readline_libs) )
+        else:
+            missing.append('readline')
+
         if platform not in ['mac']:
             # crypt module.
 
@@ -511,6 +560,8 @@
             else:
                 libs = []
             exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) )
+        else:
+            missing.append('crypt')
 
         # CSV files
         exts.append( Extension('_csv', ['_csv.c']) )
@@ -543,6 +594,8 @@
                                    library_dirs = ssl_libs,
                                    libraries = ['ssl', 'crypto'],
                                    depends = ['socketmodule.h']), )
+        else:
+            missing.append('_ssl')
 
         # find out which version of OpenSSL we have
         openssl_ver = 0
@@ -576,6 +629,7 @@
                                    include_dirs = ssl_incs,
                                    library_dirs = ssl_libs,
                                    libraries = ['ssl', 'crypto']) )
+            missing.extend(['_sha', '_md5'])
         else:
             # The _sha module implements the SHA1 hash algorithm.
             exts.append( Extension('_sha', ['shamodule.c']) )
@@ -585,12 +639,14 @@
             exts.append( Extension('_md5',
                             sources = ['md5module.c', 'md5.c'],
                             depends = ['md5.h']) )
+            missing.append('_hashlib')
 
         if (openssl_ver < 0x00908000):
             # OpenSSL doesn't do these until 0.9.8 so we'll bring our own hash
             exts.append( Extension('_sha256', ['sha256module.c']) )
             exts.append( Extension('_sha512', ['sha512module.c']) )
-
+        else:
+            missing.extend(['_sha256', '_sha512'])
 
         # Modules that provide persistent dictionary-like semantics.  You will
         # probably want to arrange for at least one of them to be available on
@@ -743,6 +799,7 @@
             db_incs = None
             dblibs = []
             dblib_dir = None
+            missing.append('_bsddb')
 
         # The sqlite interface
         sqlite_setup_debug = False   # verbose debug prints from this script?
@@ -835,6 +892,8 @@
                                   runtime_library_dirs=sqlite_libdir,
                                   extra_link_args=sqlite_extra_link_args,
                                   libraries=["sqlite3",]))
+        else:
+            missing.append('_sqlite3')
 
         # Look for Berkeley db 1.85.   Note that it is built as a different
         # module name so it can be included even when later versions are
@@ -857,6 +916,10 @@
                                           libraries=libraries))
                 else:
                     exts.append(Extension('bsddb185', ['bsddbmodule.c']))
+            else:
+                missing.append('bsddb185')
+        else:
+            missing.append('bsddb185')
 
         # The standard Unix dbm module:
         if platform not in ['cygwin']:
@@ -882,11 +945,15 @@
                                        define_macros=[('HAVE_BERKDB_H',None),
                                                       ('DB_DBM_HSEARCH',None)],
                                        libraries=dblibs))
+            else:
+                missing.append('dbm')
 
         # Anthony Baxter's gdbm module.  GNU dbm(3) will require -lgdbm:
         if (self.compiler.find_library_file(lib_dirs, 'gdbm')):
             exts.append( Extension('gdbm', ['gdbmmodule.c'],
                                    libraries = ['gdbm'] ) )
+        else:
+            missing.append('gdbm')
 
         # Unix-only modules
         if platform not in ['mac', 'win32']:
@@ -895,6 +962,8 @@
             # Jeremy Hylton's rlimit interface
             if platform not in ['atheos']:
                 exts.append( Extension('resource', ['resource.c']) )
+            else:
+                missing.append('resource')
 
             # Sun yellow pages. Some systems have the functions in libc.
             if platform not in ['cygwin', 'atheos']:
@@ -904,6 +973,10 @@
                     libs = []
                 exts.append( Extension('nis', ['nismodule.c'],
                                        libraries = libs) )
+            else:
+                missing.append('nis')
+        else:
+            missing.extend(['nis', 'resource', 'termios'])
 
         # Curses support, requiring the System V version of curses, often
         # provided by the ncurses library.
@@ -932,13 +1005,16 @@
 
             exts.append( Extension('_curses', ['_cursesmodule.c'],
                                    libraries = curses_libs) )
+        else:
+            missing.append('_curses')
 
         # If the curses module is enabled, check for the panel module
         if (module_enabled(exts, '_curses') and
             self.compiler.find_library_file(lib_dirs, panel_library)):
             exts.append( Extension('_curses_panel', ['_curses_panel.c'],
                                    libraries = [panel_library] + curses_libs) )
-
+        else:
+            missing.append('_curses_panel')
 
         # Andrew Kuchling's zlib module.  Note that some versions of zlib
         # 1.1.3 have security problems.  See CERT Advisory CA-2002-07:
@@ -974,6 +1050,12 @@
                     exts.append( Extension('zlib', ['zlibmodule.c'],
                                            libraries = ['z'],
                                            extra_link_args = zlib_extra_link_args))
+                else:
+                    missing.append('zlib')
+            else:
+                missing.append('zlib')
+        else:
+            missing.append('zlib')
 
         # Gustavo Niemeyer's bz2 module.
         if (self.compiler.find_library_file(lib_dirs, 'bz2')):
@@ -984,6 +1066,8 @@
             exts.append( Extension('bz2', ['bz2module.c'],
                                    libraries = ['bz2'],
                                    extra_link_args = bz2_extra_link_args) )
+        else:
+            missing.append('bz2')
 
         # Interface to the Expat XML parser
         #
@@ -1021,14 +1105,20 @@
                                   include_dirs = [expatinc],
                                   sources = ['_elementtree.c'],
                                   ))
+        else:
+            missing.append('_elementtree')
 
         # Hye-Shik Chang's CJKCodecs modules.
         if have_unicode:
             exts.append(Extension('_multibytecodec',
                                   ['cjkcodecs/multibytecodec.c']))
             for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
-                exts.append(Extension('_codecs_' + loc,
+                exts.append(Extension('_codecs_%s' % loc,
                                       ['cjkcodecs/_codecs_%s.c' % loc]))
+        else:
+            missing.append('_multibytecodec')
+            for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
+                missing.append('_codecs_%s' % loc)
 
         # Dynamic loading module
         if sys.maxint == 0x7fffffff:
@@ -1036,6 +1126,10 @@
             dl_inc = find_file('dlfcn.h', [], inc_dirs)
             if (dl_inc is not None) and (platform not in ['atheos']):
                 exts.append( Extension('dl', ['dlmodule.c']) )
+            else:
+                missing.append('dl')
+        else:
+            missing.append('dl')
 
         # Thomas Heller's _ctypes module
         self.detect_ctypes(inc_dirs, lib_dirs)
@@ -1044,14 +1138,20 @@
         if platform == 'linux2':
             # Linux-specific modules
             exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
+        else:
+            missing.append('linuxaudiodev')
 
         if platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
                         'freebsd7'):
             exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
+        else:
+            missing.append('ossaudiodev')
 
         if platform == 'sunos5':
             # SunOS specific modules
             exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
+        else:
+            missing.append('sunaudiodev')
 
         if platform == 'darwin' and ("--disable-toolbox-glue" not in
                 sysconfig.get_config_var("CONFIG_ARGS")):
@@ -1140,6 +1240,11 @@
         # Call the method for detecting whether _tkinter can be compiled
         self.detect_tkinter(inc_dirs, lib_dirs)
 
+        if '_tkinter' not in [e.name for e in self.extensions]:
+            missing.append('_tkinter')
+
+        return missing
+
     def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
         # The _tkinter module, using frameworks. Since frameworks are quite
         # different the UNIX search logic is not sharable.


More information about the Python-checkins mailing list