diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index 69271de8474..18d73fc79e8 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -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') diff --git a/Misc/NEWS b/Misc/NEWS index 9debe2cdc20..25b265b6c6e 100644 --- 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. diff --git a/setup.py b/setup.py index 7294a1614c7..cb65f46e349 100644 --- 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' + 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, 'ncurses')): - curses_libs = ['ncurses'] - 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')):