diff options
author | Brett Cannon <brett@python.org> | 2013-06-16 23:07:16 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2013-06-16 23:07:16 (GMT) |
commit | a269d821a11f2f84e6a211818ac1fdd76e0ab647 (patch) | |
tree | 38b313152fb1065f414362c8a6cd235bb85c9f9d /Lib | |
parent | 1d75382e81cb6f0cb22249e355cf0404102268ab (diff) | |
parent | c7b6c50f29fac4971e7271ac649ee3b7ef3deac7 (diff) | |
download | cpython-a269d821a11f2f84e6a211818ac1fdd76e0ab647.zip cpython-a269d821a11f2f84e6a211818ac1fdd76e0ab647.tar.gz cpython-a269d821a11f2f84e6a211818ac1fdd76e0ab647.tar.bz2 |
merge
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/codecs.py | 1 | ||||
-rw-r--r-- | Lib/subprocess.py | 43 | ||||
-rw-r--r-- | Lib/test/test_curses.py | 13 |
3 files changed, 39 insertions, 18 deletions
diff --git a/Lib/codecs.py b/Lib/codecs.py index 48d4c9c..6a6eb90 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -105,6 +105,7 @@ class Codec: Python will use the official U+FFFD REPLACEMENT CHARACTER for the builtin Unicode codecs on decoding and '?' on encoding. + 'surrogateescape' - replace with private codepoints U+DCnn. 'xmlcharrefreplace' - Replace with the appropriate XML character reference (only for encoding). 'backslashreplace' - Replace with backslashed escape sequences diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 689046e..a62d9a4 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -810,6 +810,7 @@ class Popen(object): if universal_newlines: self.stderr = io.TextIOWrapper(self.stderr) + self._closed_child_pipe_fds = False try: self._execute_child(args, executable, preexec_fn, close_fds, pass_fds, cwd, env, @@ -826,19 +827,21 @@ class Popen(object): except EnvironmentError: pass # Ignore EBADF or other errors. - # Make sure the child pipes are closed as well. - to_close = [] - if stdin == PIPE: - to_close.append(p2cread) - if stdout == PIPE: - to_close.append(c2pwrite) - if stderr == PIPE: - to_close.append(errwrite) - for fd in to_close: - try: - os.close(fd) - except EnvironmentError: - pass + if not self._closed_child_pipe_fds: + to_close = [] + if stdin == PIPE: + to_close.append(p2cread) + if stdout == PIPE: + to_close.append(c2pwrite) + if stderr == PIPE: + to_close.append(errwrite) + if hasattr(self, '_devnull'): + to_close.append(self._devnull) + for fd in to_close: + try: + os.close(fd) + except EnvironmentError: + pass raise @@ -1383,14 +1386,18 @@ class Popen(object): # be sure the FD is closed no matter what os.close(errpipe_write) - if p2cread != -1 and p2cwrite != -1: + # self._devnull is not always defined. + devnull_fd = getattr(self, '_devnull', None) + if p2cread != -1 and p2cwrite != -1 and p2cread != devnull_fd: os.close(p2cread) - if c2pwrite != -1 and c2pread != -1: + if c2pwrite != -1 and c2pread != -1 and c2pwrite != devnull_fd: os.close(c2pwrite) - if errwrite != -1 and errread != -1: + if errwrite != -1 and errread != -1 and errwrite != devnull_fd: os.close(errwrite) - if hasattr(self, '_devnull'): - os.close(self._devnull) + if devnull_fd is not None: + os.close(devnull_fd) + # Prevent a double close of these fds from __init__ on error. + self._closed_child_pipe_fds = True # Wait for exec to fail or succeed; possibly raising an # exception (limited in size) diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index e959622..76812b7 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -252,6 +252,18 @@ def test_userptr_without_set(stdscr): except curses.panel.error: pass +def test_userptr_memory_leak(stdscr): + w = curses.newwin(10, 10) + p = curses.panel.new_panel(w) + obj = object() + nrefs = sys.getrefcount(obj) + for i in range(100): + p.set_userptr(obj) + + p.set_userptr(None) + if sys.getrefcount(obj) != nrefs: + raise RuntimeError("set_userptr leaked references") + def test_resize_term(stdscr): if hasattr(curses, 'resizeterm'): lines, cols = curses.LINES, curses.COLS @@ -317,6 +329,7 @@ def main(stdscr): module_funcs(stdscr) window_funcs(stdscr) test_userptr_without_set(stdscr) + test_userptr_memory_leak(stdscr) test_resize_term(stdscr) test_issue6243(stdscr) test_unget_wch(stdscr) |