You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

522 lines
21 KiB

4 years ago
  1. from io import StringIO, BytesIO
  2. import codecs
  3. import os
  4. import sys
  5. import re
  6. import errno
  7. from .exceptions import ExceptionPexpect, EOF, TIMEOUT
  8. from .expect import Expecter, searcher_string, searcher_re
  9. PY3 = (sys.version_info[0] >= 3)
  10. text_type = str if PY3 else unicode
  11. class _NullCoder(object):
  12. """Pass bytes through unchanged."""
  13. @staticmethod
  14. def encode(b, final=False):
  15. return b
  16. @staticmethod
  17. def decode(b, final=False):
  18. return b
  19. class SpawnBase(object):
  20. """A base class providing the backwards-compatible spawn API for Pexpect.
  21. This should not be instantiated directly: use :class:`pexpect.spawn` or
  22. :class:`pexpect.fdpexpect.fdspawn`.
  23. """
  24. encoding = None
  25. pid = None
  26. flag_eof = False
  27. def __init__(self, timeout=30, maxread=2000, searchwindowsize=None,
  28. logfile=None, encoding=None, codec_errors='strict'):
  29. self.stdin = sys.stdin
  30. self.stdout = sys.stdout
  31. self.stderr = sys.stderr
  32. self.searcher = None
  33. self.ignorecase = False
  34. self.before = None
  35. self.after = None
  36. self.match = None
  37. self.match_index = None
  38. self.terminated = True
  39. self.exitstatus = None
  40. self.signalstatus = None
  41. # status returned by os.waitpid
  42. self.status = None
  43. # the child file descriptor is initially closed
  44. self.child_fd = -1
  45. self.timeout = timeout
  46. self.delimiter = EOF
  47. self.logfile = logfile
  48. # input from child (read_nonblocking)
  49. self.logfile_read = None
  50. # output to send (send, sendline)
  51. self.logfile_send = None
  52. # max bytes to read at one time into buffer
  53. self.maxread = maxread
  54. # Data before searchwindowsize point is preserved, but not searched.
  55. self.searchwindowsize = searchwindowsize
  56. # Delay used before sending data to child. Time in seconds.
  57. # Set this to None to skip the time.sleep() call completely.
  58. self.delaybeforesend = 0.05
  59. # Used by close() to give kernel time to update process status.
  60. # Time in seconds.
  61. self.delayafterclose = 0.1
  62. # Used by terminate() to give kernel time to update process status.
  63. # Time in seconds.
  64. self.delayafterterminate = 0.1
  65. # Delay in seconds to sleep after each call to read_nonblocking().
  66. # Set this to None to skip the time.sleep() call completely: that
  67. # would restore the behavior from pexpect-2.0 (for performance
  68. # reasons or because you don't want to release Python's global
  69. # interpreter lock).
  70. self.delayafterread = 0.0001
  71. self.softspace = False
  72. self.name = '<' + repr(self) + '>'
  73. self.closed = True
  74. # Unicode interface
  75. self.encoding = encoding
  76. self.codec_errors = codec_errors
  77. if encoding is None:
  78. # bytes mode (accepts some unicode for backwards compatibility)
  79. self._encoder = self._decoder = _NullCoder()
  80. self.string_type = bytes
  81. self.buffer_type = BytesIO
  82. self.crlf = b'\r\n'
  83. if PY3:
  84. self.allowed_string_types = (bytes, str)
  85. self.linesep = os.linesep.encode('ascii')
  86. def write_to_stdout(b):
  87. try:
  88. return sys.stdout.buffer.write(b)
  89. except AttributeError:
  90. # If stdout has been replaced, it may not have .buffer
  91. return sys.stdout.write(b.decode('ascii', 'replace'))
  92. self.write_to_stdout = write_to_stdout
  93. else:
  94. self.allowed_string_types = (basestring,) # analysis:ignore
  95. self.linesep = os.linesep
  96. self.write_to_stdout = sys.stdout.write
  97. else:
  98. # unicode mode
  99. self._encoder = codecs.getincrementalencoder(encoding)(codec_errors)
  100. self._decoder = codecs.getincrementaldecoder(encoding)(codec_errors)
  101. self.string_type = text_type
  102. self.buffer_type = StringIO
  103. self.crlf = u'\r\n'
  104. self.allowed_string_types = (text_type, )
  105. if PY3:
  106. self.linesep = os.linesep
  107. else:
  108. self.linesep = os.linesep.decode('ascii')
  109. # This can handle unicode in both Python 2 and 3
  110. self.write_to_stdout = sys.stdout.write
  111. # storage for async transport
  112. self.async_pw_transport = None
  113. # This is the read buffer. See maxread.
  114. self._buffer = self.buffer_type()
  115. def _log(self, s, direction):
  116. if self.logfile is not None:
  117. self.logfile.write(s)
  118. self.logfile.flush()
  119. second_log = self.logfile_send if (direction=='send') else self.logfile_read
  120. if second_log is not None:
  121. second_log.write(s)
  122. second_log.flush()
  123. # For backwards compatibility, in bytes mode (when encoding is None)
  124. # unicode is accepted for send and expect. Unicode mode is strictly unicode
  125. # only.
  126. def _coerce_expect_string(self, s):
  127. if self.encoding is None and not isinstance(s, bytes):
  128. return s.encode('ascii')
  129. return s
  130. def _coerce_send_string(self, s):
  131. if self.encoding is None and not isinstance(s, bytes):
  132. return s.encode('utf-8')
  133. return s
  134. def _get_buffer(self):
  135. return self._buffer.getvalue()
  136. def _set_buffer(self, value):
  137. self._buffer = self.buffer_type()
  138. self._buffer.write(value)
  139. # This property is provided for backwards compatability (self.buffer used
  140. # to be a string/bytes object)
  141. buffer = property(_get_buffer, _set_buffer)
  142. def read_nonblocking(self, size=1, timeout=None):
  143. """This reads data from the file descriptor.
  144. This is a simple implementation suitable for a regular file. Subclasses using ptys or pipes should override it.
  145. The timeout parameter is ignored.
  146. """
  147. try:
  148. s = os.read(self.child_fd, size)
  149. except OSError as err:
  150. if err.args[0] == errno.EIO:
  151. # Linux-style EOF
  152. self.flag_eof = True
  153. raise EOF('End Of File (EOF). Exception style platform.')
  154. raise
  155. if s == b'':
  156. # BSD-style EOF
  157. self.flag_eof = True
  158. raise EOF('End Of File (EOF). Empty string style platform.')
  159. s = self._decoder.decode(s, final=False)
  160. self._log(s, 'read')
  161. return s
  162. def _pattern_type_err(self, pattern):
  163. raise TypeError('got {badtype} ({badobj!r}) as pattern, must be one'
  164. ' of: {goodtypes}, pexpect.EOF, pexpect.TIMEOUT'\
  165. .format(badtype=type(pattern),
  166. badobj=pattern,
  167. goodtypes=', '.join([str(ast)\
  168. for ast in self.allowed_string_types])
  169. )
  170. )
  171. def compile_pattern_list(self, patterns):
  172. '''This compiles a pattern-string or a list of pattern-strings.
  173. Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of
  174. those. Patterns may also be None which results in an empty list (you
  175. might do this if waiting for an EOF or TIMEOUT condition without
  176. expecting any pattern).
  177. This is used by expect() when calling expect_list(). Thus expect() is
  178. nothing more than::
  179. cpl = self.compile_pattern_list(pl)
  180. return self.expect_list(cpl, timeout)
  181. If you are using expect() within a loop it may be more
  182. efficient to compile the patterns first and then call expect_list().
  183. This avoid calls in a loop to compile_pattern_list()::
  184. cpl = self.compile_pattern_list(my_pattern)
  185. while some_condition:
  186. ...
  187. i = self.expect_list(cpl, timeout)
  188. ...
  189. '''
  190. if patterns is None:
  191. return []
  192. if not isinstance(patterns, list):
  193. patterns = [patterns]
  194. # Allow dot to match \n
  195. compile_flags = re.DOTALL
  196. if self.ignorecase:
  197. compile_flags = compile_flags | re.IGNORECASE
  198. compiled_pattern_list = []
  199. for idx, p in enumerate(patterns):
  200. if isinstance(p, self.allowed_string_types):
  201. p = self._coerce_expect_string(p)
  202. compiled_pattern_list.append(re.compile(p, compile_flags))
  203. elif p is EOF:
  204. compiled_pattern_list.append(EOF)
  205. elif p is TIMEOUT:
  206. compiled_pattern_list.append(TIMEOUT)
  207. elif isinstance(p, type(re.compile(''))):
  208. compiled_pattern_list.append(p)
  209. else:
  210. self._pattern_type_err(p)
  211. return compiled_pattern_list
  212. def expect(self, pattern, timeout=-1, searchwindowsize=-1, async_=False, **kw):
  213. '''This seeks through the stream until a pattern is matched. The
  214. pattern is overloaded and may take several types. The pattern can be a
  215. StringType, EOF, a compiled re, or a list of any of those types.
  216. Strings will be compiled to re types. This returns the index into the
  217. pattern list. If the pattern was not a list this returns index 0 on a
  218. successful match. This may raise exceptions for EOF or TIMEOUT. To
  219. avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to the pattern
  220. list. That will cause expect to match an EOF or TIMEOUT condition
  221. instead of raising an exception.
  222. If you pass a list of patterns and more than one matches, the first
  223. match in the stream is chosen. If more than one pattern matches at that
  224. point, the leftmost in the pattern list is chosen. For example::
  225. # the input is 'foobar'
  226. index = p.expect(['bar', 'foo', 'foobar'])
  227. # returns 1('foo') even though 'foobar' is a "better" match
  228. Please note, however, that buffering can affect this behavior, since
  229. input arrives in unpredictable chunks. For example::
  230. # the input is 'foobar'
  231. index = p.expect(['foobar', 'foo'])
  232. # returns 0('foobar') if all input is available at once,
  233. # but returns 1('foo') if parts of the final 'bar' arrive late
  234. When a match is found for the given pattern, the class instance
  235. attribute *match* becomes an re.MatchObject result. Should an EOF
  236. or TIMEOUT pattern match, then the match attribute will be an instance
  237. of that exception class. The pairing before and after class
  238. instance attributes are views of the data preceding and following
  239. the matching pattern. On general exception, class attribute
  240. *before* is all data received up to the exception, while *match* and
  241. *after* attributes are value None.
  242. When the keyword argument timeout is -1 (default), then TIMEOUT will
  243. raise after the default value specified by the class timeout
  244. attribute. When None, TIMEOUT will not be raised and may block
  245. indefinitely until match.
  246. When the keyword argument searchwindowsize is -1 (default), then the
  247. value specified by the class maxread attribute is used.
  248. A list entry may be EOF or TIMEOUT instead of a string. This will
  249. catch these exceptions and return the index of the list entry instead
  250. of raising the exception. The attribute 'after' will be set to the
  251. exception type. The attribute 'match' will be None. This allows you to
  252. write code like this::
  253. index = p.expect(['good', 'bad', pexpect.EOF, pexpect.TIMEOUT])
  254. if index == 0:
  255. do_something()
  256. elif index == 1:
  257. do_something_else()
  258. elif index == 2:
  259. do_some_other_thing()
  260. elif index == 3:
  261. do_something_completely_different()
  262. instead of code like this::
  263. try:
  264. index = p.expect(['good', 'bad'])
  265. if index == 0:
  266. do_something()
  267. elif index == 1:
  268. do_something_else()
  269. except EOF:
  270. do_some_other_thing()
  271. except TIMEOUT:
  272. do_something_completely_different()
  273. These two forms are equivalent. It all depends on what you want. You
  274. can also just expect the EOF if you are waiting for all output of a
  275. child to finish. For example::
  276. p = pexpect.spawn('/bin/ls')
  277. p.expect(pexpect.EOF)
  278. print p.before
  279. If you are trying to optimize for speed then see expect_list().
  280. On Python 3.4, or Python 3.3 with asyncio installed, passing
  281. ``async_=True`` will make this return an :mod:`asyncio` coroutine,
  282. which you can yield from to get the same result that this method would
  283. normally give directly. So, inside a coroutine, you can replace this code::
  284. index = p.expect(patterns)
  285. With this non-blocking form::
  286. index = yield from p.expect(patterns, async_=True)
  287. '''
  288. if 'async' in kw:
  289. async_ = kw.pop('async')
  290. if kw:
  291. raise TypeError("Unknown keyword arguments: {}".format(kw))
  292. compiled_pattern_list = self.compile_pattern_list(pattern)
  293. return self.expect_list(compiled_pattern_list,
  294. timeout, searchwindowsize, async_)
  295. def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1,
  296. async_=False, **kw):
  297. '''This takes a list of compiled regular expressions and returns the
  298. index into the pattern_list that matched the child output. The list may
  299. also contain EOF or TIMEOUT(which are not compiled regular
  300. expressions). This method is similar to the expect() method except that
  301. expect_list() does not recompile the pattern list on every call. This
  302. may help if you are trying to optimize for speed, otherwise just use
  303. the expect() method. This is called by expect().
  304. Like :meth:`expect`, passing ``async_=True`` will make this return an
  305. asyncio coroutine.
  306. '''
  307. if timeout == -1:
  308. timeout = self.timeout
  309. if 'async' in kw:
  310. async_ = kw.pop('async')
  311. if kw:
  312. raise TypeError("Unknown keyword arguments: {}".format(kw))
  313. exp = Expecter(self, searcher_re(pattern_list), searchwindowsize)
  314. if async_:
  315. from ._async import expect_async
  316. return expect_async(exp, timeout)
  317. else:
  318. return exp.expect_loop(timeout)
  319. def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1,
  320. async_=False, **kw):
  321. '''This is similar to expect(), but uses plain string matching instead
  322. of compiled regular expressions in 'pattern_list'. The 'pattern_list'
  323. may be a string; a list or other sequence of strings; or TIMEOUT and
  324. EOF.
  325. This call might be faster than expect() for two reasons: string
  326. searching is faster than RE matching and it is possible to limit the
  327. search to just the end of the input buffer.
  328. This method is also useful when you don't want to have to worry about
  329. escaping regular expression characters that you want to match.
  330. Like :meth:`expect`, passing ``async_=True`` will make this return an
  331. asyncio coroutine.
  332. '''
  333. if timeout == -1:
  334. timeout = self.timeout
  335. if 'async' in kw:
  336. async_ = kw.pop('async')
  337. if kw:
  338. raise TypeError("Unknown keyword arguments: {}".format(kw))
  339. if (isinstance(pattern_list, self.allowed_string_types) or
  340. pattern_list in (TIMEOUT, EOF)):
  341. pattern_list = [pattern_list]
  342. def prepare_pattern(pattern):
  343. if pattern in (TIMEOUT, EOF):
  344. return pattern
  345. if isinstance(pattern, self.allowed_string_types):
  346. return self._coerce_expect_string(pattern)
  347. self._pattern_type_err(pattern)
  348. try:
  349. pattern_list = iter(pattern_list)
  350. except TypeError:
  351. self._pattern_type_err(pattern_list)
  352. pattern_list = [prepare_pattern(p) for p in pattern_list]
  353. exp = Expecter(self, searcher_string(pattern_list), searchwindowsize)
  354. if async_:
  355. from ._async import expect_async
  356. return expect_async(exp, timeout)
  357. else:
  358. return exp.expect_loop(timeout)
  359. def expect_loop(self, searcher, timeout=-1, searchwindowsize=-1):
  360. '''This is the common loop used inside expect. The 'searcher' should be
  361. an instance of searcher_re or searcher_string, which describes how and
  362. what to search for in the input.
  363. See expect() for other arguments, return value and exceptions. '''
  364. exp = Expecter(self, searcher, searchwindowsize)
  365. return exp.expect_loop(timeout)
  366. def read(self, size=-1):
  367. '''This reads at most "size" bytes from the file (less if the read hits
  368. EOF before obtaining size bytes). If the size argument is negative or
  369. omitted, read all data until EOF is reached. The bytes are returned as
  370. a string object. An empty string is returned when EOF is encountered
  371. immediately. '''
  372. if size == 0:
  373. return self.string_type()
  374. if size < 0:
  375. # delimiter default is EOF
  376. self.expect(self.delimiter)
  377. return self.before
  378. # I could have done this more directly by not using expect(), but
  379. # I deliberately decided to couple read() to expect() so that
  380. # I would catch any bugs early and ensure consistent behavior.
  381. # It's a little less efficient, but there is less for me to
  382. # worry about if I have to later modify read() or expect().
  383. # Note, it's OK if size==-1 in the regex. That just means it
  384. # will never match anything in which case we stop only on EOF.
  385. cre = re.compile(self._coerce_expect_string('.{%d}' % size), re.DOTALL)
  386. # delimiter default is EOF
  387. index = self.expect([cre, self.delimiter])
  388. if index == 0:
  389. ### FIXME self.before should be ''. Should I assert this?
  390. return self.after
  391. return self.before
  392. def readline(self, size=-1):
  393. '''This reads and returns one entire line. The newline at the end of
  394. line is returned as part of the string, unless the file ends without a
  395. newline. An empty string is returned if EOF is encountered immediately.
  396. This looks for a newline as a CR/LF pair (\\r\\n) even on UNIX because
  397. this is what the pseudotty device returns. So contrary to what you may
  398. expect you will receive newlines as \\r\\n.
  399. If the size argument is 0 then an empty string is returned. In all
  400. other cases the size argument is ignored, which is not standard
  401. behavior for a file-like object. '''
  402. if size == 0:
  403. return self.string_type()
  404. # delimiter default is EOF
  405. index = self.expect([self.crlf, self.delimiter])
  406. if index == 0:
  407. return self.before + self.crlf
  408. else:
  409. return self.before
  410. def __iter__(self):
  411. '''This is to support iterators over a file-like object.
  412. '''
  413. return iter(self.readline, self.string_type())
  414. def readlines(self, sizehint=-1):
  415. '''This reads until EOF using readline() and returns a list containing
  416. the lines thus read. The optional 'sizehint' argument is ignored.
  417. Remember, because this reads until EOF that means the child
  418. process should have closed its stdout. If you run this method on
  419. a child that is still running with its stdout open then this
  420. method will block until it timesout.'''
  421. lines = []
  422. while True:
  423. line = self.readline()
  424. if not line:
  425. break
  426. lines.append(line)
  427. return lines
  428. def fileno(self):
  429. '''Expose file descriptor for a file-like interface
  430. '''
  431. return self.child_fd
  432. def flush(self):
  433. '''This does nothing. It is here to support the interface for a
  434. File-like object. '''
  435. pass
  436. def isatty(self):
  437. """Overridden in subclass using tty"""
  438. return False
  439. # For 'with spawn(...) as child:'
  440. def __enter__(self):
  441. return self
  442. def __exit__(self, etype, evalue, tb):
  443. # We rely on subclasses to implement close(). If they don't, it's not
  444. # clear what a context manager should do.
  445. self.close()