iruby 0.1.13 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +13 -0
- data/CHANGES +9 -0
- data/CONTRIBUTORS +7 -1
- data/Gemfile +1 -4
- data/IRuby-Example.ipynb +3826 -3240
- data/{LICENSE → LICENSE.txt} +1 -1
- data/README.rdoc +45 -0
- data/Rakefile +2 -0
- data/bin/iruby +0 -1
- data/examples/display.ipynb +116 -106
- data/examples/stdout.ipynb +91 -93
- data/examples/table.ipynb +307 -282
- data/iruby.gemspec +12 -9
- data/lib/iruby.rb +2 -1
- data/lib/iruby/backend.rb +5 -5
- data/lib/iruby/comm.rb +60 -0
- data/lib/iruby/command.rb +68 -53
- data/lib/iruby/display.rb +4 -10
- data/lib/iruby/formatter.rb +11 -13
- data/lib/iruby/kernel.rb +69 -57
- data/lib/iruby/logger.rb +17 -0
- data/lib/iruby/ostream.rb +11 -9
- data/lib/iruby/session.rb +21 -24
- data/lib/iruby/utils.rb +2 -2
- data/lib/iruby/version.rb +1 -1
- data/{lib/iruby/static/base/images → logo}/favicon.ico +0 -0
- data/{lib/iruby/static/base/images/ipynblogo.png → logo/iruby.png} +0 -0
- data/{lib/iruby/static/base/images/src/ipynblogo.svg → logo/iruby.svg} +0 -0
- data/{lib/iruby/static/base/images/src → logo}/ruby.svg +0 -0
- data/test/integration_test.rb +41 -0
- data/test/iruby/multi_logger_test.rb +15 -0
- data/test/test_helper.rb +5 -0
- metadata +51 -35
- data/README.md +0 -24
- data/lib/iruby/static/custom/custom.css +0 -40
- data/lib/iruby/static/custom/custom.js +0 -15
data/iruby.gemspec
CHANGED
@@ -6,14 +6,14 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = 'iruby'
|
7
7
|
s.date = Date.today.to_s
|
8
8
|
s.version = IRuby::VERSION
|
9
|
-
s.authors = ['
|
10
|
-
s.email = ['
|
9
|
+
s.authors = ['Daniel Mendler', 'The SciRuby developers']
|
10
|
+
s.email = ['mail@daniel-mendler.de']
|
11
11
|
s.description = 'Ruby Kernel for IPython'
|
12
12
|
s.summary = 'A Ruby kernel for IPython frontends (notebook console, etc.)'
|
13
|
-
s.homepage = 'https://github.com/
|
13
|
+
s.homepage = 'https://github.com/SciRuby/iruby'
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
16
|
-
s.files = `git ls-files`.split($/)
|
16
|
+
s.files = `git ls-files`.split($/).reject {|f| f =~ /\Aattic/ }
|
17
17
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
s.test_files = s.files.grep(%r{^test/})
|
19
19
|
s.require_paths = %w(lib)
|
@@ -22,10 +22,13 @@ Gem::Specification.new do |s|
|
|
22
22
|
File.read('Gemfile').scan(/gem\s+'(.*?)'/) { m << " * #{$1}\n" }
|
23
23
|
s.post_install_message = m << "\n"
|
24
24
|
|
25
|
-
s.
|
25
|
+
s.required_ruby_version = '>= 2.0.0'
|
26
26
|
|
27
|
-
s.
|
28
|
-
s.
|
29
|
-
|
30
|
-
s.add_runtime_dependency '
|
27
|
+
s.add_development_dependency 'rake', '~> 10.4'
|
28
|
+
s.add_development_dependency 'minitest', '~> 5.6'
|
29
|
+
|
30
|
+
s.add_runtime_dependency 'bond', '~> 0.5'
|
31
|
+
s.add_runtime_dependency 'rbczmq', '~> 1.7'
|
32
|
+
s.add_runtime_dependency 'multi_json', '~> 1.11'
|
33
|
+
s.add_runtime_dependency 'mimemagic', '~> 0.3'
|
31
34
|
end
|
data/lib/iruby.rb
CHANGED
data/lib/iruby/backend.rb
CHANGED
@@ -8,8 +8,8 @@ module IRuby
|
|
8
8
|
TOPLEVEL_BINDING.eval(code)
|
9
9
|
end
|
10
10
|
|
11
|
-
def complete(
|
12
|
-
Bond.agent.call(
|
11
|
+
def complete(code)
|
12
|
+
Bond.agent.call(code, code)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -25,14 +25,14 @@ module IRuby
|
|
25
25
|
|
26
26
|
def eval(code)
|
27
27
|
@pry.last_result = nil
|
28
|
-
@pry.eval(code)
|
28
|
+
raise SystemExit unless @pry.eval(code)
|
29
29
|
raise @pry.last_exception if @pry.last_result_is_exception?
|
30
30
|
@pry.push_initial_binding unless @pry.current_binding
|
31
31
|
@pry.last_result
|
32
32
|
end
|
33
33
|
|
34
|
-
def complete(
|
35
|
-
@pry.complete(
|
34
|
+
def complete(code)
|
35
|
+
@pry.complete(code)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
data/lib/iruby/comm.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module IRuby
|
2
|
+
# Comm is a new messaging system for bidirectional communication.
|
3
|
+
# Both kernel and front-end listens for messages.
|
4
|
+
class Comm
|
5
|
+
attr_writer :on_msg, :on_close
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def targets
|
9
|
+
@targets ||= {}
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(target_name, comm_id = SecureRandom.uuid)
|
14
|
+
@target_name, @comm_id = target_name, comm_id
|
15
|
+
end
|
16
|
+
|
17
|
+
def open(**data)
|
18
|
+
content = {
|
19
|
+
comm_id: @comm_id,
|
20
|
+
data: data,
|
21
|
+
target_name: @target_name
|
22
|
+
}
|
23
|
+
Kernel.instance.session.send(:publish, 'comm_open', content)
|
24
|
+
Kernel.instance.comms[@comm_id] = self
|
25
|
+
end
|
26
|
+
|
27
|
+
def send(**data)
|
28
|
+
content = {
|
29
|
+
comm_id: @comm_id,
|
30
|
+
data: data
|
31
|
+
}
|
32
|
+
Kernel.instance.session.send(:publish, 'comm_msg', content)
|
33
|
+
end
|
34
|
+
|
35
|
+
def close(**data)
|
36
|
+
content = {
|
37
|
+
comm_id: @comm_id,
|
38
|
+
data: data
|
39
|
+
}
|
40
|
+
Kernel.instance.session.send(:publish, 'comm_close', content)
|
41
|
+
Kernel.instance.comms.delete(@comm_id)
|
42
|
+
end
|
43
|
+
|
44
|
+
def on_msg(&b)
|
45
|
+
@on_msg = b
|
46
|
+
end
|
47
|
+
|
48
|
+
def on_close(&b)
|
49
|
+
@on_close = b
|
50
|
+
end
|
51
|
+
|
52
|
+
def comm_msg(msg)
|
53
|
+
@on_msg.call(msg) if @on_msg
|
54
|
+
end
|
55
|
+
|
56
|
+
def comm_close
|
57
|
+
@on_close.call if @on_close
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/iruby/command.rb
CHANGED
@@ -1,18 +1,32 @@
|
|
1
|
-
require 'shellwords'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
1
|
module IRuby
|
5
2
|
class Command
|
6
|
-
IRUBYDIR = '~/.config/iruby'
|
7
|
-
|
8
3
|
def initialize(args)
|
9
4
|
@args = args
|
5
|
+
|
6
|
+
ipython_dir = ENV['IPYTHONDIR'] || '~/.ipython'
|
7
|
+
@args.each do |arg|
|
8
|
+
ipython_dir = $1 if arg =~ /\A--ipython-dir=(.*)\Z/
|
9
|
+
end
|
10
|
+
ipython_dir = File.expand_path(ipython_dir)
|
11
|
+
@kernel_file = File.join(ipython_dir, 'kernels', 'ruby', 'kernel.json')
|
10
12
|
end
|
11
13
|
|
12
14
|
def run
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
case @args.first
|
16
|
+
when 'version', '-v', '--version'
|
17
|
+
require 'iruby/version'
|
18
|
+
puts IRuby::VERSION
|
19
|
+
when 'help', '-h', '--help'
|
20
|
+
print_help
|
21
|
+
when 'register'
|
22
|
+
if File.exist?(@kernel_file) && !@args.include?('--force')
|
23
|
+
STDERR.puts "#{@kernel_file} already exists!\nUse --force to force a register."
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
register_kernel
|
27
|
+
when 'unregister'
|
28
|
+
unregister_kernel
|
29
|
+
when 'kernel'
|
16
30
|
run_kernel
|
17
31
|
else
|
18
32
|
run_ipython
|
@@ -21,20 +35,49 @@ module IRuby
|
|
21
35
|
|
22
36
|
private
|
23
37
|
|
38
|
+
def print_help
|
39
|
+
puts %{
|
40
|
+
Usage:
|
41
|
+
iruby register Register IRuby kernel into #{@kernel_file}.
|
42
|
+
iruby unregister Remove #{@kernel_file}.
|
43
|
+
iruby console Launch the IRuby terminal-based console.
|
44
|
+
iruby notebook Launch the IRuby HTML notebook server.
|
45
|
+
... Same as IPython.
|
46
|
+
|
47
|
+
Please note that IRuby accepts the same parameters as IPython.
|
48
|
+
Try `ipython help` for more information.
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
24
52
|
def run_kernel
|
53
|
+
require 'iruby/logger'
|
54
|
+
loggers = [Logger.new(STDOUT)]
|
55
|
+
@args.each do |arg|
|
56
|
+
loggers << Logger.new($1) if arg =~ /\A--log=(.*)\Z/
|
57
|
+
end
|
58
|
+
IRuby.logger = MultiLogger.new(*loggers)
|
59
|
+
IRuby.logger.level = @args.include?('--debug') ? Logger::DEBUG : Logger::INFO
|
60
|
+
|
25
61
|
raise(ArgumentError, 'Not enough arguments to the kernel') if @args.size < 2 || @args.size > 4
|
26
62
|
config_file, boot_file, working_dir = @args[1..-1]
|
27
63
|
Dir.chdir(working_dir) if working_dir
|
64
|
+
|
28
65
|
require boot_file if boot_file
|
66
|
+
|
67
|
+
begin
|
68
|
+
require 'bundler/setup'
|
69
|
+
rescue Exception
|
70
|
+
end
|
71
|
+
|
29
72
|
require 'iruby'
|
30
73
|
Kernel.new(config_file).run
|
31
74
|
rescue Exception => ex
|
32
|
-
|
75
|
+
IRuby.logger.fatal "Kernel died: #{ex.message}\n#{ex.backtrace.join("\n")}"
|
33
76
|
raise
|
34
77
|
end
|
35
78
|
|
36
79
|
def check_version
|
37
|
-
required = '
|
80
|
+
required = '3.0.0'
|
38
81
|
version = `ipython --version`.chomp
|
39
82
|
if version < required
|
40
83
|
STDERR.puts "Your IPython version #{version} is too old, at least #{required} is required"
|
@@ -45,55 +88,27 @@ module IRuby
|
|
45
88
|
def run_ipython
|
46
89
|
check_version
|
47
90
|
|
48
|
-
dir = @args.grep(/\A--iruby-dir=.*\Z/)
|
49
|
-
@args -= dir
|
50
|
-
dir = dir.last.to_s.sub(/\A--profile=/, '')
|
51
|
-
dir = ENV['IRUBYDIR'] || IRUBYDIR if dir.empty?
|
52
|
-
dir = File.expand_path(dir)
|
53
|
-
ENV['IPYTHONDIR'] = dir
|
54
|
-
|
55
|
-
if @args.size == 3 && @args[0] == 'profile' && @args[1] == 'create'
|
56
|
-
profile = @args[2]
|
57
|
-
else
|
58
|
-
profile = @args.grep(/\A--profile=.*\Z/).last.to_s.sub(/\A--profile=/, '')
|
59
|
-
profile = 'default' if profile.empty?
|
60
|
-
end
|
61
|
-
|
62
|
-
create_profile(dir, profile)
|
63
|
-
|
64
91
|
# We must use the console to launch the whole 0MQ-client-server stack
|
65
|
-
@args = %w(console
|
92
|
+
@args = %w(console) + @args if @args.first.to_s !~ /\A\w/
|
93
|
+
register_kernel if %w(console qtconsole notebook).include?(@args.first) && !File.exist?(@kernel_file)
|
94
|
+
@args += %w(--kernel ruby) if %w(console qtconsole).include? @args.first
|
66
95
|
|
67
96
|
Kernel.exec('ipython', *@args)
|
68
97
|
end
|
69
98
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
kernel_cmd = "c.KernelManager.kernel_cmd = #{kernel_cmd.inspect}"
|
81
|
-
Dir[File.join(profile_dir, '*_config.py')].each do |path|
|
82
|
-
content = File.read(path)
|
83
|
-
content << kernel_cmd unless content.gsub!(/^c\.KernelManager\.kernel_cmd.*$/, kernel_cmd)
|
84
|
-
File.open(path, 'w') {|f| f.write(content) }
|
85
|
-
end
|
99
|
+
def register_kernel
|
100
|
+
require 'fileutils'
|
101
|
+
FileUtils.mkpath(File.dirname(@kernel_file))
|
102
|
+
File.write(@kernel_file, %{{
|
103
|
+
"argv": [ "#{File.expand_path $0}", "kernel", "{connection_file}" ],
|
104
|
+
"display_name": "Ruby",
|
105
|
+
"language": "ruby"
|
106
|
+
}
|
107
|
+
})
|
108
|
+
end
|
86
109
|
|
87
|
-
|
88
|
-
|
89
|
-
unless (File.readlink(static_dir) rescue nil) == target_dir
|
90
|
-
FileUtils.rm_rf(static_dir) rescue nil
|
91
|
-
begin
|
92
|
-
FileUtils.ln_sf(target_dir, static_dir)
|
93
|
-
rescue => ex
|
94
|
-
STDERR.puts "Could not create directory #{static_dir}: #{ex.message}"
|
95
|
-
end
|
96
|
-
end
|
110
|
+
def unregister_kernel
|
111
|
+
File.unlink(@kernel_file)
|
97
112
|
end
|
98
113
|
end
|
99
114
|
end
|
data/lib/iruby/display.rb
CHANGED
@@ -30,12 +30,6 @@ module IRuby
|
|
30
30
|
# as the given mime type.
|
31
31
|
data[exact_mime] = protect(exact_mime, obj) if exact_mime && !data.any? {|m,_| exact_mime == m }
|
32
32
|
|
33
|
-
# HACK for IPython #6259
|
34
|
-
# https://github.com/ipython/ipython/issues/6259
|
35
|
-
if js = data.delete('application/javascript')
|
36
|
-
data['text/html'] = "<script type='text/javascript'>#{js}</script>"
|
37
|
-
end
|
38
|
-
|
39
33
|
data
|
40
34
|
end
|
41
35
|
|
@@ -173,7 +167,7 @@ module IRuby
|
|
173
167
|
type { NArray }
|
174
168
|
format 'text/latex' do |obj|
|
175
169
|
obj.dim == 2 ?
|
176
|
-
LaTeX.matrix(obj.transpose, obj.shape[1], obj.shape[0]) :
|
170
|
+
LaTeX.matrix(obj.transpose(1, 0), obj.shape[1], obj.shape[0]) :
|
177
171
|
LaTeX.vector(obj.to_a)
|
178
172
|
end
|
179
173
|
format 'text/html' do |obj|
|
@@ -182,7 +176,7 @@ module IRuby
|
|
182
176
|
|
183
177
|
type { Matrix }
|
184
178
|
format 'text/latex' do |obj|
|
185
|
-
LaTeX.matrix(obj, obj.
|
179
|
+
LaTeX.matrix(obj, obj.row_size, obj.column_size)
|
186
180
|
end
|
187
181
|
format 'text/html' do |obj|
|
188
182
|
HTML.table(obj.to_a)
|
@@ -228,8 +222,8 @@ module IRuby
|
|
228
222
|
end
|
229
223
|
|
230
224
|
match do |obj|
|
231
|
-
defined?(
|
232
|
-
defined?(
|
225
|
+
defined?(Magick::Image) && Magick::Image === obj ||
|
226
|
+
defined?(MiniMagick::Image) && MiniMagick::Image === obj
|
233
227
|
end
|
234
228
|
format 'image' do |obj|
|
235
229
|
format = obj.format || 'PNG'
|
data/lib/iruby/formatter.rb
CHANGED
@@ -24,11 +24,9 @@ module IRuby
|
|
24
24
|
module HTML
|
25
25
|
extend self
|
26
26
|
|
27
|
-
def table(obj,
|
28
|
-
|
29
|
-
|
30
|
-
raise ArgumentError, 'Invalid :maxrows' if options[:maxrows] && options[:maxrows] < 3
|
31
|
-
raise ArgumentError, 'Invalid :maxcols' if options[:maxcols] && options[:maxcols] < 3
|
27
|
+
def table(obj, maxrows: 15, maxcols: 15, **options)
|
28
|
+
raise ArgumentError, 'Invalid :maxrows' if maxrows && maxrows < 3
|
29
|
+
raise ArgumentError, 'Invalid :maxcols' if maxcols && maxcols < 3
|
32
30
|
|
33
31
|
return obj unless obj.respond_to?(:each)
|
34
32
|
|
@@ -77,18 +75,18 @@ module IRuby
|
|
77
75
|
keys1, keys2 = keys, nil
|
78
76
|
header1, header2 = header, nil
|
79
77
|
|
80
|
-
if
|
81
|
-
keys1 = keys[0...
|
82
|
-
keys2 = keys[-
|
78
|
+
if maxcols && keys.size > maxcols
|
79
|
+
keys1 = keys[0...maxcols / 2]
|
80
|
+
keys2 = keys[-maxcols / 2...-1]
|
83
81
|
if header
|
84
|
-
header1 = header[0...
|
85
|
-
header2 = header[-
|
82
|
+
header1 = header[0...maxcols / 2]
|
83
|
+
header2 = header[-maxcols / 2...-1]
|
86
84
|
end
|
87
85
|
end
|
88
86
|
|
89
|
-
if
|
90
|
-
rows1 = rows[0...
|
91
|
-
rows2 = rows[-
|
87
|
+
if maxrows && rows.size > maxrows
|
88
|
+
rows1 = rows[0...maxrows / 2]
|
89
|
+
rows2 = rows[-maxrows / 2...-1]
|
92
90
|
end
|
93
91
|
|
94
92
|
table = '<table>'
|
data/lib/iruby/kernel.rb
CHANGED
@@ -8,102 +8,96 @@ module IRuby
|
|
8
8
|
attr_accessor :instance
|
9
9
|
end
|
10
10
|
|
11
|
+
attr_reader :session, :comms
|
12
|
+
|
11
13
|
def initialize(config_file)
|
12
14
|
@config = MultiJson.load(File.read(config_file))
|
13
15
|
|
14
|
-
|
15
|
-
#puts config
|
16
|
-
#puts 'Use Ctrl-\\ (NOT Ctrl-C!) to terminate.'
|
16
|
+
IRuby.logger.debug("IRuby kernel start with config #{@config}")
|
17
17
|
|
18
18
|
Kernel.instance = self
|
19
19
|
|
20
20
|
c = ZMQ::Context.new
|
21
21
|
|
22
22
|
connection = "#{@config['transport']}://#{@config['ip']}:%d"
|
23
|
-
|
24
|
-
|
23
|
+
reply_socket = c.socket(:ROUTER)
|
24
|
+
reply_socket.bind(connection % @config['shell_port'])
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
pub_socket = c.socket(:PUB)
|
27
|
+
pub_socket.bind(connection % @config['iopub_port'])
|
28
28
|
|
29
29
|
Thread.new do
|
30
30
|
begin
|
31
|
-
hb_socket = c.socket(
|
31
|
+
hb_socket = c.socket(:REP)
|
32
32
|
hb_socket.bind(connection % @config['hb_port'])
|
33
|
-
ZMQ
|
33
|
+
ZMQ.proxy(hb_socket, hb_socket)
|
34
34
|
rescue Exception => ex
|
35
|
-
|
35
|
+
IRuby.logger.fatal "Kernel heartbeat died: #{ex.message}\n"#{ex.backtrace.join("\n")}"
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
@session = Session.new('kernel', @config)
|
39
|
+
@session = Session.new('kernel', @config, publish: pub_socket, reply: reply_socket)
|
40
40
|
|
41
|
-
$stdout = OStream.new(@session,
|
42
|
-
$stderr = OStream.new(@session,
|
41
|
+
$stdout = OStream.new(@session, 'stdout')
|
42
|
+
$stderr = OStream.new(@session, 'stderr')
|
43
43
|
|
44
44
|
@execution_count = 0
|
45
45
|
@backend = create_backend
|
46
46
|
@running = true
|
47
|
+
@comms = {}
|
47
48
|
end
|
48
49
|
|
49
50
|
def create_backend
|
50
51
|
PryBackend.new
|
51
52
|
rescue Exception => ex
|
52
|
-
|
53
|
+
IRuby.logger.warn ex.message unless LoadError === ex
|
53
54
|
PlainBackend.new
|
54
55
|
end
|
55
56
|
|
56
57
|
def run
|
57
58
|
send_status('starting')
|
58
59
|
while @running
|
59
|
-
ident, msg = @session.recv(
|
60
|
+
ident, msg = @session.recv(:reply)
|
60
61
|
type = msg[:header]['msg_type']
|
61
|
-
if type =~ /_request\Z/ && respond_to?(type)
|
62
|
+
if type =~ /comm_|_request\Z/ && respond_to?(type)
|
63
|
+
send_status('busy')
|
62
64
|
send(type, ident, msg)
|
65
|
+
send_status('idle')
|
63
66
|
else
|
64
|
-
|
67
|
+
IRuby.logger.error "Unknown message type: #{msg[:header]['msg_type']} #{msg.inspect}"
|
65
68
|
end
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
69
|
-
def display(obj, options={})
|
70
|
-
unless obj.nil?
|
71
|
-
content = { data: Display.display(obj, options), metadata: {}, execution_count: @execution_count }
|
72
|
-
@session.send(@pub_socket, 'pyout', content)
|
73
|
-
end
|
74
|
-
nil
|
75
|
-
end
|
76
|
-
|
77
72
|
def kernel_info_request(ident, msg)
|
78
73
|
content = {
|
79
|
-
protocol_version:
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
74
|
+
protocol_version: '5.0',
|
75
|
+
implementation: 'iruby',
|
76
|
+
implementation_version: IRuby::VERSION,
|
77
|
+
language_info: {
|
78
|
+
name: 'ruby',
|
79
|
+
version: RUBY_VERSION,
|
80
|
+
mimetype: 'text/ruby',
|
81
|
+
file_extension: 'rb',
|
82
|
+
},
|
83
|
+
banner: "IRuby #{IRuby::VERSION}"
|
89
84
|
}
|
90
|
-
@session.send(
|
85
|
+
@session.send(:reply, 'kernel_info_reply', content, ident)
|
91
86
|
end
|
92
87
|
|
93
88
|
def send_status(status)
|
94
|
-
@session.send(
|
89
|
+
@session.send(:publish, 'status', {execution_state: status})
|
95
90
|
end
|
96
91
|
|
97
92
|
def execute_request(ident, msg)
|
98
93
|
begin
|
99
94
|
code = msg[:content]['code']
|
100
95
|
rescue
|
101
|
-
|
96
|
+
IRuby.logger.fatal "Got bad message: #{msg.inspect}"
|
102
97
|
return
|
103
98
|
end
|
104
99
|
@execution_count += 1 unless msg[:content].fetch('silent', false)
|
105
|
-
|
106
|
-
@session.send(@pub_socket, 'pyin', code: code)
|
100
|
+
@session.send(:publish, 'execute_input', {code: code, execution_count: @execution_count}, ident)
|
107
101
|
|
108
102
|
result = nil
|
109
103
|
begin
|
@@ -111,33 +105,35 @@ module IRuby
|
|
111
105
|
content = {
|
112
106
|
status: 'ok',
|
113
107
|
payload: [],
|
114
|
-
user_variables: {},
|
115
108
|
user_expressions: {},
|
116
109
|
execution_count: @execution_count
|
117
110
|
}
|
111
|
+
rescue SystemExit
|
112
|
+
raise
|
118
113
|
rescue Exception => e
|
119
114
|
content = {
|
115
|
+
status: 'error',
|
120
116
|
ename: e.class.to_s,
|
121
117
|
evalue: e.message,
|
122
|
-
etype: e.class.to_s,
|
123
|
-
status: 'error',
|
124
118
|
traceback: ["#{RED}#{e.class}#{RESET}: #{e.message}", *e.backtrace.map { |l| "#{WHITE}#{l}#{RESET}" }],
|
125
119
|
execution_count: @execution_count
|
126
120
|
}
|
127
|
-
@session.send(
|
121
|
+
@session.send(:publish, 'error', content, ident)
|
122
|
+
end
|
123
|
+
@session.send(:reply, 'execute_reply', content, ident)
|
124
|
+
unless result.nil? || msg[:content]['silent']
|
125
|
+
@session.send(:publish, 'execute_result', data: Display.display(result), metadata: {}, execution_count: @execution_count)
|
128
126
|
end
|
129
|
-
@session.send(@reply_socket, 'execute_reply', content, ident)
|
130
|
-
display(result) unless msg[:content]['silent']
|
131
|
-
send_status('idle')
|
132
127
|
end
|
133
128
|
|
134
129
|
def complete_request(ident, msg)
|
135
130
|
content = {
|
136
|
-
matches: @backend.complete(msg[:content]['
|
131
|
+
matches: @backend.complete(msg[:content]['code']),
|
137
132
|
status: 'ok',
|
138
|
-
|
133
|
+
cursor_start: 0,
|
134
|
+
cursor_end: msg[:content]['cursor_pos']
|
139
135
|
}
|
140
|
-
@session.send(
|
136
|
+
@session.send(:reply, 'complete_reply', content, ident)
|
141
137
|
end
|
142
138
|
|
143
139
|
def connect_request(ident, msg)
|
@@ -147,11 +143,11 @@ module IRuby
|
|
147
143
|
stdin_port: config['stdin_port'],
|
148
144
|
hb_port: config['hb_port']
|
149
145
|
}
|
150
|
-
@session.send(
|
146
|
+
@session.send(:reply, 'connect_reply', content, ident)
|
151
147
|
end
|
152
148
|
|
153
149
|
def shutdown_request(ident, msg)
|
154
|
-
@session.send(
|
150
|
+
@session.send(:reply, 'shutdown_reply', msg[:content], ident)
|
155
151
|
@running = false
|
156
152
|
end
|
157
153
|
|
@@ -161,10 +157,10 @@ module IRuby
|
|
161
157
|
content = {
|
162
158
|
history: []
|
163
159
|
}
|
164
|
-
@session.send(
|
160
|
+
@session.send(:reply, 'history_reply', content, ident)
|
165
161
|
end
|
166
162
|
|
167
|
-
def
|
163
|
+
def inspect_request(ident, msg)
|
168
164
|
o = @backend.eval(msg[:content]['oname'])
|
169
165
|
content = {
|
170
166
|
oname: msg[:content]['oname'],
|
@@ -172,18 +168,34 @@ module IRuby
|
|
172
168
|
ismagic: false,
|
173
169
|
isalias: false,
|
174
170
|
docstring: '', # TODO
|
175
|
-
type_class: o.class.to_s,
|
176
171
|
type_class: o.class.superclass.to_s,
|
177
172
|
string_form: o.inspect
|
178
173
|
}
|
179
174
|
content[:length] = o.length if o.respond_to?(:length)
|
180
|
-
@session.send(
|
175
|
+
@session.send(:reply, 'inspect_reply', content, ident)
|
181
176
|
rescue Exception
|
182
177
|
content = {
|
183
178
|
oname: msg[:content]['oname'],
|
184
179
|
found: false
|
185
180
|
}
|
186
|
-
@session.send(
|
181
|
+
@session.send(:reply, 'inspect_reply', content, ident)
|
182
|
+
end
|
183
|
+
|
184
|
+
def comm_open(ident, msg)
|
185
|
+
comm_id = msg[:content]['comm_id']
|
186
|
+
target_name = msg[:content]['target_name']
|
187
|
+
target = Comm.targets[target_name]
|
188
|
+
@comms[comm_id] = target.new(target_name, comm_id)
|
189
|
+
end
|
190
|
+
|
191
|
+
def comm_msg(ident, msg)
|
192
|
+
@comms[msg[:content]['comm_id']].comm_msg(msg[:content]['data'])
|
193
|
+
end
|
194
|
+
|
195
|
+
def comm_close(ident, msg)
|
196
|
+
comm_id = msg[:content]['comm_id']
|
197
|
+
@comms[comm_id].comm_close
|
198
|
+
@comms.delete(comm_id)
|
187
199
|
end
|
188
200
|
end
|
189
201
|
end
|