1205fd03aSDavide Italianofrom io import StringIO, BytesIO
2205fd03aSDavide Italianoimport codecs
3205fd03aSDavide Italianoimport os
4205fd03aSDavide Italianoimport sys
5205fd03aSDavide Italianoimport re
6205fd03aSDavide Italianoimport errno
7205fd03aSDavide Italianofrom .exceptions import ExceptionPexpect, EOF, TIMEOUT
8205fd03aSDavide Italianofrom .expect import Expecter, searcher_string, searcher_re
9205fd03aSDavide Italiano
10205fd03aSDavide ItalianoPY3 = (sys.version_info[0] >= 3)
11205fd03aSDavide Italianotext_type = str if PY3 else unicode
12205fd03aSDavide Italiano
13205fd03aSDavide Italianoclass _NullCoder(object):
14205fd03aSDavide Italiano    """Pass bytes through unchanged."""
15205fd03aSDavide Italiano    @staticmethod
16205fd03aSDavide Italiano    def encode(b, final=False):
17205fd03aSDavide Italiano        return b
18205fd03aSDavide Italiano
19205fd03aSDavide Italiano    @staticmethod
20205fd03aSDavide Italiano    def decode(b, final=False):
21205fd03aSDavide Italiano        return b
22205fd03aSDavide Italiano
23205fd03aSDavide Italianoclass SpawnBase(object):
24205fd03aSDavide Italiano    """A base class providing the backwards-compatible spawn API for Pexpect.
25205fd03aSDavide Italiano
26205fd03aSDavide Italiano    This should not be instantiated directly: use :class:`pexpect.spawn` or
27205fd03aSDavide Italiano    :class:`pexpect.fdpexpect.fdspawn`.
28205fd03aSDavide Italiano    """
29205fd03aSDavide Italiano    encoding = None
30205fd03aSDavide Italiano    pid = None
31205fd03aSDavide Italiano    flag_eof = False
32205fd03aSDavide Italiano
33*97c6ef4eSMuhammad Omair Javaid    def __init__(self, timeout=60, maxread=2000, searchwindowsize=None,
34205fd03aSDavide Italiano                 logfile=None, encoding=None, codec_errors='strict'):
35205fd03aSDavide Italiano        self.stdin = sys.stdin
36205fd03aSDavide Italiano        self.stdout = sys.stdout
37205fd03aSDavide Italiano        self.stderr = sys.stderr
38205fd03aSDavide Italiano
39205fd03aSDavide Italiano        self.searcher = None
40205fd03aSDavide Italiano        self.ignorecase = False
41205fd03aSDavide Italiano        self.before = None
42205fd03aSDavide Italiano        self.after = None
43205fd03aSDavide Italiano        self.match = None
44205fd03aSDavide Italiano        self.match_index = None
45205fd03aSDavide Italiano        self.terminated = True
46205fd03aSDavide Italiano        self.exitstatus = None
47205fd03aSDavide Italiano        self.signalstatus = None
48205fd03aSDavide Italiano        # status returned by os.waitpid
49205fd03aSDavide Italiano        self.status = None
50205fd03aSDavide Italiano        # the child file descriptor is initially closed
51205fd03aSDavide Italiano        self.child_fd = -1
52205fd03aSDavide Italiano        self.timeout = timeout
53205fd03aSDavide Italiano        self.delimiter = EOF
54205fd03aSDavide Italiano        self.logfile = logfile
55205fd03aSDavide Italiano        # input from child (read_nonblocking)
56205fd03aSDavide Italiano        self.logfile_read = None
57205fd03aSDavide Italiano        # output to send (send, sendline)
58205fd03aSDavide Italiano        self.logfile_send = None
59205fd03aSDavide Italiano        # max bytes to read at one time into buffer
60205fd03aSDavide Italiano        self.maxread = maxread
61205fd03aSDavide Italiano        # Data before searchwindowsize point is preserved, but not searched.
62205fd03aSDavide Italiano        self.searchwindowsize = searchwindowsize
63205fd03aSDavide Italiano        # Delay used before sending data to child. Time in seconds.
64205fd03aSDavide Italiano        # Set this to None to skip the time.sleep() call completely.
65205fd03aSDavide Italiano        self.delaybeforesend = 0.05
66205fd03aSDavide Italiano        # Used by close() to give kernel time to update process status.
67205fd03aSDavide Italiano        # Time in seconds.
68205fd03aSDavide Italiano        self.delayafterclose = 0.1
69205fd03aSDavide Italiano        # Used by terminate() to give kernel time to update process status.
70205fd03aSDavide Italiano        # Time in seconds.
71205fd03aSDavide Italiano        self.delayafterterminate = 0.1
72205fd03aSDavide Italiano        # Delay in seconds to sleep after each call to read_nonblocking().
73205fd03aSDavide Italiano        # Set this to None to skip the time.sleep() call completely: that
74205fd03aSDavide Italiano        # would restore the behavior from pexpect-2.0 (for performance
75205fd03aSDavide Italiano        # reasons or because you don't want to release Python's global
76205fd03aSDavide Italiano        # interpreter lock).
77205fd03aSDavide Italiano        self.delayafterread = 0.0001
78205fd03aSDavide Italiano        self.softspace = False
79205fd03aSDavide Italiano        self.name = '<' + repr(self) + '>'
80205fd03aSDavide Italiano        self.closed = True
81205fd03aSDavide Italiano
82205fd03aSDavide Italiano        # Unicode interface
83205fd03aSDavide Italiano        self.encoding = encoding
84205fd03aSDavide Italiano        self.codec_errors = codec_errors
85205fd03aSDavide Italiano        if encoding is None:
86205fd03aSDavide Italiano            # bytes mode (accepts some unicode for backwards compatibility)
87205fd03aSDavide Italiano            self._encoder = self._decoder = _NullCoder()
88205fd03aSDavide Italiano            self.string_type = bytes
89205fd03aSDavide Italiano            self.buffer_type = BytesIO
90205fd03aSDavide Italiano            self.crlf = b'\r\n'
91205fd03aSDavide Italiano            if PY3:
92205fd03aSDavide Italiano                self.allowed_string_types = (bytes, str)
93205fd03aSDavide Italiano                self.linesep = os.linesep.encode('ascii')
94205fd03aSDavide Italiano                def write_to_stdout(b):
95205fd03aSDavide Italiano                    try:
96205fd03aSDavide Italiano                        return sys.stdout.buffer.write(b)
97205fd03aSDavide Italiano                    except AttributeError:
98205fd03aSDavide Italiano                        # If stdout has been replaced, it may not have .buffer
99205fd03aSDavide Italiano                        return sys.stdout.write(b.decode('ascii', 'replace'))
100205fd03aSDavide Italiano                self.write_to_stdout = write_to_stdout
101205fd03aSDavide Italiano            else:
102205fd03aSDavide Italiano                self.allowed_string_types = (basestring,)  # analysis:ignore
103205fd03aSDavide Italiano                self.linesep = os.linesep
104205fd03aSDavide Italiano                self.write_to_stdout = sys.stdout.write
105205fd03aSDavide Italiano        else:
106205fd03aSDavide Italiano            # unicode mode
107205fd03aSDavide Italiano            self._encoder = codecs.getincrementalencoder(encoding)(codec_errors)
108205fd03aSDavide Italiano            self._decoder = codecs.getincrementaldecoder(encoding)(codec_errors)
109205fd03aSDavide Italiano            self.string_type = text_type
110205fd03aSDavide Italiano            self.buffer_type = StringIO
111205fd03aSDavide Italiano            self.crlf = u'\r\n'
112205fd03aSDavide Italiano            self.allowed_string_types = (text_type, )
113205fd03aSDavide Italiano            if PY3:
114205fd03aSDavide Italiano                self.linesep = os.linesep
115205fd03aSDavide Italiano            else:
116205fd03aSDavide Italiano                self.linesep = os.linesep.decode('ascii')
117205fd03aSDavide Italiano            # This can handle unicode in both Python 2 and 3
118205fd03aSDavide Italiano            self.write_to_stdout = sys.stdout.write
119205fd03aSDavide Italiano        # storage for async transport
120205fd03aSDavide Italiano        self.async_pw_transport = None
121205fd03aSDavide Italiano        # This is the read buffer. See maxread.
122205fd03aSDavide Italiano        self._buffer = self.buffer_type()
123205fd03aSDavide Italiano
124205fd03aSDavide Italiano    def _log(self, s, direction):
125205fd03aSDavide Italiano        if self.logfile is not None:
126205fd03aSDavide Italiano            self.logfile.write(s)
127205fd03aSDavide Italiano            self.logfile.flush()
128205fd03aSDavide Italiano        second_log = self.logfile_send if (direction=='send') else self.logfile_read
129205fd03aSDavide Italiano        if second_log is not None:
130205fd03aSDavide Italiano            second_log.write(s)
131205fd03aSDavide Italiano            second_log.flush()
132205fd03aSDavide Italiano
133205fd03aSDavide Italiano    # For backwards compatibility, in bytes mode (when encoding is None)
134205fd03aSDavide Italiano    # unicode is accepted for send and expect. Unicode mode is strictly unicode
135205fd03aSDavide Italiano    # only.
136205fd03aSDavide Italiano    def _coerce_expect_string(self, s):
137205fd03aSDavide Italiano        if self.encoding is None and not isinstance(s, bytes):
138205fd03aSDavide Italiano            return s.encode('ascii')
139205fd03aSDavide Italiano        return s
140205fd03aSDavide Italiano
141205fd03aSDavide Italiano    def _coerce_send_string(self, s):
142205fd03aSDavide Italiano        if self.encoding is None and not isinstance(s, bytes):
143205fd03aSDavide Italiano            return s.encode('utf-8')
144205fd03aSDavide Italiano        return s
145205fd03aSDavide Italiano
146205fd03aSDavide Italiano    def _get_buffer(self):
147205fd03aSDavide Italiano        return self._buffer.getvalue()
148205fd03aSDavide Italiano
149205fd03aSDavide Italiano    def _set_buffer(self, value):
150205fd03aSDavide Italiano        self._buffer = self.buffer_type()
151205fd03aSDavide Italiano        self._buffer.write(value)
152205fd03aSDavide Italiano
153e9264b74SKazuaki Ishizaki    # This property is provided for backwards compatibility (self.buffer used
154205fd03aSDavide Italiano    # to be a string/bytes object)
155205fd03aSDavide Italiano    buffer = property(_get_buffer, _set_buffer)
156205fd03aSDavide Italiano
157205fd03aSDavide Italiano    def read_nonblocking(self, size=1, timeout=None):
158205fd03aSDavide Italiano        """This reads data from the file descriptor.
159205fd03aSDavide Italiano
160205fd03aSDavide Italiano        This is a simple implementation suitable for a regular file. Subclasses using ptys or pipes should override it.
161205fd03aSDavide Italiano
162205fd03aSDavide Italiano        The timeout parameter is ignored.
163205fd03aSDavide Italiano        """
164205fd03aSDavide Italiano
165205fd03aSDavide Italiano        try:
166205fd03aSDavide Italiano            s = os.read(self.child_fd, size)
167205fd03aSDavide Italiano        except OSError as err:
168205fd03aSDavide Italiano            if err.args[0] == errno.EIO:
169205fd03aSDavide Italiano                # Linux-style EOF
170205fd03aSDavide Italiano                self.flag_eof = True
171205fd03aSDavide Italiano                raise EOF('End Of File (EOF). Exception style platform.')
172205fd03aSDavide Italiano            raise
173205fd03aSDavide Italiano        if s == b'':
174205fd03aSDavide Italiano            # BSD-style EOF
175205fd03aSDavide Italiano            self.flag_eof = True
176205fd03aSDavide Italiano            raise EOF('End Of File (EOF). Empty string style platform.')
177205fd03aSDavide Italiano
178205fd03aSDavide Italiano        s = self._decoder.decode(s, final=False)
179205fd03aSDavide Italiano        self._log(s, 'read')
180205fd03aSDavide Italiano        return s
181205fd03aSDavide Italiano
182205fd03aSDavide Italiano    def _pattern_type_err(self, pattern):
183205fd03aSDavide Italiano        raise TypeError('got {badtype} ({badobj!r}) as pattern, must be one'
184205fd03aSDavide Italiano                        ' of: {goodtypes}, pexpect.EOF, pexpect.TIMEOUT'\
185205fd03aSDavide Italiano                        .format(badtype=type(pattern),
186205fd03aSDavide Italiano                                badobj=pattern,
187205fd03aSDavide Italiano                                goodtypes=', '.join([str(ast)\
188205fd03aSDavide Italiano                                    for ast in self.allowed_string_types])
189205fd03aSDavide Italiano                                )
190205fd03aSDavide Italiano                        )
191205fd03aSDavide Italiano
192205fd03aSDavide Italiano    def compile_pattern_list(self, patterns):
193205fd03aSDavide Italiano        '''This compiles a pattern-string or a list of pattern-strings.
194205fd03aSDavide Italiano        Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of
195205fd03aSDavide Italiano        those. Patterns may also be None which results in an empty list (you
196205fd03aSDavide Italiano        might do this if waiting for an EOF or TIMEOUT condition without
197205fd03aSDavide Italiano        expecting any pattern).
198205fd03aSDavide Italiano
199205fd03aSDavide Italiano        This is used by expect() when calling expect_list(). Thus expect() is
200205fd03aSDavide Italiano        nothing more than::
201205fd03aSDavide Italiano
202205fd03aSDavide Italiano             cpl = self.compile_pattern_list(pl)
203205fd03aSDavide Italiano             return self.expect_list(cpl, timeout)
204205fd03aSDavide Italiano
205205fd03aSDavide Italiano        If you are using expect() within a loop it may be more
206205fd03aSDavide Italiano        efficient to compile the patterns first and then call expect_list().
207205fd03aSDavide Italiano        This avoid calls in a loop to compile_pattern_list()::
208205fd03aSDavide Italiano
209205fd03aSDavide Italiano             cpl = self.compile_pattern_list(my_pattern)
210205fd03aSDavide Italiano             while some_condition:
211205fd03aSDavide Italiano                ...
212205fd03aSDavide Italiano                i = self.expect_list(cpl, timeout)
213205fd03aSDavide Italiano                ...
214205fd03aSDavide Italiano        '''
215205fd03aSDavide Italiano
216205fd03aSDavide Italiano        if patterns is None:
217205fd03aSDavide Italiano            return []
218205fd03aSDavide Italiano        if not isinstance(patterns, list):
219205fd03aSDavide Italiano            patterns = [patterns]
220205fd03aSDavide Italiano
221205fd03aSDavide Italiano        # Allow dot to match \n
222205fd03aSDavide Italiano        compile_flags = re.DOTALL
223205fd03aSDavide Italiano        if self.ignorecase:
224205fd03aSDavide Italiano            compile_flags = compile_flags | re.IGNORECASE
225205fd03aSDavide Italiano        compiled_pattern_list = []
226205fd03aSDavide Italiano        for idx, p in enumerate(patterns):
227205fd03aSDavide Italiano            if isinstance(p, self.allowed_string_types):
228205fd03aSDavide Italiano                p = self._coerce_expect_string(p)
229205fd03aSDavide Italiano                compiled_pattern_list.append(re.compile(p, compile_flags))
230205fd03aSDavide Italiano            elif p is EOF:
231205fd03aSDavide Italiano                compiled_pattern_list.append(EOF)
232205fd03aSDavide Italiano            elif p is TIMEOUT:
233205fd03aSDavide Italiano                compiled_pattern_list.append(TIMEOUT)
234205fd03aSDavide Italiano            elif isinstance(p, type(re.compile(''))):
235205fd03aSDavide Italiano                compiled_pattern_list.append(p)
236205fd03aSDavide Italiano            else:
237205fd03aSDavide Italiano                self._pattern_type_err(p)
238205fd03aSDavide Italiano        return compiled_pattern_list
239205fd03aSDavide Italiano
240205fd03aSDavide Italiano    def expect(self, pattern, timeout=-1, searchwindowsize=-1, async_=False, **kw):
241205fd03aSDavide Italiano        '''This seeks through the stream until a pattern is matched. The
242205fd03aSDavide Italiano        pattern is overloaded and may take several types. The pattern can be a
243205fd03aSDavide Italiano        StringType, EOF, a compiled re, or a list of any of those types.
244205fd03aSDavide Italiano        Strings will be compiled to re types. This returns the index into the
245205fd03aSDavide Italiano        pattern list. If the pattern was not a list this returns index 0 on a
246205fd03aSDavide Italiano        successful match. This may raise exceptions for EOF or TIMEOUT. To
247205fd03aSDavide Italiano        avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to the pattern
248205fd03aSDavide Italiano        list. That will cause expect to match an EOF or TIMEOUT condition
249205fd03aSDavide Italiano        instead of raising an exception.
250205fd03aSDavide Italiano
251205fd03aSDavide Italiano        If you pass a list of patterns and more than one matches, the first
252205fd03aSDavide Italiano        match in the stream is chosen. If more than one pattern matches at that
253205fd03aSDavide Italiano        point, the leftmost in the pattern list is chosen. For example::
254205fd03aSDavide Italiano
255205fd03aSDavide Italiano            # the input is 'foobar'
256205fd03aSDavide Italiano            index = p.expect(['bar', 'foo', 'foobar'])
257205fd03aSDavide Italiano            # returns 1('foo') even though 'foobar' is a "better" match
258205fd03aSDavide Italiano
259205fd03aSDavide Italiano        Please note, however, that buffering can affect this behavior, since
260205fd03aSDavide Italiano        input arrives in unpredictable chunks. For example::
261205fd03aSDavide Italiano
262205fd03aSDavide Italiano            # the input is 'foobar'
263205fd03aSDavide Italiano            index = p.expect(['foobar', 'foo'])
264205fd03aSDavide Italiano            # returns 0('foobar') if all input is available at once,
265205fd03aSDavide Italiano            # but returns 1('foo') if parts of the final 'bar' arrive late
266205fd03aSDavide Italiano
267205fd03aSDavide Italiano        When a match is found for the given pattern, the class instance
268205fd03aSDavide Italiano        attribute *match* becomes an re.MatchObject result.  Should an EOF
269205fd03aSDavide Italiano        or TIMEOUT pattern match, then the match attribute will be an instance
270205fd03aSDavide Italiano        of that exception class.  The pairing before and after class
271205fd03aSDavide Italiano        instance attributes are views of the data preceding and following
272205fd03aSDavide Italiano        the matching pattern.  On general exception, class attribute
273205fd03aSDavide Italiano        *before* is all data received up to the exception, while *match* and
274205fd03aSDavide Italiano        *after* attributes are value None.
275205fd03aSDavide Italiano
276205fd03aSDavide Italiano        When the keyword argument timeout is -1 (default), then TIMEOUT will
277205fd03aSDavide Italiano        raise after the default value specified by the class timeout
278205fd03aSDavide Italiano        attribute. When None, TIMEOUT will not be raised and may block
279205fd03aSDavide Italiano        indefinitely until match.
280205fd03aSDavide Italiano
281205fd03aSDavide Italiano        When the keyword argument searchwindowsize is -1 (default), then the
282205fd03aSDavide Italiano        value specified by the class maxread attribute is used.
283205fd03aSDavide Italiano
284205fd03aSDavide Italiano        A list entry may be EOF or TIMEOUT instead of a string. This will
285205fd03aSDavide Italiano        catch these exceptions and return the index of the list entry instead
286205fd03aSDavide Italiano        of raising the exception. The attribute 'after' will be set to the
287205fd03aSDavide Italiano        exception type. The attribute 'match' will be None. This allows you to
288205fd03aSDavide Italiano        write code like this::
289205fd03aSDavide Italiano
290205fd03aSDavide Italiano                index = p.expect(['good', 'bad', pexpect.EOF, pexpect.TIMEOUT])
291205fd03aSDavide Italiano                if index == 0:
292205fd03aSDavide Italiano                    do_something()
293205fd03aSDavide Italiano                elif index == 1:
294205fd03aSDavide Italiano                    do_something_else()
295205fd03aSDavide Italiano                elif index == 2:
296205fd03aSDavide Italiano                    do_some_other_thing()
297205fd03aSDavide Italiano                elif index == 3:
298205fd03aSDavide Italiano                    do_something_completely_different()
299205fd03aSDavide Italiano
300205fd03aSDavide Italiano        instead of code like this::
301205fd03aSDavide Italiano
302205fd03aSDavide Italiano                try:
303205fd03aSDavide Italiano                    index = p.expect(['good', 'bad'])
304205fd03aSDavide Italiano                    if index == 0:
305205fd03aSDavide Italiano                        do_something()
306205fd03aSDavide Italiano                    elif index == 1:
307205fd03aSDavide Italiano                        do_something_else()
308205fd03aSDavide Italiano                except EOF:
309205fd03aSDavide Italiano                    do_some_other_thing()
310205fd03aSDavide Italiano                except TIMEOUT:
311205fd03aSDavide Italiano                    do_something_completely_different()
312205fd03aSDavide Italiano
313205fd03aSDavide Italiano        These two forms are equivalent. It all depends on what you want. You
314205fd03aSDavide Italiano        can also just expect the EOF if you are waiting for all output of a
315205fd03aSDavide Italiano        child to finish. For example::
316205fd03aSDavide Italiano
317205fd03aSDavide Italiano                p = pexpect.spawn('/bin/ls')
318205fd03aSDavide Italiano                p.expect(pexpect.EOF)
319205fd03aSDavide Italiano                print p.before
320205fd03aSDavide Italiano
321205fd03aSDavide Italiano        If you are trying to optimize for speed then see expect_list().
322205fd03aSDavide Italiano
323205fd03aSDavide Italiano        On Python 3.4, or Python 3.3 with asyncio installed, passing
324205fd03aSDavide Italiano        ``async_=True``  will make this return an :mod:`asyncio` coroutine,
325205fd03aSDavide Italiano        which you can yield from to get the same result that this method would
326205fd03aSDavide Italiano        normally give directly. So, inside a coroutine, you can replace this code::
327205fd03aSDavide Italiano
328205fd03aSDavide Italiano            index = p.expect(patterns)
329205fd03aSDavide Italiano
330205fd03aSDavide Italiano        With this non-blocking form::
331205fd03aSDavide Italiano
332205fd03aSDavide Italiano            index = yield from p.expect(patterns, async_=True)
333205fd03aSDavide Italiano        '''
334205fd03aSDavide Italiano        if 'async' in kw:
335205fd03aSDavide Italiano            async_ = kw.pop('async')
336205fd03aSDavide Italiano        if kw:
337205fd03aSDavide Italiano            raise TypeError("Unknown keyword arguments: {}".format(kw))
338205fd03aSDavide Italiano
339205fd03aSDavide Italiano        compiled_pattern_list = self.compile_pattern_list(pattern)
340205fd03aSDavide Italiano        return self.expect_list(compiled_pattern_list,
341205fd03aSDavide Italiano                timeout, searchwindowsize, async_)
342205fd03aSDavide Italiano
343205fd03aSDavide Italiano    def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1,
344205fd03aSDavide Italiano                    async_=False, **kw):
345205fd03aSDavide Italiano        '''This takes a list of compiled regular expressions and returns the
346205fd03aSDavide Italiano        index into the pattern_list that matched the child output. The list may
347205fd03aSDavide Italiano        also contain EOF or TIMEOUT(which are not compiled regular
348205fd03aSDavide Italiano        expressions). This method is similar to the expect() method except that
349205fd03aSDavide Italiano        expect_list() does not recompile the pattern list on every call. This
350205fd03aSDavide Italiano        may help if you are trying to optimize for speed, otherwise just use
351205fd03aSDavide Italiano        the expect() method.  This is called by expect().
352205fd03aSDavide Italiano
353205fd03aSDavide Italiano
354205fd03aSDavide Italiano        Like :meth:`expect`, passing ``async_=True`` will make this return an
355205fd03aSDavide Italiano        asyncio coroutine.
356205fd03aSDavide Italiano        '''
357205fd03aSDavide Italiano        if timeout == -1:
358205fd03aSDavide Italiano            timeout = self.timeout
359205fd03aSDavide Italiano        if 'async' in kw:
360205fd03aSDavide Italiano            async_ = kw.pop('async')
361205fd03aSDavide Italiano        if kw:
362205fd03aSDavide Italiano            raise TypeError("Unknown keyword arguments: {}".format(kw))
363205fd03aSDavide Italiano
364205fd03aSDavide Italiano        exp = Expecter(self, searcher_re(pattern_list), searchwindowsize)
365205fd03aSDavide Italiano        if async_:
366205fd03aSDavide Italiano            from ._async import expect_async
367205fd03aSDavide Italiano            return expect_async(exp, timeout)
368205fd03aSDavide Italiano        else:
369205fd03aSDavide Italiano            return exp.expect_loop(timeout)
370205fd03aSDavide Italiano
371205fd03aSDavide Italiano    def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1,
372205fd03aSDavide Italiano                     async_=False, **kw):
373205fd03aSDavide Italiano
374205fd03aSDavide Italiano        '''This is similar to expect(), but uses plain string matching instead
375205fd03aSDavide Italiano        of compiled regular expressions in 'pattern_list'. The 'pattern_list'
376205fd03aSDavide Italiano        may be a string; a list or other sequence of strings; or TIMEOUT and
377205fd03aSDavide Italiano        EOF.
378205fd03aSDavide Italiano
379205fd03aSDavide Italiano        This call might be faster than expect() for two reasons: string
380205fd03aSDavide Italiano        searching is faster than RE matching and it is possible to limit the
381205fd03aSDavide Italiano        search to just the end of the input buffer.
382205fd03aSDavide Italiano
383205fd03aSDavide Italiano        This method is also useful when you don't want to have to worry about
384205fd03aSDavide Italiano        escaping regular expression characters that you want to match.
385205fd03aSDavide Italiano
386205fd03aSDavide Italiano        Like :meth:`expect`, passing ``async_=True`` will make this return an
387205fd03aSDavide Italiano        asyncio coroutine.
388205fd03aSDavide Italiano        '''
389205fd03aSDavide Italiano        if timeout == -1:
390205fd03aSDavide Italiano            timeout = self.timeout
391205fd03aSDavide Italiano        if 'async' in kw:
392205fd03aSDavide Italiano            async_ = kw.pop('async')
393205fd03aSDavide Italiano        if kw:
394205fd03aSDavide Italiano            raise TypeError("Unknown keyword arguments: {}".format(kw))
395205fd03aSDavide Italiano
396205fd03aSDavide Italiano        if (isinstance(pattern_list, self.allowed_string_types) or
397205fd03aSDavide Italiano                pattern_list in (TIMEOUT, EOF)):
398205fd03aSDavide Italiano            pattern_list = [pattern_list]
399205fd03aSDavide Italiano
400205fd03aSDavide Italiano        def prepare_pattern(pattern):
401205fd03aSDavide Italiano            if pattern in (TIMEOUT, EOF):
402205fd03aSDavide Italiano                return pattern
403205fd03aSDavide Italiano            if isinstance(pattern, self.allowed_string_types):
404205fd03aSDavide Italiano                return self._coerce_expect_string(pattern)
405205fd03aSDavide Italiano            self._pattern_type_err(pattern)
406205fd03aSDavide Italiano
407205fd03aSDavide Italiano        try:
408205fd03aSDavide Italiano            pattern_list = iter(pattern_list)
409205fd03aSDavide Italiano        except TypeError:
410205fd03aSDavide Italiano            self._pattern_type_err(pattern_list)
411205fd03aSDavide Italiano        pattern_list = [prepare_pattern(p) for p in pattern_list]
412205fd03aSDavide Italiano
413205fd03aSDavide Italiano        exp = Expecter(self, searcher_string(pattern_list), searchwindowsize)
414205fd03aSDavide Italiano        if async_:
415205fd03aSDavide Italiano            from ._async import expect_async
416205fd03aSDavide Italiano            return expect_async(exp, timeout)
417205fd03aSDavide Italiano        else:
418205fd03aSDavide Italiano            return exp.expect_loop(timeout)
419205fd03aSDavide Italiano
420205fd03aSDavide Italiano    def expect_loop(self, searcher, timeout=-1, searchwindowsize=-1):
421205fd03aSDavide Italiano        '''This is the common loop used inside expect. The 'searcher' should be
422205fd03aSDavide Italiano        an instance of searcher_re or searcher_string, which describes how and
423205fd03aSDavide Italiano        what to search for in the input.
424205fd03aSDavide Italiano
425205fd03aSDavide Italiano        See expect() for other arguments, return value and exceptions. '''
426205fd03aSDavide Italiano
427205fd03aSDavide Italiano        exp = Expecter(self, searcher, searchwindowsize)
428205fd03aSDavide Italiano        return exp.expect_loop(timeout)
429205fd03aSDavide Italiano
430205fd03aSDavide Italiano    def read(self, size=-1):
431205fd03aSDavide Italiano        '''This reads at most "size" bytes from the file (less if the read hits
432205fd03aSDavide Italiano        EOF before obtaining size bytes). If the size argument is negative or
433205fd03aSDavide Italiano        omitted, read all data until EOF is reached. The bytes are returned as
434205fd03aSDavide Italiano        a string object. An empty string is returned when EOF is encountered
435205fd03aSDavide Italiano        immediately. '''
436205fd03aSDavide Italiano
437205fd03aSDavide Italiano        if size == 0:
438205fd03aSDavide Italiano            return self.string_type()
439205fd03aSDavide Italiano        if size < 0:
440205fd03aSDavide Italiano            # delimiter default is EOF
441205fd03aSDavide Italiano            self.expect(self.delimiter)
442205fd03aSDavide Italiano            return self.before
443205fd03aSDavide Italiano
444205fd03aSDavide Italiano        # I could have done this more directly by not using expect(), but
445205fd03aSDavide Italiano        # I deliberately decided to couple read() to expect() so that
446205fd03aSDavide Italiano        # I would catch any bugs early and ensure consistent behavior.
447205fd03aSDavide Italiano        # It's a little less efficient, but there is less for me to
448205fd03aSDavide Italiano        # worry about if I have to later modify read() or expect().
449205fd03aSDavide Italiano        # Note, it's OK if size==-1 in the regex. That just means it
450205fd03aSDavide Italiano        # will never match anything in which case we stop only on EOF.
451205fd03aSDavide Italiano        cre = re.compile(self._coerce_expect_string('.{%d}' % size), re.DOTALL)
452205fd03aSDavide Italiano        # delimiter default is EOF
453205fd03aSDavide Italiano        index = self.expect([cre, self.delimiter])
454205fd03aSDavide Italiano        if index == 0:
455205fd03aSDavide Italiano            ### FIXME self.before should be ''. Should I assert this?
456205fd03aSDavide Italiano            return self.after
457205fd03aSDavide Italiano        return self.before
458205fd03aSDavide Italiano
459205fd03aSDavide Italiano    def readline(self, size=-1):
460205fd03aSDavide Italiano        '''This reads and returns one entire line. The newline at the end of
461205fd03aSDavide Italiano        line is returned as part of the string, unless the file ends without a
462205fd03aSDavide Italiano        newline. An empty string is returned if EOF is encountered immediately.
463205fd03aSDavide Italiano        This looks for a newline as a CR/LF pair (\\r\\n) even on UNIX because
464205fd03aSDavide Italiano        this is what the pseudotty device returns. So contrary to what you may
465205fd03aSDavide Italiano        expect you will receive newlines as \\r\\n.
466205fd03aSDavide Italiano
467205fd03aSDavide Italiano        If the size argument is 0 then an empty string is returned. In all
468205fd03aSDavide Italiano        other cases the size argument is ignored, which is not standard
469205fd03aSDavide Italiano        behavior for a file-like object. '''
470205fd03aSDavide Italiano
471205fd03aSDavide Italiano        if size == 0:
472205fd03aSDavide Italiano            return self.string_type()
473205fd03aSDavide Italiano        # delimiter default is EOF
474205fd03aSDavide Italiano        index = self.expect([self.crlf, self.delimiter])
475205fd03aSDavide Italiano        if index == 0:
476205fd03aSDavide Italiano            return self.before + self.crlf
477205fd03aSDavide Italiano        else:
478205fd03aSDavide Italiano            return self.before
479205fd03aSDavide Italiano
480205fd03aSDavide Italiano    def __iter__(self):
481205fd03aSDavide Italiano        '''This is to support iterators over a file-like object.
482205fd03aSDavide Italiano        '''
483205fd03aSDavide Italiano        return iter(self.readline, self.string_type())
484205fd03aSDavide Italiano
485205fd03aSDavide Italiano    def readlines(self, sizehint=-1):
486205fd03aSDavide Italiano        '''This reads until EOF using readline() and returns a list containing
487205fd03aSDavide Italiano        the lines thus read. The optional 'sizehint' argument is ignored.
488205fd03aSDavide Italiano        Remember, because this reads until EOF that means the child
489205fd03aSDavide Italiano        process should have closed its stdout. If you run this method on
490205fd03aSDavide Italiano        a child that is still running with its stdout open then this
491205fd03aSDavide Italiano        method will block until it timesout.'''
492205fd03aSDavide Italiano
493205fd03aSDavide Italiano        lines = []
494205fd03aSDavide Italiano        while True:
495205fd03aSDavide Italiano            line = self.readline()
496205fd03aSDavide Italiano            if not line:
497205fd03aSDavide Italiano                break
498205fd03aSDavide Italiano            lines.append(line)
499205fd03aSDavide Italiano        return lines
500205fd03aSDavide Italiano
501205fd03aSDavide Italiano    def fileno(self):
502205fd03aSDavide Italiano        '''Expose file descriptor for a file-like interface
503205fd03aSDavide Italiano        '''
504205fd03aSDavide Italiano        return self.child_fd
505205fd03aSDavide Italiano
506205fd03aSDavide Italiano    def flush(self):
507205fd03aSDavide Italiano        '''This does nothing. It is here to support the interface for a
508205fd03aSDavide Italiano        File-like object. '''
509205fd03aSDavide Italiano        pass
510205fd03aSDavide Italiano
511205fd03aSDavide Italiano    def isatty(self):
512205fd03aSDavide Italiano        """Overridden in subclass using tty"""
513205fd03aSDavide Italiano        return False
514205fd03aSDavide Italiano
515205fd03aSDavide Italiano    # For 'with spawn(...) as child:'
516205fd03aSDavide Italiano    def __enter__(self):
517205fd03aSDavide Italiano        return self
518205fd03aSDavide Italiano
519205fd03aSDavide Italiano    def __exit__(self, etype, evalue, tb):
520205fd03aSDavide Italiano        # We rely on subclasses to implement close(). If they don't, it's not
521205fd03aSDavide Italiano        # clear what a context manager should do.
522205fd03aSDavide Italiano        self.close()
523