forked from jamesgao/ipython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmagic.py
More file actions
147 lines (115 loc) · 4.33 KB
/
magic.py
File metadata and controls
147 lines (115 loc) · 4.33 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
# 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 __builtin__
# Local imports.
from util import Bunch
# fixme: RTK thinks magics should be implemented as separate classes rather than
# methods on a single class. This would give us the ability to plug new magics
# in and configure them separately.
class Magic(object):
""" An object that maintains magic functions.
"""
def __init__(self, interpreter, config=None):
# A reference to the interpreter.
self.interpreter = interpreter
# A reference to the configuration object.
if config is None:
# fixme: we need a better place to store this information.
config = Bunch(ESC_MAGIC='%')
self.config = config
def has_magic(self, name):
""" Return True if this object provides a given magic.
Parameters
----------
name : str
"""
return hasattr(self, 'magic_' + name)
def object_find(self, name):
""" Find an object in the available namespaces.
fixme: this should probably be moved elsewhere. The interpreter?
"""
name = name.strip()
# Namespaces to search.
# fixme: implement internal and alias namespaces.
user_ns = self.interpreter.user_ns
internal_ns = {}
builtin_ns = __builtin__.__dict__
alias_ns = {}
# Order the namespaces.
namespaces = [
('Interactive', user_ns),
('IPython internal', internal_ns),
('Python builtin', builtin_ns),
('Alias', alias_ns),
]
# Initialize all results.
found = False
obj = None
space = None
ds = None
ismagic = False
isalias = False
# Look for the given name by splitting it in parts. If the head is
# found, then we look for all the remaining parts as members, and only
# declare success if we can find them all.
parts = name.split('.')
head, rest = parts[0], parts[1:]
for nsname, ns in namespaces:
try:
obj = ns[head]
except KeyError:
continue
else:
for part in rest:
try:
obj = getattr(obj, part)
except:
# Blanket except b/c some badly implemented objects
# allow __getattr__ to raise exceptions other than
# AttributeError, which then crashes us.
break
else:
# If we finish the for loop (no break), we got all members
found = True
space = nsname
isalias = (ns == alias_ns)
break # namespace loop
# Try to see if it is a magic.
if not found:
if name.startswith(self.config.ESC_MAGIC):
name = name[1:]
obj = getattr(self, 'magic_' + name, None)
if obj is not None:
found = True
space = 'IPython internal'
ismagic = True
# Last try: special-case some literals like '', [], {}, etc:
if not found and head in ["''", '""', '[]', '{}', '()']:
obj = eval(head)
found = True
space = 'Interactive'
return dict(
found=found,
obj=obj,
namespace=space,
ismagic=ismagic,
isalias=isalias,
)
def magic_pwd(self, parameter_s=''):
""" Return the current working directory path.
"""
return os.getcwd()
def magic_env(self, parameter_s=''):
""" List environment variables.
"""
return os.environ.data