Fix pipe name suffix, sync from origin dev

This commit is contained in:
clearml
2024-11-14 11:27:23 +02:00
parent aa03a0785e
commit 44cf524366
3 changed files with 31 additions and 24 deletions

View File

@@ -30,9 +30,9 @@ def main():
parser.add_argument('--port', type=int, help=
"If the console reader class is SpawnSocket, this option specifies the "
"socket's port.", default=False)
parser.add_argument('--pipe_file_name', type=str, help=
parser.add_argument('--pipe_file_suffix', type=str, help=
"If the console reader class is SpawnPipe, this option specifies the "
"pipe's name.", default=None)
"pipe's name suffix.", default=None)
try:
args = parser.parse_args()
@@ -51,7 +51,8 @@ def main():
command = wexpect_util.join_args(args.command)
cons = conole_reader_class(
path=command, host_pid=args.host_pid, codepage=args.codepage, port=args.port, pipe_file_name=args.pipe_file_name,
path=command, host_pid=args.host_pid, codepage=args.codepage, port=args.port,
pipe_file_suffix=args.pipe_file_suffix,
window_size_x=args.window_size_x, window_size_y=args.window_size_y,
buffer_size_x=args.buffer_size_x, buffer_size_y=args.buffer_size_y,
local_echo=wexpect_util.str2bool(args.local_echo), interact=wexpect_util.str2bool(args.interact))

View File

@@ -77,6 +77,7 @@ class ConsoleReaderBase:
self.enable_signal_chars = True
self.timeout = 30
self.child_exitstatus = None
self.pipe_file_suffix = kwargs.get("pipe_file_suffix")
logger.info(f'ConsoleReader started. location {os.path.abspath(__file__)}')
@@ -97,7 +98,10 @@ class ConsoleReaderBase:
logger.info('Spawning %s' % path)
try:
self.initConsole()
self.child_process = psutil.Popen(path)
si = win32process.GetStartupInfo()
self.__childProcess, _, self.child_pid, self.child_tid = win32process.CreateProcess(
None, path, None, None, False, 0, None, None, si)
self.child_process = psutil.Process(self.child_pid)
logger.info(f'Child pid: {self.child_pid} Console pid: {self.console_pid}')
@@ -134,12 +138,10 @@ class ConsoleReaderBase:
logger.info('Host process has been died.')
return
try:
self.child_exitstatus = self.child_process.wait(0)
self.child_exitstatus = win32process.GetExitCodeProcess(self.__childProcess)
if self.child_exitstatus != win32con.STILL_ACTIVE:
logger.info(f'Child finished with code: {self.child_exitstatus}')
return
except psutil.TimeoutExpired:
pass
consinfo = self.consout.GetConsoleScreenBufferInfo()
cursorPos = consinfo['CursorPosition']
@@ -514,12 +516,11 @@ class ConsoleReaderPipe(ConsoleReaderBase):
else:
end_time = time.time() + timeout
try:
self.pipe_name = kwargs['pipe_file_name']
except KeyError:
self.pipe_name = 'wexpect_{}'.format(self.console_pid)
pipe_name = 'wexpect_{}'.format(self.console_pid)
if self.pipe_file_suffix:
pipe_name += self.pipe_file_suffix
pipe_full_path = r'\\.\pipe\{}'.format(self.pipe_name)
pipe_full_path = r'\\.\pipe\{}'.format(pipe_name)
logger.info('Start pipe server: %s', pipe_full_path)
self.pipe = win32pipe.CreateNamedPipe(
pipe_full_path,

View File

@@ -1,4 +1,4 @@
"""Host module contains calsses and functions for the host application. These will spawn the child
"""Host module contains classes and functions for the host application. These will spawn the child
application. These host classes (and some util classes) are the interface for the user. Handle other
modules as protected.
"""
@@ -148,11 +148,13 @@ def run(command, timeout=-1, withexitstatus=False, events=None, extra_args=None,
else:
return child_result
return s.decode(encoding=self.encoding, errors=self.decode_errors)
class SpawnBase:
def __init__(self, command, args=[], timeout=30, maxread=60000, searchwindowsize=None,
logfile=None, cwd=None, env=None, codepage=None, echo=True, safe_exit=True,
interact=False, coverage_console_reader=False, **kwargs):
def __init__(self, command, args=[], timeout=30, encoding='UTF-8', decode_errors='ignore',
maxread=60000, searchwindowsize=None, logfile=None, cwd=None, env=None,
codepage=None, echo=True, safe_exit=True, interact=False,
coverage_console_reader=False, **kwargs):
"""This starts the given command in a child process. This does all the
fork/exec type of stuff for a pty. This is called by __init__. If args
is empty then command will be parsed (split on spaces) and args will be
@@ -172,6 +174,8 @@ class SpawnBase:
self.console_pid = None
self.child_process = None
self.child_pid = None
self.encoding = encoding
self.decode_errors = decode_errors
self.safe_exit = safe_exit
self.searcher = None
@@ -354,7 +358,7 @@ class SpawnBase:
wexpect_executable = os.environ['WEXPECT_EXECUTABLE']
except KeyError:
dirname = os.path.dirname(sys.executable)
wexpect_executable = os.path.join(dirname, '..', 'wexpect', 'wexpect.exe')
wexpect_executable = os.path.abspath(os.path.join(dirname, '..', 'wexpect', 'wexpect.exe'))
if not os.path.exists(wexpect_executable):
logger.error(f'ExceptionPexpect: Wexpect executable: >>{wexpect_executable}<< not found.')
@@ -379,7 +383,7 @@ class SpawnBase:
spath = ';'.join(spath)
environ['PYTHONPATH'] = f'{spath};{python_path}'
child_class_initializator = f"wexpect {console_args}"
child_class_initializator = f"wexpect_venv {console_args}"
pyargs = ' '.join(pyargs)
commandLine = f'"{python_executable}" {pyargs} {child_class_initializator}'
@@ -871,8 +875,8 @@ class SpawnPipe(SpawnBase):
**kwargs):
self.pipe = None
self.console_class_name = 'ConsoleReaderPipe'
self.pipe_file_name = f'wexpect_{generate_id()}'
self.console_class_parameters = {'pipe_file_name': self.pipe_file_name}
self.pipe_file_suffix = f'_{generate_id()}'
self.console_class_parameters = {'pipe_file_suffix': self.pipe_file_suffix}
super().__init__(
command=command, args=args, timeout=timeout, maxread=maxread,
@@ -891,7 +895,8 @@ class SpawnPipe(SpawnBase):
else:
end_time = time.time() + timeout
pipe_full_path = r'\\.\pipe\{}'.format(self.pipe_file_name)
pipe_name = 'wexpect_{}{}'.format(self.console_pid, self.pipe_file_suffix)
pipe_full_path = r'\\.\pipe\{}'.format(pipe_name)
logger.debug(f'Trying to connect to pipe: {pipe_full_path}')
while True:
if end_time < time.time():
@@ -951,7 +956,7 @@ class SpawnPipe(SpawnBase):
logger.info("EOF: EOF character has been arrived")
s = s.split(EOF_CHAR)[0]
return s.decode()
return s.decode(encoding=self.encoding, errors=self.decode_errors)
except pywintypes.error as e:
if e.args[0] == winerror.ERROR_BROKEN_PIPE: # 109
self.flag_eof = True
@@ -1078,7 +1083,7 @@ class SpawnSocket(SpawnBase):
except socket.timeout:
return ''
return s.decode()
return s.decode(encoding=self.encoding, errors=self.decode_errors)
class searcher_re (object):