iruby 0.7.0 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14aea673b75a6fe8884eff08c52b8831bbcec141df2525ed4c0a877738654271
4
- data.tar.gz: 89e5e091e67b7ef85f98ca0cb9ebe65cef0e32aacd75351c81b0c287666939c0
3
+ metadata.gz: 8e37561d8cd48b57f5ad431cfdf984306e638a262113f2cb741cf3a7d7a8e2e1
4
+ data.tar.gz: b1cd1da09bd9a6158749225e0097f92442ec5d600ab6f40a6189b50d0f2a4bb6
5
5
  SHA512:
6
- metadata.gz: 53b824e32c52cbf2893b24310ba4d3c7caa52ec872f36f57644a95bdd139232b4b5e032f161fb86baf94d011964caf9d739a4795af6805fd174360ed866477fa
7
- data.tar.gz: ee663bca3c4a67730d73e709c24d827af73e7c58734afe4dffc22c685c909462e9c9113f9548a8f1c8b5ce33b0b94338386b24c07978db547fab1caa21828ea7
6
+ metadata.gz: 6f70bdf2fa9da79a2e072f8a27ae729f5656a02a1d34a14bdd01287a16bfe257732875fc7a76db3f498cfd25cf49f4a9aa5ce2c82040ec90082bfca5e5d2f4e2
7
+ data.tar.gz: 789fe4b197775ef1245e96db8ac039a0df166898652c689ce2f66a7eb25db99a5f4806bccb7b76cc52cbdc7c4e6a3749eebda903b586b170842c9630f50af082
@@ -0,0 +1,124 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ types:
9
+ - opened
10
+ - synchronize
11
+ - reopened
12
+
13
+ jobs:
14
+ ubuntu:
15
+ name: Ubuntu
16
+ runs-on: ${{ matrix.os }}
17
+
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ os:
22
+ - ubuntu-latest
23
+ ruby:
24
+ - "3.0"
25
+ - "2.7"
26
+ - "2.6"
27
+ - "2.5"
28
+ - "2.4"
29
+ - "2.3"
30
+ - debug
31
+
32
+ steps:
33
+ - uses: actions/checkout@v2
34
+ with:
35
+ fetch-depth: 1
36
+
37
+ - uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.ruby }}
40
+
41
+ - run: rake build
42
+
43
+ - name: Install irb for old Ruby
44
+ if: |
45
+ matrix.ruby == '2.5' ||
46
+ matrix.ruby == '2.4' ||
47
+ matrix.ruby == '2.3'
48
+ run: |
49
+ cat <<GEMFILE > Gemfile.irb
50
+ source 'https://rubygems.org'
51
+ gem 'irb'
52
+ GEMFILE
53
+ BUNDLE_GEMFILE=Gemfile.irb bundle install --jobs 4 --retry 3
54
+
55
+ - run: gem install pkg/*.gem
56
+
57
+ - run: ruby -r iruby -e "p IRuby::SessionAdapter.select_adapter_class"
58
+ env:
59
+ IRUBY_SESSION_ADAPTER: ffi-rzmq
60
+
61
+ - name: Install requirements on ubuntu
62
+ run: |
63
+ sudo apt update
64
+ sudo apt install -y --no-install-recommends \
65
+ libczmq-dev \
66
+ python3 \
67
+ python3-pip \
68
+ python3-setuptools
69
+ sudo pip3 install wheel
70
+ sudo pip3 install -r ci/requirements.txt
71
+
72
+ - run: bundle install --jobs 4 --retry 3
73
+
74
+ - name: Run tests
75
+ env:
76
+ PYTHON: python3
77
+ ADAPTERS: cztop ffi-rzmq
78
+ run: |
79
+ for adapter in $ADAPTERS; do
80
+ export IRUBY_TEST_SESSION_ADAPTER_NAME=$adapter
81
+ bundle exec rake test TESTOPTS=-v
82
+ done
83
+
84
+ windows:
85
+ name: Windows
86
+ runs-on: windows-latest
87
+
88
+ steps:
89
+ - uses: actions/checkout@v2
90
+ with:
91
+ fetch-depth: 1
92
+
93
+ - uses: ruby/setup-ruby@v1
94
+ with:
95
+ ruby-version: "3.0"
96
+
97
+ - run: rake build
98
+
99
+ - run: gem install pkg/*.gem
100
+
101
+ - run: ruby -r iruby -e "p IRuby::SessionAdapter.select_adapter_class"
102
+ env:
103
+ IRUBY_SESSION_ADAPTER: ffi-rzmq
104
+
105
+ macos:
106
+ name: macOS
107
+ runs-on: macos-latest
108
+
109
+ steps:
110
+ - uses: actions/checkout@v2
111
+ with:
112
+ fetch-depth: 1
113
+
114
+ - uses: ruby/setup-ruby@v1
115
+ with:
116
+ ruby-version: "3.0"
117
+
118
+ - run: rake build
119
+
120
+ - run: gem install pkg/*.gem
121
+
122
+ - run: ruby -r iruby -e "p IRuby::SessionAdapter.select_adapter_class"
123
+ env:
124
+ IRUBY_SESSION_ADAPTER: ffi-rzmq
data/CHANGES.md CHANGED
@@ -1,3 +1,35 @@
1
+ # 0.7.4 (2021-08-16)
2
+
3
+ ## Enhancements
4
+
5
+ * Install zeromq library automatically https://github.com/SciRuby/iruby/pull/307, https://github.com/SciRuby/iruby/pull/308 (@mrkn, @kou)
6
+ * Remove pyzmq session adapter (@mrkn)
7
+ * Make cztop session adapter deprecated (@mrkn)
8
+
9
+ # 0.7.3 (2021-07-08)
10
+
11
+ ## Bug Fixes
12
+
13
+ * Do not call default renderers when to_iruby_mimebundle is available (@mrkn)
14
+
15
+ # 0.7.2 (2021-06-23)
16
+
17
+ ## Bug Fixes
18
+
19
+ * Fix IRuby.table for Ruby >= 2.7 https://github.com/SciRuby/iruby/pull/305 (@topofocus)
20
+ * Fix PlainBackend to include modules https://github.com/SciRuby/iruby/issues/303 (@UliKuch, @mrkn)
21
+
22
+ # 0.7.1 (2021-06-21)
23
+
24
+ ## Enhancements
25
+
26
+ * Add support of `to_iruby_mimebundle` format method https://github.com/SciRuby/iruby/pull/304 (@mrkn)
27
+
28
+ ## Bug Fixes
29
+
30
+ * Prevent unintentional display the result of Session#send (@mrkn)
31
+ * Update display formatter for Gruff::Base to prevent warning (@mrkn)
32
+
1
33
  # 0.7.0 (2021-05-28)
2
34
 
3
35
  ## Enhancements
@@ -7,9 +39,14 @@
7
39
 
8
40
  ## Bug Fixes
9
41
 
10
- * Follow the messages and hooks orders during execute_request processing (@mrkn)
11
42
  * Fix the handling of image/svg+xml https://github.com/SciRuby/iruby/pull/300, https://github.com/SciRuby/iruby/pull/301 (@kojix2)
12
43
 
44
+ # 0.6.1 (2021-05-26)
45
+
46
+ ## Bug Fixes
47
+
48
+ * Follow the messages and hooks orders during execute_request processing (@mrkn)
49
+
13
50
  # 0.6.0 (2021-05-25)
14
51
 
15
52
  ## Bug Fixes
data/README.md CHANGED
@@ -21,67 +21,53 @@ https://mybinder.org/v2/gh/RubyData/binder/master?filepath=../lab
21
21
  ### Requirements
22
22
 
23
23
  * [Jupyter](https://jupyter.org)
24
- * One of the following is required
25
- * [ffi-rzmq](https://github.com/chuckremes/ffi-rzmq) and [libzmq](https://github.com/zeromq/libzmq)
26
- * [CZTop](https://gitlab.com/paddor/cztop) and [CZMQ](https://github.com/zeromq/czmq)
27
24
 
28
- If both ffi-rzmq and cztop are installed, ffi-rzmq is used. If you prefer cztop, set the following environment variable.
25
+ The following requirements are automatically installed.
29
26
 
30
- ```sh
31
- export IRUBY_SESSION_ADAPTER="cztop"
32
- ```
27
+ * [ffi-rzmq](https://github.com/chuckremes/ffi-rzmq)
28
+ * [libzmq](https://github.com/zeromq/libzmq)
29
+
30
+ The following dependencies are optional.
33
31
 
34
32
  * [Pry][Pry], if you want to use [Pry][Pry] instead of IRB for the code execution backend
35
- * If you want to install the development version of IRuby from the source code, try [specific_install](https://github.com/rdp/specific_install).
36
33
 
37
- ```
38
- gem specific_install https://github.com/SciRuby/iruby
39
- ```
40
34
 
41
- ### Ubuntu
35
+ ### Installing Jupyter Notebook and/or JupyterLab
42
36
 
43
- Install Jupyter.
37
+ See the official document to know how to install Jupyter Notebook and/or JupyterLab.
38
+
39
+ * https://jupyter.readthedocs.io/en/latest/install/notebook-classic.html
40
+ * https://jupyter.readthedocs.io/en/latest/install.html
41
+
42
+ ### Ubuntu
44
43
 
45
44
  #### Ubuntu 17+
46
45
 
47
46
  ```shell
48
47
  sudo apt install libtool libffi-dev ruby ruby-dev make
49
- sudo apt install libzmq3-dev libczmq-dev
50
48
 
51
- gem install ffi-rzmq
52
- gem install iruby --pre
49
+ gem install --user-install iruby
53
50
  iruby register --force
54
51
  ```
55
52
 
56
53
  #### Ubuntu 16
57
54
 
58
- CZTop requires CZMQ >= 4.0.0 and ZMQ >= 4.2.0. The official packages for Ubuntu 16.04 don't satisfy these version requrements, so you need to install from source.
55
+ The latest IRuby requires Ruby >= 2.4 while Ubuntu's official Ruby package is version 2.3.
56
+ So you need to install Ruby >= 2.4 by yourself before preparing IRuby.
57
+ We recommend to use rbenv.
59
58
 
60
59
  ```shell
61
60
  sudo apt install libtool libffi-dev ruby ruby-dev make
62
- sudo apt install git libzmq-dev autoconf pkg-config
63
- git clone https://github.com/zeromq/czmq
64
- cd czmq
65
- ./autogen.sh && ./configure && sudo make && sudo make install
66
-
67
- gem install cztop
68
- gem install iruby --pre
61
+ gem install --user-install iruby
69
62
  iruby register --force
70
63
  ```
71
64
 
72
65
  ### Windows
73
66
 
74
- Install git and Jupyter.
75
67
  [DevKit](https://rubyinstaller.org/add-ons/devkit.html) is necessary for building RubyGems with native C-based extensions.
76
68
 
77
- Install ZeroMQ.
78
- ```shell
79
- pacman -S mingw64/mingw-w64-x86_64-zeromq
80
- ```
81
-
82
69
  ```shell
83
- gem install ffi-rzmq
84
- gem install iruby --pre
70
+ gem install iruby
85
71
  iruby register --force
86
72
  ```
87
73
 
@@ -93,17 +79,7 @@ Install Jupyter.
93
79
  #### Homebrew
94
80
 
95
81
  ```shell
96
- brew install automake gmp libtool wget
97
- brew install zeromq --HEAD
98
- brew install czmq --HEAD
99
- ```
100
-
101
- ```shell
102
- # export LIBZMQ_PATH=$(brew --prefix zeromq)/lib
103
- # export LIBCZMQ_PATH=$(brew --prefix czmq)/lib
104
- # gem install cztop
105
- gem install ffi-rzmq
106
- gem install iruby --pre
82
+ gem install iruby
107
83
  iruby register --force
108
84
  ```
109
85
 
@@ -113,8 +89,8 @@ If you are using macports, run the following commands.
113
89
 
114
90
  ```shell
115
91
  port install libtool autoconf automake autogen
116
- gem install ffi-rzmq
117
92
  gem install iruby
93
+ iruby register --force
118
94
  ```
119
95
 
120
96
  ### Docker
@@ -123,7 +99,7 @@ Try [RubyData Docker Stacks](https://github.com/RubyData/docker-stacks).
123
99
  Running jupyter notebook:
124
100
 
125
101
  ```shell
126
- docker run -p 8888:8888 rubydata/datascience-notebook
102
+ docker run --rm -it -p 8888:8888 rubydata/datascience-notebook
127
103
  ```
128
104
 
129
105
  ### Installation for JRuby
@@ -131,7 +107,6 @@ docker run -p 8888:8888 rubydata/datascience-notebook
131
107
  You can use Java classes in your IRuby notebook.
132
108
 
133
109
  * JRuby version >= 9.0.4.0
134
- * cztop gem
135
110
  * iruby gem
136
111
 
137
112
  After installation, make sure that your `env` is set up to use jruby.
@@ -148,6 +123,29 @@ If you have already used IRuby with a different version, you need to generate a
148
123
  $ iruby register --force
149
124
  ```
150
125
 
126
+ ### Install the development version of IRuby
127
+
128
+ **Be careful to use the development version because it is usually unstable.**
129
+
130
+ If you want to install the development version of IRuby from the source code, try [specific_install](https://github.com/rdp/specific_install).
131
+
132
+ ```
133
+ gem specific_install https://github.com/SciRuby/iruby
134
+ ```
135
+
136
+ ### Note for using with CZTop and CZMQ
137
+
138
+ [CZTop](https://gitlab.com/paddor/cztop) adapter has been deprecated since IRuby version 0.7.4.
139
+ It will be removed after several versions.
140
+
141
+ If you want to use IRuby with CZTop, you need to install it and [CZMQ](https://github.com/zeromq/czmq).
142
+
143
+ If both ffi-rzmq and cztop are installed, ffi-rzmq is used. If you prefer cztop, set the following environment variable.
144
+
145
+ ```sh
146
+ export IRUBY_SESSION_ADAPTER="cztop"
147
+ ```
148
+
151
149
  ## Backends
152
150
 
153
151
  There are two backends: PlainBackend and PryBackend.
data/ext/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ task default: :all
2
+
3
+ task all: [:ensure_zeromq]
4
+
5
+ task :ensure_zeromq do
6
+ begin
7
+ require 'ffi-rzmq'
8
+ rescue LoadError
9
+ require 'native-package-installer'
10
+ unless NativePackageInstaller.install(arch_linux: 'zeromq',
11
+ debian: 'libzmq3-dev',
12
+ freebsd: 'libzmq4',
13
+ homebrew: 'zmq',
14
+ macports: 'zmq',
15
+ redhat: 'zeromq-devel')
16
+ raise 'Failed to install ZeroMQ'
17
+ end
18
+ end
19
+ end
data/iruby.gemspec CHANGED
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
15
  s.test_files = s.files.grep(%r{^test/})
16
16
  s.require_paths = %w[lib]
17
+ s.extensions = %w[ext/Rakefile]
17
18
 
18
19
  s.required_ruby_version = '>= 2.3.0'
19
20
 
@@ -22,9 +23,12 @@ Gem::Specification.new do |s|
22
23
  s.add_dependency 'irb'
23
24
  s.add_dependency 'mime-types', '>= 3.3.1'
24
25
  s.add_dependency 'multi_json', '~> 1.11'
26
+ s.add_dependency 'native-package-installer'
25
27
 
26
28
  s.add_development_dependency 'pycall', '>= 1.2.1'
27
29
  s.add_development_dependency 'rake'
28
30
  s.add_development_dependency 'test-unit'
29
31
  s.add_development_dependency 'test-unit-rr'
32
+
33
+ s.metadata['msys2_mingw_dependencies'] = 'zeromq'
30
34
  end
data/lib/iruby/backend.rb CHANGED
@@ -40,6 +40,7 @@ module IRuby
40
40
  require 'irb/completion'
41
41
  IRB.setup(nil)
42
42
  @main = TOPLEVEL_BINDING.eval("self").dup
43
+ init_main_object(@main)
43
44
  @workspace = IRB::WorkSpace.new(@main)
44
45
  @irb = IRB::Irb.new(@workspace)
45
46
  @eval_path = @irb.context.irb_path
@@ -58,6 +59,16 @@ module IRuby
58
59
  def complete(code)
59
60
  IRB::InputCompletor::CompletionProc.call(code)
60
61
  end
62
+
63
+ private
64
+
65
+ def init_main_object(main)
66
+ wrapper_module = Module.new
67
+ main.extend(wrapper_module)
68
+ main.define_singleton_method(:include) do |*args|
69
+ wrapper_module.include(*args)
70
+ end
71
+ end
61
72
  end
62
73
 
63
74
  class PryBackend
data/lib/iruby/display.rb CHANGED
@@ -2,6 +2,22 @@ require "set"
2
2
 
3
3
  module IRuby
4
4
  module Display
5
+ DEFAULT_MIME_TYPE_FORMAT_METHODS = {
6
+ "text/html" => :to_html,
7
+ "text/markdown" => :to_markdown,
8
+ "image/svg+xml" => :to_svg,
9
+ "image/png" => :to_png,
10
+ "appliation/pdf" => :to_pdf,
11
+ "image/jpeg" => :to_jpeg,
12
+ "text/latex" => [:to_latex, :to_tex],
13
+ # NOTE: Do not include the entry of "application/json" because
14
+ # all objects can respond to `to_json` due to json library
15
+ # "application/json" => :to_json,
16
+ "application/javascript" => :to_javascript,
17
+ nil => :to_iruby,
18
+ "text/plain" => :inspect
19
+ }.freeze
20
+
5
21
  class << self
6
22
  # @private
7
23
  def convert(obj, options)
@@ -24,17 +40,51 @@ module IRuby
24
40
  raise 'Invalid mime type' unless exact_mime.include?('/')
25
41
  end
26
42
 
27
- data = {}
28
-
29
- # Render additional representation
30
- render(data, obj, exact_mime, fuzzy_mime)
31
-
32
- # IPython always requires a text representation
33
- render(data, obj, 'text/plain', nil) unless data['text/plain']
43
+ data = if obj.respond_to?(:to_iruby_mimebundle)
44
+ render_mimebundle(obj, exact_mime, fuzzy_mime)
45
+ else
46
+ {}
47
+ end
48
+
49
+ # Render by additional formatters
50
+ render_by_registry(data, obj, exact_mime, fuzzy_mime)
51
+
52
+ # Render by to_xxx methods
53
+ default_renderers = if obj.respond_to?(:to_iruby_mimebundle)
54
+ # Do not use Hash#slice for Ruby < 2.5
55
+ {"text/plain" => DEFAULT_MIME_TYPE_FORMAT_METHODS["text/plain"]}
56
+ else
57
+ DEFAULT_MIME_TYPE_FORMAT_METHODS
58
+ end
59
+ default_renderers.each do |mime, methods|
60
+ next if mime.nil? && !data.empty? # for to_iruby
61
+
62
+ next if mime && data.key?(mime) # do not overwrite
63
+
64
+ method = Array(methods).find {|m| obj.respond_to?(m) }
65
+ next if method.nil?
66
+
67
+ result = obj.send(method)
68
+ case mime
69
+ when nil # to_iruby
70
+ case result
71
+ when nil
72
+ # do nothing
73
+ next
74
+ when Array
75
+ mime, result = result
76
+ else
77
+ warn(("Ignore the result of to_iruby method of %p because " +
78
+ "it does not return a pair of mime-type and formatted representation") % obj)
79
+ next
80
+ end
81
+ end
82
+ data[mime] = result
83
+ end
34
84
 
35
85
  # As a last resort, interpret string representation of the object
36
86
  # as the given mime type.
37
- if exact_mime && data.none? { |m, _| exact_mime == m }
87
+ if exact_mime && !data.key?(exact_mime)
38
88
  data[exact_mime] = protect(exact_mime, obj)
39
89
  end
40
90
 
@@ -67,7 +117,19 @@ module IRuby
67
117
  end
68
118
  end
69
119
 
70
- def render(data, obj, exact_mime, fuzzy_mime)
120
+ private def render_mimebundle(obj, exact_mime, fuzzy_mime)
121
+ data = {}
122
+ include_mime = [exact_mime].compact
123
+ formats, metadata = obj.to_iruby_mimebundle(include: include_mime)
124
+ formats.each do |mime, value|
125
+ if fuzzy_mime.nil? || mime.include?(fuzzy_mime)
126
+ data[mime] = value
127
+ end
128
+ end
129
+ data
130
+ end
131
+
132
+ private def render_by_registry(data, obj, exact_mime, fuzzy_mime)
71
133
  # Filter matching renderer by object type
72
134
  renderer = Registry.renderer.select { |r| r.match?(obj) }
73
135
 
@@ -88,6 +150,8 @@ module IRuby
88
150
  # Return first render result which has the right mime type
89
151
  renderer.each do |r|
90
152
  mime, result = r.render(obj)
153
+ next if data.key?(mime)
154
+
91
155
  if mime && result && (!exact_mime || exact_mime == mime) && (!fuzzy_mime || mime.include?(fuzzy_mime))
92
156
  data[mime] = protect(mime, result)
93
157
  break
@@ -98,6 +162,19 @@ module IRuby
98
162
  end
99
163
  end
100
164
 
165
+ private def render_by_to_iruby(data, obj)
166
+ if obj.respond_to?(:to_iruby)
167
+ result = obj.to_iruby
168
+ mime, rep = case result
169
+ when Array
170
+ result
171
+ else
172
+ [nil, result]
173
+ end
174
+ data[mime] = rep
175
+ end
176
+ end
177
+
101
178
  class Representation
102
179
  attr_reader :object, :options
103
180
 
@@ -120,6 +197,60 @@ module IRuby
120
197
  end
121
198
  end
122
199
 
200
+ class FormatMatcher
201
+ def initialize(&block)
202
+ @block = block
203
+ end
204
+
205
+ def call(obj)
206
+ @block.(obj)
207
+ end
208
+
209
+ def inspect
210
+ "#{self.class.name}[%p]" % @block
211
+ end
212
+ end
213
+
214
+ class RespondToFormatMatcher < FormatMatcher
215
+ def initialize(name)
216
+ super() {|obj| obj.respond_to?(name) }
217
+ @name = name
218
+ end
219
+
220
+ attr_reader :name
221
+
222
+ def inspect
223
+ "#{self.class.name}[respond_to?(%p)]" % name
224
+ end
225
+ end
226
+
227
+ class TypeFormatMatcher < FormatMatcher
228
+ def initialize(class_block)
229
+ super() do |obj|
230
+ begin
231
+ self.klass === obj
232
+ # We have to rescue all exceptions since constant autoloading could fail with a different error
233
+ rescue Exception
234
+ false
235
+ end
236
+ end
237
+ @class_block = class_block
238
+ end
239
+
240
+ def klass
241
+ @class_block.()
242
+ end
243
+
244
+ def inspect
245
+ klass = begin
246
+ @class_block.()
247
+ rescue Exception
248
+ @class_block
249
+ end
250
+ "#{self.class.name}[%p]" % klass
251
+ end
252
+ end
253
+
123
254
  class Renderer
124
255
  attr_reader :match, :mime, :priority
125
256
 
@@ -147,37 +278,22 @@ module IRuby
147
278
  @renderer ||= []
148
279
  end
149
280
 
150
- SUPPORTED_MIMES = %w[
151
- text/plain
152
- text/html
153
- text/latex
154
- application/json
155
- application/javascript
156
- image/png
157
- image/jpeg
158
- image/svg+xml
159
- ]
160
-
161
281
  def match(&block)
162
- @match = block
282
+ @match = FormatMatcher.new(&block)
163
283
  priority 0
164
284
  nil
165
285
  end
166
286
 
167
287
  def respond_to(name)
168
- match { |obj| obj.respond_to?(name) }
288
+ @match = RespondToFormatMatcher.new(name)
289
+ priority 0
290
+ nil
169
291
  end
170
292
 
171
293
  def type(&block)
172
- match do |obj|
173
- begin
174
- block.call === obj
175
- # We have to rescue all exceptions since constant autoloading could fail with a different error
176
- rescue Exception
177
- rescue #NameError
178
- false
179
- end
180
- end
294
+ @match = TypeFormatMatcher.new(block)
295
+ priority 0
296
+ nil
181
297
  end
182
298
 
183
299
  def priority(p)
@@ -275,13 +391,24 @@ module IRuby
275
391
  end
276
392
  end
277
393
 
394
+ format_magick_image = ->(obj) do
395
+ format = obj.format || 'PNG'
396
+ [
397
+ format == 'PNG' ? 'image/png' : 'image/jpeg',
398
+ obj.to_blob {|i| i.format = format }
399
+ ]
400
+ end
401
+
278
402
  match do |obj|
279
403
  defined?(Magick::Image) && Magick::Image === obj ||
280
404
  defined?(MiniMagick::Image) && MiniMagick::Image === obj
281
405
  end
406
+ format 'image', &format_magick_image
407
+
408
+ type { Gruff::Base }
282
409
  format 'image' do |obj|
283
- format = obj.format || 'PNG'
284
- [format == 'PNG' ? 'image/png' : 'image/jpeg', obj.to_blob { |i| i.format = format }]
410
+ image = obj.to_image
411
+ format_magick_image.(obj.to_image)
285
412
  end
286
413
 
287
414
  match do |obj|
@@ -298,39 +425,19 @@ module IRuby
298
425
  end
299
426
  end
300
427
 
301
- type { Gruff::Base }
302
- format 'image/png', &:to_blob
303
-
304
- respond_to :to_html
305
- format 'text/html', &:to_html
306
-
307
- respond_to :to_latex
308
- format 'text/latex', &:to_latex
309
-
310
- respond_to :to_tex
311
- format 'text/latex', &:to_tex
312
-
313
- respond_to :to_javascript
314
- format 'text/javascript', &:to_javascript
315
-
316
- respond_to :to_svg
428
+ type { Rubyvis::Mark }
317
429
  format 'image/svg+xml' do |obj|
318
- obj.render if defined?(Rubyvis) && Rubyvis::Mark === obj
430
+ obj.render
319
431
  obj.to_svg
320
432
  end
321
433
 
322
- respond_to :to_iruby
323
- format(&:to_iruby)
324
-
325
434
  match { |obj| obj.respond_to?(:path) && obj.method(:path).arity == 0 && File.readable?(obj.path) }
326
435
  format do |obj|
327
436
  mime = MIME::Types.of(obj.path).first.to_s
328
- [mime, File.read(obj.path)] if SUPPORTED_MIMES.include?(mime)
437
+ if mime && DEFAULT_MIME_TYPE_FORMAT_METHODS.key?(mime)
438
+ [mime, File.read(obj.path)]
439
+ end
329
440
  end
330
-
331
- type { Object }
332
- priority(-1000)
333
- format 'text/plain', &:inspect
334
441
  end
335
442
  end
336
443
  end
@@ -23,7 +23,7 @@ module IRuby
23
23
  idents, msg_list = frames[0..i-1], frames[i+1..-1]
24
24
 
25
25
  minlen = 5
26
- raise 'malformed message, must have at least #{minlen} elements' unless msg_list.length >= minlen
26
+ raise "malformed message, must have at least #{minlen} elements" unless msg_list.length >= minlen
27
27
  s, header, parent_header, metadata, content, buffers = *msg_list
28
28
  raise 'Invalid signature' unless s == sign(msg_list[1..-1])
29
29
  {
@@ -40,14 +40,12 @@ module IRuby
40
40
 
41
41
  require_relative 'session_adapter/ffirzmq_adapter'
42
42
  require_relative 'session_adapter/cztop_adapter'
43
- require_relative 'session_adapter/pyzmq_adapter'
44
43
  require_relative 'session_adapter/test_adapter'
45
44
 
46
45
  def self.select_adapter_class(name=nil)
47
46
  classes = {
48
47
  'ffi-rzmq' => SessionAdapter::FfirzmqAdapter,
49
48
  'cztop' => SessionAdapter::CztopAdapter,
50
- # 'pyzmq' => SessionAdapter::PyzmqAdapter
51
49
  'test' => SessionAdapter::TestAdapter,
52
50
  }
53
51
  if (name ||= ENV.fetch('IRUBY_SESSION_ADAPTER', nil))
@@ -61,6 +59,9 @@ module IRuby
61
59
  "Session adapter `#{name}` is unavailable"
62
60
  end
63
61
  end
62
+ if name == 'cztop'
63
+ warn "WARNING: cztop was deprecated and will be removed; Use ffi-rzmq, instead."
64
+ end
64
65
  return cls
65
66
  end
66
67
  classes.each_value do |cls|
data/lib/iruby/utils.rb CHANGED
@@ -9,6 +9,9 @@ module IRuby
9
9
  Kernel.instance.session.send(:publish, :display_data,
10
10
  data: Display.display(obj, options),
11
11
  metadata: {}) unless obj.nil?
12
+ # The next `nil` is necessary to prevent unintentional displaying
13
+ # the result of Session#send
14
+ nil
12
15
  end
13
16
 
14
17
  # Clear the output area
@@ -18,7 +21,7 @@ module IRuby
18
21
 
19
22
  # Format the given object into HTML table
20
23
  def table(s, **options)
21
- html(HTML.table(s, options))
24
+ html(HTML.table(s, **options))
22
25
  end
23
26
 
24
27
  # Treat the given string as LaTeX text
data/lib/iruby/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module IRuby
2
- VERSION = '0.7.0'
2
+ VERSION = '0.7.4'
3
3
  end
@@ -8,6 +8,12 @@ module IRubyTest
8
8
  assert_equal 3, @plainbackend.eval('1+2', false)
9
9
  end
10
10
 
11
+ def test_include_module
12
+ assert_nothing_raised do
13
+ @plainbackend.eval("include Math, Comparable", false)
14
+ end
15
+ end
16
+
11
17
  def test_complete_req
12
18
  assert_includes @plainbackend.complete('req'), 'require'
13
19
  end
@@ -26,6 +32,12 @@ module IRubyTest
26
32
  assert_equal 3, @prybackend.eval('1+2', false)
27
33
  end
28
34
 
35
+ def test_include_module
36
+ assert_nothing_raised do
37
+ @prybackend.eval("include Math, Comparable", false)
38
+ end
39
+ end
40
+
29
41
  def test_complete_req
30
42
  assert_includes @prybackend.complete('req'), 'require'
31
43
  end
@@ -0,0 +1,185 @@
1
+ module IRubyTest
2
+ class DisplayTest < TestBase
3
+ def setup
4
+ @object = Object.new
5
+ @object.instance_variable_set(:@to_html_called, false)
6
+ @object.instance_variable_set(:@to_markdown_called, false)
7
+ @object.instance_variable_set(:@to_iruby_called, false)
8
+ @object.instance_variable_set(:@to_iruby_mimebundle_called, false)
9
+
10
+ class << @object
11
+ attr_reader :to_html_called
12
+ attr_reader :to_markdown_called
13
+ attr_reader :to_iruby_called
14
+ attr_reader :to_iruby_mimebundle_called
15
+
16
+ def html
17
+ "<b>html</b>"
18
+ end
19
+
20
+ def markdown
21
+ "*markdown*"
22
+ end
23
+
24
+ def inspect
25
+ "!!! inspect !!!"
26
+ end
27
+ end
28
+ end
29
+
30
+ def define_to_html
31
+ class << @object
32
+ def to_html
33
+ @to_html_called = true
34
+ html
35
+ end
36
+ end
37
+ end
38
+
39
+ def define_to_markdown
40
+ class << @object
41
+ def to_markdown
42
+ @to_markdown_called = true
43
+ markdown
44
+ end
45
+ end
46
+ end
47
+
48
+ def define_to_iruby
49
+ class << @object
50
+ def to_iruby
51
+ @to_iruby_called = true
52
+ ["text/html", "<b>to_iruby</b>"]
53
+ end
54
+ end
55
+ end
56
+
57
+ def define_to_iruby_mimebundle
58
+ class << @object
59
+ def to_iruby_mimebundle(include: [])
60
+ @to_iruby_mimebundle_called = true
61
+ mimes = if include.empty?
62
+ ["text/markdown", "application/json"]
63
+ else
64
+ include
65
+ end
66
+ formats = mimes.map { |mime|
67
+ result = case mime
68
+ when "text/markdown"
69
+ "**markdown**"
70
+ when "application/json"
71
+ %Q[{"mimebundle": "json"}]
72
+ end
73
+ [mime, result]
74
+ }.to_h
75
+ metadata = {}
76
+ return formats, metadata
77
+ end
78
+ end
79
+ end
80
+
81
+ def assert_iruby_display(expected)
82
+ assert_equal(expected,
83
+ {
84
+ result: IRuby::Display.display(@object),
85
+ to_html_called: @object.to_html_called,
86
+ to_markdown_called: @object.to_markdown_called,
87
+ to_iruby_called: @object.to_iruby_called,
88
+ to_iruby_mimebundle_called: @object.to_iruby_mimebundle_called
89
+ })
90
+ end
91
+
92
+ sub_test_case("the object cannot handle all the mime types") do
93
+ def test_display
94
+ assert_iruby_display({
95
+ result: {"text/plain" => "!!! inspect !!!"},
96
+ to_html_called: false,
97
+ to_markdown_called: false,
98
+ to_iruby_called: false,
99
+ to_iruby_mimebundle_called: false
100
+ })
101
+ end
102
+ end
103
+
104
+ sub_test_case("the object can respond to to_iruby") do
105
+ def setup
106
+ super
107
+ define_to_iruby
108
+ end
109
+
110
+ def test_display
111
+ assert_iruby_display({
112
+ result: {
113
+ "text/html" => "<b>to_iruby</b>",
114
+ "text/plain" => "!!! inspect !!!"
115
+ },
116
+ to_html_called: false,
117
+ to_markdown_called: false,
118
+ to_iruby_called: true,
119
+ to_iruby_mimebundle_called: false
120
+ })
121
+ end
122
+
123
+ sub_test_case("the object can respond to to_markdown") do
124
+ def setup
125
+ super
126
+ define_to_markdown
127
+ end
128
+
129
+ def test_display
130
+ assert_iruby_display({
131
+ result: {
132
+ "text/markdown" => "*markdown*",
133
+ "text/plain" => "!!! inspect !!!"
134
+ },
135
+ to_html_called: false,
136
+ to_markdown_called: true,
137
+ to_iruby_called: false,
138
+ to_iruby_mimebundle_called: false
139
+ })
140
+ end
141
+ end
142
+
143
+ sub_test_case("the object can respond to to_html") do
144
+ def setup
145
+ super
146
+ define_to_html
147
+ end
148
+
149
+ def test_display
150
+ assert_iruby_display({
151
+ result: {
152
+ "text/html" => "<b>html</b>",
153
+ "text/plain" => "!!! inspect !!!"
154
+ },
155
+ to_html_called: true,
156
+ to_markdown_called: false,
157
+ to_iruby_called: false,
158
+ to_iruby_mimebundle_called: false
159
+ })
160
+ end
161
+
162
+ sub_test_case("the object can respond to to_iruby_mimebundle") do
163
+ def setup
164
+ super
165
+ define_to_iruby_mimebundle
166
+ end
167
+
168
+ def test_display
169
+ assert_iruby_display({
170
+ result: {
171
+ "text/markdown" => "**markdown**",
172
+ "application/json" => %Q[{"mimebundle": "json"}],
173
+ "text/plain" => "!!! inspect !!!"
174
+ },
175
+ to_html_called: false,
176
+ to_markdown_called: false,
177
+ to_iruby_called: false,
178
+ to_iruby_mimebundle_called: true
179
+ })
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
@@ -14,7 +14,6 @@ module IRubyTest
14
14
  assert_rr do
15
15
  stub(IRuby::SessionAdapter::CztopAdapter).available? { true }
16
16
  stub(IRuby::SessionAdapter::FfirzmqAdapter).available? { false }
17
- stub(IRuby::SessionAdapter::PyzmqAdapter).available? { false }
18
17
 
19
18
  cls = IRuby::SessionAdapter.select_adapter_class
20
19
  assert_equal IRuby::SessionAdapter::CztopAdapter, cls
@@ -25,25 +24,12 @@ module IRubyTest
25
24
  assert_rr do
26
25
  stub(IRuby::SessionAdapter::FfirzmqAdapter).available? { true }
27
26
  stub(IRuby::SessionAdapter::CztopAdapter).available? { false }
28
- stub(IRuby::SessionAdapter::PyzmqAdapter).available? { false }
29
27
 
30
28
  cls = IRuby::SessionAdapter.select_adapter_class
31
29
  assert_equal IRuby::SessionAdapter::FfirzmqAdapter, cls
32
30
  end
33
31
  end
34
32
 
35
- def test_select_adapter_class_with_pyzmq
36
- omit("pyzmq adapter is disabled")
37
- assert_rr do
38
- stub(IRuby::SessionAdapter::PyzmqAdapter).available? { true }
39
- stub(IRuby::SessionAdapter::FfirzmqAdapter).available? { false }
40
- stub(IRuby::SessionAdapter::CztopAdapter).available? { false }
41
-
42
- cls = IRuby::SessionAdapter.select_adapter_class
43
- assert_equal IRuby::SessionAdapter::PyzmqAdapter, cls
44
- end
45
- end
46
-
47
33
  def test_select_adapter_class_with_env
48
34
  with_env('IRUBY_SESSION_ADAPTER' => 'cztop') do
49
35
  assert_rr do
@@ -72,20 +58,6 @@ module IRubyTest
72
58
  end
73
59
  end
74
60
  end
75
-
76
- with_env('IRUBY_SESSION_ADAPTER' => 'pyzmq') do
77
- # pyzmq adapter is disabled
78
- #
79
- # IRuby::SessionAdapter::PyzmqAdapter.stub :available?, true do
80
- # assert_equal IRuby::SessionAdapter::PyzmqAdapter, IRuby::SessionAdapter.select_adapter_class
81
- # end
82
- #
83
- # IRuby::SessionAdapter::PyzmqAdapter.stub :available?, false do
84
- # assert_raises IRuby::SessionAdapterNotFound do
85
- # IRuby::SessionAdapter.select_adapter_class
86
- # end
87
- # end
88
- end
89
61
  end
90
62
  end
91
63
  end
@@ -22,9 +22,6 @@ module IRubyTest
22
22
  IRuby::SessionAdapter::CztopAdapter
23
23
  when 'ffi-rzmq'
24
24
  IRuby::SessionAdapter::FfirzmqAdapter
25
- when 'pyzmq'
26
- omit("pyzmq adapter is disabled")
27
- # IRuby::SessionAdapter::PyzmqAdapter
28
25
  else
29
26
  flunk "Unknown session adapter: #{adapter_name.inspect}"
30
27
  end
@@ -37,7 +34,6 @@ module IRubyTest
37
34
  assert_rr do
38
35
  stub(IRuby::SessionAdapter::CztopAdapter).available? { false }
39
36
  stub(IRuby::SessionAdapter::FfirzmqAdapter).available? { false }
40
- stub(IRuby::SessionAdapter::PyzmqAdapter).available? { false }
41
37
  stub(IRuby::SessionAdapter::TestAdapter).available? { false }
42
38
  assert_raises IRuby::SessionAdapterNotFound do
43
39
  IRuby::Session.new(@session_config)
@@ -0,0 +1,25 @@
1
+ module IRubyTest
2
+ class UtilsTest < TestBase
3
+ sub_test_case("IRuby.table") do
4
+ def setup
5
+ @data = {
6
+ X: [ 1, 2, 3 ],
7
+ Y: [ 4, 5, 6 ]
8
+ }
9
+ end
10
+ sub_test_case("without header: option") do
11
+ def test_table
12
+ result = IRuby.table(@data)
13
+ assert_include(result.object, "<th>X</th>")
14
+ end
15
+ end
16
+
17
+ sub_test_case("with header: false") do
18
+ def test_table
19
+ result = IRuby.table(@data, header: false)
20
+ assert_not_include(result.object, "<th>X</th>")
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Mendler
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-05-28 00:00:00.000000000 Z
12
+ date: 2021-08-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: data_uri
@@ -81,6 +81,20 @@ dependencies:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
83
  version: '1.11'
84
+ - !ruby/object:Gem::Dependency
85
+ name: native-package-installer
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
84
98
  - !ruby/object:Gem::Dependency
85
99
  name: pycall
86
100
  requirement: !ruby/object:Gem::Requirement
@@ -142,10 +156,11 @@ email:
142
156
  - mail@daniel-mendler.de
143
157
  executables:
144
158
  - iruby
145
- extensions: []
159
+ extensions:
160
+ - ext/Rakefile
146
161
  extra_rdoc_files: []
147
162
  files:
148
- - ".github/workflows/ubuntu.yml"
163
+ - ".github/workflows/ci.yml"
149
164
  - ".gitignore"
150
165
  - CHANGES.md
151
166
  - Gemfile
@@ -158,6 +173,7 @@ files:
158
173
  - ci/requirements.txt
159
174
  - docker/setup.sh
160
175
  - docker/test.sh
176
+ - ext/Rakefile
161
177
  - iruby.gemspec
162
178
  - lib/iruby.rb
163
179
  - lib/iruby/assets/kernel.css
@@ -200,7 +216,6 @@ files:
200
216
  - lib/iruby/session_adapter.rb
201
217
  - lib/iruby/session_adapter/cztop_adapter.rb
202
218
  - lib/iruby/session_adapter/ffirzmq_adapter.rb
203
- - lib/iruby/session_adapter/pyzmq_adapter.rb
204
219
  - lib/iruby/session_adapter/test_adapter.rb
205
220
  - lib/iruby/utils.rb
206
221
  - lib/iruby/version.rb
@@ -213,6 +228,7 @@ files:
213
228
  - test/integration_test.rb
214
229
  - test/iruby/backend_test.rb
215
230
  - test/iruby/command_test.rb
231
+ - test/iruby/display_test.rb
216
232
  - test/iruby/event_manager_test.rb
217
233
  - test/iruby/jupyter_test.rb
218
234
  - test/iruby/kernel_test.rb
@@ -223,11 +239,13 @@ files:
223
239
  - test/iruby/session_adapter/session_adapter_test_base.rb
224
240
  - test/iruby/session_adapter_test.rb
225
241
  - test/iruby/session_test.rb
242
+ - test/iruby/utils_test.rb
226
243
  - test/run-test.rb
227
244
  homepage: https://github.com/SciRuby/iruby
228
245
  licenses:
229
246
  - MIT
230
- metadata: {}
247
+ metadata:
248
+ msys2_mingw_dependencies: zeromq
231
249
  post_install_message:
232
250
  rdoc_options: []
233
251
  require_paths:
@@ -243,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
261
  - !ruby/object:Gem::Version
244
262
  version: '0'
245
263
  requirements: []
246
- rubygems_version: 3.3.0.dev
264
+ rubygems_version: 3.2.23
247
265
  signing_key:
248
266
  specification_version: 4
249
267
  summary: Ruby Kernel for Jupyter
@@ -252,6 +270,7 @@ test_files:
252
270
  - test/integration_test.rb
253
271
  - test/iruby/backend_test.rb
254
272
  - test/iruby/command_test.rb
273
+ - test/iruby/display_test.rb
255
274
  - test/iruby/event_manager_test.rb
256
275
  - test/iruby/jupyter_test.rb
257
276
  - test/iruby/kernel_test.rb
@@ -262,4 +281,5 @@ test_files:
262
281
  - test/iruby/session_adapter/session_adapter_test_base.rb
263
282
  - test/iruby/session_adapter_test.rb
264
283
  - test/iruby/session_test.rb
284
+ - test/iruby/utils_test.rb
265
285
  - test/run-test.rb
@@ -1,62 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- - push
5
- - pull_request
6
-
7
- jobs:
8
- test:
9
- name: Test
10
- runs-on: ${{ matrix.os }}
11
-
12
- strategy:
13
- fail-fast: false
14
- matrix:
15
- os:
16
- - ubuntu-20.04
17
- - ubuntu-latest
18
- ruby:
19
- - 3.0
20
- - 2.7
21
- - 2.6
22
- - 2.5
23
- - 2.4
24
- - 2.3
25
- - debug
26
-
27
- steps:
28
- - uses: actions/checkout@v2
29
- with:
30
- fetch-depth: 1
31
-
32
- - uses: ruby/setup-ruby@v1
33
- with:
34
- ruby-version: ${{ matrix.ruby }}
35
-
36
- - name: Install requirements on ubuntu
37
- run: |
38
- sudo apt install -y --no-install-recommends \
39
- libczmq-dev \
40
- python3 \
41
- python3-pip \
42
- python3-setuptools
43
- sudo pip3 install wheel
44
- sudo pip3 install -r ci/requirements.txt
45
-
46
- - run: gem install bundler
47
-
48
- - run: bundle install --jobs 4 --retry 3
49
-
50
- - name: Run tests
51
- env:
52
- PYTHON: python3
53
- ADAPTERS: cztop ffi-rzmq pyzmq
54
- run: |
55
- for adapter in $ADAPTERS; do
56
- export IRUBY_TEST_SESSION_ADAPTER_NAME=$adapter
57
- bundle exec rake test TESTOPTS=-v
58
- done
59
-
60
- - run: rake build
61
-
62
- - run: gem install pkg/*.gem
@@ -1,77 +0,0 @@
1
- module IRuby
2
- module SessionAdapter
3
- class PyzmqAdapter < BaseAdapter
4
-
5
- class << self
6
- def load_requirements
7
- require 'pycall'
8
- import_pyzmq
9
- end
10
-
11
- def import_pyzmq
12
- @zmq = PyCall.import_module('zmq')
13
- rescue PyCall::PyError => error
14
- raise LoadError, error.message
15
- end
16
-
17
- attr_reader :zmq
18
- end
19
-
20
- def make_router_socket(protocol, host, port)
21
- make_socket(:ROUTER, protocol, host, port)
22
- end
23
-
24
- def make_pub_socket(protocol, host, port)
25
- make_socket(:PUB, protocol, host, port)
26
- end
27
-
28
- def heartbeat_loop(sock)
29
- PyCall.sys.path.append(File.expand_path('../pyzmq', __FILE__))
30
- heartbeat = PyCall.import_module('iruby.heartbeat')
31
- @heartbeat_thread = heartbeat.Heartbeat.new(sock)
32
- @heartbeat_thread.start
33
- end
34
-
35
- private
36
-
37
- def socket_type(type_symbol)
38
- case type_symbol
39
- when :ROUTER, :PUB, :REP
40
- zmq[type_symbol]
41
- else
42
- raise ArgumentError, "Unknown ZMQ socket type: #{type_symbol}"
43
- end
44
- end
45
-
46
- def make_socket(type_symbol, protocol, host, port)
47
- type = socket_type(type_symbol)
48
- sock = zmq_context.socket(type)
49
- bind_socket(sock, protocol, host, port)
50
- sock
51
- end
52
-
53
- def bind_socket(sock, protocol, host, port)
54
- iface = "#{protocol}://#{host}"
55
- case protocol
56
- when 'tcp'
57
- if port <= 0
58
- port = sock.bind_to_random_port(iface)
59
- else
60
- sock.bind("#{iface}:#{port}")
61
- end
62
- else
63
- raise ArgumentError, "Unsupported protocol: #{protocol}"
64
- end
65
- [sock, port]
66
- end
67
-
68
- def zmq_context
69
- zmq.Context.instance
70
- end
71
-
72
- def zmq
73
- self.class.zmq
74
- end
75
- end
76
- end
77
- end