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