| 1 |
"""Definitions used by commands sent to inferior Python in python.el.""" |
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
import os, sys, traceback, inspect, __main__ |
|---|
| 24 |
from sets import Set |
|---|
| 25 |
|
|---|
| 26 |
__all__ = ["eexecfile", "eargs", "complete", "ehelp", "eimport", "modpath"] |
|---|
| 27 |
|
|---|
| 28 |
def format_exception (filename, should_remove_self): |
|---|
| 29 |
type, value, tb = sys.exc_info () |
|---|
| 30 |
sys.last_type = type |
|---|
| 31 |
sys.last_value = value |
|---|
| 32 |
sys.last_traceback = tb |
|---|
| 33 |
if type is SyntaxError: |
|---|
| 34 |
try: |
|---|
| 35 |
msg, (dummy_filename, lineno, offset, line) = value |
|---|
| 36 |
except: |
|---|
| 37 |
pass |
|---|
| 38 |
else: |
|---|
| 39 |
|
|---|
| 40 |
value = SyntaxError(msg, (filename, lineno, offset, line)) |
|---|
| 41 |
sys.last_value = value |
|---|
| 42 |
res = traceback.format_exception_only (type, value) |
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
if should_remove_self: |
|---|
| 46 |
tblist = traceback.extract_tb (tb) |
|---|
| 47 |
del tblist[:1] |
|---|
| 48 |
res = traceback.format_list (tblist) |
|---|
| 49 |
if res: |
|---|
| 50 |
res.insert(0, "Traceback (most recent call last):\n") |
|---|
| 51 |
res[len(res):] = traceback.format_exception_only (type, value) |
|---|
| 52 |
|
|---|
| 53 |
for line in res: print line, |
|---|
| 54 |
|
|---|
| 55 |
def eexecfile (file): |
|---|
| 56 |
"""Execute FILE and then remove it. |
|---|
| 57 |
Execute the file within the __main__ namespace. |
|---|
| 58 |
If we get an exception, print a traceback with the top frame |
|---|
| 59 |
(ourselves) excluded.""" |
|---|
| 60 |
|
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
try: |
|---|
| 64 |
try: |
|---|
| 65 |
source = open (file, "r").read() |
|---|
| 66 |
code = compile (source, file, "exec") |
|---|
| 67 |
|
|---|
| 68 |
|
|---|
| 69 |
except (OverflowError, SyntaxError, ValueError): |
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
format_exception (file, False) |
|---|
| 73 |
return |
|---|
| 74 |
try: |
|---|
| 75 |
exec code in __main__.__dict__ |
|---|
| 76 |
except: |
|---|
| 77 |
format_exception (file, True) |
|---|
| 78 |
finally: |
|---|
| 79 |
os.remove (file) |
|---|
| 80 |
|
|---|
| 81 |
def eargs (name, imports): |
|---|
| 82 |
"Get arglist of NAME for Eldoc &c." |
|---|
| 83 |
try: |
|---|
| 84 |
if imports: exec imports |
|---|
| 85 |
parts = name.split ('.') |
|---|
| 86 |
if len (parts) > 1: |
|---|
| 87 |
exec 'import ' + parts[0] |
|---|
| 88 |
func = eval (name) |
|---|
| 89 |
if inspect.isbuiltin (func) or type(func) is type: |
|---|
| 90 |
doc = func.__doc__ |
|---|
| 91 |
if doc.find (' ->') != -1: |
|---|
| 92 |
print '_emacs_out', doc.split (' ->')[0] |
|---|
| 93 |
else: |
|---|
| 94 |
print '_emacs_out', doc.split ('\n')[0] |
|---|
| 95 |
return |
|---|
| 96 |
if inspect.ismethod (func): |
|---|
| 97 |
func = func.im_func |
|---|
| 98 |
if not inspect.isfunction (func): |
|---|
| 99 |
print '_emacs_out ' |
|---|
| 100 |
return |
|---|
| 101 |
(args, varargs, varkw, defaults) = inspect.getargspec (func) |
|---|
| 102 |
|
|---|
| 103 |
print '_emacs_out', \ |
|---|
| 104 |
func.__name__ + inspect.formatargspec (args, varargs, varkw, |
|---|
| 105 |
defaults) |
|---|
| 106 |
except: |
|---|
| 107 |
print "_emacs_out " |
|---|
| 108 |
|
|---|
| 109 |
def all_names (object): |
|---|
| 110 |
"""Return (an approximation to) a list of all possible attribute |
|---|
| 111 |
names reachable via the attributes of OBJECT, i.e. roughly the |
|---|
| 112 |
leaves of the dictionary tree under it.""" |
|---|
| 113 |
|
|---|
| 114 |
def do_object (object, names): |
|---|
| 115 |
if inspect.ismodule (object): |
|---|
| 116 |
do_module (object, names) |
|---|
| 117 |
elif inspect.isclass (object): |
|---|
| 118 |
do_class (object, names) |
|---|
| 119 |
|
|---|
| 120 |
elif hasattr (object, '__class__'): |
|---|
| 121 |
names.add ('__class__') |
|---|
| 122 |
do_class (object.__class__, names) |
|---|
| 123 |
|
|---|
| 124 |
|
|---|
| 125 |
return names |
|---|
| 126 |
|
|---|
| 127 |
def do_module (module, names): |
|---|
| 128 |
if hasattr (module, '__all__'): |
|---|
| 129 |
names.union_update (module.__all__) |
|---|
| 130 |
for i in module.__all__: |
|---|
| 131 |
do_object (getattr (module, i), names) |
|---|
| 132 |
else: |
|---|
| 133 |
names.union_update (dir (module)) |
|---|
| 134 |
for i in dir (module): |
|---|
| 135 |
do_object (getattr (module, i), names) |
|---|
| 136 |
return names |
|---|
| 137 |
|
|---|
| 138 |
def do_class (object, names): |
|---|
| 139 |
ns = dir (object) |
|---|
| 140 |
names.union_update (ns) |
|---|
| 141 |
if hasattr (object, '__bases__'): |
|---|
| 142 |
for i in object.__bases__: do_object (i, names) |
|---|
| 143 |
return names |
|---|
| 144 |
|
|---|
| 145 |
return do_object (object, Set ([])) |
|---|
| 146 |
|
|---|
| 147 |
def complete (name, imports): |
|---|
| 148 |
"""Complete TEXT in NAMESPACE and print a Lisp list of completions. |
|---|
| 149 |
Exec IMPORTS first.""" |
|---|
| 150 |
import __main__, keyword |
|---|
| 151 |
|
|---|
| 152 |
def class_members(object): |
|---|
| 153 |
names = dir (object) |
|---|
| 154 |
if hasattr (object, '__bases__'): |
|---|
| 155 |
for super in object.__bases__: |
|---|
| 156 |
names = class_members (super) |
|---|
| 157 |
return names |
|---|
| 158 |
|
|---|
| 159 |
names = Set ([]) |
|---|
| 160 |
base = None |
|---|
| 161 |
try: |
|---|
| 162 |
dict = __main__.__dict__.copy() |
|---|
| 163 |
if imports: exec imports in dict |
|---|
| 164 |
l = len (name) |
|---|
| 165 |
if not "." in name: |
|---|
| 166 |
for list in [dir (__builtins__), keyword.kwlist, dict.keys()]: |
|---|
| 167 |
for elt in list: |
|---|
| 168 |
if elt[:l] == name: names.add(elt) |
|---|
| 169 |
else: |
|---|
| 170 |
base = name[:name.rfind ('.')] |
|---|
| 171 |
name = name[name.rfind('.')+1:] |
|---|
| 172 |
try: |
|---|
| 173 |
object = eval (base, dict) |
|---|
| 174 |
names = Set (dir (object)) |
|---|
| 175 |
if hasattr (object, '__class__'): |
|---|
| 176 |
names.add('__class__') |
|---|
| 177 |
names.union_update (class_members (object)) |
|---|
| 178 |
except: names = all_names (dict) |
|---|
| 179 |
except: |
|---|
| 180 |
print '_emacs_out ()' |
|---|
| 181 |
return [] |
|---|
| 182 |
l = len(name) |
|---|
| 183 |
print '_emacs_out (', |
|---|
| 184 |
for n in names: |
|---|
| 185 |
if name == n[:l]: |
|---|
| 186 |
if base: print '"%s.%s"' % (base, n), |
|---|
| 187 |
else: print '"%s"' % n, |
|---|
| 188 |
print ')' |
|---|
| 189 |
|
|---|
| 190 |
def ehelp (name, imports): |
|---|
| 191 |
"""Get help on string NAME. |
|---|
| 192 |
First try to eval name for, e.g. user definitions where we need |
|---|
| 193 |
the object. Otherwise try the string form.""" |
|---|
| 194 |
locls = {} |
|---|
| 195 |
if imports: |
|---|
| 196 |
try: exec imports in locls |
|---|
| 197 |
except: pass |
|---|
| 198 |
try: help (eval (name, globals(), locls)) |
|---|
| 199 |
except: help (name) |
|---|
| 200 |
|
|---|
| 201 |
def eimport (mod, dir): |
|---|
| 202 |
"""Import module MOD with directory DIR at the head of the search path. |
|---|
| 203 |
NB doesn't load from DIR if MOD shadows a system module.""" |
|---|
| 204 |
from __main__ import __dict__ |
|---|
| 205 |
|
|---|
| 206 |
path0 = sys.path[0] |
|---|
| 207 |
sys.path[0] = dir |
|---|
| 208 |
try: |
|---|
| 209 |
try: |
|---|
| 210 |
if __dict__.has_key(mod) and inspect.ismodule (__dict__[mod]): |
|---|
| 211 |
reload (__dict__[mod]) |
|---|
| 212 |
else: |
|---|
| 213 |
__dict__[mod] = __import__ (mod) |
|---|
| 214 |
except: |
|---|
| 215 |
(type, value, tb) = sys.exc_info () |
|---|
| 216 |
print "Traceback (most recent call last):" |
|---|
| 217 |
traceback.print_exception (type, value, tb.tb_next) |
|---|
| 218 |
finally: |
|---|
| 219 |
sys.path[0] = path0 |
|---|
| 220 |
|
|---|
| 221 |
def modpath (module): |
|---|
| 222 |
"""Return the source file for the given MODULE (or None). |
|---|
| 223 |
Assumes that MODULE.py and MODULE.pyc are in the same directory.""" |
|---|
| 224 |
try: |
|---|
| 225 |
path = __import__ (module).__file__ |
|---|
| 226 |
if path[-4:] == '.pyc' and os.path.exists (path[0:-1]): |
|---|
| 227 |
path = path[:-1] |
|---|
| 228 |
print "_emacs_out", path |
|---|
| 229 |
except: |
|---|
| 230 |
print "_emacs_out ()" |
|---|
| 231 |
|
|---|
| 232 |
|
|---|
| 233 |
|
|---|
| 234 |
|
|---|