##// END OF EJS Templates
Merge pull request #6662 from minrk/dependencies...
Thomas Kluyver -
r20848:e94a8ddf merge
parent child Browse files
Show More
@@ -14,7 +14,7 import sys
14 14 from copy import deepcopy
15 15 from collections import defaultdict
16 16
17 from IPython.external.decorator import decorator
17 from decorator import decorator
18 18
19 19 from IPython.config.configurable import SingletonConfigurable
20 20 from IPython.config.loader import (
@@ -17,7 +17,7 import sys
17 17 import traceback
18 18 import warnings
19 19
20 from IPython.external.decorator import decorator
20 from decorator import decorator
21 21
22 22 from IPython.config.configurable import Configurable
23 23 from IPython.core.getipython import get_ipython
@@ -28,7 +28,7 import threading
28 28
29 29 # Our own packages
30 30 from IPython.config.configurable import Configurable
31 from IPython.external.decorator import decorator
31 from decorator import decorator
32 32 from IPython.utils.decorators import undoc
33 33 from IPython.utils.path import locate_profile
34 34 from IPython.utils import py3compat
@@ -27,6 +27,8 import types
27 27 import subprocess
28 28 from io import open as io_open
29 29
30 from pickleshare import PickleShareDB
31
30 32 from IPython.config.configurable import SingletonConfigurable
31 33 from IPython.core import debugger, oinspect
32 34 from IPython.core import magic
@@ -63,7 +65,6 from IPython.utils.decorators import undoc
63 65 from IPython.utils.io import ask_yes_no
64 66 from IPython.utils.ipstruct import Struct
65 67 from IPython.utils.path import get_home_dir, get_ipython_dir, get_py_filename, unquote_filename, ensure_dir_exists
66 from IPython.utils.pickleshare import PickleShareDB
67 68 from IPython.utils.process import system, getoutput
68 69 from IPython.utils.py3compat import (builtin_mod, unicode_type, string_types,
69 70 with_metaclass, iteritems)
@@ -27,7 +27,7 from IPython.config.configurable import Configurable
27 27 from IPython.core import oinspect
28 28 from IPython.core.error import UsageError
29 29 from IPython.core.inputsplitter import ESC_MAGIC, ESC_MAGIC2
30 from IPython.external.decorator import decorator
30 from decorator import decorator
31 31 from IPython.utils.ipstruct import Struct
32 32 from IPython.utils.process import arg_split
33 33 from IPython.utils.py3compat import string_types, iteritems
@@ -26,7 +26,7 from IPython.core.magic import (Magics, magics_class, line_magic,
26 26 cell_magic, line_cell_magic,
27 27 register_line_magic, register_cell_magic,
28 28 register_line_cell_magic)
29 from IPython.external.decorator import decorator
29 from decorator import decorator
30 30 from IPython.testing.decorators import skipif
31 31 from IPython.testing.tools import AssertPrints
32 32 from IPython.utils.path import compress_user
@@ -73,7 +73,7 from IPython.testing.skipdoctest import skip_doctest
73 73 from IPython.core.magic_arguments import (
74 74 argument, magic_arguments, parse_argstring
75 75 )
76 from IPython.external.simplegeneric import generic
76 from simplegeneric import generic
77 77 from IPython.utils.py3compat import (str_to_unicode, unicode_to_str, PY3,
78 78 unicode_type)
79 79 from IPython.utils.text import dedent
@@ -11,19 +11,14 import zmq
11 11
12 12 from IPython.config.application import Application
13 13 from IPython.utils import io
14
15
16 def _on_os_x_10_9():
17 import platform
18 from distutils.version import LooseVersion as V
19 return sys.platform == 'darwin' and V(platform.mac_ver()[0]) >= V('10.9')
14 from IPython.lib.inputhook import _use_appnope
20 15
21 16 def _notify_stream_qt(kernel, stream):
22 17
23 18 from IPython.external.qt_for_kernel import QtCore
24 19
25 if _on_os_x_10_9() and kernel._darwin_app_nap:
26 from IPython.external.appnope import nope_scope as context
20 if _use_appnope() and kernel._darwin_app_nap:
21 from appnope import nope_scope as context
27 22 else:
28 23 from IPython.core.interactiveshell import NoOpContext as context
29 24
@@ -93,10 +88,10 def loop_wx(kernel):
93 88 import wx
94 89 from IPython.lib.guisupport import start_event_loop_wx
95 90
96 if _on_os_x_10_9() and kernel._darwin_app_nap:
91 if _use_appnope() and kernel._darwin_app_nap:
97 92 # we don't hook up App Nap contexts for Wx,
98 93 # just disable it outright.
99 from IPython.external.appnope import nope
94 from appnope import nope
100 95 nope()
101 96
102 97 doi = kernel.do_one_iteration
@@ -3,16 +3,8
3 3 Inputhook management for GUI event loop integration.
4 4 """
5 5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
16 8
17 9 try:
18 10 import ctypes
@@ -21,6 +13,7 except ImportError:
21 13 except SystemError: # IronPython issue, 2/8/2014
22 14 ctypes = None
23 15 import os
16 import platform
24 17 import sys
25 18 from distutils.version import LooseVersion as V
26 19
@@ -57,8 +50,14 def _stdin_ready_nt():
57 50
58 51 def _stdin_ready_other():
59 52 """Return True, assuming there's something to read on stdin."""
60 return True #
53 return True
54
55 def _use_appnope():
56 """Should we use appnope for dealing with OS X app nap?
61 57
58 Checks if we are on OS X 10.9 or greater.
59 """
60 return sys.platform == 'darwin' and V(platform.mac_ver()[0]) >= V('10.9')
62 61
63 62 def _ignore_CTRL_C_posix():
64 63 """Ignore CTRL+C (SIGINT)."""
@@ -317,9 +316,10 class WxInputHook(InputHookBase):
317 316 raise ValueError("requires wxPython >= 2.8, but you have %s" % wx.__version__)
318 317
319 318 from IPython.lib.inputhookwx import inputhook_wx
320 from IPython.external.appnope import nope
321 319 self.manager.set_inputhook(inputhook_wx)
322 nope()
320 if _use_appnope():
321 from appnope import nope
322 nope()
323 323
324 324 import wx
325 325 if app is None:
@@ -334,8 +334,9 class WxInputHook(InputHookBase):
334 334
335 335 This restores appnapp on OS X
336 336 """
337 from IPython.external.appnope import nap
338 nap()
337 if _use_appnope():
338 from appnope import nap
339 nap()
339 340
340 341 @inputhook_manager.register('qt', 'qt4')
341 342 class Qt4InputHook(InputHookBase):
@@ -362,10 +363,11 class Qt4InputHook(InputHookBase):
362 363 app = QtGui.QApplication(sys.argv)
363 364 """
364 365 from IPython.lib.inputhookqt4 import create_inputhook_qt4
365 from IPython.external.appnope import nope
366 app, inputhook_qt4 = create_inputhook_qt4(self.manager, app)
366 app, inputhook_qt4 = create_inputhook_qt4(self, app)
367 367 self.manager.set_inputhook(inputhook_qt4)
368 nope()
368 if _use_appnope():
369 from appnope import nope
370 nope()
369 371
370 372 return app
371 373
@@ -374,8 +376,9 class Qt4InputHook(InputHookBase):
374 376
375 377 This restores appnapp on OS X
376 378 """
377 from IPython.external.appnope import nap
378 nap()
379 if _use_appnope():
380 from appnope import nap
381 nap()
379 382
380 383
381 384 @inputhook_manager.register('qt5')
@@ -12,7 +12,7 from datetime import datetime
12 12 from zmq import MessageTracker
13 13
14 14 from IPython.core.display import clear_output, display, display_pretty
15 from IPython.external.decorator import decorator
15 from decorator import decorator
16 16 from IPython.parallel import error
17 17 from IPython.utils.py3compat import string_types
18 18
@@ -31,7 +31,7 from IPython.utils.path import get_ipython_dir, compress_user
31 31 from IPython.utils.py3compat import cast_bytes, string_types, xrange, iteritems
32 32 from IPython.utils.traitlets import (HasTraits, Integer, Instance, Unicode,
33 33 Dict, List, Bool, Set, Any)
34 from IPython.external.decorator import decorator
34 from decorator import decorator
35 35
36 36 from IPython.parallel import Reference
37 37 from IPython.parallel import error
@@ -8,7 +8,7 from __future__ import division
8 8 import sys
9 9 import warnings
10 10
11 from IPython.external.decorator import decorator
11 from decorator import decorator
12 12 from IPython.testing.skipdoctest import skip_doctest
13 13
14 14 from . import map as Map
@@ -18,7 +18,7 from IPython.utils import pickleutil
18 18 from IPython.utils.traitlets import (
19 19 HasTraits, Any, Bool, List, Dict, Set, Instance, CFloat, Integer
20 20 )
21 from IPython.external.decorator import decorator
21 from decorator import decorator
22 22
23 23 from IPython.parallel import util
24 24 from IPython.parallel.controller.dependency import Dependency, dependent
@@ -26,7 +26,7 import zmq
26 26 from zmq.eventloop import ioloop, zmqstream
27 27
28 28 # local imports
29 from IPython.external.decorator import decorator
29 from decorator import decorator
30 30 from IPython.config.application import Application
31 31 from IPython.config.loader import Config
32 32 from IPython.utils.traitlets import Instance, Dict, List, Set, Integer, Enum, CBytes
@@ -22,7 +22,7 from nose import SkipTest
22 22 import zmq
23 23 from zmq.tests import BaseZMQTestCase
24 24
25 from IPython.external.decorator import decorator
25 from decorator import decorator
26 26
27 27 from IPython.parallel import error
28 28 from IPython.parallel import Client
@@ -28,7 +28,7 import zmq
28 28 from zmq.log import handlers
29 29
30 30 from IPython.utils.log import get_logger
31 from IPython.external.decorator import decorator
31 from decorator import decorator
32 32
33 33 from IPython.config.application import Application
34 34 from IPython.utils.localinterfaces import localhost, is_public_ip, public_ips
@@ -62,7 +62,7 def stop_console(p, pexpect, t):
62 62
63 63 def start_console():
64 64 "Start `ipython console` using pexpect"
65 from IPython.external import pexpect
65 import pexpect
66 66
67 67 args = ['-m', 'IPython', 'console', '--colors=NoColor']
68 68 cmd = sys.executable
@@ -60,7 +60,7 def test_ipython_embed():
60 60 @skip_win32
61 61 def test_nest_embed():
62 62 """test that `IPython.embed()` is nestable"""
63 from IPython.external import pexpect
63 import pexpect
64 64 ipy_prompt = r']:' #ansi color codes give problems matching beyond this
65 65
66 66
@@ -52,7 +52,7 import unittest
52 52 # Third-party imports
53 53
54 54 # This is Michele Simionato's decorator module, kept verbatim.
55 from IPython.external.decorator import decorator
55 from decorator import decorator
56 56
57 57 # Expose the unittest-driven decorators
58 58 from .ipunittest import ipdoctest, ipdocstring
@@ -42,12 +42,6 from IPython.external.decorators import KnownFailure, knownfailureif
42 42
43 43 pjoin = path.join
44 44
45
46 #-----------------------------------------------------------------------------
47 # Globals
48 #-----------------------------------------------------------------------------
49
50
51 45 #-----------------------------------------------------------------------------
52 46 # Warnings control
53 47 #-----------------------------------------------------------------------------
@@ -127,7 +121,7 have = {}
127 121 have['curses'] = test_for('_curses')
128 122 have['matplotlib'] = test_for('matplotlib')
129 123 have['numpy'] = test_for('numpy')
130 have['pexpect'] = test_for('IPython.external.pexpect')
124 have['pexpect'] = test_for('pexpect')
131 125 have['pymongo'] = test_for('pymongo')
132 126 have['pygments'] = test_for('pygments')
133 127 have['qt'] = test_for('IPython.external.qt')
@@ -21,7 +21,7 import os
21 21 import subprocess as sp
22 22 import sys
23 23
24 from IPython.external import pexpect
24 import pexpect
25 25
26 26 # Our own
27 27 from ._process_common import getoutput, arg_split
@@ -1,26 +1,11
1 1 # encoding: utf-8
2 2 """Generic functions for extending IPython.
3 3
4 See http://cheeseshop.python.org/pypi/simplegeneric.
4 See http://pypi.python.org/pypi/simplegeneric.
5 5 """
6 6
7 #-----------------------------------------------------------------------------
8 # Copyright (C) 2008-2011 The IPython Development Team
9 #
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
12 #-----------------------------------------------------------------------------
13
14 #-----------------------------------------------------------------------------
15 # Imports
16 #-----------------------------------------------------------------------------
17
18 7 from IPython.core.error import TryNext
19 from IPython.external.simplegeneric import generic
20
21 #-----------------------------------------------------------------------------
22 # Imports
23 #-----------------------------------------------------------------------------
8 from simplegeneric import generic
24 9
25 10
26 11 @generic
@@ -8,42 +8,21 Inheritance diagram:
8 8 :parts: 3
9 9 """
10 10
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2011 The IPython Development Team
13 #
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
17
18 #-----------------------------------------------------------------------------
19 # Imports
20 #-----------------------------------------------------------------------------
21
22 11 import os
23 12 import re
24 13 import sys
25 14 import textwrap
26 15 from string import Formatter
27 16
28 from IPython.external.path import path
29 17 from IPython.testing.skipdoctest import skip_doctest_py3, skip_doctest
30 18 from IPython.utils import py3compat
31 19
32 #-----------------------------------------------------------------------------
33 # Declarations
34 #-----------------------------------------------------------------------------
35
36 20 # datetime.strftime date format for ipython
37 21 if sys.platform == 'win32':
38 22 date_format = "%B %d, %Y"
39 23 else:
40 24 date_format = "%B %-d, %Y"
41 25
42
43 #-----------------------------------------------------------------------------
44 # Code
45 #-----------------------------------------------------------------------------
46
47 26 class LSString(str):
48 27 """String derivative with a special access attributes.
49 28
@@ -52,7 +31,7 class LSString(str):
52 31 .l (or .list) : value as list (split on newlines).
53 32 .n (or .nlstr): original value (the string itself).
54 33 .s (or .spstr): value as whitespace-separated string.
55 .p (or .paths): list of path objects
34 .p (or .paths): list of path objects (requires path.py package)
56 35
57 36 Any values which require transformations are computed only once and
58 37 cached.
@@ -84,6 +63,7 class LSString(str):
84 63 n = nlstr = property(get_nlstr)
85 64
86 65 def get_paths(self):
66 from path import path
87 67 try:
88 68 return self.__paths
89 69 except AttributeError:
@@ -113,7 +93,7 class SList(list):
113 93 * .l (or .list) : value as list (the list itself).
114 94 * .n (or .nlstr): value as a string, joined on newlines.
115 95 * .s (or .spstr): value as a string, joined on spaces.
116 * .p (or .paths): list of path objects
96 * .p (or .paths): list of path objects (requires path.py package)
117 97
118 98 Any values which require transformations are computed only once and
119 99 cached."""
@@ -142,6 +122,7 class SList(list):
142 122 n = nlstr = property(get_nlstr)
143 123
144 124 def get_paths(self):
125 from path import path
145 126 try:
146 127 return self.__paths
147 128 except AttributeError:
@@ -63,7 +63,7 from setupbase import (
63 63 find_entry_points,
64 64 build_scripts_entrypt,
65 65 find_data_files,
66 check_for_dependencies,
66 check_for_readline,
67 67 git_prebuild,
68 68 check_submodule_status,
69 69 update_submodules,
@@ -78,7 +78,6 from setupbase import (
78 78 install_scripts_for_symlink,
79 79 unsymlink,
80 80 )
81 from setupext import setupext
82 81
83 82 isfile = os.path.isfile
84 83 pjoin = os.path.join
@@ -268,14 +267,22 if sys.version_info < (3, 3):
268 267 extras_require['notebook'].extend(extras_require['nbformat'])
269 268 extras_require['nbconvert'].extend(extras_require['nbformat'])
270 269
271 install_requires = []
270 install_requires = [
271 'decorator',
272 'pickleshare',
273 'simplegeneric>0.8',
274 ]
272 275
273 # add readline
276 # add platform-specific dependencies
274 277 if sys.platform == 'darwin':
275 if 'bdist_wheel' in sys.argv[1:] or not setupext.check_for_readline():
278 install_requires.append('appnope')
279 if 'bdist_wheel' in sys.argv[1:] or not check_for_readline():
276 280 install_requires.append('gnureadline')
277 elif sys.platform.startswith('win'):
281
282 if sys.platform.startswith('win'):
278 283 extras_require['terminal'].append('pyreadline>=2.0')
284 else:
285 install_requires.append('pexpect')
279 286
280 287 everything = set()
281 288 for deps in extras_require.values():
@@ -317,13 +324,6 if 'setuptools' in sys.modules:
317 324 "ipython_win_post_install.py"}}
318 325
319 326 else:
320 # If we are installing without setuptools, call this function which will
321 # check for dependencies an inform the user what is needed. This is
322 # just to make life easy for users.
323 for install_cmd in ('install', 'symlink'):
324 if install_cmd in sys.argv:
325 check_for_dependencies()
326 break
327 327 # scripts has to be a non-empty list, or install_scripts isn't called
328 328 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
329 329
@@ -490,37 +490,23 class install_scripts_for_symlink(install_scripts):
490 490 # Verify all dependencies
491 491 #---------------------------------------------------------------------------
492 492
493 def check_for_dependencies():
494 """Check for IPython's dependencies.
495
496 This function should NOT be called if running under setuptools!
497 """
498 from setupext.setupext import (
499 print_line, print_raw, print_status,
500 check_for_sphinx, check_for_pygments,
501 check_for_nose, check_for_pexpect,
502 check_for_pyzmq, check_for_readline,
503 check_for_jinja2, check_for_tornado
504 )
505 print_line()
506 print_raw("BUILDING IPYTHON")
507 print_status('python', sys.version)
508 print_status('platform', sys.platform)
509 if sys.platform == 'win32':
510 print_status('Windows version', sys.getwindowsversion())
511
512 print_raw("")
513 print_raw("OPTIONAL DEPENDENCIES")
514
515 check_for_sphinx()
516 check_for_pygments()
517 check_for_nose()
518 if os.name == 'posix':
519 check_for_pexpect()
520 check_for_pyzmq()
521 check_for_tornado()
522 check_for_readline()
523 check_for_jinja2()
493 def check_for_readline():
494 """Check for GNU readline"""
495 try:
496 import gnureadline as readline
497 except ImportError:
498 pass
499 else:
500 return True
501 try:
502 import readline
503 except ImportError:
504 return False
505 else:
506 if sys.platform == 'darwin' and 'libedit' in readline.__doc__:
507 print("Ignoring readline linked to libedit", file=sys.stderr)
508 return False
509 return True
524 510
525 511 #---------------------------------------------------------------------------
526 512 # VCS related
@@ -670,7 +656,7 def get_bdist_wheel():
670 656 if found:
671 657 lis.pop(idx)
672 658
673 for pkg in ("gnureadline", "pyreadline", "mock", "terminado"):
659 for pkg in ("gnureadline", "pyreadline", "mock", "terminado", "appnope", "pexpect"):
674 660 _remove_startswith(requires, pkg)
675 661 requires.append("gnureadline; sys.platform == 'darwin' and platform.python_implementation == 'CPython'")
676 662 requires.append("terminado (>=0.3.3); extra == 'notebook' and sys.platform != 'win32'")
@@ -678,6 +664,8 def get_bdist_wheel():
678 664 requires.append("pyreadline (>=2.0); extra == 'terminal' and sys.platform == 'win32' and platform.python_implementation == 'CPython'")
679 665 requires.append("pyreadline (>=2.0); extra == 'all' and sys.platform == 'win32' and platform.python_implementation == 'CPython'")
680 666 requires.append("mock; extra == 'test' and python_version < '3.3'")
667 requires.append("appnope; sys.platform == 'darwin'")
668 requires.append("pexpect; sys.platform != 'win32'")
681 669 for r in requires:
682 670 pkg_info['Requires-Dist'] = r
683 671 write_pkg_info(metadata_path, pkg_info)
@@ -1,15 +0,0
1
2 try:
3 from appnope import *
4 except ImportError:
5 __version__ = '0.0.5'
6 import sys
7 import platform
8 from distutils.version import LooseVersion as V
9
10 if sys.platform != "darwin" or V(platform.mac_ver()[0]) < V("10.9"):
11 from ._dummy import *
12 else:
13 from ._nope import *
14
15 del sys, platform, V
@@ -1,30 +0,0
1 #-----------------------------------------------------------------------------
2 # Copyright (C) 2013 Min RK
3 #
4 # Distributed under the terms of the 2-clause BSD License.
5 #-----------------------------------------------------------------------------
6
7 from contextlib import contextmanager
8
9 def beginActivityWithOptions(options, reason=""):
10 return
11
12 def endActivity(activity):
13 return
14
15 def nope():
16 return
17
18 def nap():
19 return
20
21
22 @contextmanager
23 def nope_scope(
24 options=0,
25 reason="Because Reasons"
26 ):
27 yield
28
29 def napping_allowed():
30 return True No newline at end of file
@@ -1,126 +0,0
1 #-----------------------------------------------------------------------------
2 # Copyright (C) 2013 Min RK
3 #
4 # Distributed under the terms of the 2-clause BSD License.
5 #-----------------------------------------------------------------------------
6
7 from contextlib import contextmanager
8
9 import ctypes
10 import ctypes.util
11
12 objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc'))
13
14 void_p = ctypes.c_void_p
15 ull = ctypes.c_uint64
16
17 objc.objc_getClass.restype = void_p
18 objc.sel_registerName.restype = void_p
19 objc.objc_msgSend.restype = void_p
20 objc.objc_msgSend.argtypes = [void_p, void_p]
21
22 msg = objc.objc_msgSend
23
24 def _utf8(s):
25 """ensure utf8 bytes"""
26 if not isinstance(s, bytes):
27 s = s.encode('utf8')
28 return s
29
30 def n(name):
31 """create a selector name (for methods)"""
32 return objc.sel_registerName(_utf8(name))
33
34 def C(classname):
35 """get an ObjC Class by name"""
36 return objc.objc_getClass(_utf8(classname))
37
38 # constants from Foundation
39
40 NSActivityIdleDisplaySleepDisabled = (1 << 40)
41 NSActivityIdleSystemSleepDisabled = (1 << 20)
42 NSActivitySuddenTerminationDisabled = (1 << 14)
43 NSActivityAutomaticTerminationDisabled = (1 << 15)
44 NSActivityUserInitiated = (0x00FFFFFF | NSActivityIdleSystemSleepDisabled)
45 NSActivityUserInitiatedAllowingIdleSystemSleep = (NSActivityUserInitiated & ~NSActivityIdleSystemSleepDisabled)
46 NSActivityBackground = 0x000000FF
47 NSActivityLatencyCritical = 0xFF00000000
48
49 def beginActivityWithOptions(options, reason=""):
50 """Wrapper for:
51
52 [ [ NSProcessInfo processInfo]
53 beginActivityWithOptions: (uint64)options
54 reason: (str)reason
55 ]
56 """
57 NSProcessInfo = C('NSProcessInfo')
58 NSString = C('NSString')
59
60 reason = msg(NSString, n("stringWithUTF8String:"), _utf8(reason))
61 info = msg(NSProcessInfo, n('processInfo'))
62 activity = msg(info,
63 n('beginActivityWithOptions:reason:'),
64 ull(options),
65 void_p(reason)
66 )
67 return activity
68
69 def endActivity(activity):
70 """end a process activity assertion"""
71 NSProcessInfo = C('NSProcessInfo')
72 info = msg(NSProcessInfo, n('processInfo'))
73 msg(info, n("endActivity:"), void_p(activity))
74
75 _theactivity = None
76
77 def nope():
78 """disable App Nap by setting NSActivityUserInitiatedAllowingIdleSystemSleep"""
79 global _theactivity
80 _theactivity = beginActivityWithOptions(
81 NSActivityUserInitiatedAllowingIdleSystemSleep,
82 "Because Reasons"
83 )
84
85 def nap():
86 """end the caffeinated state started by `nope`"""
87 global _theactivity
88 if _theactivity is not None:
89 endActivity(_theactivity)
90 _theactivity = None
91
92 def napping_allowed():
93 """is napping allowed?"""
94 return _theactivity is None
95
96 @contextmanager
97 def nope_scope(
98 options=NSActivityUserInitiatedAllowingIdleSystemSleep,
99 reason="Because Reasons"
100 ):
101 """context manager for beginActivityWithOptions.
102
103 Within this context, App Nap will be disabled.
104 """
105 activity = beginActivityWithOptions(options, reason)
106 try:
107 yield
108 finally:
109 endActivity(activity)
110
111 __all__ = [
112 "NSActivityIdleDisplaySleepDisabled",
113 "NSActivityIdleSystemSleepDisabled",
114 "NSActivitySuddenTerminationDisabled",
115 "NSActivityAutomaticTerminationDisabled",
116 "NSActivityUserInitiated",
117 "NSActivityUserInitiatedAllowingIdleSystemSleep",
118 "NSActivityBackground",
119 "NSActivityLatencyCritical",
120 "beginActivityWithOptions",
121 "endActivity",
122 "nope",
123 "nap",
124 "napping_allowed",
125 "nope_scope",
126 ]
@@ -1,4 +0,0
1 try:
2 from decorator import *
3 except ImportError:
4 from ._decorator import *
@@ -1,229 +0,0
1 ########################## LICENCE ###############################
2
3 # Copyright (c) 2005-2012, Michele Simionato
4 # All rights reserved.
5
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions are
8 # met:
9
10 # Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # Redistributions in bytecode form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in
14 # the documentation and/or other materials provided with the
15 # distribution.
16
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
28 # DAMAGE.
29
30 """
31 Decorator module, see http://pypi.python.org/pypi/decorator
32 for the documentation.
33
34 NOTE: this is an IPython-patched version to work on IronPython. See
35 FIXED comment below.
36 """
37 from __future__ import print_function
38
39 __version__ = '3.3.3'
40
41 __all__ = ["decorator", "FunctionMaker", "partial"]
42
43 import sys, re, inspect
44
45 try:
46 from functools import partial
47 except ImportError: # for Python version < 2.5
48 class partial(object):
49 "A simple replacement of functools.partial"
50 def __init__(self, func, *args, **kw):
51 self.func = func
52 self.args = args
53 self.keywords = kw
54 def __call__(self, *otherargs, **otherkw):
55 kw = self.keywords.copy()
56 kw.update(otherkw)
57 return self.func(*(self.args + otherargs), **kw)
58
59 if sys.version >= '3':
60 from inspect import getfullargspec
61 else:
62 class getfullargspec(object):
63 "A quick and dirty replacement for getfullargspec for Python 2.X"
64 def __init__(self, f):
65 self.args, self.varargs, self.varkw, self.defaults = \
66 inspect.getargspec(f)
67 self.kwonlyargs = []
68 self.kwonlydefaults = None
69 def __iter__(self):
70 yield self.args
71 yield self.varargs
72 yield self.varkw
73 yield self.defaults
74
75 DEF = re.compile('\s*def\s*([_\w][_\w\d]*)\s*\(')
76
77 # basic functionality
78 class FunctionMaker(object):
79 """
80 An object with the ability to create functions with a given signature.
81 It has attributes name, doc, module, signature, defaults, dict and
82 methods update and make.
83 """
84 def __init__(self, func=None, name=None, signature=None,
85 defaults=None, doc=None, module=None, funcdict=None):
86 self.shortsignature = signature
87 if func:
88 # func can be a class or a callable, but not an instance method
89 self.name = func.__name__
90 if self.name == '<lambda>': # small hack for lambda functions
91 self.name = '_lambda_'
92 self.doc = func.__doc__
93 self.module = func.__module__
94 if inspect.isfunction(func):
95 argspec = getfullargspec(func)
96 self.annotations = getattr(func, '__annotations__', {})
97 for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs',
98 'kwonlydefaults'):
99 setattr(self, a, getattr(argspec, a))
100 for i, arg in enumerate(self.args):
101 setattr(self, 'arg%d' % i, arg)
102 if sys.version < '3': # easy way
103 self.shortsignature = self.signature = \
104 inspect.formatargspec(
105 formatvalue=lambda val: "", *argspec)[1:-1]
106 else: # Python 3 way
107 self.signature = self.shortsignature = ', '.join(self.args)
108 if self.varargs:
109 self.signature += ', *' + self.varargs
110 self.shortsignature += ', *' + self.varargs
111 if self.kwonlyargs:
112 for a in self.kwonlyargs:
113 self.signature += ', %s=None' % a
114 self.shortsignature += ', %s=%s' % (a, a)
115 if self.varkw:
116 self.signature += ', **' + self.varkw
117 self.shortsignature += ', **' + self.varkw
118 self.dict = func.__dict__.copy()
119 # func=None happens when decorating a caller
120 if name:
121 self.name = name
122 if signature is not None:
123 self.signature = signature
124 if defaults:
125 self.defaults = defaults
126 if doc:
127 self.doc = doc
128 if module:
129 self.module = module
130 if funcdict:
131 self.dict = funcdict
132 # check existence required attributes
133 assert hasattr(self, 'name')
134 if not hasattr(self, 'signature'):
135 raise TypeError('You are decorating a non function: %s' % func)
136
137 def update(self, func, **kw):
138 "Update the signature of func with the data in self"
139 func.__name__ = self.name
140 func.__doc__ = getattr(self, 'doc', None)
141 func.__dict__ = getattr(self, 'dict', {})
142 func.__defaults__ = getattr(self, 'defaults', ())
143 func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None)
144 func.__annotations__ = getattr(self, 'annotations', None)
145 # FIXED: The following is try/excepted in IPython to work
146 # with IronPython.
147 try:
148 callermodule = sys._getframe(3).f_globals.get('__name__', '?')
149 except AttributeError: # IronPython _getframe only exists with FullFrames
150 callermodule = '?'
151 func.__module__ = getattr(self, 'module', callermodule)
152 func.__dict__.update(kw)
153
154 def make(self, src_templ, evaldict=None, addsource=False, **attrs):
155 "Make a new function from a given template and update the signature"
156 src = src_templ % vars(self) # expand name and signature
157 evaldict = evaldict or {}
158 mo = DEF.match(src)
159 if mo is None:
160 raise SyntaxError('not a valid function template\n%s' % src)
161 name = mo.group(1) # extract the function name
162 names = set([name] + [arg.strip(' *') for arg in
163 self.shortsignature.split(',')])
164 for n in names:
165 if n in ('_func_', '_call_'):
166 raise NameError('%s is overridden in\n%s' % (n, src))
167 if not src.endswith('\n'): # add a newline just for safety
168 src += '\n' # this is needed in old versions of Python
169 try:
170 code = compile(src, '<string>', 'single')
171 # print >> sys.stderr, 'Compiling %s' % src
172 exec(code, evaldict)
173 except:
174 print('Error in generated code:', file=sys.stderr)
175 print(src, file=sys.stderr)
176 raise
177 func = evaldict[name]
178 if addsource:
179 attrs['__source__'] = src
180 self.update(func, **attrs)
181 return func
182
183 @classmethod
184 def create(cls, obj, body, evaldict, defaults=None,
185 doc=None, module=None, addsource=True, **attrs):
186 """
187 Create a function from the strings name, signature and body.
188 evaldict is the evaluation dictionary. If addsource is true an attribute
189 __source__ is added to the result. The attributes attrs are added,
190 if any.
191 """
192 if isinstance(obj, str): # "name(signature)"
193 name, rest = obj.strip().split('(', 1)
194 signature = rest[:-1] #strip a right parens
195 func = None
196 else: # a function
197 name = None
198 signature = None
199 func = obj
200 self = cls(func, name, signature, defaults, doc, module)
201 ibody = '\n'.join(' ' + line for line in body.splitlines())
202 return self.make('def %(name)s(%(signature)s):\n' + ibody,
203 evaldict, addsource, **attrs)
204
205 def decorator(caller, func=None):
206 """
207 decorator(caller) converts a caller function into a decorator;
208 decorator(caller, func) decorates a function using a caller.
209 """
210 if func is not None: # returns a decorated function
211 evaldict = func.__globals__.copy()
212 evaldict['_call_'] = caller
213 evaldict['_func_'] = func
214 return FunctionMaker.create(
215 func, "return _call_(_func_, %(shortsignature)s)",
216 evaldict, undecorated=func, __wrapped__=func)
217 else: # returns a decorator
218 if isinstance(caller, partial):
219 return partial(decorator, caller)
220 # otherwise assume caller is a function
221 first = inspect.getargspec(caller)[0][0] # first arg
222 evaldict = caller.__globals__.copy()
223 evaldict['_call_'] = caller
224 evaldict['decorator'] = decorator
225 return FunctionMaker.create(
226 '%s(%s)' % (caller.__name__, first),
227 'return decorator(_call_, %s)' % first,
228 evaldict, undecorated=caller, __wrapped__=caller,
229 doc=caller.__doc__, module=caller.__module__)
@@ -1,4 +0,0
1 try:
2 from path import *
3 except ImportError:
4 from ._path import *
This diff has been collapsed as it changes many lines, (1267 lines changed) Show them Hide them
@@ -1,1267 +0,0
1 #
2 # Copyright (c) 2010 Mikhail Gusarov
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining a copy
5 # of this software and associated documentation files (the "Software"), to deal
6 # in the Software without restriction, including without limitation the rights
7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 # copies of the Software, and to permit persons to whom the Software is
9 # furnished to do so, subject to the following conditions:
10 #
11 # The above copyright notice and this permission notice shall be included in
12 # all copies or substantial portions of the Software.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 # SOFTWARE.
21 #
22
23 """ path.py - An object representing a path to a file or directory.
24
25 Original author:
26 Jason Orendorff <jason.orendorff\x40gmail\x2ecom>
27
28 Current maintainer:
29 Jason R. Coombs <jaraco@jaraco.com>
30
31 Contributors:
32 Mikhail Gusarov <dottedmag@dottedmag.net>
33 Marc Abramowitz <marc@marc-abramowitz.com>
34 Jason R. Coombs <jaraco@jaraco.com>
35 Jason Chu <jchu@xentac.net>
36 Vojislav Stojkovic <vstojkovic@syntertainment.com>
37
38 Example::
39
40 from path import path
41 d = path('/home/guido/bin')
42 for f in d.files('*.py'):
43 f.chmod(0755)
44
45 path.py requires Python 2.5 or later.
46 """
47
48 from __future__ import with_statement
49
50 import sys
51 import warnings
52 import os
53 import fnmatch
54 import glob
55 import shutil
56 import codecs
57 import hashlib
58 import errno
59 import tempfile
60 import functools
61 import operator
62 import re
63
64 try:
65 import win32security
66 except ImportError:
67 pass
68
69 try:
70 import pwd
71 except ImportError:
72 pass
73
74 ################################
75 # Monkey patchy python 3 support
76 try:
77 basestring
78 except NameError:
79 basestring = str
80
81 try:
82 unicode
83 except NameError:
84 unicode = str
85
86 try:
87 getcwdu = os.getcwdu
88 except AttributeError:
89 getcwdu = os.getcwd
90
91 if sys.version < '3':
92 def u(x):
93 return codecs.unicode_escape_decode(x)[0]
94 else:
95 def u(x):
96 return x
97
98 o777 = 511
99 o766 = 502
100 o666 = 438
101 o554 = 364
102 ################################
103
104 __version__ = '4.3'
105 __all__ = ['path']
106
107
108 class TreeWalkWarning(Warning):
109 pass
110
111
112 def simple_cache(func):
113 """
114 Save results for the 'using_module' classmethod.
115 When Python 3.2 is available, use functools.lru_cache instead.
116 """
117 saved_results = {}
118
119 def wrapper(cls, module):
120 if module in saved_results:
121 return saved_results[module]
122 saved_results[module] = func(cls, module)
123 return saved_results[module]
124 return wrapper
125
126
127 class ClassProperty(property):
128 def __get__(self, cls, owner):
129 return self.fget.__get__(None, owner)()
130
131
132 class multimethod(object):
133 """
134 Acts like a classmethod when invoked from the class and like an
135 instancemethod when invoked from the instance.
136 """
137 def __init__(self, func):
138 self.func = func
139
140 def __get__(self, instance, owner):
141 return (
142 functools.partial(self.func, owner) if instance is None
143 else functools.partial(self.func, owner, instance)
144 )
145
146
147 class path(unicode):
148 """ Represents a filesystem path.
149
150 For documentation on individual methods, consult their
151 counterparts in os.path.
152 """
153
154 module = os.path
155 "The path module to use for path operations."
156
157 def __init__(self, other=''):
158 if other is None:
159 raise TypeError("Invalid initial value for path: None")
160
161 @classmethod
162 @simple_cache
163 def using_module(cls, module):
164 subclass_name = cls.__name__ + '_' + module.__name__
165 bases = (cls,)
166 ns = {'module': module}
167 return type(subclass_name, bases, ns)
168
169 @ClassProperty
170 @classmethod
171 def _next_class(cls):
172 """
173 What class should be used to construct new instances from this class
174 """
175 return cls
176
177 # --- Special Python methods.
178
179 def __repr__(self):
180 return '%s(%s)' % (type(self).__name__, super(path, self).__repr__())
181
182 # Adding a path and a string yields a path.
183 def __add__(self, more):
184 try:
185 return self._next_class(super(path, self).__add__(more))
186 except TypeError: # Python bug
187 return NotImplemented
188
189 def __radd__(self, other):
190 if not isinstance(other, basestring):
191 return NotImplemented
192 return self._next_class(other.__add__(self))
193
194 # The / operator joins paths.
195 def __div__(self, rel):
196 """ fp.__div__(rel) == fp / rel == fp.joinpath(rel)
197
198 Join two path components, adding a separator character if
199 needed.
200 """
201 return self._next_class(self.module.join(self, rel))
202
203 # Make the / operator work even when true division is enabled.
204 __truediv__ = __div__
205
206 def __enter__(self):
207 self._old_dir = self.getcwd()
208 os.chdir(self)
209 return self
210
211 def __exit__(self, *_):
212 os.chdir(self._old_dir)
213
214 @classmethod
215 def getcwd(cls):
216 """ Return the current working directory as a path object. """
217 return cls(getcwdu())
218
219 #
220 # --- Operations on path strings.
221
222 def abspath(self):
223 return self._next_class(self.module.abspath(self))
224
225 def normcase(self):
226 return self._next_class(self.module.normcase(self))
227
228 def normpath(self):
229 return self._next_class(self.module.normpath(self))
230
231 def realpath(self):
232 return self._next_class(self.module.realpath(self))
233
234 def expanduser(self):
235 return self._next_class(self.module.expanduser(self))
236
237 def expandvars(self):
238 return self._next_class(self.module.expandvars(self))
239
240 def dirname(self):
241 return self._next_class(self.module.dirname(self))
242
243 def basename(self):
244 return self._next_class(self.module.basename(self))
245
246 def expand(self):
247 """ Clean up a filename by calling expandvars(),
248 expanduser(), and normpath() on it.
249
250 This is commonly everything needed to clean up a filename
251 read from a configuration file, for example.
252 """
253 return self.expandvars().expanduser().normpath()
254
255 @property
256 def namebase(self):
257 """ The same as path.name, but with one file extension stripped off.
258
259 For example, path('/home/guido/python.tar.gz').name == 'python.tar.gz',
260 but path('/home/guido/python.tar.gz').namebase == 'python.tar'
261 """
262 base, ext = self.module.splitext(self.name)
263 return base
264
265 @property
266 def ext(self):
267 """ The file extension, for example '.py'. """
268 f, ext = self.module.splitext(self)
269 return ext
270
271 @property
272 def drive(self):
273 """ The drive specifier, for example 'C:'.
274 This is always empty on systems that don't use drive specifiers.
275 """
276 drive, r = self.module.splitdrive(self)
277 return self._next_class(drive)
278
279 parent = property(
280 dirname, None, None,
281 """ This path's parent directory, as a new path object.
282
283 For example,
284 path('/usr/local/lib/libpython.so').parent == path('/usr/local/lib')
285 """)
286
287 name = property(
288 basename, None, None,
289 """ The name of this file or directory without the full path.
290
291 For example, path('/usr/local/lib/libpython.so').name == 'libpython.so'
292 """)
293
294 def splitpath(self):
295 """ p.splitpath() -> Return (p.parent, p.name). """
296 parent, child = self.module.split(self)
297 return self._next_class(parent), child
298
299 def splitdrive(self):
300 """ p.splitdrive() -> Return (p.drive, <the rest of p>).
301
302 Split the drive specifier from this path. If there is
303 no drive specifier, p.drive is empty, so the return value
304 is simply (path(''), p). This is always the case on Unix.
305 """
306 drive, rel = self.module.splitdrive(self)
307 return self._next_class(drive), rel
308
309 def splitext(self):
310 """ p.splitext() -> Return (p.stripext(), p.ext).
311
312 Split the filename extension from this path and return
313 the two parts. Either part may be empty.
314
315 The extension is everything from '.' to the end of the
316 last path segment. This has the property that if
317 (a, b) == p.splitext(), then a + b == p.
318 """
319 filename, ext = self.module.splitext(self)
320 return self._next_class(filename), ext
321
322 def stripext(self):
323 """ p.stripext() -> Remove one file extension from the path.
324
325 For example, path('/home/guido/python.tar.gz').stripext()
326 returns path('/home/guido/python.tar').
327 """
328 return self.splitext()[0]
329
330 def splitunc(self):
331 unc, rest = self.module.splitunc(self)
332 return self._next_class(unc), rest
333
334 @property
335 def uncshare(self):
336 """
337 The UNC mount point for this path.
338 This is empty for paths on local drives.
339 """
340 unc, r = self.module.splitunc(self)
341 return self._next_class(unc)
342
343 @multimethod
344 def joinpath(cls, first, *others):
345 """
346 Join first to zero or more path components, adding a separator
347 character (first.module.sep) if needed. Returns a new instance of
348 first._next_class.
349 """
350 if not isinstance(first, cls):
351 first = cls(first)
352 return first._next_class(first.module.join(first, *others))
353
354 def splitall(self):
355 r""" Return a list of the path components in this path.
356
357 The first item in the list will be a path. Its value will be
358 either os.curdir, os.pardir, empty, or the root directory of
359 this path (for example, ``'/'`` or ``'C:\\'``). The other items in
360 the list will be strings.
361
362 ``path.path.joinpath(*result)`` will yield the original path.
363 """
364 parts = []
365 loc = self
366 while loc != os.curdir and loc != os.pardir:
367 prev = loc
368 loc, child = prev.splitpath()
369 if loc == prev:
370 break
371 parts.append(child)
372 parts.append(loc)
373 parts.reverse()
374 return parts
375
376 def relpath(self, start='.'):
377 """ Return this path as a relative path,
378 based from start, which defaults to the current working directory.
379 """
380 cwd = self._next_class(start)
381 return cwd.relpathto(self)
382
383 def relpathto(self, dest):
384 """ Return a relative path from self to dest.
385
386 If there is no relative path from self to dest, for example if
387 they reside on different drives in Windows, then this returns
388 dest.abspath().
389 """
390 origin = self.abspath()
391 dest = self._next_class(dest).abspath()
392
393 orig_list = origin.normcase().splitall()
394 # Don't normcase dest! We want to preserve the case.
395 dest_list = dest.splitall()
396
397 if orig_list[0] != self.module.normcase(dest_list[0]):
398 # Can't get here from there.
399 return dest
400
401 # Find the location where the two paths start to differ.
402 i = 0
403 for start_seg, dest_seg in zip(orig_list, dest_list):
404 if start_seg != self.module.normcase(dest_seg):
405 break
406 i += 1
407
408 # Now i is the point where the two paths diverge.
409 # Need a certain number of "os.pardir"s to work up
410 # from the origin to the point of divergence.
411 segments = [os.pardir] * (len(orig_list) - i)
412 # Need to add the diverging part of dest_list.
413 segments += dest_list[i:]
414 if len(segments) == 0:
415 # If they happen to be identical, use os.curdir.
416 relpath = os.curdir
417 else:
418 relpath = self.module.join(*segments)
419 return self._next_class(relpath)
420
421 # --- Listing, searching, walking, and matching
422
423 def listdir(self, pattern=None):
424 """ D.listdir() -> List of items in this directory.
425
426 Use D.files() or D.dirs() instead if you want a listing
427 of just files or just subdirectories.
428
429 The elements of the list are path objects.
430
431 With the optional 'pattern' argument, this only lists
432 items whose names match the given pattern.
433 """
434 names = os.listdir(self)
435 if pattern is not None:
436 names = fnmatch.filter(names, pattern)
437 return [self / child for child in names]
438
439 def dirs(self, pattern=None):
440 """ D.dirs() -> List of this directory's subdirectories.
441
442 The elements of the list are path objects.
443 This does not walk recursively into subdirectories
444 (but see path.walkdirs).
445
446 With the optional 'pattern' argument, this only lists
447 directories whose names match the given pattern. For
448 example, ``d.dirs('build-*')``.
449 """
450 return [p for p in self.listdir(pattern) if p.isdir()]
451
452 def files(self, pattern=None):
453 """ D.files() -> List of the files in this directory.
454
455 The elements of the list are path objects.
456 This does not walk into subdirectories (see path.walkfiles).
457
458 With the optional 'pattern' argument, this only lists files
459 whose names match the given pattern. For example,
460 ``d.files('*.pyc')``.
461 """
462
463 return [p for p in self.listdir(pattern) if p.isfile()]
464
465 def walk(self, pattern=None, errors='strict'):
466 """ D.walk() -> iterator over files and subdirs, recursively.
467
468 The iterator yields path objects naming each child item of
469 this directory and its descendants. This requires that
470 D.isdir().
471
472 This performs a depth-first traversal of the directory tree.
473 Each directory is returned just before all its children.
474
475 The errors= keyword argument controls behavior when an
476 error occurs. The default is 'strict', which causes an
477 exception. The other allowed values are 'warn', which
478 reports the error via warnings.warn(), and 'ignore'.
479 """
480 if errors not in ('strict', 'warn', 'ignore'):
481 raise ValueError("invalid errors parameter")
482
483 try:
484 childList = self.listdir()
485 except Exception:
486 if errors == 'ignore':
487 return
488 elif errors == 'warn':
489 warnings.warn(
490 "Unable to list directory '%s': %s"
491 % (self, sys.exc_info()[1]),
492 TreeWalkWarning)
493 return
494 else:
495 raise
496
497 for child in childList:
498 if pattern is None or child.fnmatch(pattern):
499 yield child
500 try:
501 isdir = child.isdir()
502 except Exception:
503 if errors == 'ignore':
504 isdir = False
505 elif errors == 'warn':
506 warnings.warn(
507 "Unable to access '%s': %s"
508 % (child, sys.exc_info()[1]),
509 TreeWalkWarning)
510 isdir = False
511 else:
512 raise
513
514 if isdir:
515 for item in child.walk(pattern, errors):
516 yield item
517
518 def walkdirs(self, pattern=None, errors='strict'):
519 """ D.walkdirs() -> iterator over subdirs, recursively.
520
521 With the optional 'pattern' argument, this yields only
522 directories whose names match the given pattern. For
523 example, ``mydir.walkdirs('*test')`` yields only directories
524 with names ending in 'test'.
525
526 The errors= keyword argument controls behavior when an
527 error occurs. The default is 'strict', which causes an
528 exception. The other allowed values are 'warn', which
529 reports the error via warnings.warn(), and 'ignore'.
530 """
531 if errors not in ('strict', 'warn', 'ignore'):
532 raise ValueError("invalid errors parameter")
533
534 try:
535 dirs = self.dirs()
536 except Exception:
537 if errors == 'ignore':
538 return
539 elif errors == 'warn':
540 warnings.warn(
541 "Unable to list directory '%s': %s"
542 % (self, sys.exc_info()[1]),
543 TreeWalkWarning)
544 return
545 else:
546 raise
547
548 for child in dirs:
549 if pattern is None or child.fnmatch(pattern):
550 yield child
551 for subsubdir in child.walkdirs(pattern, errors):
552 yield subsubdir
553
554 def walkfiles(self, pattern=None, errors='strict'):
555 """ D.walkfiles() -> iterator over files in D, recursively.
556
557 The optional argument, pattern, limits the results to files
558 with names that match the pattern. For example,
559 ``mydir.walkfiles('*.tmp')`` yields only files with the .tmp
560 extension.
561 """
562 if errors not in ('strict', 'warn', 'ignore'):
563 raise ValueError("invalid errors parameter")
564
565 try:
566 childList = self.listdir()
567 except Exception:
568 if errors == 'ignore':
569 return
570 elif errors == 'warn':
571 warnings.warn(
572 "Unable to list directory '%s': %s"
573 % (self, sys.exc_info()[1]),
574 TreeWalkWarning)
575 return
576 else:
577 raise
578
579 for child in childList:
580 try:
581 isfile = child.isfile()
582 isdir = not isfile and child.isdir()
583 except:
584 if errors == 'ignore':
585 continue
586 elif errors == 'warn':
587 warnings.warn(
588 "Unable to access '%s': %s"
589 % (self, sys.exc_info()[1]),
590 TreeWalkWarning)
591 continue
592 else:
593 raise
594
595 if isfile:
596 if pattern is None or child.fnmatch(pattern):
597 yield child
598 elif isdir:
599 for f in child.walkfiles(pattern, errors):
600 yield f
601
602 def fnmatch(self, pattern):
603 """ Return True if self.name matches the given pattern.
604
605 pattern - A filename pattern with wildcards,
606 for example ``'*.py'``.
607 """
608 return fnmatch.fnmatch(self.name, pattern)
609
610 def glob(self, pattern):
611 """ Return a list of path objects that match the pattern.
612
613 pattern - a path relative to this directory, with wildcards.
614
615 For example, path('/users').glob('*/bin/*') returns a list
616 of all the files users have in their bin directories.
617 """
618 cls = self._next_class
619 return [cls(s) for s in glob.glob(self / pattern)]
620
621 #
622 # --- Reading or writing an entire file at once.
623
624 def open(self, *args, **kwargs):
625 """ Open this file. Return a file object. """
626 return open(self, *args, **kwargs)
627
628 def bytes(self):
629 """ Open this file, read all bytes, return them as a string. """
630 with self.open('rb') as f:
631 return f.read()
632
633 def chunks(self, size, *args, **kwargs):
634 """ Returns a generator yielding chunks of the file, so it can
635 be read piece by piece with a simple for loop.
636
637 Any argument you pass after `size` will be passed to `open()`.
638
639 :example:
640
641 >>> for chunk in path("file.txt").chunk(8192):
642 ... print(chunk)
643
644 This will read the file by chunks of 8192 bytes.
645 """
646 with open(self, *args, **kwargs) as f:
647 while True:
648 d = f.read(size)
649 if not d:
650 break
651 yield d
652
653 def write_bytes(self, bytes, append=False):
654 """ Open this file and write the given bytes to it.
655
656 Default behavior is to overwrite any existing file.
657 Call p.write_bytes(bytes, append=True) to append instead.
658 """
659 if append:
660 mode = 'ab'
661 else:
662 mode = 'wb'
663 with self.open(mode) as f:
664 f.write(bytes)
665
666 def text(self, encoding=None, errors='strict'):
667 r""" Open this file, read it in, return the content as a string.
668
669 This method uses 'U' mode, so '\r\n' and '\r' are automatically
670 translated to '\n'.
671
672 Optional arguments:
673
674 encoding - The Unicode encoding (or character set) of
675 the file. If present, the content of the file is
676 decoded and returned as a unicode object; otherwise
677 it is returned as an 8-bit str.
678 errors - How to handle Unicode errors; see help(str.decode)
679 for the options. Default is 'strict'.
680 """
681 if encoding is None:
682 # 8-bit
683 with self.open('U') as f:
684 return f.read()
685 else:
686 # Unicode
687 with codecs.open(self, 'r', encoding, errors) as f:
688 # (Note - Can't use 'U' mode here, since codecs.open
689 # doesn't support 'U' mode.)
690 t = f.read()
691 return (t.replace(u('\r\n'), u('\n'))
692 .replace(u('\r\x85'), u('\n'))
693 .replace(u('\r'), u('\n'))
694 .replace(u('\x85'), u('\n'))
695 .replace(u('\u2028'), u('\n')))
696
697 def write_text(self, text, encoding=None, errors='strict',
698 linesep=os.linesep, append=False):
699 r""" Write the given text to this file.
700
701 The default behavior is to overwrite any existing file;
702 to append instead, use the 'append=True' keyword argument.
703
704 There are two differences between path.write_text() and
705 path.write_bytes(): newline handling and Unicode handling.
706 See below.
707
708 Parameters:
709
710 - text - str/unicode - The text to be written.
711
712 - encoding - str - The Unicode encoding that will be used.
713 This is ignored if 'text' isn't a Unicode string.
714
715 - errors - str - How to handle Unicode encoding errors.
716 Default is 'strict'. See help(unicode.encode) for the
717 options. This is ignored if 'text' isn't a Unicode
718 string.
719
720 - linesep - keyword argument - str/unicode - The sequence of
721 characters to be used to mark end-of-line. The default is
722 os.linesep. You can also specify None; this means to
723 leave all newlines as they are in 'text'.
724
725 - append - keyword argument - bool - Specifies what to do if
726 the file already exists (True: append to the end of it;
727 False: overwrite it.) The default is False.
728
729
730 --- Newline handling.
731
732 write_text() converts all standard end-of-line sequences
733 ('\n', '\r', and '\r\n') to your platform's default end-of-line
734 sequence (see os.linesep; on Windows, for example, the
735 end-of-line marker is '\r\n').
736
737 If you don't like your platform's default, you can override it
738 using the 'linesep=' keyword argument. If you specifically want
739 write_text() to preserve the newlines as-is, use 'linesep=None'.
740
741 This applies to Unicode text the same as to 8-bit text, except
742 there are three additional standard Unicode end-of-line sequences:
743 u'\x85', u'\r\x85', and u'\u2028'.
744
745 (This is slightly different from when you open a file for
746 writing with fopen(filename, "w") in C or open(filename, 'w')
747 in Python.)
748
749
750 --- Unicode
751
752 If 'text' isn't Unicode, then apart from newline handling, the
753 bytes are written verbatim to the file. The 'encoding' and
754 'errors' arguments are not used and must be omitted.
755
756 If 'text' is Unicode, it is first converted to bytes using the
757 specified 'encoding' (or the default encoding if 'encoding'
758 isn't specified). The 'errors' argument applies only to this
759 conversion.
760
761 """
762 if isinstance(text, unicode):
763 if linesep is not None:
764 # Convert all standard end-of-line sequences to
765 # ordinary newline characters.
766 text = (text.replace(u('\r\n'), u('\n'))
767 .replace(u('\r\x85'), u('\n'))
768 .replace(u('\r'), u('\n'))
769 .replace(u('\x85'), u('\n'))
770 .replace(u('\u2028'), u('\n')))
771 text = text.replace(u('\n'), linesep)
772 if encoding is None:
773 encoding = sys.getdefaultencoding()
774 bytes = text.encode(encoding, errors)
775 else:
776 # It is an error to specify an encoding if 'text' is
777 # an 8-bit string.
778 assert encoding is None
779
780 if linesep is not None:
781 text = (text.replace('\r\n', '\n')
782 .replace('\r', '\n'))
783 bytes = text.replace('\n', linesep)
784
785 self.write_bytes(bytes, append)
786
787 def lines(self, encoding=None, errors='strict', retain=True):
788 r""" Open this file, read all lines, return them in a list.
789
790 Optional arguments:
791 encoding - The Unicode encoding (or character set) of
792 the file. The default is None, meaning the content
793 of the file is read as 8-bit characters and returned
794 as a list of (non-Unicode) str objects.
795 errors - How to handle Unicode errors; see help(str.decode)
796 for the options. Default is 'strict'
797 retain - If true, retain newline characters; but all newline
798 character combinations ('\r', '\n', '\r\n') are
799 translated to '\n'. If false, newline characters are
800 stripped off. Default is True.
801
802 This uses 'U' mode.
803 """
804 if encoding is None and retain:
805 with self.open('U') as f:
806 return f.readlines()
807 else:
808 return self.text(encoding, errors).splitlines(retain)
809
810 def write_lines(self, lines, encoding=None, errors='strict',
811 linesep=os.linesep, append=False):
812 r""" Write the given lines of text to this file.
813
814 By default this overwrites any existing file at this path.
815
816 This puts a platform-specific newline sequence on every line.
817 See 'linesep' below.
818
819 lines - A list of strings.
820
821 encoding - A Unicode encoding to use. This applies only if
822 'lines' contains any Unicode strings.
823
824 errors - How to handle errors in Unicode encoding. This
825 also applies only to Unicode strings.
826
827 linesep - The desired line-ending. This line-ending is
828 applied to every line. If a line already has any
829 standard line ending ('\r', '\n', '\r\n', u'\x85',
830 u'\r\x85', u'\u2028'), that will be stripped off and
831 this will be used instead. The default is os.linesep,
832 which is platform-dependent ('\r\n' on Windows, '\n' on
833 Unix, etc.) Specify None to write the lines as-is,
834 like file.writelines().
835
836 Use the keyword argument append=True to append lines to the
837 file. The default is to overwrite the file. Warning:
838 When you use this with Unicode data, if the encoding of the
839 existing data in the file is different from the encoding
840 you specify with the encoding= parameter, the result is
841 mixed-encoding data, which can really confuse someone trying
842 to read the file later.
843 """
844 if append:
845 mode = 'ab'
846 else:
847 mode = 'wb'
848 with self.open(mode) as f:
849 for line in lines:
850 isUnicode = isinstance(line, unicode)
851 if linesep is not None:
852 # Strip off any existing line-end and add the
853 # specified linesep string.
854 if isUnicode:
855 if line[-2:] in (u('\r\n'), u('\x0d\x85')):
856 line = line[:-2]
857 elif line[-1:] in (u('\r'), u('\n'),
858 u('\x85'), u('\u2028')):
859 line = line[:-1]
860 else:
861 if line[-2:] == '\r\n':
862 line = line[:-2]
863 elif line[-1:] in ('\r', '\n'):
864 line = line[:-1]
865 line += linesep
866 if isUnicode:
867 if encoding is None:
868 encoding = sys.getdefaultencoding()
869 line = line.encode(encoding, errors)
870 f.write(line)
871
872 def read_md5(self):
873 """ Calculate the md5 hash for this file.
874
875 This reads through the entire file.
876 """
877 return self.read_hash('md5')
878
879 def _hash(self, hash_name):
880 """ Returns a hash object for the file at the current path.
881
882 `hash_name` should be a hash algo name such as 'md5' or 'sha1'
883 that's available in the `hashlib` module.
884 """
885 m = hashlib.new(hash_name)
886 for chunk in self.chunks(8192):
887 m.update(chunk)
888 return m
889
890 def read_hash(self, hash_name):
891 """ Calculate given hash for this file.
892
893 List of supported hashes can be obtained from hashlib package. This
894 reads the entire file.
895 """
896 return self._hash(hash_name).digest()
897
898 def read_hexhash(self, hash_name):
899 """ Calculate given hash for this file, returning hexdigest.
900
901 List of supported hashes can be obtained from hashlib package. This
902 reads the entire file.
903 """
904 return self._hash(hash_name).hexdigest()
905
906 # --- Methods for querying the filesystem.
907 # N.B. On some platforms, the os.path functions may be implemented in C
908 # (e.g. isdir on Windows, Python 3.2.2), and compiled functions don't get
909 # bound. Playing it safe and wrapping them all in method calls.
910
911 def isabs(self):
912 return self.module.isabs(self)
913
914 def exists(self):
915 return self.module.exists(self)
916
917 def isdir(self):
918 return self.module.isdir(self)
919
920 def isfile(self):
921 return self.module.isfile(self)
922
923 def islink(self):
924 return self.module.islink(self)
925
926 def ismount(self):
927 return self.module.ismount(self)
928
929 def samefile(self, other):
930 return self.module.samefile(self, other)
931
932 def getatime(self):
933 return self.module.getatime(self)
934
935 atime = property(
936 getatime, None, None,
937 """ Last access time of the file. """)
938
939 def getmtime(self):
940 return self.module.getmtime(self)
941
942 mtime = property(
943 getmtime, None, None,
944 """ Last-modified time of the file. """)
945
946 def getctime(self):
947 return self.module.getctime(self)
948
949 ctime = property(
950 getctime, None, None,
951 """ Creation time of the file. """)
952
953 def getsize(self):
954 return self.module.getsize(self)
955
956 size = property(
957 getsize, None, None,
958 """ Size of the file, in bytes. """)
959
960 if hasattr(os, 'access'):
961 def access(self, mode):
962 """ Return true if current user has access to this path.
963
964 mode - One of the constants os.F_OK, os.R_OK, os.W_OK, os.X_OK
965 """
966 return os.access(self, mode)
967
968 def stat(self):
969 """ Perform a stat() system call on this path. """
970 return os.stat(self)
971
972 def lstat(self):
973 """ Like path.stat(), but do not follow symbolic links. """
974 return os.lstat(self)
975
976 def __get_owner_windows(self):
977 r"""
978 Return the name of the owner of this file or directory. Follow
979 symbolic links.
980
981 Return a name of the form ur'DOMAIN\User Name'; may be a group.
982 """
983 desc = win32security.GetFileSecurity(
984 self, win32security.OWNER_SECURITY_INFORMATION)
985 sid = desc.GetSecurityDescriptorOwner()
986 account, domain, typecode = win32security.LookupAccountSid(None, sid)
987 return domain + u('\\') + account
988
989 def __get_owner_unix(self):
990 """
991 Return the name of the owner of this file or directory. Follow
992 symbolic links.
993 """
994 st = self.stat()
995 return pwd.getpwuid(st.st_uid).pw_name
996
997 def __get_owner_not_implemented(self):
998 raise NotImplementedError("Ownership not available on this platform.")
999
1000 if 'win32security' in globals():
1001 get_owner = __get_owner_windows
1002 elif 'pwd' in globals():
1003 get_owner = __get_owner_unix
1004 else:
1005 get_owner = __get_owner_not_implemented
1006
1007 owner = property(
1008 get_owner, None, None,
1009 """ Name of the owner of this file or directory. """)
1010
1011 if hasattr(os, 'statvfs'):
1012 def statvfs(self):
1013 """ Perform a statvfs() system call on this path. """
1014 return os.statvfs(self)
1015
1016 if hasattr(os, 'pathconf'):
1017 def pathconf(self, name):
1018 return os.pathconf(self, name)
1019
1020 #
1021 # --- Modifying operations on files and directories
1022
1023 def utime(self, times):
1024 """ Set the access and modified times of this file. """
1025 os.utime(self, times)
1026 return self
1027
1028 def chmod(self, mode):
1029 os.chmod(self, mode)
1030 return self
1031
1032 if hasattr(os, 'chown'):
1033 def chown(self, uid=-1, gid=-1):
1034 os.chown(self, uid, gid)
1035 return self
1036
1037 def rename(self, new):
1038 os.rename(self, new)
1039 return self._next_class(new)
1040
1041 def renames(self, new):
1042 os.renames(self, new)
1043 return self._next_class(new)
1044
1045 #
1046 # --- Create/delete operations on directories
1047
1048 def mkdir(self, mode=o777):
1049 os.mkdir(self, mode)
1050 return self
1051
1052 def mkdir_p(self, mode=o777):
1053 try:
1054 self.mkdir(mode)
1055 except OSError:
1056 _, e, _ = sys.exc_info()
1057 if e.errno != errno.EEXIST:
1058 raise
1059 return self
1060
1061 def makedirs(self, mode=o777):
1062 os.makedirs(self, mode)
1063 return self
1064
1065 def makedirs_p(self, mode=o777):
1066 try:
1067 self.makedirs(mode)
1068 except OSError:
1069 _, e, _ = sys.exc_info()
1070 if e.errno != errno.EEXIST:
1071 raise
1072 return self
1073
1074 def rmdir(self):
1075 os.rmdir(self)
1076 return self
1077
1078 def rmdir_p(self):
1079 try:
1080 self.rmdir()
1081 except OSError:
1082 _, e, _ = sys.exc_info()
1083 if e.errno != errno.ENOTEMPTY and e.errno != errno.EEXIST:
1084 raise
1085 return self
1086
1087 def removedirs(self):
1088 os.removedirs(self)
1089 return self
1090
1091 def removedirs_p(self):
1092 try:
1093 self.removedirs()
1094 except OSError:
1095 _, e, _ = sys.exc_info()
1096 if e.errno != errno.ENOTEMPTY and e.errno != errno.EEXIST:
1097 raise
1098 return self
1099
1100 # --- Modifying operations on files
1101
1102 def touch(self):
1103 """ Set the access/modified times of this file to the current time.
1104 Create the file if it does not exist.
1105 """
1106 fd = os.open(self, os.O_WRONLY | os.O_CREAT, o666)
1107 os.close(fd)
1108 os.utime(self, None)
1109 return self
1110
1111 def remove(self):
1112 os.remove(self)
1113 return self
1114
1115 def remove_p(self):
1116 try:
1117 self.unlink()
1118 except OSError:
1119 _, e, _ = sys.exc_info()
1120 if e.errno != errno.ENOENT:
1121 raise
1122 return self
1123
1124 def unlink(self):
1125 os.unlink(self)
1126 return self
1127
1128 def unlink_p(self):
1129 self.remove_p()
1130 return self
1131
1132 # --- Links
1133
1134 if hasattr(os, 'link'):
1135 def link(self, newpath):
1136 """ Create a hard link at 'newpath', pointing to this file. """
1137 os.link(self, newpath)
1138 return self._next_class(newpath)
1139
1140 if hasattr(os, 'symlink'):
1141 def symlink(self, newlink):
1142 """ Create a symbolic link at 'newlink', pointing here. """
1143 os.symlink(self, newlink)
1144 return self._next_class(newlink)
1145
1146 if hasattr(os, 'readlink'):
1147 def readlink(self):
1148 """ Return the path to which this symbolic link points.
1149
1150 The result may be an absolute or a relative path.
1151 """
1152 return self._next_class(os.readlink(self))
1153
1154 def readlinkabs(self):
1155 """ Return the path to which this symbolic link points.
1156
1157 The result is always an absolute path.
1158 """
1159 p = self.readlink()
1160 if p.isabs():
1161 return p
1162 else:
1163 return (self.parent / p).abspath()
1164
1165 #
1166 # --- High-level functions from shutil
1167
1168 copyfile = shutil.copyfile
1169 copymode = shutil.copymode
1170 copystat = shutil.copystat
1171 copy = shutil.copy
1172 copy2 = shutil.copy2
1173 copytree = shutil.copytree
1174 if hasattr(shutil, 'move'):
1175 move = shutil.move
1176 rmtree = shutil.rmtree
1177
1178 def rmtree_p(self):
1179 try:
1180 self.rmtree()
1181 except OSError:
1182 _, e, _ = sys.exc_info()
1183 if e.errno != errno.ENOENT:
1184 raise
1185 return self
1186
1187 def chdir(self):
1188 os.chdir(self)
1189
1190 cd = chdir
1191
1192 #
1193 # --- Special stuff from os
1194
1195 if hasattr(os, 'chroot'):
1196 def chroot(self):
1197 os.chroot(self)
1198
1199 if hasattr(os, 'startfile'):
1200 def startfile(self):
1201 os.startfile(self)
1202 return self
1203
1204
1205 class tempdir(path):
1206 """
1207 A temporary directory via tempfile.mkdtemp, and constructed with the
1208 same parameters that you can use as a context manager.
1209
1210 Example:
1211
1212 with tempdir() as d:
1213 # do stuff with the path object "d"
1214
1215 # here the directory is deleted automatically
1216 """
1217
1218 @ClassProperty
1219 @classmethod
1220 def _next_class(cls):
1221 return path
1222
1223 def __new__(cls, *args, **kwargs):
1224 dirname = tempfile.mkdtemp(*args, **kwargs)
1225 return super(tempdir, cls).__new__(cls, dirname)
1226
1227 def __init__(self, *args, **kwargs):
1228 pass
1229
1230 def __enter__(self):
1231 return self
1232
1233 def __exit__(self, exc_type, exc_value, traceback):
1234 if not exc_value:
1235 self.rmtree()
1236
1237
1238 def _permission_mask(mode):
1239 """
1240 Convert a Unix chmod symbolic mode like 'ugo+rwx' to a function
1241 suitable for applying to a mask to affect that change.
1242
1243 >>> mask = _permission_mask('ugo+rwx')
1244 >>> oct(mask(o554))
1245 'o777'
1246
1247 >>> oct(_permission_mask('gw-x')(o777))
1248 'o766'
1249 """
1250 parsed = re.match('(?P<who>[ugo]+)(?P<op>[-+])(?P<what>[rwx]+)$', mode)
1251 if not parsed:
1252 raise ValueError("Unrecognized symbolic mode", mode)
1253 spec_map = dict(r=4, w=2, x=1)
1254 spec = reduce(operator.or_, [spec_map[perm]
1255 for perm in parsed.group('what')])
1256 # now apply spec to each in who
1257 shift_map = dict(u=6, g=3, o=0)
1258 mask = reduce(operator.or_, [spec << shift_map[subj]
1259 for subj in parsed.group('who')])
1260
1261 op = parsed.group('op')
1262 # if op is -, invert the mask
1263 if op == '-':
1264 mask ^= o777
1265
1266 op_map = {'+': operator.or_, '-': operator.and_}
1267 return functools.partial(op_map[op], mask)
@@ -1,5 +0,0
1 try:
2 import pexpect
3 from pexpect import *
4 except ImportError:
5 from ._pexpect import *
This diff has been collapsed as it changes many lines, (2123 lines changed) Show them Hide them
@@ -1,2123 +0,0
1 '''Pexpect is a Python module for spawning child applications and controlling
2 them automatically. Pexpect can be used for automating interactive applications
3 such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup
4 scripts for duplicating software package installations on different servers. It
5 can be used for automated software testing. Pexpect is in the spirit of Don
6 Libes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python
7 require TCL and Expect or require C extensions to be compiled. Pexpect does not
8 use C, Expect, or TCL extensions. It should work on any platform that supports
9 the standard Python pty module. The Pexpect interface focuses on ease of use so
10 that simple tasks are easy.
11
12 There are two main interfaces to the Pexpect system; these are the function,
13 run() and the class, spawn. The spawn class is more powerful. The run()
14 function is simpler than spawn, and is good for quickly calling program. When
15 you call the run() function it executes a given program and then returns the
16 output. This is a handy replacement for os.system().
17
18 For example::
19
20 pexpect.run('ls -la')
21
22 The spawn class is the more powerful interface to the Pexpect system. You can
23 use this to spawn a child program then interact with it by sending input and
24 expecting responses (waiting for patterns in the child's output).
25
26 For example::
27
28 child = pexpect.spawn('scp foo user@example.com:.')
29 child.expect('Password:')
30 child.sendline(mypassword)
31
32 This works even for commands that ask for passwords or other input outside of
33 the normal stdio streams. For example, ssh reads input directly from the TTY
34 device which bypasses stdin.
35
36 Credits: Noah Spurrier, Richard Holden, Marco Molteni, Kimberley Burchett,
37 Robert Stone, Hartmut Goebel, Chad Schroeder, Erick Tryzelaar, Dave Kirby, Ids
38 vander Molen, George Todd, Noel Taylor, Nicolas D. Cesar, Alexander Gattin,
39 Jacques-Etienne Baudoux, Geoffrey Marshall, Francisco Lourenco, Glen Mabey,
40 Karthik Gurusamy, Fernando Perez, Corey Minyard, Jon Cohen, Guillaume
41 Chazarain, Andrew Ryan, Nick Craig-Wood, Andrew Stone, Jorgen Grahn, John
42 Spiegel, Jan Grant, and Shane Kerr. Let me know if I forgot anyone.
43
44 Pexpect is free, open source, and all that good stuff.
45 http://pexpect.sourceforge.net/
46
47 PEXPECT LICENSE
48
49 This license is approved by the OSI and FSF as GPL-compatible.
50 http://opensource.org/licenses/isc-license.txt
51
52 Copyright (c) 2012, Noah Spurrier <noah@noah.org>
53 PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
54 PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
55 COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
56 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
57 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
58 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
59 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
60 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
61 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
62 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
63
64 '''
65
66 try:
67 import os
68 import sys
69 import time
70 import select
71 import re
72 import struct
73 import resource
74 import types
75 import pty
76 import tty
77 import termios
78 import fcntl
79 import errno
80 import traceback
81 import signal
82 import codecs
83 import stat
84 except ImportError: # pragma: no cover
85 err = sys.exc_info()[1]
86 raise ImportError(str(err) + '''
87
88 A critical module was not found. Probably this operating system does not
89 support it. Pexpect is intended for UNIX-like operating systems.''')
90
91 __version__ = '3.3'
92 __revision__ = ''
93 __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'spawnu', 'run', 'runu',
94 'which', 'split_command_line', '__version__', '__revision__']
95
96 PY3 = (sys.version_info[0] >= 3)
97
98 # Exception classes used by this module.
99 class ExceptionPexpect(Exception):
100 '''Base class for all exceptions raised by this module.
101 '''
102
103 def __init__(self, value):
104 super(ExceptionPexpect, self).__init__(value)
105 self.value = value
106
107 def __str__(self):
108 return str(self.value)
109
110 def get_trace(self):
111 '''This returns an abbreviated stack trace with lines that only concern
112 the caller. In other words, the stack trace inside the Pexpect module
113 is not included. '''
114
115 tblist = traceback.extract_tb(sys.exc_info()[2])
116 tblist = [item for item in tblist if 'pexpect/__init__' not in item[0]]
117 tblist = traceback.format_list(tblist)
118 return ''.join(tblist)
119
120
121 class EOF(ExceptionPexpect):
122 '''Raised when EOF is read from a child.
123 This usually means the child has exited.'''
124
125
126 class TIMEOUT(ExceptionPexpect):
127 '''Raised when a read time exceeds the timeout. '''
128
129 ##class TIMEOUT_PATTERN(TIMEOUT):
130 ## '''Raised when the pattern match time exceeds the timeout.
131 ## This is different than a read TIMEOUT because the child process may
132 ## give output, thus never give a TIMEOUT, but the output
133 ## may never match a pattern.
134 ## '''
135 ##class MAXBUFFER(ExceptionPexpect):
136 ## '''Raised when a buffer fills before matching an expected pattern.'''
137
138
139 def run(command, timeout=-1, withexitstatus=False, events=None,
140 extra_args=None, logfile=None, cwd=None, env=None):
141
142 '''
143 This function runs the given command; waits for it to finish; then
144 returns all output as a string. STDERR is included in output. If the full
145 path to the command is not given then the path is searched.
146
147 Note that lines are terminated by CR/LF (\\r\\n) combination even on
148 UNIX-like systems because this is the standard for pseudottys. If you set
149 'withexitstatus' to true, then run will return a tuple of (command_output,
150 exitstatus). If 'withexitstatus' is false then this returns just
151 command_output.
152
153 The run() function can often be used instead of creating a spawn instance.
154 For example, the following code uses spawn::
155
156 from pexpect import *
157 child = spawn('scp foo user@example.com:.')
158 child.expect('(?i)password')
159 child.sendline(mypassword)
160
161 The previous code can be replace with the following::
162
163 from pexpect import *
164 run('scp foo user@example.com:.', events={'(?i)password': mypassword})
165
166 **Examples**
167
168 Start the apache daemon on the local machine::
169
170 from pexpect import *
171 run("/usr/local/apache/bin/apachectl start")
172
173 Check in a file using SVN::
174
175 from pexpect import *
176 run("svn ci -m 'automatic commit' my_file.py")
177
178 Run a command and capture exit status::
179
180 from pexpect import *
181 (command_output, exitstatus) = run('ls -l /bin', withexitstatus=1)
182
183 The following will run SSH and execute 'ls -l' on the remote machine. The
184 password 'secret' will be sent if the '(?i)password' pattern is ever seen::
185
186 run("ssh username@machine.example.com 'ls -l'",
187 events={'(?i)password':'secret\\n'})
188
189 This will start mencoder to rip a video from DVD. This will also display
190 progress ticks every 5 seconds as it runs. For example::
191
192 from pexpect import *
193 def print_ticks(d):
194 print d['event_count'],
195 run("mencoder dvd://1 -o video.avi -oac copy -ovc copy",
196 events={TIMEOUT:print_ticks}, timeout=5)
197
198 The 'events' argument should be a dictionary of patterns and responses.
199 Whenever one of the patterns is seen in the command out run() will send the
200 associated response string. Note that you should put newlines in your
201 string if Enter is necessary. The responses may also contain callback
202 functions. Any callback is function that takes a dictionary as an argument.
203 The dictionary contains all the locals from the run() function, so you can
204 access the child spawn object or any other variable defined in run()
205 (event_count, child, and extra_args are the most useful). A callback may
206 return True to stop the current run process otherwise run() continues until
207 the next event. A callback may also return a string which will be sent to
208 the child. 'extra_args' is not used by directly run(). It provides a way to
209 pass data to a callback function through run() through the locals
210 dictionary passed to a callback.
211 '''
212 return _run(command, timeout=timeout, withexitstatus=withexitstatus,
213 events=events, extra_args=extra_args, logfile=logfile, cwd=cwd,
214 env=env, _spawn=spawn)
215
216 def runu(command, timeout=-1, withexitstatus=False, events=None,
217 extra_args=None, logfile=None, cwd=None, env=None, **kwargs):
218 """This offers the same interface as :func:`run`, but using unicode.
219
220 Like :class:`spawnu`, you can pass ``encoding`` and ``errors`` parameters,
221 which will be used for both input and output.
222 """
223 return _run(command, timeout=timeout, withexitstatus=withexitstatus,
224 events=events, extra_args=extra_args, logfile=logfile, cwd=cwd,
225 env=env, _spawn=spawnu, **kwargs)
226
227 def _run(command, timeout, withexitstatus, events, extra_args, logfile, cwd,
228 env, _spawn, **kwargs):
229 if timeout == -1:
230 child = _spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env,
231 **kwargs)
232 else:
233 child = _spawn(command, timeout=timeout, maxread=2000, logfile=logfile,
234 cwd=cwd, env=env, **kwargs)
235 if events is not None:
236 patterns = list(events.keys())
237 responses = list(events.values())
238 else:
239 # This assumes EOF or TIMEOUT will eventually cause run to terminate.
240 patterns = None
241 responses = None
242 child_result_list = []
243 event_count = 0
244 while True:
245 try:
246 index = child.expect(patterns)
247 if isinstance(child.after, child.allowed_string_types):
248 child_result_list.append(child.before + child.after)
249 else:
250 # child.after may have been a TIMEOUT or EOF,
251 # which we don't want appended to the list.
252 child_result_list.append(child.before)
253 if isinstance(responses[index], child.allowed_string_types):
254 child.send(responses[index])
255 elif isinstance(responses[index], types.FunctionType):
256 callback_result = responses[index](locals())
257 sys.stdout.flush()
258 if isinstance(callback_result, child.allowed_string_types):
259 child.send(callback_result)
260 elif callback_result:
261 break
262 else:
263 raise TypeError('The callback must be a string or function.')
264 event_count = event_count + 1
265 except TIMEOUT:
266 child_result_list.append(child.before)
267 break
268 except EOF:
269 child_result_list.append(child.before)
270 break
271 child_result = child.string_type().join(child_result_list)
272 if withexitstatus:
273 child.close()
274 return (child_result, child.exitstatus)
275 else:
276 return child_result
277
278 class spawn(object):
279 '''This is the main class interface for Pexpect. Use this class to start
280 and control child applications. '''
281 string_type = bytes
282 if PY3:
283 allowed_string_types = (bytes, str)
284 @staticmethod
285 def _chr(c):
286 return bytes([c])
287 linesep = os.linesep.encode('ascii')
288 crlf = '\r\n'.encode('ascii')
289
290 @staticmethod
291 def write_to_stdout(b):
292 try:
293 return sys.stdout.buffer.write(b)
294 except AttributeError:
295 # If stdout has been replaced, it may not have .buffer
296 return sys.stdout.write(b.decode('ascii', 'replace'))
297 else:
298 allowed_string_types = (basestring,) # analysis:ignore
299 _chr = staticmethod(chr)
300 linesep = os.linesep
301 crlf = '\r\n'
302 write_to_stdout = sys.stdout.write
303
304 encoding = None
305
306 def __init__(self, command, args=[], timeout=30, maxread=2000,
307 searchwindowsize=None, logfile=None, cwd=None, env=None,
308 ignore_sighup=True, echo=True):
309
310 '''This is the constructor. The command parameter may be a string that
311 includes a command and any arguments to the command. For example::
312
313 child = pexpect.spawn('/usr/bin/ftp')
314 child = pexpect.spawn('/usr/bin/ssh user@example.com')
315 child = pexpect.spawn('ls -latr /tmp')
316
317 You may also construct it with a list of arguments like so::
318
319 child = pexpect.spawn('/usr/bin/ftp', [])
320 child = pexpect.spawn('/usr/bin/ssh', ['user@example.com'])
321 child = pexpect.spawn('ls', ['-latr', '/tmp'])
322
323 After this the child application will be created and will be ready to
324 talk to. For normal use, see expect() and send() and sendline().
325
326 Remember that Pexpect does NOT interpret shell meta characters such as
327 redirect, pipe, or wild cards (``>``, ``|``, or ``*``). This is a
328 common mistake. If you want to run a command and pipe it through
329 another command then you must also start a shell. For example::
330
331 child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"')
332 child.expect(pexpect.EOF)
333
334 The second form of spawn (where you pass a list of arguments) is useful
335 in situations where you wish to spawn a command and pass it its own
336 argument list. This can make syntax more clear. For example, the
337 following is equivalent to the previous example::
338
339 shell_cmd = 'ls -l | grep LOG > logs.txt'
340 child = pexpect.spawn('/bin/bash', ['-c', shell_cmd])
341 child.expect(pexpect.EOF)
342
343 The maxread attribute sets the read buffer size. This is maximum number
344 of bytes that Pexpect will try to read from a TTY at one time. Setting
345 the maxread size to 1 will turn off buffering. Setting the maxread
346 value higher may help performance in cases where large amounts of
347 output are read back from the child. This feature is useful in
348 conjunction with searchwindowsize.
349
350 The searchwindowsize attribute sets the how far back in the incoming
351 seach buffer Pexpect will search for pattern matches. Every time
352 Pexpect reads some data from the child it will append the data to the
353 incoming buffer. The default is to search from the beginning of the
354 incoming buffer each time new data is read from the child. But this is
355 very inefficient if you are running a command that generates a large
356 amount of data where you want to match. The searchwindowsize does not
357 affect the size of the incoming data buffer. You will still have
358 access to the full buffer after expect() returns.
359
360 The logfile member turns on or off logging. All input and output will
361 be copied to the given file object. Set logfile to None to stop
362 logging. This is the default. Set logfile to sys.stdout to echo
363 everything to standard output. The logfile is flushed after each write.
364
365 Example log input and output to a file::
366
367 child = pexpect.spawn('some_command')
368 fout = file('mylog.txt','w')
369 child.logfile = fout
370
371 Example log to stdout::
372
373 child = pexpect.spawn('some_command')
374 child.logfile = sys.stdout
375
376 The logfile_read and logfile_send members can be used to separately log
377 the input from the child and output sent to the child. Sometimes you
378 don't want to see everything you write to the child. You only want to
379 log what the child sends back. For example::
380
381 child = pexpect.spawn('some_command')
382 child.logfile_read = sys.stdout
383
384 To separately log output sent to the child use logfile_send::
385
386 self.logfile_send = fout
387
388 If ``ignore_sighup`` is True, the child process will ignore SIGHUP
389 signals. For now, the default is True, to preserve the behaviour of
390 earlier versions of Pexpect, but you should pass this explicitly if you
391 want to rely on it.
392
393 The delaybeforesend helps overcome a weird behavior that many users
394 were experiencing. The typical problem was that a user would expect() a
395 "Password:" prompt and then immediately call sendline() to send the
396 password. The user would then see that their password was echoed back
397 to them. Passwords don't normally echo. The problem is caused by the
398 fact that most applications print out the "Password" prompt and then
399 turn off stdin echo, but if you send your password before the
400 application turned off echo, then you get your password echoed.
401 Normally this wouldn't be a problem when interacting with a human at a
402 real keyboard. If you introduce a slight delay just before writing then
403 this seems to clear up the problem. This was such a common problem for
404 many users that I decided that the default pexpect behavior should be
405 to sleep just before writing to the child application. 1/20th of a
406 second (50 ms) seems to be enough to clear up the problem. You can set
407 delaybeforesend to 0 to return to the old behavior. Most Linux machines
408 don't like this to be below 0.03. I don't know why.
409
410 Note that spawn is clever about finding commands on your path.
411 It uses the same logic that "which" uses to find executables.
412
413 If you wish to get the exit status of the child you must call the
414 close() method. The exit or signal status of the child will be stored
415 in self.exitstatus or self.signalstatus. If the child exited normally
416 then exitstatus will store the exit return code and signalstatus will
417 be None. If the child was terminated abnormally with a signal then
418 signalstatus will store the signal value and exitstatus will be None.
419 If you need more detail you can also read the self.status member which
420 stores the status returned by os.waitpid. You can interpret this using
421 os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG.
422
423 The echo attribute may be set to False to disable echoing of input.
424 As a pseudo-terminal, all input echoed by the "keyboard" (send()
425 or sendline()) will be repeated to output. For many cases, it is
426 not desirable to have echo enabled, and it may be later disabled
427 using setecho(False) followed by waitnoecho(). However, for some
428 platforms such as Solaris, this is not possible, and should be
429 disabled immediately on spawn.
430 '''
431
432 self.STDIN_FILENO = pty.STDIN_FILENO
433 self.STDOUT_FILENO = pty.STDOUT_FILENO
434 self.STDERR_FILENO = pty.STDERR_FILENO
435 self.stdin = sys.stdin
436 self.stdout = sys.stdout
437 self.stderr = sys.stderr
438
439 self.searcher = None
440 self.ignorecase = False
441 self.before = None
442 self.after = None
443 self.match = None
444 self.match_index = None
445 self.terminated = True
446 self.exitstatus = None
447 self.signalstatus = None
448 # status returned by os.waitpid
449 self.status = None
450 self.flag_eof = False
451 self.pid = None
452 # the child file descriptor is initially closed
453 self.child_fd = -1
454 self.timeout = timeout
455 self.delimiter = EOF
456 self.logfile = logfile
457 # input from child (read_nonblocking)
458 self.logfile_read = None
459 # output to send (send, sendline)
460 self.logfile_send = None
461 # max bytes to read at one time into buffer
462 self.maxread = maxread
463 # This is the read buffer. See maxread.
464 self.buffer = self.string_type()
465 # Data before searchwindowsize point is preserved, but not searched.
466 self.searchwindowsize = searchwindowsize
467 # Delay used before sending data to child. Time in seconds.
468 # Most Linux machines don't like this to be below 0.03 (30 ms).
469 self.delaybeforesend = 0.05
470 # Used by close() to give kernel time to update process status.
471 # Time in seconds.
472 self.delayafterclose = 0.1
473 # Used by terminate() to give kernel time to update process status.
474 # Time in seconds.
475 self.delayafterterminate = 0.1
476 self.softspace = False
477 self.name = '<' + repr(self) + '>'
478 self.closed = True
479 self.cwd = cwd
480 self.env = env
481 self.echo = echo
482 self.ignore_sighup = ignore_sighup
483 _platform = sys.platform.lower()
484 # This flags if we are running on irix
485 self.__irix_hack = _platform.startswith('irix')
486 # Solaris uses internal __fork_pty(). All others use pty.fork().
487 self.use_native_pty_fork = not (
488 _platform.startswith('solaris') or
489 _platform.startswith('sunos'))
490 # inherit EOF and INTR definitions from controlling process.
491 try:
492 from termios import VEOF, VINTR
493 fd = sys.__stdin__.fileno()
494 self._INTR = ord(termios.tcgetattr(fd)[6][VINTR])
495 self._EOF = ord(termios.tcgetattr(fd)[6][VEOF])
496 except (ImportError, OSError, IOError, termios.error):
497 # unless the controlling process is also not a terminal,
498 # such as cron(1). Fall-back to using CEOF and CINTR.
499 try:
500 from termios import CEOF, CINTR
501 (self._INTR, self._EOF) = (CINTR, CEOF)
502 except ImportError:
503 # ^C, ^D
504 (self._INTR, self._EOF) = (3, 4)
505 # Support subclasses that do not use command or args.
506 if command is None:
507 self.command = None
508 self.args = None
509 self.name = '<pexpect factory incomplete>'
510 else:
511 self._spawn(command, args)
512
513 @staticmethod
514 def _coerce_expect_string(s):
515 if not isinstance(s, bytes):
516 return s.encode('ascii')
517 return s
518
519 @staticmethod
520 def _coerce_send_string(s):
521 if not isinstance(s, bytes):
522 return s.encode('utf-8')
523 return s
524
525 @staticmethod
526 def _coerce_read_string(s):
527 return s
528
529 def __del__(self):
530 '''This makes sure that no system resources are left open. Python only
531 garbage collects Python objects. OS file descriptors are not Python
532 objects, so they must be handled explicitly. If the child file
533 descriptor was opened outside of this class (passed to the constructor)
534 then this does not close it. '''
535
536 if not self.closed:
537 # It is possible for __del__ methods to execute during the
538 # teardown of the Python VM itself. Thus self.close() may
539 # trigger an exception because os.close may be None.
540 try:
541 self.close()
542 # which exception, shouldnt' we catch explicitly .. ?
543 except:
544 pass
545
546 def __str__(self):
547 '''This returns a human-readable string that represents the state of
548 the object. '''
549
550 s = []
551 s.append(repr(self))
552 s.append('version: ' + __version__)
553 s.append('command: ' + str(self.command))
554 s.append('args: %r' % (self.args,))
555 s.append('searcher: %r' % (self.searcher,))
556 s.append('buffer (last 100 chars): %r' % (self.buffer)[-100:],)
557 s.append('before (last 100 chars): %r' % (self.before)[-100:],)
558 s.append('after: %r' % (self.after,))
559 s.append('match: %r' % (self.match,))
560 s.append('match_index: ' + str(self.match_index))
561 s.append('exitstatus: ' + str(self.exitstatus))
562 s.append('flag_eof: ' + str(self.flag_eof))
563 s.append('pid: ' + str(self.pid))
564 s.append('child_fd: ' + str(self.child_fd))
565 s.append('closed: ' + str(self.closed))
566 s.append('timeout: ' + str(self.timeout))
567 s.append('delimiter: ' + str(self.delimiter))
568 s.append('logfile: ' + str(self.logfile))
569 s.append('logfile_read: ' + str(self.logfile_read))
570 s.append('logfile_send: ' + str(self.logfile_send))
571 s.append('maxread: ' + str(self.maxread))
572 s.append('ignorecase: ' + str(self.ignorecase))
573 s.append('searchwindowsize: ' + str(self.searchwindowsize))
574 s.append('delaybeforesend: ' + str(self.delaybeforesend))
575 s.append('delayafterclose: ' + str(self.delayafterclose))
576 s.append('delayafterterminate: ' + str(self.delayafterterminate))
577 return '\n'.join(s)
578
579 def _spawn(self, command, args=[]):
580 '''This starts the given command in a child process. This does all the
581 fork/exec type of stuff for a pty. This is called by __init__. If args
582 is empty then command will be parsed (split on spaces) and args will be
583 set to parsed arguments. '''
584
585 # The pid and child_fd of this object get set by this method.
586 # Note that it is difficult for this method to fail.
587 # You cannot detect if the child process cannot start.
588 # So the only way you can tell if the child process started
589 # or not is to try to read from the file descriptor. If you get
590 # EOF immediately then it means that the child is already dead.
591 # That may not necessarily be bad because you may have spawned a child
592 # that performs some task; creates no stdout output; and then dies.
593
594 # If command is an int type then it may represent a file descriptor.
595 if isinstance(command, type(0)):
596 raise ExceptionPexpect('Command is an int type. ' +
597 'If this is a file descriptor then maybe you want to ' +
598 'use fdpexpect.fdspawn which takes an existing ' +
599 'file descriptor instead of a command string.')
600
601 if not isinstance(args, type([])):
602 raise TypeError('The argument, args, must be a list.')
603
604 if args == []:
605 self.args = split_command_line(command)
606 self.command = self.args[0]
607 else:
608 # Make a shallow copy of the args list.
609 self.args = args[:]
610 self.args.insert(0, command)
611 self.command = command
612
613 command_with_path = which(self.command)
614 if command_with_path is None:
615 raise ExceptionPexpect('The command was not found or was not ' +
616 'executable: %s.' % self.command)
617 self.command = command_with_path
618 self.args[0] = self.command
619
620 self.name = '<' + ' '.join(self.args) + '>'
621
622 assert self.pid is None, 'The pid member must be None.'
623 assert self.command is not None, 'The command member must not be None.'
624
625 if self.use_native_pty_fork:
626 try:
627 self.pid, self.child_fd = pty.fork()
628 except OSError: # pragma: no cover
629 err = sys.exc_info()[1]
630 raise ExceptionPexpect('pty.fork() failed: ' + str(err))
631 else:
632 # Use internal __fork_pty
633 self.pid, self.child_fd = self.__fork_pty()
634
635 # Some platforms must call setwinsize() and setecho() from the
636 # child process, and others from the master process. We do both,
637 # allowing IOError for either.
638
639 if self.pid == pty.CHILD:
640 # Child
641 self.child_fd = self.STDIN_FILENO
642
643 # set default window size of 24 rows by 80 columns
644 try:
645 self.setwinsize(24, 80)
646 except IOError as err:
647 if err.args[0] not in (errno.EINVAL, errno.ENOTTY):
648 raise
649
650 # disable echo if spawn argument echo was unset
651 if not self.echo:
652 try:
653 self.setecho(self.echo)
654 except (IOError, termios.error) as err:
655 if err.args[0] not in (errno.EINVAL, errno.ENOTTY):
656 raise
657
658 # Do not allow child to inherit open file descriptors from parent.
659 max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0]
660 os.closerange(3, max_fd)
661
662 if self.ignore_sighup:
663 signal.signal(signal.SIGHUP, signal.SIG_IGN)
664
665 if self.cwd is not None:
666 os.chdir(self.cwd)
667 if self.env is None:
668 os.execv(self.command, self.args)
669 else:
670 os.execvpe(self.command, self.args, self.env)
671
672 # Parent
673 try:
674 self.setwinsize(24, 80)
675 except IOError as err:
676 if err.args[0] not in (errno.EINVAL, errno.ENOTTY):
677 raise
678
679
680 self.terminated = False
681 self.closed = False
682
683 def __fork_pty(self):
684 '''This implements a substitute for the forkpty system call. This
685 should be more portable than the pty.fork() function. Specifically,
686 this should work on Solaris.
687
688 Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to
689 resolve the issue with Python's pty.fork() not supporting Solaris,
690 particularly ssh. Based on patch to posixmodule.c authored by Noah
691 Spurrier::
692
693 http://mail.python.org/pipermail/python-dev/2003-May/035281.html
694
695 '''
696
697 parent_fd, child_fd = os.openpty()
698 if parent_fd < 0 or child_fd < 0:
699 raise ExceptionPexpect("Could not open with os.openpty().")
700
701 pid = os.fork()
702 if pid == pty.CHILD:
703 # Child.
704 os.close(parent_fd)
705 self.__pty_make_controlling_tty(child_fd)
706
707 os.dup2(child_fd, self.STDIN_FILENO)
708 os.dup2(child_fd, self.STDOUT_FILENO)
709 os.dup2(child_fd, self.STDERR_FILENO)
710
711 else:
712 # Parent.
713 os.close(child_fd)
714
715 return pid, parent_fd
716
717 def __pty_make_controlling_tty(self, tty_fd):
718 '''This makes the pseudo-terminal the controlling tty. This should be
719 more portable than the pty.fork() function. Specifically, this should
720 work on Solaris. '''
721
722 child_name = os.ttyname(tty_fd)
723
724 # Disconnect from controlling tty, if any. Raises OSError of ENXIO
725 # if there was no controlling tty to begin with, such as when
726 # executed by a cron(1) job.
727 try:
728 fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
729 os.close(fd)
730 except OSError as err:
731 if err.errno != errno.ENXIO:
732 raise
733
734 os.setsid()
735
736 # Verify we are disconnected from controlling tty by attempting to open
737 # it again. We expect that OSError of ENXIO should always be raised.
738 try:
739 fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
740 os.close(fd)
741 raise ExceptionPexpect("OSError of errno.ENXIO should be raised.")
742 except OSError as err:
743 if err.errno != errno.ENXIO:
744 raise
745
746 # Verify we can open child pty.
747 fd = os.open(child_name, os.O_RDWR)
748 os.close(fd)
749
750 # Verify we now have a controlling tty.
751 fd = os.open("/dev/tty", os.O_WRONLY)
752 os.close(fd)
753
754
755 def fileno(self):
756 '''This returns the file descriptor of the pty for the child.
757 '''
758 return self.child_fd
759
760 def close(self, force=True):
761 '''This closes the connection with the child application. Note that
762 calling close() more than once is valid. This emulates standard Python
763 behavior with files. Set force to True if you want to make sure that
764 the child is terminated (SIGKILL is sent if the child ignores SIGHUP
765 and SIGINT). '''
766
767 if not self.closed:
768 self.flush()
769 os.close(self.child_fd)
770 # Give kernel time to update process status.
771 time.sleep(self.delayafterclose)
772 if self.isalive():
773 if not self.terminate(force):
774 raise ExceptionPexpect('Could not terminate the child.')
775 self.child_fd = -1
776 self.closed = True
777 #self.pid = None
778
779 def flush(self):
780 '''This does nothing. It is here to support the interface for a
781 File-like object. '''
782
783 pass
784
785 def isatty(self):
786 '''This returns True if the file descriptor is open and connected to a
787 tty(-like) device, else False.
788
789 On SVR4-style platforms implementing streams, such as SunOS and HP-UX,
790 the child pty may not appear as a terminal device. This means
791 methods such as setecho(), setwinsize(), getwinsize() may raise an
792 IOError. '''
793
794 return os.isatty(self.child_fd)
795
796 def waitnoecho(self, timeout=-1):
797 '''This waits until the terminal ECHO flag is set False. This returns
798 True if the echo mode is off. This returns False if the ECHO flag was
799 not set False before the timeout. This can be used to detect when the
800 child is waiting for a password. Usually a child application will turn
801 off echo mode when it is waiting for the user to enter a password. For
802 example, instead of expecting the "password:" prompt you can wait for
803 the child to set ECHO off::
804
805 p = pexpect.spawn('ssh user@example.com')
806 p.waitnoecho()
807 p.sendline(mypassword)
808
809 If timeout==-1 then this method will use the value in self.timeout.
810 If timeout==None then this method to block until ECHO flag is False.
811 '''
812
813 if timeout == -1:
814 timeout = self.timeout
815 if timeout is not None:
816 end_time = time.time() + timeout
817 while True:
818 if not self.getecho():
819 return True
820 if timeout < 0 and timeout is not None:
821 return False
822 if timeout is not None:
823 timeout = end_time - time.time()
824 time.sleep(0.1)
825
826 def getecho(self):
827 '''This returns the terminal echo mode. This returns True if echo is
828 on or False if echo is off. Child applications that are expecting you
829 to enter a password often set ECHO False. See waitnoecho().
830
831 Not supported on platforms where ``isatty()`` returns False. '''
832
833 try:
834 attr = termios.tcgetattr(self.child_fd)
835 except termios.error as err:
836 errmsg = 'getecho() may not be called on this platform'
837 if err.args[0] == errno.EINVAL:
838 raise IOError(err.args[0], '%s: %s.' % (err.args[1], errmsg))
839 raise
840
841 self.echo = bool(attr[3] & termios.ECHO)
842 return self.echo
843
844 def setecho(self, state):
845 '''This sets the terminal echo mode on or off. Note that anything the
846 child sent before the echo will be lost, so you should be sure that
847 your input buffer is empty before you call setecho(). For example, the
848 following will work as expected::
849
850 p = pexpect.spawn('cat') # Echo is on by default.
851 p.sendline('1234') # We expect see this twice from the child...
852 p.expect(['1234']) # ... once from the tty echo...
853 p.expect(['1234']) # ... and again from cat itself.
854 p.setecho(False) # Turn off tty echo
855 p.sendline('abcd') # We will set this only once (echoed by cat).
856 p.sendline('wxyz') # We will set this only once (echoed by cat)
857 p.expect(['abcd'])
858 p.expect(['wxyz'])
859
860 The following WILL NOT WORK because the lines sent before the setecho
861 will be lost::
862
863 p = pexpect.spawn('cat')
864 p.sendline('1234')
865 p.setecho(False) # Turn off tty echo
866 p.sendline('abcd') # We will set this only once (echoed by cat).
867 p.sendline('wxyz') # We will set this only once (echoed by cat)
868 p.expect(['1234'])
869 p.expect(['1234'])
870 p.expect(['abcd'])
871 p.expect(['wxyz'])
872
873
874 Not supported on platforms where ``isatty()`` returns False.
875 '''
876
877 errmsg = 'setecho() may not be called on this platform'
878
879 try:
880 attr = termios.tcgetattr(self.child_fd)
881 except termios.error as err:
882 if err.args[0] == errno.EINVAL:
883 raise IOError(err.args[0], '%s: %s.' % (err.args[1], errmsg))
884 raise
885
886 if state:
887 attr[3] = attr[3] | termios.ECHO
888 else:
889 attr[3] = attr[3] & ~termios.ECHO
890
891 try:
892 # I tried TCSADRAIN and TCSAFLUSH, but these were inconsistent and
893 # blocked on some platforms. TCSADRAIN would probably be ideal.
894 termios.tcsetattr(self.child_fd, termios.TCSANOW, attr)
895 except IOError as err:
896 if err.args[0] == errno.EINVAL:
897 raise IOError(err.args[0], '%s: %s.' % (err.args[1], errmsg))
898 raise
899
900 self.echo = state
901
902 def _log(self, s, direction):
903 if self.logfile is not None:
904 self.logfile.write(s)
905 self.logfile.flush()
906 second_log = self.logfile_send if (direction=='send') else self.logfile_read
907 if second_log is not None:
908 second_log.write(s)
909 second_log.flush()
910
911 def read_nonblocking(self, size=1, timeout=-1):
912 '''This reads at most size characters from the child application. It
913 includes a timeout. If the read does not complete within the timeout
914 period then a TIMEOUT exception is raised. If the end of file is read
915 then an EOF exception will be raised. If a log file was set using
916 setlog() then all data will also be written to the log file.
917
918 If timeout is None then the read may block indefinitely.
919 If timeout is -1 then the self.timeout value is used. If timeout is 0
920 then the child is polled and if there is no data immediately ready
921 then this will raise a TIMEOUT exception.
922
923 The timeout refers only to the amount of time to read at least one
924 character. This is not effected by the 'size' parameter, so if you call
925 read_nonblocking(size=100, timeout=30) and only one character is
926 available right away then one character will be returned immediately.
927 It will not wait for 30 seconds for another 99 characters to come in.
928
929 This is a wrapper around os.read(). It uses select.select() to
930 implement the timeout. '''
931
932 if self.closed:
933 raise ValueError('I/O operation on closed file.')
934
935 if timeout == -1:
936 timeout = self.timeout
937
938 # Note that some systems such as Solaris do not give an EOF when
939 # the child dies. In fact, you can still try to read
940 # from the child_fd -- it will block forever or until TIMEOUT.
941 # For this case, I test isalive() before doing any reading.
942 # If isalive() is false, then I pretend that this is the same as EOF.
943 if not self.isalive():
944 # timeout of 0 means "poll"
945 r, w, e = self.__select([self.child_fd], [], [], 0)
946 if not r:
947 self.flag_eof = True
948 raise EOF('End Of File (EOF). Braindead platform.')
949 elif self.__irix_hack:
950 # Irix takes a long time before it realizes a child was terminated.
951 # FIXME So does this mean Irix systems are forced to always have
952 # FIXME a 2 second delay when calling read_nonblocking? That sucks.
953 r, w, e = self.__select([self.child_fd], [], [], 2)
954 if not r and not self.isalive():
955 self.flag_eof = True
956 raise EOF('End Of File (EOF). Slow platform.')
957
958 r, w, e = self.__select([self.child_fd], [], [], timeout)
959
960 if not r:
961 if not self.isalive():
962 # Some platforms, such as Irix, will claim that their
963 # processes are alive; timeout on the select; and
964 # then finally admit that they are not alive.
965 self.flag_eof = True
966 raise EOF('End of File (EOF). Very slow platform.')
967 else:
968 raise TIMEOUT('Timeout exceeded.')
969
970 if self.child_fd in r:
971 try:
972 s = os.read(self.child_fd, size)
973 except OSError as err:
974 if err.args[0] == errno.EIO:
975 # Linux-style EOF
976 self.flag_eof = True
977 raise EOF('End Of File (EOF). Exception style platform.')
978 raise
979 if s == b'':
980 # BSD-style EOF
981 self.flag_eof = True
982 raise EOF('End Of File (EOF). Empty string style platform.')
983
984 s = self._coerce_read_string(s)
985 self._log(s, 'read')
986 return s
987
988 raise ExceptionPexpect('Reached an unexpected state.') # pragma: no cover
989
990 def read(self, size=-1):
991 '''This reads at most "size" bytes from the file (less if the read hits
992 EOF before obtaining size bytes). If the size argument is negative or
993 omitted, read all data until EOF is reached. The bytes are returned as
994 a string object. An empty string is returned when EOF is encountered
995 immediately. '''
996
997 if size == 0:
998 return self.string_type()
999 if size < 0:
1000 # delimiter default is EOF
1001 self.expect(self.delimiter)
1002 return self.before
1003
1004 # I could have done this more directly by not using expect(), but
1005 # I deliberately decided to couple read() to expect() so that
1006 # I would catch any bugs early and ensure consistant behavior.
1007 # It's a little less efficient, but there is less for me to
1008 # worry about if I have to later modify read() or expect().
1009 # Note, it's OK if size==-1 in the regex. That just means it
1010 # will never match anything in which case we stop only on EOF.
1011 cre = re.compile(self._coerce_expect_string('.{%d}' % size), re.DOTALL)
1012 # delimiter default is EOF
1013 index = self.expect([cre, self.delimiter])
1014 if index == 0:
1015 ### FIXME self.before should be ''. Should I assert this?
1016 return self.after
1017 return self.before
1018
1019 def readline(self, size=-1):
1020 '''This reads and returns one entire line. The newline at the end of
1021 line is returned as part of the string, unless the file ends without a
1022 newline. An empty string is returned if EOF is encountered immediately.
1023 This looks for a newline as a CR/LF pair (\\r\\n) even on UNIX because
1024 this is what the pseudotty device returns. So contrary to what you may
1025 expect you will receive newlines as \\r\\n.
1026
1027 If the size argument is 0 then an empty string is returned. In all
1028 other cases the size argument is ignored, which is not standard
1029 behavior for a file-like object. '''
1030
1031 if size == 0:
1032 return self.string_type()
1033 # delimiter default is EOF
1034 index = self.expect([self.crlf, self.delimiter])
1035 if index == 0:
1036 return self.before + self.crlf
1037 else:
1038 return self.before
1039
1040 def __iter__(self):
1041 '''This is to support iterators over a file-like object.
1042 '''
1043 return iter(self.readline, self.string_type())
1044
1045 def readlines(self, sizehint=-1):
1046 '''This reads until EOF using readline() and returns a list containing
1047 the lines thus read. The optional 'sizehint' argument is ignored.
1048 Remember, because this reads until EOF that means the child
1049 process should have closed its stdout. If you run this method on
1050 a child that is still running with its stdout open then this
1051 method will block until it timesout.'''
1052
1053 lines = []
1054 while True:
1055 line = self.readline()
1056 if not line:
1057 break
1058 lines.append(line)
1059 return lines
1060
1061 def write(self, s):
1062 '''This is similar to send() except that there is no return value.
1063 '''
1064
1065 self.send(s)
1066
1067 def writelines(self, sequence):
1068 '''This calls write() for each element in the sequence. The sequence
1069 can be any iterable object producing strings, typically a list of
1070 strings. This does not add line separators. There is no return value.
1071 '''
1072
1073 for s in sequence:
1074 self.write(s)
1075
1076 def send(self, s):
1077 '''Sends string ``s`` to the child process, returning the number of
1078 bytes written. If a logfile is specified, a copy is written to that
1079 log. '''
1080
1081 time.sleep(self.delaybeforesend)
1082
1083 s = self._coerce_send_string(s)
1084 self._log(s, 'send')
1085
1086 return self._send(s)
1087
1088 def _send(self, s):
1089 return os.write(self.child_fd, s)
1090
1091 def sendline(self, s=''):
1092 '''Wraps send(), sending string ``s`` to child process, with os.linesep
1093 automatically appended. Returns number of bytes written. '''
1094
1095 n = self.send(s)
1096 n = n + self.send(self.linesep)
1097 return n
1098
1099 def sendcontrol(self, char):
1100
1101 '''Helper method that wraps send() with mnemonic access for sending control
1102 character to the child (such as Ctrl-C or Ctrl-D). For example, to send
1103 Ctrl-G (ASCII 7, bell, '\a')::
1104
1105 child.sendcontrol('g')
1106
1107 See also, sendintr() and sendeof().
1108 '''
1109
1110 char = char.lower()
1111 a = ord(char)
1112 if a >= 97 and a <= 122:
1113 a = a - ord('a') + 1
1114 return self.send(self._chr(a))
1115 d = {'@': 0, '`': 0,
1116 '[': 27, '{': 27,
1117 '\\': 28, '|': 28,
1118 ']': 29, '}': 29,
1119 '^': 30, '~': 30,
1120 '_': 31,
1121 '?': 127}
1122 if char not in d:
1123 return 0
1124 return self.send(self._chr(d[char]))
1125
1126 def sendeof(self):
1127
1128 '''This sends an EOF to the child. This sends a character which causes
1129 the pending parent output buffer to be sent to the waiting child
1130 program without waiting for end-of-line. If it is the first character
1131 of the line, the read() in the user program returns 0, which signifies
1132 end-of-file. This means to work as expected a sendeof() has to be
1133 called at the beginning of a line. This method does not send a newline.
1134 It is the responsibility of the caller to ensure the eof is sent at the
1135 beginning of a line. '''
1136
1137 self.send(self._chr(self._EOF))
1138
1139 def sendintr(self):
1140
1141 '''This sends a SIGINT to the child. It does not require
1142 the SIGINT to be the first character on a line. '''
1143
1144 self.send(self._chr(self._INTR))
1145
1146 def eof(self):
1147
1148 '''This returns True if the EOF exception was ever raised.
1149 '''
1150
1151 return self.flag_eof
1152
1153 def terminate(self, force=False):
1154
1155 '''This forces a child process to terminate. It starts nicely with
1156 SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This
1157 returns True if the child was terminated. This returns False if the
1158 child could not be terminated. '''
1159
1160 if not self.isalive():
1161 return True
1162 try:
1163 self.kill(signal.SIGHUP)
1164 time.sleep(self.delayafterterminate)
1165 if not self.isalive():
1166 return True
1167 self.kill(signal.SIGCONT)
1168 time.sleep(self.delayafterterminate)
1169 if not self.isalive():
1170 return True
1171 self.kill(signal.SIGINT)
1172 time.sleep(self.delayafterterminate)
1173 if not self.isalive():
1174 return True
1175 if force:
1176 self.kill(signal.SIGKILL)
1177 time.sleep(self.delayafterterminate)
1178 if not self.isalive():
1179 return True
1180 else:
1181 return False
1182 return False
1183 except OSError:
1184 # I think there are kernel timing issues that sometimes cause
1185 # this to happen. I think isalive() reports True, but the
1186 # process is dead to the kernel.
1187 # Make one last attempt to see if the kernel is up to date.
1188 time.sleep(self.delayafterterminate)
1189 if not self.isalive():
1190 return True
1191 else:
1192 return False
1193
1194 def wait(self):
1195
1196 '''This waits until the child exits. This is a blocking call. This will
1197 not read any data from the child, so this will block forever if the
1198 child has unread output and has terminated. In other words, the child
1199 may have printed output then called exit(), but, the child is
1200 technically still alive until its output is read by the parent. '''
1201
1202 if self.isalive():
1203 pid, status = os.waitpid(self.pid, 0)
1204 else:
1205 raise ExceptionPexpect('Cannot wait for dead child process.')
1206 self.exitstatus = os.WEXITSTATUS(status)
1207 if os.WIFEXITED(status):
1208 self.status = status
1209 self.exitstatus = os.WEXITSTATUS(status)
1210 self.signalstatus = None
1211 self.terminated = True
1212 elif os.WIFSIGNALED(status):
1213 self.status = status
1214 self.exitstatus = None
1215 self.signalstatus = os.WTERMSIG(status)
1216 self.terminated = True
1217 elif os.WIFSTOPPED(status): # pragma: no cover
1218 # You can't call wait() on a child process in the stopped state.
1219 raise ExceptionPexpect('Called wait() on a stopped child ' +
1220 'process. This is not supported. Is some other ' +
1221 'process attempting job control with our child pid?')
1222 return self.exitstatus
1223
1224 def isalive(self):
1225
1226 '''This tests if the child process is running or not. This is
1227 non-blocking. If the child was terminated then this will read the
1228 exitstatus or signalstatus of the child. This returns True if the child
1229 process appears to be running or False if not. It can take literally
1230 SECONDS for Solaris to return the right status. '''
1231
1232 if self.terminated:
1233 return False
1234
1235 if self.flag_eof:
1236 # This is for Linux, which requires the blocking form
1237 # of waitpid to get the status of a defunct process.
1238 # This is super-lame. The flag_eof would have been set
1239 # in read_nonblocking(), so this should be safe.
1240 waitpid_options = 0
1241 else:
1242 waitpid_options = os.WNOHANG
1243
1244 try:
1245 pid, status = os.waitpid(self.pid, waitpid_options)
1246 except OSError:
1247 err = sys.exc_info()[1]
1248 # No child processes
1249 if err.errno == errno.ECHILD:
1250 raise ExceptionPexpect('isalive() encountered condition ' +
1251 'where "terminated" is 0, but there was no child ' +
1252 'process. Did someone else call waitpid() ' +
1253 'on our process?')
1254 else:
1255 raise err
1256
1257 # I have to do this twice for Solaris.
1258 # I can't even believe that I figured this out...
1259 # If waitpid() returns 0 it means that no child process
1260 # wishes to report, and the value of status is undefined.
1261 if pid == 0:
1262 try:
1263 ### os.WNOHANG) # Solaris!
1264 pid, status = os.waitpid(self.pid, waitpid_options)
1265 except OSError as e: # pragma: no cover
1266 # This should never happen...
1267 if e.errno == errno.ECHILD:
1268 raise ExceptionPexpect('isalive() encountered condition ' +
1269 'that should never happen. There was no child ' +
1270 'process. Did someone else call waitpid() ' +
1271 'on our process?')
1272 else:
1273 raise
1274
1275 # If pid is still 0 after two calls to waitpid() then the process
1276 # really is alive. This seems to work on all platforms, except for
1277 # Irix which seems to require a blocking call on waitpid or select,
1278 # so I let read_nonblocking take care of this situation
1279 # (unfortunately, this requires waiting through the timeout).
1280 if pid == 0:
1281 return True
1282
1283 if pid == 0:
1284 return True
1285
1286 if os.WIFEXITED(status):
1287 self.status = status
1288 self.exitstatus = os.WEXITSTATUS(status)
1289 self.signalstatus = None
1290 self.terminated = True
1291 elif os.WIFSIGNALED(status):
1292 self.status = status
1293 self.exitstatus = None
1294 self.signalstatus = os.WTERMSIG(status)
1295 self.terminated = True
1296 elif os.WIFSTOPPED(status):
1297 raise ExceptionPexpect('isalive() encountered condition ' +
1298 'where child process is stopped. This is not ' +
1299 'supported. Is some other process attempting ' +
1300 'job control with our child pid?')
1301 return False
1302
1303 def kill(self, sig):
1304
1305 '''This sends the given signal to the child application. In keeping
1306 with UNIX tradition it has a misleading name. It does not necessarily
1307 kill the child unless you send the right signal. '''
1308
1309 # Same as os.kill, but the pid is given for you.
1310 if self.isalive():
1311 os.kill(self.pid, sig)
1312
1313 def _pattern_type_err(self, pattern):
1314 raise TypeError('got {badtype} ({badobj!r}) as pattern, must be one'
1315 ' of: {goodtypes}, pexpect.EOF, pexpect.TIMEOUT'\
1316 .format(badtype=type(pattern),
1317 badobj=pattern,
1318 goodtypes=', '.join([str(ast)\
1319 for ast in self.allowed_string_types])
1320 )
1321 )
1322
1323 def compile_pattern_list(self, patterns):
1324
1325 '''This compiles a pattern-string or a list of pattern-strings.
1326 Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of
1327 those. Patterns may also be None which results in an empty list (you
1328 might do this if waiting for an EOF or TIMEOUT condition without
1329 expecting any pattern).
1330
1331 This is used by expect() when calling expect_list(). Thus expect() is
1332 nothing more than::
1333
1334 cpl = self.compile_pattern_list(pl)
1335 return self.expect_list(cpl, timeout)
1336
1337 If you are using expect() within a loop it may be more
1338 efficient to compile the patterns first and then call expect_list().
1339 This avoid calls in a loop to compile_pattern_list()::
1340
1341 cpl = self.compile_pattern_list(my_pattern)
1342 while some_condition:
1343 ...
1344 i = self.expect_list(clp, timeout)
1345 ...
1346 '''
1347
1348 if patterns is None:
1349 return []
1350 if not isinstance(patterns, list):
1351 patterns = [patterns]
1352
1353 # Allow dot to match \n
1354 compile_flags = re.DOTALL
1355 if self.ignorecase:
1356 compile_flags = compile_flags | re.IGNORECASE
1357 compiled_pattern_list = []
1358 for idx, p in enumerate(patterns):
1359 if isinstance(p, self.allowed_string_types):
1360 p = self._coerce_expect_string(p)
1361 compiled_pattern_list.append(re.compile(p, compile_flags))
1362 elif p is EOF:
1363 compiled_pattern_list.append(EOF)
1364 elif p is TIMEOUT:
1365 compiled_pattern_list.append(TIMEOUT)
1366 elif isinstance(p, type(re.compile(''))):
1367 compiled_pattern_list.append(p)
1368 else:
1369 self._pattern_type_err(p)
1370 return compiled_pattern_list
1371
1372 def expect(self, pattern, timeout=-1, searchwindowsize=-1):
1373
1374 '''This seeks through the stream until a pattern is matched. The
1375 pattern is overloaded and may take several types. The pattern can be a
1376 StringType, EOF, a compiled re, or a list of any of those types.
1377 Strings will be compiled to re types. This returns the index into the
1378 pattern list. If the pattern was not a list this returns index 0 on a
1379 successful match. This may raise exceptions for EOF or TIMEOUT. To
1380 avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to the pattern
1381 list. That will cause expect to match an EOF or TIMEOUT condition
1382 instead of raising an exception.
1383
1384 If you pass a list of patterns and more than one matches, the first
1385 match in the stream is chosen. If more than one pattern matches at that
1386 point, the leftmost in the pattern list is chosen. For example::
1387
1388 # the input is 'foobar'
1389 index = p.expect(['bar', 'foo', 'foobar'])
1390 # returns 1('foo') even though 'foobar' is a "better" match
1391
1392 Please note, however, that buffering can affect this behavior, since
1393 input arrives in unpredictable chunks. For example::
1394
1395 # the input is 'foobar'
1396 index = p.expect(['foobar', 'foo'])
1397 # returns 0('foobar') if all input is available at once,
1398 # but returs 1('foo') if parts of the final 'bar' arrive late
1399
1400 After a match is found the instance attributes 'before', 'after' and
1401 'match' will be set. You can see all the data read before the match in
1402 'before'. You can see the data that was matched in 'after'. The
1403 re.MatchObject used in the re match will be in 'match'. If an error
1404 occurred then 'before' will be set to all the data read so far and
1405 'after' and 'match' will be None.
1406
1407 If timeout is -1 then timeout will be set to the self.timeout value.
1408
1409 A list entry may be EOF or TIMEOUT instead of a string. This will
1410 catch these exceptions and return the index of the list entry instead
1411 of raising the exception. The attribute 'after' will be set to the
1412 exception type. The attribute 'match' will be None. This allows you to
1413 write code like this::
1414
1415 index = p.expect(['good', 'bad', pexpect.EOF, pexpect.TIMEOUT])
1416 if index == 0:
1417 do_something()
1418 elif index == 1:
1419 do_something_else()
1420 elif index == 2:
1421 do_some_other_thing()
1422 elif index == 3:
1423 do_something_completely_different()
1424
1425 instead of code like this::
1426
1427 try:
1428 index = p.expect(['good', 'bad'])
1429 if index == 0:
1430 do_something()
1431 elif index == 1:
1432 do_something_else()
1433 except EOF:
1434 do_some_other_thing()
1435 except TIMEOUT:
1436 do_something_completely_different()
1437
1438 These two forms are equivalent. It all depends on what you want. You
1439 can also just expect the EOF if you are waiting for all output of a
1440 child to finish. For example::
1441
1442 p = pexpect.spawn('/bin/ls')
1443 p.expect(pexpect.EOF)
1444 print p.before
1445
1446 If you are trying to optimize for speed then see expect_list().
1447 '''
1448
1449 compiled_pattern_list = self.compile_pattern_list(pattern)
1450 return self.expect_list(compiled_pattern_list,
1451 timeout, searchwindowsize)
1452
1453 def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1):
1454
1455 '''This takes a list of compiled regular expressions and returns the
1456 index into the pattern_list that matched the child output. The list may
1457 also contain EOF or TIMEOUT(which are not compiled regular
1458 expressions). This method is similar to the expect() method except that
1459 expect_list() does not recompile the pattern list on every call. This
1460 may help if you are trying to optimize for speed, otherwise just use
1461 the expect() method. This is called by expect(). If timeout==-1 then
1462 the self.timeout value is used. If searchwindowsize==-1 then the
1463 self.searchwindowsize value is used. '''
1464
1465 return self.expect_loop(searcher_re(pattern_list),
1466 timeout, searchwindowsize)
1467
1468 def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1):
1469
1470 '''This is similar to expect(), but uses plain string matching instead
1471 of compiled regular expressions in 'pattern_list'. The 'pattern_list'
1472 may be a string; a list or other sequence of strings; or TIMEOUT and
1473 EOF.
1474
1475 This call might be faster than expect() for two reasons: string
1476 searching is faster than RE matching and it is possible to limit the
1477 search to just the end of the input buffer.
1478
1479 This method is also useful when you don't want to have to worry about
1480 escaping regular expression characters that you want to match.'''
1481
1482 if (isinstance(pattern_list, self.allowed_string_types) or
1483 pattern_list in (TIMEOUT, EOF)):
1484 pattern_list = [pattern_list]
1485
1486 def prepare_pattern(pattern):
1487 if pattern in (TIMEOUT, EOF):
1488 return pattern
1489 if isinstance(pattern, self.allowed_string_types):
1490 return self._coerce_expect_string(pattern)
1491 self._pattern_type_err(pattern)
1492
1493 try:
1494 pattern_list = iter(pattern_list)
1495 except TypeError:
1496 self._pattern_type_err(pattern_list)
1497 pattern_list = [prepare_pattern(p) for p in pattern_list]
1498 return self.expect_loop(searcher_string(pattern_list),
1499 timeout, searchwindowsize)
1500
1501 def expect_loop(self, searcher, timeout=-1, searchwindowsize=-1):
1502
1503 '''This is the common loop used inside expect. The 'searcher' should be
1504 an instance of searcher_re or searcher_string, which describes how and
1505 what to search for in the input.
1506
1507 See expect() for other arguments, return value and exceptions. '''
1508
1509 self.searcher = searcher
1510
1511 if timeout == -1:
1512 timeout = self.timeout
1513 if timeout is not None:
1514 end_time = time.time() + timeout
1515 if searchwindowsize == -1:
1516 searchwindowsize = self.searchwindowsize
1517
1518 try:
1519 incoming = self.buffer
1520 freshlen = len(incoming)
1521 while True:
1522 # Keep reading until exception or return.
1523 index = searcher.search(incoming, freshlen, searchwindowsize)
1524 if index >= 0:
1525 self.buffer = incoming[searcher.end:]
1526 self.before = incoming[: searcher.start]
1527 self.after = incoming[searcher.start: searcher.end]
1528 self.match = searcher.match
1529 self.match_index = index
1530 return self.match_index
1531 # No match at this point
1532 if (timeout is not None) and (timeout < 0):
1533 raise TIMEOUT('Timeout exceeded in expect_any().')
1534 # Still have time left, so read more data
1535 c = self.read_nonblocking(self.maxread, timeout)
1536 freshlen = len(c)
1537 time.sleep(0.0001)
1538 incoming = incoming + c
1539 if timeout is not None:
1540 timeout = end_time - time.time()
1541 except EOF:
1542 err = sys.exc_info()[1]
1543 self.buffer = self.string_type()
1544 self.before = incoming
1545 self.after = EOF
1546 index = searcher.eof_index
1547 if index >= 0:
1548 self.match = EOF
1549 self.match_index = index
1550 return self.match_index
1551 else:
1552 self.match = None
1553 self.match_index = None
1554 raise EOF(str(err) + '\n' + str(self))
1555 except TIMEOUT:
1556 err = sys.exc_info()[1]
1557 self.buffer = incoming
1558 self.before = incoming
1559 self.after = TIMEOUT
1560 index = searcher.timeout_index
1561 if index >= 0:
1562 self.match = TIMEOUT
1563 self.match_index = index
1564 return self.match_index
1565 else:
1566 self.match = None
1567 self.match_index = None
1568 raise TIMEOUT(str(err) + '\n' + str(self))
1569 except:
1570 self.before = incoming
1571 self.after = None
1572 self.match = None
1573 self.match_index = None
1574 raise
1575
1576 def getwinsize(self):
1577
1578 '''This returns the terminal window size of the child tty. The return
1579 value is a tuple of (rows, cols). '''
1580
1581 TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912)
1582 s = struct.pack('HHHH', 0, 0, 0, 0)
1583 x = fcntl.ioctl(self.child_fd, TIOCGWINSZ, s)
1584 return struct.unpack('HHHH', x)[0:2]
1585
1586 def setwinsize(self, rows, cols):
1587
1588 '''This sets the terminal window size of the child tty. This will cause
1589 a SIGWINCH signal to be sent to the child. This does not change the
1590 physical window size. It changes the size reported to TTY-aware
1591 applications like vi or curses -- applications that respond to the
1592 SIGWINCH signal. '''
1593
1594 # Some very old platforms have a bug that causes the value for
1595 # termios.TIOCSWINSZ to be truncated. There was a hack here to work
1596 # around this, but it caused problems with newer platforms so has been
1597 # removed. For details see https://github.com/pexpect/pexpect/issues/39
1598 TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561)
1599 # Note, assume ws_xpixel and ws_ypixel are zero.
1600 s = struct.pack('HHHH', rows, cols, 0, 0)
1601 fcntl.ioctl(self.fileno(), TIOCSWINSZ, s)
1602
1603 def interact(self, escape_character=chr(29),
1604 input_filter=None, output_filter=None):
1605
1606 '''This gives control of the child process to the interactive user (the
1607 human at the keyboard). Keystrokes are sent to the child process, and
1608 the stdout and stderr output of the child process is printed. This
1609 simply echos the child stdout and child stderr to the real stdout and
1610 it echos the real stdin to the child stdin. When the user types the
1611 escape_character this method will stop. The default for
1612 escape_character is ^]. This should not be confused with ASCII 27 --
1613 the ESC character. ASCII 29 was chosen for historical merit because
1614 this is the character used by 'telnet' as the escape character. The
1615 escape_character will not be sent to the child process.
1616
1617 You may pass in optional input and output filter functions. These
1618 functions should take a string and return a string. The output_filter
1619 will be passed all the output from the child process. The input_filter
1620 will be passed all the keyboard input from the user. The input_filter
1621 is run BEFORE the check for the escape_character.
1622
1623 Note that if you change the window size of the parent the SIGWINCH
1624 signal will not be passed through to the child. If you want the child
1625 window size to change when the parent's window size changes then do
1626 something like the following example::
1627
1628 import pexpect, struct, fcntl, termios, signal, sys
1629 def sigwinch_passthrough (sig, data):
1630 s = struct.pack("HHHH", 0, 0, 0, 0)
1631 a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(),
1632 termios.TIOCGWINSZ , s))
1633 global p
1634 p.setwinsize(a[0],a[1])
1635 # Note this 'p' global and used in sigwinch_passthrough.
1636 p = pexpect.spawn('/bin/bash')
1637 signal.signal(signal.SIGWINCH, sigwinch_passthrough)
1638 p.interact()
1639 '''
1640
1641 # Flush the buffer.
1642 self.write_to_stdout(self.buffer)
1643 self.stdout.flush()
1644 self.buffer = self.string_type()
1645 mode = tty.tcgetattr(self.STDIN_FILENO)
1646 tty.setraw(self.STDIN_FILENO)
1647 if PY3:
1648 escape_character = escape_character.encode('latin-1')
1649 try:
1650 self.__interact_copy(escape_character, input_filter, output_filter)
1651 finally:
1652 tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode)
1653
1654 def __interact_writen(self, fd, data):
1655 '''This is used by the interact() method.
1656 '''
1657
1658 while data != b'' and self.isalive():
1659 n = os.write(fd, data)
1660 data = data[n:]
1661
1662 def __interact_read(self, fd):
1663 '''This is used by the interact() method.
1664 '''
1665
1666 return os.read(fd, 1000)
1667
1668 def __interact_copy(self, escape_character=None,
1669 input_filter=None, output_filter=None):
1670
1671 '''This is used by the interact() method.
1672 '''
1673
1674 while self.isalive():
1675 r, w, e = self.__select([self.child_fd, self.STDIN_FILENO], [], [])
1676 if self.child_fd in r:
1677 try:
1678 data = self.__interact_read(self.child_fd)
1679 except OSError as err:
1680 if err.args[0] == errno.EIO:
1681 # Linux-style EOF
1682 break
1683 raise
1684 if data == b'':
1685 # BSD-style EOF
1686 break
1687 if output_filter:
1688 data = output_filter(data)
1689 if self.logfile is not None:
1690 self.logfile.write(data)
1691 self.logfile.flush()
1692 os.write(self.STDOUT_FILENO, data)
1693 if self.STDIN_FILENO in r:
1694 data = self.__interact_read(self.STDIN_FILENO)
1695 if input_filter:
1696 data = input_filter(data)
1697 i = data.rfind(escape_character)
1698 if i != -1:
1699 data = data[:i]
1700 self.__interact_writen(self.child_fd, data)
1701 break
1702 self.__interact_writen(self.child_fd, data)
1703
1704 def __select(self, iwtd, owtd, ewtd, timeout=None):
1705
1706 '''This is a wrapper around select.select() that ignores signals. If
1707 select.select raises a select.error exception and errno is an EINTR
1708 error then it is ignored. Mainly this is used to ignore sigwinch
1709 (terminal resize). '''
1710
1711 # if select() is interrupted by a signal (errno==EINTR) then
1712 # we loop back and enter the select() again.
1713 if timeout is not None:
1714 end_time = time.time() + timeout
1715 while True:
1716 try:
1717 return select.select(iwtd, owtd, ewtd, timeout)
1718 except select.error:
1719 err = sys.exc_info()[1]
1720 if err.args[0] == errno.EINTR:
1721 # if we loop back we have to subtract the
1722 # amount of time we already waited.
1723 if timeout is not None:
1724 timeout = end_time - time.time()
1725 if timeout < 0:
1726 return([], [], [])
1727 else:
1728 # something else caused the select.error, so
1729 # this actually is an exception.
1730 raise
1731
1732 ##############################################################################
1733 # The following methods are no longer supported or allowed.
1734
1735 def setmaxread(self, maxread): # pragma: no cover
1736
1737 '''This method is no longer supported or allowed. I don't like getters
1738 and setters without a good reason. '''
1739
1740 raise ExceptionPexpect('This method is no longer supported ' +
1741 'or allowed. Just assign a value to the ' +
1742 'maxread member variable.')
1743
1744 def setlog(self, fileobject): # pragma: no cover
1745
1746 '''This method is no longer supported or allowed.
1747 '''
1748
1749 raise ExceptionPexpect('This method is no longer supported ' +
1750 'or allowed. Just assign a value to the logfile ' +
1751 'member variable.')
1752
1753 ##############################################################################
1754 # End of spawn class
1755 ##############################################################################
1756
1757 class spawnu(spawn):
1758 """Works like spawn, but accepts and returns unicode strings.
1759
1760 Extra parameters:
1761
1762 :param encoding: The encoding to use for communications (default: 'utf-8')
1763 :param errors: How to handle encoding/decoding errors; one of 'strict'
1764 (the default), 'ignore', or 'replace', as described
1765 for :meth:`~bytes.decode` and :meth:`~str.encode`.
1766 """
1767 if PY3:
1768 string_type = str
1769 allowed_string_types = (str, )
1770 _chr = staticmethod(chr)
1771 linesep = os.linesep
1772 crlf = '\r\n'
1773 else:
1774 string_type = unicode
1775 allowed_string_types = (unicode, )
1776 _chr = staticmethod(unichr)
1777 linesep = os.linesep.decode('ascii')
1778 crlf = '\r\n'.decode('ascii')
1779 # This can handle unicode in both Python 2 and 3
1780 write_to_stdout = sys.stdout.write
1781
1782 def __init__(self, *args, **kwargs):
1783 self.encoding = kwargs.pop('encoding', 'utf-8')
1784 self.errors = kwargs.pop('errors', 'strict')
1785 self._decoder = codecs.getincrementaldecoder(self.encoding)(errors=self.errors)
1786 super(spawnu, self).__init__(*args, **kwargs)
1787
1788 @staticmethod
1789 def _coerce_expect_string(s):
1790 return s
1791
1792 @staticmethod
1793 def _coerce_send_string(s):
1794 return s
1795
1796 def _coerce_read_string(self, s):
1797 return self._decoder.decode(s, final=False)
1798
1799 def _send(self, s):
1800 return os.write(self.child_fd, s.encode(self.encoding, self.errors))
1801
1802
1803 class searcher_string(object):
1804
1805 '''This is a plain string search helper for the spawn.expect_any() method.
1806 This helper class is for speed. For more powerful regex patterns
1807 see the helper class, searcher_re.
1808
1809 Attributes:
1810
1811 eof_index - index of EOF, or -1
1812 timeout_index - index of TIMEOUT, or -1
1813
1814 After a successful match by the search() method the following attributes
1815 are available:
1816
1817 start - index into the buffer, first byte of match
1818 end - index into the buffer, first byte after match
1819 match - the matching string itself
1820
1821 '''
1822
1823 def __init__(self, strings):
1824
1825 '''This creates an instance of searcher_string. This argument 'strings'
1826 may be a list; a sequence of strings; or the EOF or TIMEOUT types. '''
1827
1828 self.eof_index = -1
1829 self.timeout_index = -1
1830 self._strings = []
1831 for n, s in enumerate(strings):
1832 if s is EOF:
1833 self.eof_index = n
1834 continue
1835 if s is TIMEOUT:
1836 self.timeout_index = n
1837 continue
1838 self._strings.append((n, s))
1839
1840 def __str__(self):
1841
1842 '''This returns a human-readable string that represents the state of
1843 the object.'''
1844
1845 ss = [(ns[0], ' %d: "%s"' % ns) for ns in self._strings]
1846 ss.append((-1, 'searcher_string:'))
1847 if self.eof_index >= 0:
1848 ss.append((self.eof_index, ' %d: EOF' % self.eof_index))
1849 if self.timeout_index >= 0:
1850 ss.append((self.timeout_index,
1851 ' %d: TIMEOUT' % self.timeout_index))
1852 ss.sort()
1853 ss = list(zip(*ss))[1]
1854 return '\n'.join(ss)
1855
1856 def search(self, buffer, freshlen, searchwindowsize=None):
1857
1858 '''This searches 'buffer' for the first occurence of one of the search
1859 strings. 'freshlen' must indicate the number of bytes at the end of
1860 'buffer' which have not been searched before. It helps to avoid
1861 searching the same, possibly big, buffer over and over again.
1862
1863 See class spawn for the 'searchwindowsize' argument.
1864
1865 If there is a match this returns the index of that string, and sets
1866 'start', 'end' and 'match'. Otherwise, this returns -1. '''
1867
1868 first_match = None
1869
1870 # 'freshlen' helps a lot here. Further optimizations could
1871 # possibly include:
1872 #
1873 # using something like the Boyer-Moore Fast String Searching
1874 # Algorithm; pre-compiling the search through a list of
1875 # strings into something that can scan the input once to
1876 # search for all N strings; realize that if we search for
1877 # ['bar', 'baz'] and the input is '...foo' we need not bother
1878 # rescanning until we've read three more bytes.
1879 #
1880 # Sadly, I don't know enough about this interesting topic. /grahn
1881
1882 for index, s in self._strings:
1883 if searchwindowsize is None:
1884 # the match, if any, can only be in the fresh data,
1885 # or at the very end of the old data
1886 offset = -(freshlen + len(s))
1887 else:
1888 # better obey searchwindowsize
1889 offset = -searchwindowsize
1890 n = buffer.find(s, offset)
1891 if n >= 0 and (first_match is None or n < first_match):
1892 first_match = n
1893 best_index, best_match = index, s
1894 if first_match is None:
1895 return -1
1896 self.match = best_match
1897 self.start = first_match
1898 self.end = self.start + len(self.match)
1899 return best_index
1900
1901
1902 class searcher_re(object):
1903
1904 '''This is regular expression string search helper for the
1905 spawn.expect_any() method. This helper class is for powerful
1906 pattern matching. For speed, see the helper class, searcher_string.
1907
1908 Attributes:
1909
1910 eof_index - index of EOF, or -1
1911 timeout_index - index of TIMEOUT, or -1
1912
1913 After a successful match by the search() method the following attributes
1914 are available:
1915
1916 start - index into the buffer, first byte of match
1917 end - index into the buffer, first byte after match
1918 match - the re.match object returned by a succesful re.search
1919
1920 '''
1921
1922 def __init__(self, patterns):
1923
1924 '''This creates an instance that searches for 'patterns' Where
1925 'patterns' may be a list or other sequence of compiled regular
1926 expressions, or the EOF or TIMEOUT types.'''
1927
1928 self.eof_index = -1
1929 self.timeout_index = -1
1930 self._searches = []
1931 for n, s in zip(list(range(len(patterns))), patterns):
1932 if s is EOF:
1933 self.eof_index = n
1934 continue
1935 if s is TIMEOUT:
1936 self.timeout_index = n
1937 continue
1938 self._searches.append((n, s))
1939
1940 def __str__(self):
1941
1942 '''This returns a human-readable string that represents the state of
1943 the object.'''
1944
1945 #ss = [(n, ' %d: re.compile("%s")' %
1946 # (n, repr(s.pattern))) for n, s in self._searches]
1947 ss = list()
1948 for n, s in self._searches:
1949 try:
1950 ss.append((n, ' %d: re.compile("%s")' % (n, s.pattern)))
1951 except UnicodeEncodeError:
1952 # for test cases that display __str__ of searches, dont throw
1953 # another exception just because stdout is ascii-only, using
1954 # repr()
1955 ss.append((n, ' %d: re.compile(%r)' % (n, s.pattern)))
1956 ss.append((-1, 'searcher_re:'))
1957 if self.eof_index >= 0:
1958 ss.append((self.eof_index, ' %d: EOF' % self.eof_index))
1959 if self.timeout_index >= 0:
1960 ss.append((self.timeout_index, ' %d: TIMEOUT' %
1961 self.timeout_index))
1962 ss.sort()
1963 ss = list(zip(*ss))[1]
1964 return '\n'.join(ss)
1965
1966 def search(self, buffer, freshlen, searchwindowsize=None):
1967
1968 '''This searches 'buffer' for the first occurence of one of the regular
1969 expressions. 'freshlen' must indicate the number of bytes at the end of
1970 'buffer' which have not been searched before.
1971
1972 See class spawn for the 'searchwindowsize' argument.
1973
1974 If there is a match this returns the index of that string, and sets
1975 'start', 'end' and 'match'. Otherwise, returns -1.'''
1976
1977 first_match = None
1978 # 'freshlen' doesn't help here -- we cannot predict the
1979 # length of a match, and the re module provides no help.
1980 if searchwindowsize is None:
1981 searchstart = 0
1982 else:
1983 searchstart = max(0, len(buffer) - searchwindowsize)
1984 for index, s in self._searches:
1985 match = s.search(buffer, searchstart)
1986 if match is None:
1987 continue
1988 n = match.start()
1989 if first_match is None or n < first_match:
1990 first_match = n
1991 the_match = match
1992 best_index = index
1993 if first_match is None:
1994 return -1
1995 self.start = first_match
1996 self.match = the_match
1997 self.end = self.match.end()
1998 return best_index
1999
2000
2001 def is_executable_file(path):
2002 """Checks that path is an executable regular file (or a symlink to a file).
2003
2004 This is roughly ``os.path isfile(path) and os.access(path, os.X_OK)``, but
2005 on some platforms :func:`os.access` gives us the wrong answer, so this
2006 checks permission bits directly.
2007 """
2008 # follow symlinks,
2009 fpath = os.path.realpath(path)
2010
2011 # return False for non-files (directories, fifo, etc.)
2012 if not os.path.isfile(fpath):
2013 return False
2014
2015 # On Solaris, etc., "If the process has appropriate privileges, an
2016 # implementation may indicate success for X_OK even if none of the
2017 # execute file permission bits are set."
2018 #
2019 # For this reason, it is necessary to explicitly check st_mode
2020
2021 # get file mode using os.stat, and check if `other',
2022 # that is anybody, may read and execute.
2023 mode = os.stat(fpath).st_mode
2024 if mode & stat.S_IROTH and mode & stat.S_IXOTH:
2025 return True
2026
2027 # get current user's group ids, and check if `group',
2028 # when matching ours, may read and execute.
2029 user_gids = os.getgroups() + [os.getgid()]
2030 if (os.stat(fpath).st_gid in user_gids and
2031 mode & stat.S_IRGRP and mode & stat.S_IXGRP):
2032 return True
2033
2034 # finally, if file owner matches our effective userid,
2035 # check if `user', may read and execute.
2036 user_gids = os.getgroups() + [os.getgid()]
2037 if (os.stat(fpath).st_uid == os.geteuid() and
2038 mode & stat.S_IRUSR and mode & stat.S_IXUSR):
2039 return True
2040
2041 return False
2042
2043 def which(filename):
2044 '''This takes a given filename; tries to find it in the environment path;
2045 then checks if it is executable. This returns the full path to the filename
2046 if found and executable. Otherwise this returns None.'''
2047
2048 # Special case where filename contains an explicit path.
2049 if os.path.dirname(filename) != '' and is_executable_file(filename):
2050 return filename
2051 if 'PATH' not in os.environ or os.environ['PATH'] == '':
2052 p = os.defpath
2053 else:
2054 p = os.environ['PATH']
2055 pathlist = p.split(os.pathsep)
2056 for path in pathlist:
2057 ff = os.path.join(path, filename)
2058 if is_executable_file(ff):
2059 return ff
2060 return None
2061
2062
2063 def split_command_line(command_line):
2064
2065 '''This splits a command line into a list of arguments. It splits arguments
2066 on spaces, but handles embedded quotes, doublequotes, and escaped
2067 characters. It's impossible to do this with a regular expression, so I
2068 wrote a little state machine to parse the command line. '''
2069
2070 arg_list = []
2071 arg = ''
2072
2073 # Constants to name the states we can be in.
2074 state_basic = 0
2075 state_esc = 1
2076 state_singlequote = 2
2077 state_doublequote = 3
2078 # The state when consuming whitespace between commands.
2079 state_whitespace = 4
2080 state = state_basic
2081
2082 for c in command_line:
2083 if state == state_basic or state == state_whitespace:
2084 if c == '\\':
2085 # Escape the next character
2086 state = state_esc
2087 elif c == r"'":
2088 # Handle single quote
2089 state = state_singlequote
2090 elif c == r'"':
2091 # Handle double quote
2092 state = state_doublequote
2093 elif c.isspace():
2094 # Add arg to arg_list if we aren't in the middle of whitespace.
2095 if state == state_whitespace:
2096 # Do nothing.
2097 None
2098 else:
2099 arg_list.append(arg)
2100 arg = ''
2101 state = state_whitespace
2102 else:
2103 arg = arg + c
2104 state = state_basic
2105 elif state == state_esc:
2106 arg = arg + c
2107 state = state_basic
2108 elif state == state_singlequote:
2109 if c == r"'":
2110 state = state_basic
2111 else:
2112 arg = arg + c
2113 elif state == state_doublequote:
2114 if c == r'"':
2115 state = state_basic
2116 else:
2117 arg = arg + c
2118
2119 if arg != '':
2120 arg_list.append(arg)
2121 return arg_list
2122
2123 # vim: set shiftround expandtab tabstop=4 shiftwidth=4 ft=python autoindent :
@@ -1,4 +0,0
1 try:
2 from simplegeneric import *
3 except ImportError:
4 from ._simplegeneric import *
@@ -1,109 +0,0
1 """This is version 0.7 of Philip J. Eby's simplegeneric module
2 (http://pypi.python.org/pypi/simplegeneric), patched to work with Python 3,
3 which doesn't support old-style classes.
4 """
5
6 #Name: simplegeneric
7 #Version: 0.7
8 #Summary: Simple generic functions (similar to Python's own len(), pickle.dump(), etc.)
9 #Home-page: http://pypi.python.org/pypi/simplegeneric
10 #Author: Phillip J. Eby
11 #Author-email: peak@eby-sarna.com
12 #License: PSF or ZPL
13
14 __all__ = ["generic"]
15
16 try:
17 from types import ClassType, InstanceType
18 except ImportError:
19 classtypes = type
20 else:
21 classtypes = type, ClassType
22
23 def generic(func):
24 """Create a simple generic function"""
25
26 _sentinel = object()
27
28 def _by_class(*args, **kw):
29 cls = args[0].__class__
30 for t in type(cls.__name__, (cls,object), {}).__mro__:
31 f = _gbt(t, _sentinel)
32 if f is not _sentinel:
33 return f(*args, **kw)
34 else:
35 return func(*args, **kw)
36
37 _by_type = {object: func}
38 try:
39 _by_type[InstanceType] = _by_class
40 except NameError: # Python 3
41 pass
42
43 _gbt = _by_type.get
44
45 def when_type(*types):
46 """Decorator to add a method that will be called for the given types"""
47 for t in types:
48 if not isinstance(t, classtypes):
49 raise TypeError(
50 "%r is not a type or class" % (t,)
51 )
52 def decorate(f):
53 for t in types:
54 if _by_type.setdefault(t,f) is not f:
55 raise TypeError(
56 "%r already has method for type %r" % (func, t)
57 )
58 return f
59 return decorate
60
61
62
63
64 _by_object = {}
65 _gbo = _by_object.get
66
67 def when_object(*obs):
68 """Decorator to add a method to be called for the given object(s)"""
69 def decorate(f):
70 for o in obs:
71 if _by_object.setdefault(id(o), (o,f))[1] is not f:
72 raise TypeError(
73 "%r already has method for object %r" % (func, o)
74 )
75 return f
76 return decorate
77
78
79 def dispatch(*args, **kw):
80 f = _gbo(id(args[0]), _sentinel)
81 if f is _sentinel:
82 for t in type(args[0]).__mro__:
83 f = _gbt(t, _sentinel)
84 if f is not _sentinel:
85 return f(*args, **kw)
86 else:
87 return func(*args, **kw)
88 else:
89 return f[1](*args, **kw)
90
91 dispatch.__name__ = func.__name__
92 dispatch.__dict__ = func.__dict__.copy()
93 dispatch.__doc__ = func.__doc__
94 dispatch.__module__ = func.__module__
95
96 dispatch.when_type = when_type
97 dispatch.when_object = when_object
98 dispatch.default = func
99 dispatch.has_object = lambda o: id(o) in _by_object
100 dispatch.has_type = lambda t: t in _by_type
101 return dispatch
102
103
104 def test_suite():
105 import doctest
106 return doctest.DocFileSuite(
107 'README.txt',
108 optionflags=doctest.ELLIPSIS|doctest.REPORT_ONLY_FIRST_FAILURE,
109 )
@@ -1,325 +0,0
1 #!/usr/bin/env python
2
3 """ PickleShare - a small 'shelve' like datastore with concurrency support
4
5 Like shelve, a PickleShareDB object acts like a normal dictionary. Unlike
6 shelve, many processes can access the database simultaneously. Changing a
7 value in database is immediately visible to other processes accessing the
8 same database.
9
10 Concurrency is possible because the values are stored in separate files. Hence
11 the "database" is a directory where *all* files are governed by PickleShare.
12
13 Example usage::
14
15 from pickleshare import *
16 db = PickleShareDB('~/testpickleshare')
17 db.clear()
18 print "Should be empty:",db.items()
19 db['hello'] = 15
20 db['aku ankka'] = [1,2,313]
21 db['paths/are/ok/key'] = [1,(5,46)]
22 print db.keys()
23 del db['aku ankka']
24
25 This module is certainly not ZODB, but can be used for low-load
26 (non-mission-critical) situations where tiny code size trumps the
27 advanced features of a "real" object database.
28
29 Installation guide: easy_install pickleshare
30
31 Author: Ville Vainio <vivainio@gmail.com>
32 License: MIT open source license.
33
34 """
35 from __future__ import print_function
36
37 from IPython.external.path import path as Path
38 import stat, time
39 import collections
40 try:
41 import cPickle as pickle
42 except ImportError:
43 import pickle
44 import glob
45
46 def gethashfile(key):
47 return ("%02x" % abs(hash(key) % 256))[-2:]
48
49 _sentinel = object()
50
51 class PickleShareDB(collections.MutableMapping):
52 """ The main 'connection' object for PickleShare database """
53 def __init__(self,root):
54 """ Return a db object that will manage the specied directory"""
55 self.root = Path(root).expanduser().abspath()
56 if not self.root.isdir():
57 self.root.makedirs_p()
58 # cache has { 'key' : (obj, orig_mod_time) }
59 self.cache = {}
60
61
62 def __getitem__(self,key):
63 """ db['key'] reading """
64 fil = self.root / key
65 try:
66 mtime = (fil.stat()[stat.ST_MTIME])
67 except OSError:
68 raise KeyError(key)
69
70 if fil in self.cache and mtime == self.cache[fil][1]:
71 return self.cache[fil][0]
72 try:
73 # The cached item has expired, need to read
74 with fil.open("rb") as f:
75 obj = pickle.loads(f.read())
76 except:
77 raise KeyError(key)
78
79 self.cache[fil] = (obj,mtime)
80 return obj
81
82 def __setitem__(self,key,value):
83 """ db['key'] = 5 """
84 fil = self.root / key
85 parent = fil.parent
86 if parent and not parent.isdir():
87 parent.makedirs()
88 # We specify protocol 2, so that we can mostly go between Python 2
89 # and Python 3. We can upgrade to protocol 3 when Python 2 is obsolete.
90 with fil.open('wb') as f:
91 pickled = pickle.dump(value, f, protocol=2)
92 try:
93 self.cache[fil] = (value,fil.mtime)
94 except OSError as e:
95 if e.errno != 2:
96 raise
97
98 def hset(self, hashroot, key, value):
99 """ hashed set """
100 hroot = self.root / hashroot
101 if not hroot.isdir():
102 hroot.makedirs()
103 hfile = hroot / gethashfile(key)
104 d = self.get(hfile, {})
105 d.update( {key : value})
106 self[hfile] = d
107
108
109
110 def hget(self, hashroot, key, default = _sentinel, fast_only = True):
111 """ hashed get """
112 hroot = self.root / hashroot
113 hfile = hroot / gethashfile(key)
114
115 d = self.get(hfile, _sentinel )
116 #print "got dict",d,"from",hfile
117 if d is _sentinel:
118 if fast_only:
119 if default is _sentinel:
120 raise KeyError(key)
121
122 return default
123
124 # slow mode ok, works even after hcompress()
125 d = self.hdict(hashroot)
126
127 return d.get(key, default)
128
129 def hdict(self, hashroot):
130 """ Get all data contained in hashed category 'hashroot' as dict """
131 hfiles = self.keys(hashroot + "/*")
132 hfiles.sort()
133 last = len(hfiles) and hfiles[-1] or ''
134 if last.endswith('xx'):
135 # print "using xx"
136 hfiles = [last] + hfiles[:-1]
137
138 all = {}
139
140 for f in hfiles:
141 # print "using",f
142 try:
143 all.update(self[f])
144 except KeyError:
145 print("Corrupt",f,"deleted - hset is not threadsafe!")
146 del self[f]
147
148 self.uncache(f)
149
150 return all
151
152 def hcompress(self, hashroot):
153 """ Compress category 'hashroot', so hset is fast again
154
155 hget will fail if fast_only is True for compressed items (that were
156 hset before hcompress).
157
158 """
159 hfiles = self.keys(hashroot + "/*")
160 all = {}
161 for f in hfiles:
162 # print "using",f
163 all.update(self[f])
164 self.uncache(f)
165
166 self[hashroot + '/xx'] = all
167 for f in hfiles:
168 p = self.root / f
169 if p.basename() == 'xx':
170 continue
171 p.remove()
172
173
174
175 def __delitem__(self,key):
176 """ del db["key"] """
177 fil = self.root / key
178 self.cache.pop(fil,None)
179 try:
180 fil.remove()
181 except OSError:
182 # notfound and permission denied are ok - we
183 # lost, the other process wins the conflict
184 pass
185
186 def _normalized(self, p):
187 """ Make a key suitable for user's eyes """
188 return str(self.root.relpathto(p)).replace('\\','/')
189
190 def keys(self, globpat = None):
191 """ All keys in DB, or all keys matching a glob"""
192
193 if globpat is None:
194 files = self.root.walkfiles()
195 else:
196 files = [Path(p) for p in glob.glob(self.root/globpat)]
197 return [self._normalized(p) for p in files if p.isfile()]
198
199 def __iter__(self):
200 return iter(self.keys())
201
202 def __len__(self):
203 return len(self.keys())
204
205 def uncache(self,*items):
206 """ Removes all, or specified items from cache
207
208 Use this after reading a large amount of large objects
209 to free up memory, when you won't be needing the objects
210 for a while.
211
212 """
213 if not items:
214 self.cache = {}
215 for it in items:
216 self.cache.pop(it,None)
217
218 def waitget(self,key, maxwaittime = 60 ):
219 """ Wait (poll) for a key to get a value
220
221 Will wait for `maxwaittime` seconds before raising a KeyError.
222 The call exits normally if the `key` field in db gets a value
223 within the timeout period.
224
225 Use this for synchronizing different processes or for ensuring
226 that an unfortunately timed "db['key'] = newvalue" operation
227 in another process (which causes all 'get' operation to cause a
228 KeyError for the duration of pickling) won't screw up your program
229 logic.
230 """
231
232 wtimes = [0.2] * 3 + [0.5] * 2 + [1]
233 tries = 0
234 waited = 0
235 while 1:
236 try:
237 val = self[key]
238 return val
239 except KeyError:
240 pass
241
242 if waited > maxwaittime:
243 raise KeyError(key)
244
245 time.sleep(wtimes[tries])
246 waited+=wtimes[tries]
247 if tries < len(wtimes) -1:
248 tries+=1
249
250 def getlink(self,folder):
251 """ Get a convenient link for accessing items """
252 return PickleShareLink(self, folder)
253
254 def __repr__(self):
255 return "PickleShareDB('%s')" % self.root
256
257
258
259 class PickleShareLink:
260 """ A shortdand for accessing nested PickleShare data conveniently.
261
262 Created through PickleShareDB.getlink(), example::
263
264 lnk = db.getlink('myobjects/test')
265 lnk.foo = 2
266 lnk.bar = lnk.foo + 5
267
268 """
269 def __init__(self, db, keydir ):
270 self.__dict__.update(locals())
271
272 def __getattr__(self,key):
273 return self.__dict__['db'][self.__dict__['keydir']+'/' + key]
274 def __setattr__(self,key,val):
275 self.db[self.keydir+'/' + key] = val
276 def __repr__(self):
277 db = self.__dict__['db']
278 keys = db.keys( self.__dict__['keydir'] +"/*")
279 return "<PickleShareLink '%s': %s>" % (
280 self.__dict__['keydir'],
281 ";".join([Path(k).basename() for k in keys]))
282
283 def main():
284 import textwrap
285 usage = textwrap.dedent("""\
286 pickleshare - manage PickleShare databases
287
288 Usage:
289
290 pickleshare dump /path/to/db > dump.txt
291 pickleshare load /path/to/db < dump.txt
292 pickleshare test /path/to/db
293 """)
294 DB = PickleShareDB
295 import sys
296 if len(sys.argv) < 2:
297 print(usage)
298 return
299
300 cmd = sys.argv[1]
301 args = sys.argv[2:]
302 if cmd == 'dump':
303 if not args: args= ['.']
304 db = DB(args[0])
305 import pprint
306 pprint.pprint(db.items())
307 elif cmd == 'load':
308 cont = sys.stdin.read()
309 db = DB(args[0])
310 data = eval(cont)
311 db.clear()
312 for k,v in db.items():
313 db[k] = v
314 elif cmd == 'testwait':
315 db = DB(args[0])
316 db.clear()
317 print(db.waitget('250'))
318 elif cmd == 'test':
319 test()
320 stress()
321
322 if __name__== "__main__":
323 main()
324
325
@@ -1,61 +0,0
1 from __future__ import print_function
2
3 import os
4 from unittest import TestCase
5
6 from IPython.testing.decorators import skip
7 from IPython.utils.tempdir import TemporaryDirectory
8 from IPython.utils.pickleshare import PickleShareDB
9
10
11 class PickleShareDBTestCase(TestCase):
12 def setUp(self):
13 self.tempdir = TemporaryDirectory()
14
15 def tearDown(self):
16 self.tempdir.cleanup()
17
18 def test_picklesharedb(self):
19 db = PickleShareDB(self.tempdir.name)
20 db.clear()
21 print("Should be empty:",db.items())
22 db['hello'] = 15
23 db['aku ankka'] = [1,2,313]
24 db['paths/nest/ok/keyname'] = [1,(5,46)]
25 db.hset('hash', 'aku', 12)
26 db.hset('hash', 'ankka', 313)
27 self.assertEqual(db.hget('hash','aku'), 12)
28 self.assertEqual(db.hget('hash','ankka'), 313)
29 print("all hashed",db.hdict('hash'))
30 print(db.keys())
31 print(db.keys('paths/nest/ok/k*'))
32 print(dict(db)) # snapsot of whole db
33 db.uncache() # frees memory, causes re-reads later
34
35 # shorthand for accessing deeply nested files
36 lnk = db.getlink('myobjects/test')
37 lnk.foo = 2
38 lnk.bar = lnk.foo + 5
39 self.assertEqual(lnk.bar, 7)
40
41 @skip("Too slow for regular running.")
42 def test_stress(self):
43 db = PickleShareDB('~/fsdbtest')
44 import time,sys
45 for i in range(1000):
46 for j in range(1000):
47 if i % 15 == 0 and i < 200:
48 if str(j) in db:
49 del db[str(j)]
50 continue
51
52 if j%33 == 0:
53 time.sleep(0.02)
54
55 db[str(j)] = db.get(str(j), []) + [(i,j,"proc %d" % os.getpid())]
56 db.hset('hash',j, db.hget('hash',j,15) + 1 )
57
58 print(i, end=' ')
59 sys.stdout.flush()
60 if i % 10 == 0:
61 db.uncache() No newline at end of file
@@ -1,177 +0,0
1 # encoding: utf-8
2 from __future__ import print_function
3
4 __docformat__ = "restructuredtext en"
5
6 #-------------------------------------------------------------------------------
7 # Copyright (C) 2008 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-------------------------------------------------------------------------------
12
13 #-------------------------------------------------------------------------------
14 # Imports
15 #-------------------------------------------------------------------------------
16
17 import sys
18 from textwrap import fill
19
20 display_status=True
21
22 def check_display(f):
23 """decorator to allow display methods to be muted by mod.display_status"""
24 def maybe_display(*args, **kwargs):
25 if display_status:
26 return f(*args, **kwargs)
27 return maybe_display
28
29 @check_display
30 def print_line(char='='):
31 print(char * 76)
32
33 @check_display
34 def print_status(package, status):
35 initial_indent = "%22s: " % package
36 indent = ' ' * 24
37 print(fill(str(status), width=76,
38 initial_indent=initial_indent,
39 subsequent_indent=indent))
40
41 @check_display
42 def print_message(message):
43 indent = ' ' * 24 + "* "
44 print(fill(str(message), width=76,
45 initial_indent=indent,
46 subsequent_indent=indent))
47
48 @check_display
49 def print_raw(section):
50 print(section)
51
52 #-------------------------------------------------------------------------------
53 # Tests for specific packages
54 #-------------------------------------------------------------------------------
55
56 def check_for_ipython():
57 try:
58 import IPython
59 except ImportError:
60 print_status("IPython", "Not found")
61 return False
62 else:
63 print_status("IPython", IPython.__version__)
64 return True
65
66 def check_for_sphinx():
67 try:
68 import sphinx
69 except ImportError:
70 print_status('sphinx', "Not found (required for docs and nbconvert)")
71 return False
72 else:
73 print_status('sphinx', sphinx.__version__)
74 return True
75
76 def check_for_pygments():
77 try:
78 import pygments
79 except ImportError:
80 print_status('pygments', "Not found (required for docs and nbconvert)")
81 return False
82 else:
83 print_status('pygments', pygments.__version__)
84 return True
85
86 def check_for_jinja2():
87 try:
88 import jinja2
89 except ImportError:
90 print_status('jinja2', "Not found (required for notebook and nbconvert)")
91 return False
92 else:
93 print_status('jinja2', jinja2.__version__)
94 return True
95
96 def check_for_nose():
97 try:
98 import nose
99 except ImportError:
100 print_status('nose', "Not found (required for running the test suite)")
101 return False
102 else:
103 print_status('nose', nose.__version__)
104 return True
105
106 def check_for_pexpect():
107 try:
108 import pexpect
109 except ImportError:
110 print_status("pexpect", "no (will use bundled version in IPython.external)")
111 return False
112 else:
113 print_status("pexpect", pexpect.__version__)
114 return True
115
116 def check_for_pyzmq():
117 try:
118 import zmq
119 except ImportError:
120 print_status('pyzmq', "no (required for qtconsole, notebook, and parallel computing capabilities)")
121 return False
122 else:
123 # pyzmq 2.1.10 adds pyzmq_version_info funtion for returning
124 # version as a tuple
125 if hasattr(zmq, 'pyzmq_version_info') and zmq.pyzmq_version_info() >= (2,1,11):
126 print_status("pyzmq", zmq.__version__)
127 return True
128 else:
129 print_status('pyzmq', "no (have %s, but require >= 2.1.11 for"
130 " qtconsole, notebook, and parallel computing capabilities)" % zmq.__version__)
131 return False
132
133 def check_for_tornado():
134 try:
135 import tornado
136 except ImportError:
137 print_status('tornado', "no (required for notebook)")
138 return False
139 else:
140 if getattr(tornado, 'version_info', (0,)) < (3,1):
141 print_status('tornado', "no (have %s, but require >= 3.1.0)" % tornado.version)
142 return False
143 else:
144 print_status('tornado', tornado.version)
145 return True
146
147 def check_for_readline():
148 from distutils.version import LooseVersion
149 readline = None
150 try:
151 import gnureadline as readline
152 except ImportError:
153 pass
154 if readline is None:
155 try:
156 import readline
157 except ImportError:
158 pass
159 if readline is None:
160 try:
161 import pyreadline
162 vs = pyreadline.release.version
163 except (ImportError, AttributeError):
164 print_status('readline', "no (required for good interactive behavior)")
165 return False
166 if LooseVersion(vs).version >= [1,7,1]:
167 print_status('readline', "yes pyreadline-" + vs)
168 return True
169 else:
170 print_status('readline', "no pyreadline-%s < 1.7.1" % vs)
171 return False
172 else:
173 if sys.platform == 'darwin' and 'libedit' in readline.__doc__:
174 print_status('readline', "no (libedit detected)")
175 return False
176 print_status('readline', "yes")
177 return True
General Comments 0
You need to be logged in to leave comments. Login now