-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathreplhelper.py
More file actions
141 lines (110 loc) · 3.86 KB
/
replhelper.py
File metadata and controls
141 lines (110 loc) · 3.86 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
from __future__ import print_function
import sys
def jl_name(name):
if name.endswith('_b'):
return name[:-2] + '!'
return name
class JuliaNameSpace(object):
def __init__(self, julia):
self.__julia = julia
def __setattr__(self, name, value):
if name.startswith('_'):
super(JuliaNameSpace, self).__setattr__(name, value)
else:
setter = '''
Main.PyCall.pyfunctionret(
(x) -> eval(:({} = $x)),
Any,
PyCall.PyAny)
'''.format(jl_name(name))
self.__julia.eval(setter)(value)
def __getattr__(self, name):
if name.startswith('_'):
return super(JuliaNameSpace, self).__getattr__(name)
else:
return self.__julia.eval(jl_name(name))
instruction_template = """
Python package "{package}" cannot be imported from Python interpreter
{python}.
{additional_message}
Use your favorite method to install "{need_install}" or run the following
command in Julia (which *tries* to the right thing):
IPython.install_dependency("{need_install}")
It prints the installation command to be executed and prompts your
input (yes/no) before really executing it.
"""
ipython_dependency_missing = """
IPython (version: {IPython.__version__}) is importable but {dependency}
cannot be imported. It is very strange and I'm not sure what is the
best instruction here. Updating IPython could help.
"""
def make_instruction(package, need_install=None, **kwargs):
return instruction_template.format(**dict(dict(
package=package,
need_install=need_install or package.lower(),
python=sys.executable,
additional_message='',
), **kwargs))
def make_dependency_missing_instruction(IPython, dependency):
return make_instruction(
dependency,
need_install='ipython',
additional_message=ipython_dependency_missing.format(
IPython=IPython,
dependency=dependency,
))
def package_name(err):
try:
return err.name
except AttributeError:
# Python 2 support:
prefix = 'No module named '
message = str(err)
if message.startswith(prefix):
return message[len(prefix):].rstrip()
raise ValueError('Cannot determine missing package for error {}'
.format(err))
def print_instruction_on_import_error(f):
def wrapped(*args, **kwargs):
try:
return f(*args, **kwargs)
except ImportError as err:
name = package_name(err)
if name in ('IPython', 'julia'):
print(make_instruction(name))
return
if name == 'traitlets':
try:
import IPython
except ImportError:
print(make_instruction('IPython'))
return
print(make_dependency_missing_instruction(IPython, name))
return
raise
return wrapped
def ipython_options(**kwargs):
from traitlets.config import Config
from julia import Julia
julia = Julia(**kwargs)
Main = JuliaNameSpace(julia)
user_ns = dict(
julia=julia,
Main=Main,
)
c = Config()
c.TerminalIPythonApp.display_banner = False
c.TerminalInteractiveShell.confirm_exit = False
return dict(user_ns=user_ns, config=c)
@print_instruction_on_import_error
def customized_ipython(**kwargs):
import IPython
print()
IPython.start_ipython(**ipython_options(**kwargs))
@print_instruction_on_import_error
def customized_ptipython(**kwargs):
from ptpython.ipython import embed
print()
embed(**ipython_options(**kwargs))
# https://github.com/jonathanslenders/ptpython/blob/master/ptpython/entry_points/run_ptipython.py
# https://github.com/jonathanslenders/ptpython/blob/master/ptpython/ipython.py