iruby 0.1.13 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|