Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagecell
Path: blob/master/kernel_init.py
447 views
1
import codecs
2
import sys
3
import time
4
5
import ipykernel.jsonutil
6
7
import misc
8
9
10
def threejs(p, **kwds):
11
from warnings import warn
12
warn("""
13
threejs(graphic_object, **keywords)
14
is now equivalent to
15
graphic_object.show(viewer='threejs', **kwds)
16
and will be completely removed in future versions""",
17
DeprecationWarning, 2)
18
kwds["viewer"] = "threejs"
19
p.show(**kwds)
20
21
22
def initialize(kernel):
23
24
def new_files(root="./"):
25
import os
26
import sys
27
new_files = []
28
for top, dirs, files in os.walk(root):
29
for dir in dirs:
30
if dir.endswith(".jmol"):
31
dirs.remove(dir)
32
for name in files:
33
path = os.path.join(top, name)
34
if path.startswith("./"):
35
path = path[2:]
36
mtime = os.stat(path).st_mtime
37
if (path == "sagemathcell.py"
38
or path in sys._sage_.sent_files
39
and sys._sage_.sent_files[path] >= mtime):
40
continue
41
if (path.startswith("Rplot")
42
and path[-4:] in [".bmp", "jpeg", ".png", ".svg"]):
43
misc.display_file(path, "text/image-filename")
44
continue
45
if path == "octave.png":
46
misc.display_file(path, "text/image-filename")
47
continue
48
new_files.append(path)
49
sys._sage_.sent_files[path] = mtime
50
ip = user_ns["get_ipython"]()
51
ip.payload_manager.write_payload({"new_files": new_files})
52
return ""
53
54
class TempClass(object):
55
pass
56
57
_sage_ = TempClass()
58
_sage_.display_message = misc.display_message
59
_sage_.stream_message = misc.stream_message
60
_sage_.reset_kernel_timeout = misc.reset_kernel_timeout
61
_sage_.javascript = misc.javascript
62
_sage_.new_files = new_files
63
_sage_.sent_files = {}
64
_sage_.threejs = threejs
65
66
67
def handler_wrapper(key, handler):
68
from functools import wraps
69
70
@wraps(handler)
71
def f(stream, ident, parent, *args, **kwargs):
72
md = kernel.init_metadata(parent)
73
kernel._publish_status("busy", "shell", parent)
74
# Set the parent message of the display hook and out streams.
75
kernel.shell.set_parent(parent)
76
try:
77
reply = {
78
"result": handler(stream, ident, parent, *args, **kwargs),
79
"status": "ok",
80
# TODO: this should be refactored probably to use existing
81
# IPython code
82
"user_expressions": kernel.shell.user_expressions(
83
parent["content"].get("user_expressions", {}))
84
}
85
except:
86
kernel.log.debug("handler exception for %s", key)
87
etype, evalue, tb = sys.exc_info()
88
reply = {
89
"ename": etype.__name__, # needed by finish_metadata
90
"status": "error",
91
"user_expressions": {}
92
}
93
import traceback
94
tb_list = traceback.format_exception(etype, evalue, tb)
95
kernel.shell._showtraceback(etype, evalue, tb_list)
96
97
# Payloads should be retrieved regardless of outcome, so we can both
98
# recover partial output (that could have been generated early in a
99
# block, before an error) and clear the payload system always.
100
reply['payload'] = kernel.shell.payload_manager.read_payload()
101
# Be agressive about clearing the payload because we don't want
102
# it to sit in memory until the next execute_request comes in.
103
kernel.shell.payload_manager.clear_payload()
104
# Flush output before sending the reply.
105
sys.stdout.flush()
106
sys.stderr.flush()
107
# FIXME: on rare occasions, the flush doesn't seem to make it to the
108
# clients... This seems to mitigate the problem, but we definitely
109
# need to better understand what's going on.
110
if kernel._execute_sleep:
111
time.sleep(kernel._execute_sleep)
112
113
reply = ipykernel.jsonutil.json_clean(reply)
114
md = kernel.finish_metadata(parent, md, reply)
115
reply_msg = kernel.session.send(
116
stream, key + '_reply', reply, parent, metadata=md, ident=ident)
117
kernel.log.debug("handler reply for %s %s", key, reply_msg)
118
kernel._publish_status("idle", "shell", parent)
119
return f
120
121
def register_handler(key, handler):
122
if key not in [
123
'apply_request',
124
'complete_request',
125
'connect_request',
126
'execute_request',
127
'history_request',
128
'object_info_request',
129
'shutdown_request',
130
]:
131
kernel.shell_handlers[key] = handler_wrapper(key, handler)
132
133
_sage_.register_handler = register_handler
134
135
def send_message(stream, msg_type, content, parent, **kwargs):
136
kernel.session.send(
137
stream, msg_type, content=content, parent=parent, **kwargs)
138
139
_sage_.send_message = send_message
140
141
# Enable Sage types to be sent via session messages
142
from zmq.utils import jsonapi
143
kernel.session.pack = lambda x: jsonapi.dumps(x, default=misc.sage_json)
144
145
sys._sage_ = _sage_
146
user_ns = kernel.shell.user_module.__dict__
147
#ka.kernel.shell.user_ns = ka.kernel.shell.Completer.namespace = user_ns
148
sys._sage_.namespace = user_ns
149
# TODO: maybe we don't want to cut down the flush interval?
150
sys.stdout.flush_interval = sys.stderr.flush_interval = 0.0
151
def clear(changed=None):
152
sys._sage_.display_message({
153
"application/sage-clear": {"changed": changed},
154
"text/plain": "Clear display"
155
})
156
sys._sage_.clear = clear
157
kernel.shell.extension_manager.load_extension('sage.repl.ipython_extension')
158
import sage
159
user_ns["sage"] = sage
160
sage_code = """
161
# Ensure unique random state after forking
162
set_random_seed()
163
import numpy.random
164
numpy.random.seed()
165
from sage.repl.rich_output import get_display_manager
166
from backend_cell import BackendCell
167
get_display_manager().switch_backend(BackendCell(), shell=get_ipython())
168
"""
169
exec(sage_code, user_ns)
170
171
from IPython.core import oinspect
172
from sage.misc.sagedoc import my_getsource
173
oinspect.getsource = my_getsource
174
175
import interact_sagecell
176
import interact_compatibility
177
import dynamic
178
import exercise
179
# overwrite Sage's interact command with our own
180
user_ns.update(interact_sagecell.imports)
181
user_ns.update(interact_compatibility.imports)
182
user_ns.update(dynamic.imports)
183
user_ns.update(exercise.imports)
184
user_ns['threejs'] = sys._sage_.threejs
185
sys._sage_.update_interact = interact_sagecell.update_interact
186
187
# In order to show the correct code line when a (deprecation) warning
188
# is triggered, we change the main module name and save user code to
189
# a file with the same name.
190
sys.argv = ['sagemathcell.py']
191
old_execute = kernel.do_execute
192
193
def new_execute(code, *args, **kwds):
194
with codecs.open('sagemathcell.py', 'w', encoding='utf-8') as f:
195
f.write(code)
196
return old_execute(code, *args, **kwds)
197
198
kernel.do_execute = new_execute
199
200
201