iruby 0.7.0 → 0.7.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14aea673b75a6fe8884eff08c52b8831bbcec141df2525ed4c0a877738654271
4
- data.tar.gz: 89e5e091e67b7ef85f98ca0cb9ebe65cef0e32aacd75351c81b0c287666939c0
3
+ metadata.gz: 11ac6e3f7e6588a384c9f149d6c3fe4060b7cea7d1ff6461c3ea1acc8cadebf6
4
+ data.tar.gz: 4c57af32989ee7a9d7671220647279f727021d9e6d29f9d40bf1bed0e0fc4ec0
5
5
  SHA512:
6
- metadata.gz: 53b824e32c52cbf2893b24310ba4d3c7caa52ec872f36f57644a95bdd139232b4b5e032f161fb86baf94d011964caf9d739a4795af6805fd174360ed866477fa
7
- data.tar.gz: ee663bca3c4a67730d73e709c24d827af73e7c58734afe4dffc22c685c909462e9c9113f9548a8f1c8b5ce33b0b94338386b24c07978db547fab1caa21828ea7
6
+ metadata.gz: a1d623a6b5b4e46c2845048241fa6abfd535d72e648fd431f42c21c7f895f72f29b2443d74339342e83c5017040ff5f55ff4b0442909649b1ef0afb452c0ba20
7
+ data.tar.gz: '0394ca9c46e802a2532534058acc3af98c6e93e62a60cc035977af441c61145cfda13b224f8f1da1a8b90b48159f6aa858da7c939db2fed4f4329dcd5f2e9ea0'
@@ -1,8 +1,14 @@
1
1
  name: CI
2
2
 
3
3
  on:
4
- - push
5
- - pull_request
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+ types:
9
+ - opened
10
+ - synchronize
11
+ - reopened
6
12
 
7
13
  jobs:
8
14
  test:
@@ -35,6 +41,7 @@ jobs:
35
41
 
36
42
  - name: Install requirements on ubuntu
37
43
  run: |
44
+ sudo apt update
38
45
  sudo apt install -y --no-install-recommends \
39
46
  libczmq-dev \
40
47
  python3 \
data/CHANGES.md CHANGED
@@ -1,3 +1,14 @@
1
+ # 0.7.1 (2021-06-21)
2
+
3
+ ## Enhancements
4
+
5
+ * Add support of `to_iruby_mimebundle` format method https://github.com/SciRuby/iruby/pull/304 (@mrkn)
6
+
7
+ ## Bug Fixes
8
+
9
+ * Prevent unintentional display the result of Session#send (@mrkn)
10
+ * Update display formatter for Gruff::Base to prevent warning (@mrkn)
11
+
1
12
  # 0.7.0 (2021-05-28)
2
13
 
3
14
  ## Enhancements
@@ -7,9 +18,14 @@
7
18
 
8
19
  ## Bug Fixes
9
20
 
10
- * Follow the messages and hooks orders during execute_request processing (@mrkn)
11
21
  * Fix the handling of image/svg+xml https://github.com/SciRuby/iruby/pull/300, https://github.com/SciRuby/iruby/pull/301 (@kojix2)
12
22
 
23
+ # 0.6.1 (2021-05-26)
24
+
25
+ ## Bug Fixes
26
+
27
+ * Follow the messages and hooks orders during execute_request processing (@mrkn)
28
+
13
29
  # 0.6.0 (2021-05-25)
14
30
 
15
31
  ## Bug Fixes
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,41 @@ 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 = render_mimebundle(obj, exact_mime, fuzzy_mime)
44
+
45
+ # Render by additional formatters
46
+ render_by_registry(data, obj, exact_mime, fuzzy_mime)
47
+
48
+ # Render by to_xxx methods
49
+ DEFAULT_MIME_TYPE_FORMAT_METHODS.each do |mime, methods|
50
+ next if mime.nil? && !data.empty? # for to_iruby
51
+
52
+ next if mime && data.key?(mime) # do not overwrite
53
+
54
+ method = Array(methods).find {|m| obj.respond_to?(m) }
55
+ next if method.nil?
56
+
57
+ result = obj.send(method)
58
+ case mime
59
+ when nil # to_iruby
60
+ case result
61
+ when nil
62
+ # do nothing
63
+ next
64
+ when Array
65
+ mime, result = result
66
+ else
67
+ warn(("Ignore the result of to_iruby method of %p because " +
68
+ "it does not return a pair of mime-type and formatted representation") % obj)
69
+ next
70
+ end
71
+ end
72
+ data[mime] = result
73
+ end
34
74
 
35
75
  # As a last resort, interpret string representation of the object
36
76
  # as the given mime type.
37
- if exact_mime && data.none? { |m, _| exact_mime == m }
77
+ if exact_mime && !data.key?(exact_mime)
38
78
  data[exact_mime] = protect(exact_mime, obj)
39
79
  end
40
80
 
@@ -67,7 +107,21 @@ module IRuby
67
107
  end
68
108
  end
69
109
 
70
- def render(data, obj, exact_mime, fuzzy_mime)
110
+ private def render_mimebundle(obj, exact_mime, fuzzy_mime)
111
+ data = {}
112
+ if obj.respond_to?(:to_iruby_mimebundle)
113
+ include_mime = [exact_mime].compact
114
+ formats, metadata = obj.to_iruby_mimebundle(include: include_mime)
115
+ formats.each do |mime, value|
116
+ if fuzzy_mime.nil? || mime.include?(fuzzy_mime)
117
+ data[mime] = value
118
+ end
119
+ end
120
+ end
121
+ data
122
+ end
123
+
124
+ private def render_by_registry(data, obj, exact_mime, fuzzy_mime)
71
125
  # Filter matching renderer by object type
72
126
  renderer = Registry.renderer.select { |r| r.match?(obj) }
73
127
 
@@ -88,6 +142,8 @@ module IRuby
88
142
  # Return first render result which has the right mime type
89
143
  renderer.each do |r|
90
144
  mime, result = r.render(obj)
145
+ next if data.key?(mime)
146
+
91
147
  if mime && result && (!exact_mime || exact_mime == mime) && (!fuzzy_mime || mime.include?(fuzzy_mime))
92
148
  data[mime] = protect(mime, result)
93
149
  break
@@ -98,6 +154,19 @@ module IRuby
98
154
  end
99
155
  end
100
156
 
157
+ private def render_by_to_iruby(data, obj)
158
+ if obj.respond_to?(:to_iruby)
159
+ result = obj.to_iruby
160
+ mime, rep = case result
161
+ when Array
162
+ result
163
+ else
164
+ [nil, result]
165
+ end
166
+ data[mime] = rep
167
+ end
168
+ end
169
+
101
170
  class Representation
102
171
  attr_reader :object, :options
103
172
 
@@ -120,6 +189,60 @@ module IRuby
120
189
  end
121
190
  end
122
191
 
192
+ class FormatMatcher
193
+ def initialize(&block)
194
+ @block = block
195
+ end
196
+
197
+ def call(obj)
198
+ @block.(obj)
199
+ end
200
+
201
+ def inspect
202
+ "#{self.class.name}[%p]" % @block
203
+ end
204
+ end
205
+
206
+ class RespondToFormatMatcher < FormatMatcher
207
+ def initialize(name)
208
+ super() {|obj| obj.respond_to?(name) }
209
+ @name = name
210
+ end
211
+
212
+ attr_reader :name
213
+
214
+ def inspect
215
+ "#{self.class.name}[respond_to?(%p)]" % name
216
+ end
217
+ end
218
+
219
+ class TypeFormatMatcher < FormatMatcher
220
+ def initialize(class_block)
221
+ super() do |obj|
222
+ begin
223
+ self.klass === obj
224
+ # We have to rescue all exceptions since constant autoloading could fail with a different error
225
+ rescue Exception
226
+ false
227
+ end
228
+ end
229
+ @class_block = class_block
230
+ end
231
+
232
+ def klass
233
+ @class_block.()
234
+ end
235
+
236
+ def inspect
237
+ klass = begin
238
+ @class_block.()
239
+ rescue Exception
240
+ @class_block
241
+ end
242
+ "#{self.class.name}[%p]" % klass
243
+ end
244
+ end
245
+
123
246
  class Renderer
124
247
  attr_reader :match, :mime, :priority
125
248
 
@@ -147,37 +270,22 @@ module IRuby
147
270
  @renderer ||= []
148
271
  end
149
272
 
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
273
  def match(&block)
162
- @match = block
274
+ @match = FormatMatcher.new(&block)
163
275
  priority 0
164
276
  nil
165
277
  end
166
278
 
167
279
  def respond_to(name)
168
- match { |obj| obj.respond_to?(name) }
280
+ @match = RespondToFormatMatcher.new(name)
281
+ priority 0
282
+ nil
169
283
  end
170
284
 
171
285
  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
286
+ @match = TypeFormatMatcher.new(block)
287
+ priority 0
288
+ nil
181
289
  end
182
290
 
183
291
  def priority(p)
@@ -275,13 +383,24 @@ module IRuby
275
383
  end
276
384
  end
277
385
 
386
+ format_magick_image = ->(obj) do
387
+ format = obj.format || 'PNG'
388
+ [
389
+ format == 'PNG' ? 'image/png' : 'image/jpeg',
390
+ obj.to_blob {|i| i.format = format }
391
+ ]
392
+ end
393
+
278
394
  match do |obj|
279
395
  defined?(Magick::Image) && Magick::Image === obj ||
280
396
  defined?(MiniMagick::Image) && MiniMagick::Image === obj
281
397
  end
398
+ format 'image', &format_magick_image
399
+
400
+ type { Gruff::Base }
282
401
  format 'image' do |obj|
283
- format = obj.format || 'PNG'
284
- [format == 'PNG' ? 'image/png' : 'image/jpeg', obj.to_blob { |i| i.format = format }]
402
+ image = obj.to_image
403
+ format_magick_image.(obj.to_image)
285
404
  end
286
405
 
287
406
  match do |obj|
@@ -298,39 +417,19 @@ module IRuby
298
417
  end
299
418
  end
300
419
 
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
420
+ type { Rubyvis::Mark }
317
421
  format 'image/svg+xml' do |obj|
318
- obj.render if defined?(Rubyvis) && Rubyvis::Mark === obj
422
+ obj.render
319
423
  obj.to_svg
320
424
  end
321
425
 
322
- respond_to :to_iruby
323
- format(&:to_iruby)
324
-
325
426
  match { |obj| obj.respond_to?(:path) && obj.method(:path).arity == 0 && File.readable?(obj.path) }
326
427
  format do |obj|
327
428
  mime = MIME::Types.of(obj.path).first.to_s
328
- [mime, File.read(obj.path)] if SUPPORTED_MIMES.include?(mime)
429
+ if mime && DEFAULT_MIME_TYPE_FORMAT_METHODS.key?(mime)
430
+ [mime, File.read(obj.path)]
431
+ end
329
432
  end
330
-
331
- type { Object }
332
- priority(-1000)
333
- format 'text/plain', &:inspect
334
433
  end
335
434
  end
336
435
  end
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
data/lib/iruby/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module IRuby
2
- VERSION = '0.7.0'
2
+ VERSION = '0.7.1'
3
3
  end
@@ -0,0 +1,188 @@
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/html", "text/markdown", "application/json"]
63
+ else
64
+ include
65
+ end
66
+ formats = mimes.map { |mime|
67
+ result = case mime
68
+ when "text/html"
69
+ "<i>html</i>"
70
+ when "text/markdown"
71
+ "**markdown**"
72
+ when "application/json"
73
+ %Q[{"mimebundle": "json"}]
74
+ end
75
+ [mime, result]
76
+ }.to_h
77
+ metadata = {}
78
+ return formats, metadata
79
+ end
80
+ end
81
+ end
82
+
83
+ def assert_iruby_display(expected)
84
+ assert_equal(expected,
85
+ {
86
+ result: IRuby::Display.display(@object),
87
+ to_html_called: @object.to_html_called,
88
+ to_markdown_called: @object.to_markdown_called,
89
+ to_iruby_called: @object.to_iruby_called,
90
+ to_iruby_mimebundle_called: @object.to_iruby_mimebundle_called
91
+ })
92
+ end
93
+
94
+ sub_test_case("the object cannot handle all the mime types") do
95
+ def test_display
96
+ assert_iruby_display({
97
+ result: {"text/plain" => "!!! inspect !!!"},
98
+ to_html_called: false,
99
+ to_markdown_called: false,
100
+ to_iruby_called: false,
101
+ to_iruby_mimebundle_called: false
102
+ })
103
+ end
104
+ end
105
+
106
+ sub_test_case("the object can respond to to_iruby") do
107
+ def setup
108
+ super
109
+ define_to_iruby
110
+ end
111
+
112
+ def test_display
113
+ assert_iruby_display({
114
+ result: {
115
+ "text/html" => "<b>to_iruby</b>",
116
+ "text/plain" => "!!! inspect !!!"
117
+ },
118
+ to_html_called: false,
119
+ to_markdown_called: false,
120
+ to_iruby_called: true,
121
+ to_iruby_mimebundle_called: false
122
+ })
123
+ end
124
+
125
+ sub_test_case("the object can respond to to_markdown") do
126
+ def setup
127
+ super
128
+ define_to_markdown
129
+ end
130
+
131
+ def test_display
132
+ assert_iruby_display({
133
+ result: {
134
+ "text/markdown" => "*markdown*",
135
+ "text/plain" => "!!! inspect !!!"
136
+ },
137
+ to_html_called: false,
138
+ to_markdown_called: true,
139
+ to_iruby_called: false,
140
+ to_iruby_mimebundle_called: false
141
+ })
142
+ end
143
+ end
144
+
145
+ sub_test_case("the object can respond to to_html") do
146
+ def setup
147
+ super
148
+ define_to_html
149
+ end
150
+
151
+ def test_display
152
+ assert_iruby_display({
153
+ result: {
154
+ "text/html" => "<b>html</b>",
155
+ "text/plain" => "!!! inspect !!!"
156
+ },
157
+ to_html_called: true,
158
+ to_markdown_called: false,
159
+ to_iruby_called: false,
160
+ to_iruby_mimebundle_called: false
161
+ })
162
+ end
163
+
164
+ sub_test_case("the object can respond to to_iruby_mimebundle") do
165
+ def setup
166
+ super
167
+ define_to_iruby_mimebundle
168
+ end
169
+
170
+ def test_display
171
+ assert_iruby_display({
172
+ result: {
173
+ "text/html" => "<i>html</i>",
174
+ "text/markdown" => "**markdown**",
175
+ "application/json" => %Q[{"mimebundle": "json"}],
176
+ "text/plain" => "!!! inspect !!!"
177
+ },
178
+ to_html_called: false,
179
+ to_markdown_called: false,
180
+ to_iruby_called: false,
181
+ to_iruby_mimebundle_called: true
182
+ })
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+ 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.1
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-06-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: data_uri
@@ -213,6 +213,7 @@ files:
213
213
  - test/integration_test.rb
214
214
  - test/iruby/backend_test.rb
215
215
  - test/iruby/command_test.rb
216
+ - test/iruby/display_test.rb
216
217
  - test/iruby/event_manager_test.rb
217
218
  - test/iruby/jupyter_test.rb
218
219
  - test/iruby/kernel_test.rb
@@ -243,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
244
  - !ruby/object:Gem::Version
244
245
  version: '0'
245
246
  requirements: []
246
- rubygems_version: 3.3.0.dev
247
+ rubygems_version: 3.2.3
247
248
  signing_key:
248
249
  specification_version: 4
249
250
  summary: Ruby Kernel for Jupyter
@@ -252,6 +253,7 @@ test_files:
252
253
  - test/integration_test.rb
253
254
  - test/iruby/backend_test.rb
254
255
  - test/iruby/command_test.rb
256
+ - test/iruby/display_test.rb
255
257
  - test/iruby/event_manager_test.rb
256
258
  - test/iruby/jupyter_test.rb
257
259
  - test/iruby/kernel_test.rb