util.py
197 lines
| 5.5 KiB
| text/x-python
|
PythonLexer
Brian E Granger
|
r1234 | # 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 | ||||