Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d7cc1bd

Browse files
author
Michael W. Hudson
committed
Fix
[ 924301 ] A leak case with cmd.py & readline & exception by ensuring that the readline completion function is always reset even in the case of an exception being raised. As a bonus, this makes the documentation for pre & postloop accurate again.
1 parent 1f34eb1 commit d7cc1bd

1 file changed

Lines changed: 44 additions & 39 deletions

File tree

Lib/cmd.py

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -107,32 +107,49 @@ def cmdloop(self, intro=None):
107107
"""
108108

109109
self.preloop()
110-
if intro is not None:
111-
self.intro = intro
112-
if self.intro:
113-
self.stdout.write(str(self.intro)+"\n")
114-
stop = None
115-
while not stop:
116-
if self.cmdqueue:
117-
line = self.cmdqueue.pop(0)
118-
else:
119-
if self.use_rawinput:
120-
try:
121-
line = raw_input(self.prompt)
122-
except EOFError:
123-
line = 'EOF'
110+
if self.use_rawinput and self.completekey:
111+
try:
112+
import readline
113+
self.old_completer = readline.get_completer()
114+
readline.set_completer(self.complete)
115+
readline.parse_and_bind(self.completekey+": complete")
116+
except ImportError:
117+
pass
118+
try:
119+
if intro is not None:
120+
self.intro = intro
121+
if self.intro:
122+
self.stdout.write(str(self.intro)+"\n")
123+
stop = None
124+
while not stop:
125+
if self.cmdqueue:
126+
line = self.cmdqueue.pop(0)
124127
else:
125-
self.stdout.write(self.prompt)
126-
self.stdout.flush()
127-
line = self.stdin.readline()
128-
if not len(line):
129-
line = 'EOF'
128+
if self.use_rawinput:
129+
try:
130+
line = raw_input(self.prompt)
131+
except EOFError:
132+
line = 'EOF'
130133
else:
131-
line = line[:-1] # chop \n
132-
line = self.precmd(line)
133-
stop = self.onecmd(line)
134-
stop = self.postcmd(stop, line)
135-
self.postloop()
134+
self.stdout.write(self.prompt)
135+
self.stdout.flush()
136+
line = self.stdin.readline()
137+
if not len(line):
138+
line = 'EOF'
139+
else:
140+
line = line[:-1] # chop \n
141+
line = self.precmd(line)
142+
stop = self.onecmd(line)
143+
stop = self.postcmd(stop, line)
144+
self.postloop()
145+
finally:
146+
if self.use_rawinput and self.completekey:
147+
try:
148+
import readline
149+
readline.set_completer(self.old_completer)
150+
except ImportError:
151+
pass
152+
136153

137154
def precmd(self, line):
138155
"""Hook method executed just before the command line is
@@ -147,27 +164,15 @@ def postcmd(self, stop, line):
147164

148165
def preloop(self):
149166
"""Hook method executed once when the cmdloop() method is called."""
150-
if self.completekey:
151-
try:
152-
import readline
153-
self.old_completer = readline.get_completer()
154-
readline.set_completer(self.complete)
155-
readline.parse_and_bind(self.completekey+": complete")
156-
except ImportError:
157-
pass
167+
pass
158168

159169
def postloop(self):
160170
"""Hook method executed once when the cmdloop() method is about to
161171
return.
162172
163173
"""
164-
if self.completekey:
165-
try:
166-
import readline
167-
readline.set_completer(self.old_completer)
168-
except ImportError:
169-
pass
170-
174+
pass
175+
171176
def parseline(self, line):
172177
"""Parse the line into a command name and a string containing
173178
the arguments. Returns a tuple containing (command, args, line).

0 commit comments

Comments
 (0)