forked from jamesgao/ipython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.py
More file actions
197 lines (156 loc) · 5.47 KB
/
util.py
File metadata and controls
197 lines (156 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# encoding: utf-8
__docformat__ = "restructuredtext en"
#-------------------------------------------------------------------------------
# Copyright (C) 2008 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Imports
#-------------------------------------------------------------------------------
import os
import sys
# This class is mostly taken from IPython.
class InputList(list):
""" Class to store user input.
It's basically a list, but slices return a string instead of a list, thus
allowing things like (assuming 'In' is an instance):
exec In[4:7]
or
exec In[5:9] + In[14] + In[21:25]
"""
def __getslice__(self, i, j):
return ''.join(list.__getslice__(self, i, j))
def add(self, index, command):
""" Add a command to the list with the appropriate index.
If the index is greater than the current length of the list, empty
strings are added in between.
"""
length = len(self)
if length == index:
self.append(command)
elif length > index:
self[index] = command
else:
extras = index - length
self.extend([''] * extras)
self.append(command)
class Bunch(dict):
""" A dictionary that exposes its keys as attributes.
"""
def __init__(self, *args, **kwds):
dict.__init__(self, *args, **kwds)
self.__dict__ = self
def esc_quotes(strng):
""" Return the input string with single and double quotes escaped out.
"""
return strng.replace('"', '\\"').replace("'", "\\'")
def make_quoted_expr(s):
"""Return string s in appropriate quotes, using raw string if possible.
Effectively this turns string: cd \ao\ao\
to: r"cd \ao\ao\_"[:-1]
Note the use of raw string and padding at the end to allow trailing
backslash.
"""
tail = ''
tailpadding = ''
raw = ''
if "\\" in s:
raw = 'r'
if s.endswith('\\'):
tail = '[:-1]'
tailpadding = '_'
if '"' not in s:
quote = '"'
elif "'" not in s:
quote = "'"
elif '"""' not in s and not s.endswith('"'):
quote = '"""'
elif "'''" not in s and not s.endswith("'"):
quote = "'''"
else:
# Give up, backslash-escaped string will do
return '"%s"' % esc_quotes(s)
res = ''.join([raw, quote, s, tailpadding, quote, tail])
return res
# This function is used by ipython in a lot of places to make system calls.
# We need it to be slightly different under win32, due to the vagaries of
# 'network shares'. A win32 override is below.
def system_shell(cmd, verbose=False, debug=False, header=''):
""" Execute a command in the system shell; always return None.
Parameters
----------
cmd : str
The command to execute.
verbose : bool
If True, print the command to be executed.
debug : bool
Only print, do not actually execute.
header : str
Header to print to screen prior to the executed command. No extra
newlines are added.
Description
-----------
This returns None so it can be conveniently used in interactive loops
without getting the return value (typically 0) printed many times.
"""
if verbose or debug:
print header + cmd
# Flush stdout so we don't mangle python's buffering.
sys.stdout.flush()
if not debug:
os.system(cmd)
# Override shell() for win32 to deal with network shares.
if os.name in ('nt', 'dos'):
system_shell_ori = system_shell
def system_shell(cmd, verbose=False, debug=False, header=''):
if os.getcwd().startswith(r"\\"):
path = os.getcwd()
# Change to c drive (cannot be on UNC-share when issuing os.system,
# as cmd.exe cannot handle UNC addresses).
os.chdir("c:")
# Issue pushd to the UNC-share and then run the command.
try:
system_shell_ori('"pushd %s&&"'%path+cmd,verbose,debug,header)
finally:
os.chdir(path)
else:
system_shell_ori(cmd,verbose,debug,header)
system_shell.__doc__ = system_shell_ori.__doc__
def getoutputerror(cmd, verbose=False, debug=False, header='', split=False):
""" Executes a command and returns the output.
Parameters
----------
cmd : str
The command to execute.
verbose : bool
If True, print the command to be executed.
debug : bool
Only print, do not actually execute.
header : str
Header to print to screen prior to the executed command. No extra
newlines are added.
split : bool
If True, return the output as a list split on newlines.
"""
if verbose or debug:
print header+cmd
if not cmd:
# Return empty lists or strings.
if split:
return [], []
else:
return '', ''
if not debug:
# fixme: use subprocess.
pin,pout,perr = os.popen3(cmd)
tout = pout.read().rstrip()
terr = perr.read().rstrip()
pin.close()
pout.close()
perr.close()
if split:
return tout.split('\n'), terr.split('\n')
else:
return tout, terr