[FIX] Add workaround for setecho/getecho

This commit is contained in:
Benedek Racz 2020-01-09 11:10:43 +01:00
parent 1ae6ce32c1
commit 54515dffb4
2 changed files with 33 additions and 69 deletions

View File

@ -182,7 +182,7 @@ class ExpectTestCase (PexpectTestCase.PexpectTestCase):
self.assertEqual(index, 2, "index="+str(index)) self.assertEqual(index, 2, "index="+str(index))
p.sendline ('abcd') p.sendline ('abcd')
index = p.expect ([wexpect.TIMEOUT,'abcd','wxyz','1234',wexpect.EOF]) index = p.expect ([wexpect.TIMEOUT,'abcd','wxyz','1234',wexpect.EOF])
self.assertEqual(index, 1, "index="+str(index)+str(p)) self.assertEqual(index, 1, "index="+str(index))
p.sendline ('wxyz') p.sendline ('wxyz')
index = p.expect (['54321',wexpect.TIMEOUT,'abcd','wxyz','1234',wexpect.EOF]) index = p.expect (['54321',wexpect.TIMEOUT,'abcd','wxyz','1234',wexpect.EOF])
self.assertEqual(index, 3, "index="+str(index)) # Expect 'wxyz' self.assertEqual(index, 3, "index="+str(index)) # Expect 'wxyz'

View File

@ -629,31 +629,14 @@ class spawn_windows ():
timeout = end_time - time.time() timeout = end_time - time.time()
time.sleep(0.1) time.sleep(0.1)
def getecho (self): # pragma: no cover def getecho (self):
faulty_method_warning = '''
################################## WARNING ##################################
setecho() is faulty!
Please contact me and report it at
https://github.com/raczben/wexpect/issues/18 if you use it.
################################## WARNING ##################################
'''
warnings.warn(faulty_method_warning, DeprecationWarning)
"""This returns the terminal echo mode. This returns True if echo is """This returns the terminal echo mode. This returns True if echo is
on or False if echo is off. Child applications that are expecting you on or False if echo is off. Child applications that are expecting you
to enter a password often set ECHO False. See waitnoecho().""" to enter a password often set ECHO False. See waitnoecho()."""
return self.wtty.getecho() return self.wtty.getecho()
def setecho (self, state): # pragma: no cover def setecho (self, state):
faulty_method_warning = '''
################################## WARNING ##################################
setecho() is faulty!
Please contact me and report it at
https://github.com/raczben/wexpect/issues/18 if you use it.
################################## WARNING ##################################
'''
warnings.warn(faulty_method_warning, DeprecationWarning)
"""This sets the terminal echo mode on or off.""" """This sets the terminal echo mode on or off."""
self.wtty.setecho(state) self.wtty.setecho(state)
@ -1198,6 +1181,7 @@ class Wtty:
# We need a timeout for connecting to the child process # We need a timeout for connecting to the child process
self.timeout = timeout self.timeout = timeout
self.totalRead = 0 self.totalRead = 0
self.local_echo = False
def spawn(self, command, args=[], env=None): def spawn(self, command, args=[], env=None):
"""Spawns spawner.py with correct arguments.""" """Spawns spawner.py with correct arguments."""
@ -1399,21 +1383,28 @@ class Wtty:
records = [self.createKeyEvent(c) for c in str(s)] records = [self.createKeyEvent(c) for c in str(s)]
if not self.__consout: if not self.__consout:
return "" return ""
# Store the current cursor position to hide characters in local echo disabled mode (workaround).
consinfo = self.__consout.GetConsoleScreenBufferInfo() consinfo = self.__consout.GetConsoleScreenBufferInfo()
startCo = consinfo['CursorPosition'] startCo = consinfo['CursorPosition']
# Send the string to console input
wrote = self.__consin.WriteConsoleInput(records) wrote = self.__consin.WriteConsoleInput(records)
# Wait until all input has been recorded by the console.
ts = time.time() ts = time.time()
while self.__consin and self.__consin.PeekConsoleInput(8) != (): while self.__consin.PeekConsoleInput(8) != ():
if time.time() > ts + len(s) * .05: if time.time() > ts + len(s) * .1 + .5:
break break
time.sleep(.05) time.sleep(.05)
if self.__consout:
# Hide characters in local echo disabled mode (workaround).
if not self.local_echo:
self.__consout.FillConsoleOutputCharacter(screenbufferfillchar, len(s), startCo) self.__consout.FillConsoleOutputCharacter(screenbufferfillchar, len(s), startCo)
except:
return wrote
finally:
self.switchBack() self.switchBack()
raise
self.switchBack()
return wrote
def getCoord(self, offset): def getCoord(self, offset):
"""Converts an offset to a point represented as a tuple.""" """Converts an offset to a point represented as a tuple."""
@ -1614,50 +1605,23 @@ class Wtty:
#log('refreshConsole: cursorPos %s' % cursorPos) #log('refreshConsole: cursorPos %s' % cursorPos)
def setecho(self, state): # pragma: no cover def setecho(self, state):
faulty_method_warning = ''' """Sets the echo mode of the child console.
################################## WARNING ################################## This is a workaround of the setecho. The original GetConsoleMode() / SetConsoleMode()
setecho() is faulty! methods didn't work. See git history for the concrete implementation.
Please contact me and report it at 2020.01.09 raczben
https://github.com/raczben/wexpect/issues/18 if you use it. """
################################## WARNING ##################################
'''
warnings.warn(faulty_method_warning, DeprecationWarning)
"""Sets the echo mode of the child console."""
self.switchTo()
try:
mode = self.__consin.GetConsoleMode()
if state:
mode |= 0x0004
else:
mode &= ~0x0004
self.__consin.SetConsoleMode(mode)
except:
self.switchBack()
raise
self.switchBack()
def getecho(self): # pragma: no cover self.local_echo = state
faulty_method_warning = '''
################################## WARNING ##################################
getecho() is faulty!
Please contact me and report it at
https://github.com/raczben/wexpect/issues/18 if you use it.
################################## WARNING ##################################
'''
warnings.warn(faulty_method_warning, DeprecationWarning)
"""Returns the echo mode of the child console."""
self.switchTo() def getecho(self):
try: """Returns the echo mode of the child console.
mode = self.__consin.GetConsoleMode() This is a workaround of the getecho. The original GetConsoleMode() / SetConsoleMode()
ret = (mode & 0x0004) > 0 methods didn't work. See git history for the concrete implementation.
finally: 2020.01.09 raczben
self.switchBack() """
return ret
return self.local_echo
def getwinsize(self): def getwinsize(self):
"""Returns the size of the child console as a tuple of """Returns the size of the child console as a tuple of