]> granicus.if.org Git - python/commitdiff
Issue #7384: If the system readline library is linked against ncurses,
authorStefan Krah <stefan@bytereef.org>
Thu, 3 Jun 2010 12:39:50 +0000 (12:39 +0000)
committerStefan Krah <stefan@bytereef.org>
Thu, 3 Jun 2010 12:39:50 +0000 (12:39 +0000)
the curses module must be linked against ncurses as well. Otherwise it
is not safe to load both the readline and curses modules in an application.

Thanks Thomas Dickey for answering questions about ncurses/ncursesw
and readline!

Lib/test/test_curses.py
Misc/NEWS
setup.py

index 69271de847412e3b25efa33f386bce43db86bbdd..18d73fc79e86615c305cc3befd02ef927284ed9f 100644 (file)
@@ -21,11 +21,6 @@ requires('curses')
 curses = import_module('curses')
 curses.panel = import_module('curses.panel')
 
-# skip all these tests on FreeBSD: test_curses currently hangs the
-# FreeBSD buildbots, preventing other tests from running.  See issue
-# #7384.
-if 'freebsd' in sys.platform:
-    raise unittest.SkipTest('The curses module is broken on FreeBSD.  See http://bugs.python.org/issue7384.')
 
 # XXX: if newterm was supported we could use it instead of initscr and not exit
 term = os.environ.get('TERM')
index 9debe2cdc20b546d3579f8634728967a2a59763f..25b265b6c6e506d58b312c158733629a3a7b5096 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -89,6 +89,10 @@ Library
 Extension Modules
 -----------------
 
+- Issue #7384: If the system readline library is linked against ncurses,
+  the curses module must be linked against ncurses as well. Otherwise it
+  is not safe to load both the readline and curses modules in an application.
+
 - Issue #2810: Fix cases where the Windows registry API returns
   ERROR_MORE_DATA, requiring a re-try in order to get the complete result.
 
index 7294a1614c74c42dfa5f7f48f4b7195c9b463da7..cb65f46e349eea7acfca83013af4ebf523864606 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -588,6 +588,32 @@ class PyBuildExt(build_ext):
 
         # readline
         do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
+        readline_termcap_library = ""
+        curses_library = ""
+        # Determine if readline is already linked against curses or tinfo.
+        if do_readline and platform != 'darwin': # OS X does not have ldd.
+            fp = os.popen("ldd %s" % do_readline)
+            for ln in fp:
+                if 'curses' in ln:
+                    readline_termcap_library = re.sub(
+                        r'.*lib(n?cursesw?)\.so.*', r'\1', ln
+                    ).rstrip()
+                    break
+                if 'tinfo' in ln: # termcap interface split out from ncurses
+                    readline_termcap_library = 'tinfo'
+                    break
+            fp.close()
+        # Issue 7384: If readline is already linked against curses,
+        # use the same library for the readline and curses modules.
+        if 'curses' in readline_termcap_library:
+            curses_library = readline_termcap_library
+        elif self.compiler_obj.find_library_file(lib_dirs, 'ncursesw'):
+            curses_library = 'ncursesw'
+        elif self.compiler_obj.find_library_file(lib_dirs, 'ncurses'):
+            curses_library = 'ncurses'
+        elif self.compiler_obj.find_library_file(lib_dirs, 'curses'):
+            curses_library = 'curses'
+
         if platform == 'darwin':
             os_release = int(os.uname()[2].split('.')[0])
             dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
@@ -611,14 +637,10 @@ class PyBuildExt(build_ext):
                 readline_extra_link_args = ()
 
             readline_libs = ['readline']
-            if self.compiler.find_library_file(lib_dirs,
-                                                   'ncursesw'):
-                readline_libs.append('ncursesw')
-            elif self.compiler.find_library_file(lib_dirs,
-                                                     'ncurses'):
-                readline_libs.append('ncurses')
-            elif self.compiler.find_library_file(lib_dirs, 'curses'):
-                readline_libs.append('curses')
+            if readline_termcap_library:
+                pass # Issue 7384: Already linked against curses or tinfo.
+            elif curses_library:
+                readline_libs.append(curses_library)
             elif self.compiler.find_library_file(lib_dirs +
                                                      ['/usr/lib/termcap'],
                                                      'termcap'):
@@ -1187,19 +1209,15 @@ class PyBuildExt(build_ext):
         # Curses support, requiring the System V version of curses, often
         # provided by the ncurses library.
         panel_library = 'panel'
-        if (self.compiler.find_library_file(lib_dirs, 'ncursesw')):
-            curses_libs = ['ncursesw']
-            # Bug 1464056: If _curses.so links with ncursesw,
-            # _curses_panel.so must link with panelw.
-            panel_library = 'panelw'
-            exts.append( Extension('_curses', ['_cursesmodule.c'],
-                                   libraries = curses_libs) )
-        elif (self.compiler.find_library_file(lib_dirs, 'ncurses')):
-            curses_libs = ['ncurses']
+        if curses_library.startswith('ncurses'):
+            if curses_library == 'ncursesw':
+                # Bug 1464056: If _curses.so links with ncursesw,
+                # _curses_panel.so must link with panelw.
+                panel_library = 'panelw'
+            curses_libs = [curses_library]
             exts.append( Extension('_curses', ['_cursesmodule.c'],
                                    libraries = curses_libs) )
-        elif (self.compiler.find_library_file(lib_dirs, 'curses')
-              and platform != 'darwin'):
+        elif curses_library == 'curses' and platform != 'darwin':
                 # OSX has an old Berkeley curses, not good enough for
                 # the _curses module.
             if (self.compiler.find_library_file(lib_dirs, 'terminfo')):