psych 2.2.1 → 5.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/CONTRIBUTING.md +24 -0
  3. data/{ext/psych/yaml/LICENSE → LICENSE} +9 -7
  4. data/README.md +13 -13
  5. data/ext/psych/depend +14 -0
  6. data/ext/psych/extconf.rb +43 -29
  7. data/ext/psych/psych.c +6 -3
  8. data/ext/psych/psych_emitter.c +10 -9
  9. data/ext/psych/psych_parser.c +69 -72
  10. data/ext/psych/psych_yaml_tree.c +0 -12
  11. data/lib/psych/class_loader.rb +11 -9
  12. data/lib/psych/coder.rb +1 -1
  13. data/lib/psych/core_ext.rb +3 -20
  14. data/lib/psych/exception.rb +17 -3
  15. data/lib/psych/handler.rb +8 -3
  16. data/lib/psych/handlers/document_stream.rb +2 -2
  17. data/lib/psych/handlers/recorder.rb +2 -2
  18. data/lib/psych/json/ruby_events.rb +1 -1
  19. data/lib/psych/json/stream.rb +3 -3
  20. data/lib/psych/json/tree_builder.rb +2 -2
  21. data/lib/psych/json/yaml_events.rb +1 -1
  22. data/lib/psych/nodes/alias.rb +3 -1
  23. data/lib/psych/nodes/document.rb +3 -1
  24. data/lib/psych/nodes/mapping.rb +3 -1
  25. data/lib/psych/nodes/node.rb +24 -5
  26. data/lib/psych/nodes/scalar.rb +4 -2
  27. data/lib/psych/nodes/sequence.rb +3 -1
  28. data/lib/psych/nodes/stream.rb +3 -1
  29. data/lib/psych/nodes.rb +8 -8
  30. data/lib/psych/omap.rb +1 -1
  31. data/lib/psych/parser.rb +14 -1
  32. data/lib/psych/scalar_scanner.rb +39 -47
  33. data/lib/psych/set.rb +1 -1
  34. data/lib/psych/stream.rb +1 -1
  35. data/lib/psych/streaming.rb +1 -1
  36. data/lib/psych/syntax_error.rb +2 -2
  37. data/lib/psych/tree_builder.rb +48 -8
  38. data/lib/psych/versions.rb +5 -4
  39. data/lib/psych/visitors/depth_first.rb +1 -1
  40. data/lib/psych/visitors/emitter.rb +1 -1
  41. data/lib/psych/visitors/json_tree.rb +2 -2
  42. data/lib/psych/visitors/to_ruby.rb +61 -31
  43. data/lib/psych/visitors/visitor.rb +18 -4
  44. data/lib/psych/visitors/yaml_tree.rb +111 -123
  45. data/lib/psych/visitors.rb +7 -7
  46. data/lib/psych/y.rb +1 -1
  47. data/lib/psych.rb +333 -96
  48. metadata +16 -52
  49. data/.gitignore +0 -14
  50. data/.travis.yml +0 -18
  51. data/CHANGELOG.rdoc +0 -576
  52. data/Gemfile +0 -3
  53. data/Mavenfile +0 -7
  54. data/Rakefile +0 -33
  55. data/bin/console +0 -7
  56. data/bin/setup +0 -6
  57. data/ext/psych/.gitignore +0 -11
  58. data/ext/psych/yaml/api.c +0 -1392
  59. data/ext/psych/yaml/config.h +0 -10
  60. data/ext/psych/yaml/dumper.c +0 -394
  61. data/ext/psych/yaml/emitter.c +0 -2329
  62. data/ext/psych/yaml/loader.c +0 -444
  63. data/ext/psych/yaml/parser.c +0 -1374
  64. data/ext/psych/yaml/reader.c +0 -469
  65. data/ext/psych/yaml/scanner.c +0 -3576
  66. data/ext/psych/yaml/writer.c +0 -141
  67. data/ext/psych/yaml/yaml.h +0 -1971
  68. data/ext/psych/yaml/yaml_private.h +0 -662
  69. data/lib/psych/deprecated.rb +0 -86
  70. data/psych.gemspec +0 -43
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: false
2
- require 'psych/handler'
1
+ # frozen_string_literal: true
2
+ require_relative 'handler'
3
3
 
4
4
  module Psych
5
5
  ###
@@ -23,23 +23,38 @@ module Psych
23
23
  @stack = []
24
24
  @last = nil
25
25
  @root = nil
26
+
27
+ @start_line = nil
28
+ @start_column = nil
29
+ @end_line = nil
30
+ @end_column = nil
31
+ end
32
+
33
+ def event_location(start_line, start_column, end_line, end_column)
34
+ @start_line = start_line
35
+ @start_column = start_column
36
+ @end_line = end_line
37
+ @end_column = end_column
26
38
  end
27
39
 
28
40
  %w{
29
41
  Sequence
30
42
  Mapping
31
43
  }.each do |node|
32
- class_eval %{
44
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
33
45
  def start_#{node.downcase}(anchor, tag, implicit, style)
34
46
  n = Nodes::#{node}.new(anchor, tag, implicit, style)
47
+ set_start_location(n)
35
48
  @last.children << n
36
49
  push n
37
50
  end
38
51
 
39
52
  def end_#{node.downcase}
40
- pop
53
+ n = pop
54
+ set_end_location(n)
55
+ n
41
56
  end
42
- }
57
+ RUBY
43
58
  end
44
59
 
45
60
  ###
@@ -49,6 +64,7 @@ module Psych
49
64
  # See Psych::Handler#start_document
50
65
  def start_document version, tag_directives, implicit
51
66
  n = Nodes::Document.new version, tag_directives, implicit
67
+ set_start_location(n)
52
68
  @last.children << n
53
69
  push n
54
70
  end
@@ -60,26 +76,35 @@ module Psych
60
76
  # See Psych::Handler#start_document
61
77
  def end_document implicit_end = !streaming?
62
78
  @last.implicit_end = implicit_end
63
- pop
79
+ n = pop
80
+ set_end_location(n)
81
+ n
64
82
  end
65
83
 
66
84
  def start_stream encoding
67
85
  @root = Nodes::Stream.new(encoding)
86
+ set_start_location(@root)
68
87
  push @root
69
88
  end
70
89
 
71
90
  def end_stream
72
- pop
91
+ n = pop
92
+ set_end_location(n)
93
+ n
73
94
  end
74
95
 
75
96
  def scalar value, anchor, tag, plain, quoted, style
76
97
  s = Nodes::Scalar.new(value,anchor,tag,plain,quoted,style)
98
+ set_location(s)
77
99
  @last.children << s
78
100
  s
79
101
  end
80
102
 
81
103
  def alias anchor
82
- @last.children << Nodes::Alias.new(anchor)
104
+ a = Nodes::Alias.new(anchor)
105
+ set_location(a)
106
+ @last.children << a
107
+ a
83
108
  end
84
109
 
85
110
  private
@@ -93,5 +118,20 @@ module Psych
93
118
  @last = @stack.last
94
119
  x
95
120
  end
121
+
122
+ def set_location(node)
123
+ set_start_location(node)
124
+ set_end_location(node)
125
+ end
126
+
127
+ def set_start_location(node)
128
+ node.start_line = @start_line
129
+ node.start_column = @start_column
130
+ end
131
+
132
+ def set_end_location(node)
133
+ node.end_line = @end_line
134
+ node.end_column = @end_column
135
+ end
96
136
  end
97
137
  end
@@ -1,9 +1,10 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
+
2
3
  module Psych
3
- # The version is Psych you're using
4
- VERSION = '2.2.1'
4
+ # The version of Psych you are using
5
+ VERSION = '5.1.2'
5
6
 
6
7
  if RUBY_ENGINE == 'jruby'
7
- DEFAULT_SNAKEYAML_VERSION = '1.17'.freeze
8
+ DEFAULT_SNAKEYAML_VERSION = '2.7'.freeze
8
9
  end
9
10
  end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  module Psych
3
3
  module Visitors
4
4
  class DepthFirst < Psych::Visitors::Visitor
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  module Psych
3
3
  module Visitors
4
4
  class Emitter < Psych::Visitors::Visitor
@@ -1,5 +1,5 @@
1
- # frozen_string_literal: false
2
- require 'psych/json/ruby_events'
1
+ # frozen_string_literal: true
2
+ require_relative '../json/ruby_events'
3
3
 
4
4
  module Psych
5
5
  module Visitors
@@ -1,7 +1,7 @@
1
- # frozen_string_literal: false
2
- require 'psych/scalar_scanner'
3
- require 'psych/class_loader'
4
- require 'psych/exception'
1
+ # frozen_string_literal: true
2
+ require_relative '../scalar_scanner'
3
+ require_relative '../class_loader'
4
+ require_relative '../exception'
5
5
 
6
6
  unless defined?(Regexp::NOENCODING)
7
7
  Regexp::NOENCODING = 32
@@ -12,39 +12,44 @@ module Psych
12
12
  ###
13
13
  # This class walks a YAML AST, converting each node to Ruby
14
14
  class ToRuby < Psych::Visitors::Visitor
15
- def self.create
15
+ def self.create(symbolize_names: false, freeze: false, strict_integer: false)
16
16
  class_loader = ClassLoader.new
17
- scanner = ScalarScanner.new class_loader
18
- new(scanner, class_loader)
17
+ scanner = ScalarScanner.new class_loader, strict_integer: strict_integer
18
+ new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze)
19
19
  end
20
20
 
21
21
  attr_reader :class_loader
22
22
 
23
- def initialize ss, class_loader
23
+ def initialize ss, class_loader, symbolize_names: false, freeze: false
24
24
  super()
25
25
  @st = {}
26
26
  @ss = ss
27
+ @load_tags = Psych.load_tags
27
28
  @domain_types = Psych.domain_types
28
29
  @class_loader = class_loader
30
+ @symbolize_names = symbolize_names
31
+ @freeze = freeze
29
32
  end
30
33
 
31
34
  def accept target
32
35
  result = super
33
- return result if @domain_types.empty? || !target.tag
34
36
 
35
- key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:')
36
- key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/
37
+ unless @domain_types.empty? || !target.tag
38
+ key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:')
39
+ key = "tag:#{key}" unless key =~ /^(?:tag:|x-private)/
37
40
 
38
- if @domain_types.key? key
39
- value, block = @domain_types[key]
40
- return block.call value, result
41
+ if @domain_types.key? key
42
+ value, block = @domain_types[key]
43
+ result = block.call value, result
44
+ end
41
45
  end
42
46
 
47
+ result = deduplicate(result).freeze if @freeze
43
48
  result
44
49
  end
45
50
 
46
51
  def deserialize o
47
- if klass = resolve_class(Psych.load_tags[o.tag])
52
+ if klass = resolve_class(@load_tags[o.tag])
48
53
  instance = klass.allocate
49
54
 
50
55
  if instance.respond_to?(:init_with)
@@ -75,7 +80,9 @@ module Psych
75
80
  when "!ruby/object:DateTime"
76
81
  class_loader.date_time
77
82
  require 'date' unless defined? DateTime
78
- @ss.parse_time(o.value).to_datetime
83
+ t = @ss.parse_time(o.value)
84
+ DateTime.civil(*t.to_a[0, 6].reverse, Rational(t.utc_offset, 86400)) +
85
+ (t.subsec/86400)
79
86
  when '!ruby/encoding'
80
87
  ::Encoding.find o.value
81
88
  when "!ruby/object:Complex"
@@ -94,7 +101,7 @@ module Psych
94
101
  source = $1
95
102
  options = 0
96
103
  lang = nil
97
- ($2 || '').split('').each do |option|
104
+ $2&.each_char do |option|
98
105
  case option
99
106
  when 'x' then options |= Regexp::EXTENDED
100
107
  when 'i' then options |= Regexp::IGNORECASE
@@ -124,7 +131,7 @@ module Psych
124
131
  end
125
132
 
126
133
  def visit_Psych_Nodes_Sequence o
127
- if klass = resolve_class(Psych.load_tags[o.tag])
134
+ if klass = resolve_class(@load_tags[o.tag])
128
135
  instance = klass.allocate
129
136
 
130
137
  if instance.respond_to?(:init_with)
@@ -156,8 +163,8 @@ module Psych
156
163
  end
157
164
 
158
165
  def visit_Psych_Nodes_Mapping o
159
- if Psych.load_tags[o.tag]
160
- return revive(resolve_class(Psych.load_tags[o.tag]), o)
166
+ if @load_tags[o.tag]
167
+ return revive(resolve_class(@load_tags[o.tag]), o)
161
168
  end
162
169
  return revive_hash(register(o, {}), o) unless o.tag
163
170
 
@@ -252,6 +259,8 @@ module Psych
252
259
 
253
260
  e = build_exception((resolve_class($1) || class_loader.exception),
254
261
  h.delete('message'))
262
+
263
+ e.set_backtrace h.delete('backtrace') if h.key? 'backtrace'
255
264
  init_with(e, h, o)
256
265
 
257
266
  when '!set', 'tag:yaml.org,2002:set'
@@ -316,10 +325,11 @@ module Psych
316
325
  end
317
326
 
318
327
  def visit_Psych_Nodes_Alias o
319
- @st.fetch(o.anchor) { raise BadAlias, "Unknown alias: #{o.anchor}" }
328
+ @st.fetch(o.anchor) { raise AnchorNotDefined, o.anchor }
320
329
  end
321
330
 
322
331
  private
332
+
323
333
  def register node, object
324
334
  @st[node.anchor] = object if node.anchor
325
335
  object
@@ -331,13 +341,12 @@ module Psych
331
341
  list
332
342
  end
333
343
 
334
- SHOVEL = '<<'
335
- def revive_hash hash, o
344
+ def revive_hash hash, o, tagged= false
336
345
  o.children.each_slice(2) { |k,v|
337
346
  key = accept(k)
338
347
  val = accept(v)
339
348
 
340
- if key == SHOVEL && k.tag != "tag:yaml.org,2002:str"
349
+ if key == '<<' && k.tag != "tag:yaml.org,2002:str"
341
350
  case v
342
351
  when Nodes::Alias, Nodes::Mapping
343
352
  begin
@@ -359,6 +368,12 @@ module Psych
359
368
  hash[key] = val
360
369
  end
361
370
  else
371
+ if !tagged && @symbolize_names && key.is_a?(String)
372
+ key = key.to_sym
373
+ elsif !@freeze
374
+ key = deduplicate(key)
375
+ end
376
+
362
377
  hash[key] = val
363
378
  end
364
379
 
@@ -366,12 +381,32 @@ module Psych
366
381
  hash
367
382
  end
368
383
 
384
+ if RUBY_VERSION < '2.7'
385
+ def deduplicate key
386
+ if key.is_a?(String)
387
+ # It is important to untaint the string, otherwise it won't
388
+ # be deduplicated into an fstring, but simply frozen.
389
+ -(key.untaint)
390
+ else
391
+ key
392
+ end
393
+ end
394
+ else
395
+ def deduplicate key
396
+ if key.is_a?(String)
397
+ -key
398
+ else
399
+ key
400
+ end
401
+ end
402
+ end
403
+
369
404
  def merge_key hash, key, val
370
405
  end
371
406
 
372
407
  def revive klass, node
373
408
  s = register(node, klass.allocate)
374
- init_with(s, revive_hash({}, node), node)
409
+ init_with(s, revive_hash({}, node, true), node)
375
410
  end
376
411
 
377
412
  def init_with o, h, node
@@ -380,11 +415,6 @@ module Psych
380
415
 
381
416
  if o.respond_to?(:init_with)
382
417
  o.init_with c
383
- elsif o.respond_to?(:yaml_initialize)
384
- if $VERBOSE
385
- warn "Implementing #{o.class}#yaml_initialize is deprecated, please implement \"init_with(coder)\""
386
- end
387
- o.yaml_initialize c.tag, c.map
388
418
  else
389
419
  h.each { |k,v| o.instance_variable_set(:"@#{k}", v) }
390
420
  end
@@ -399,7 +429,7 @@ module Psych
399
429
 
400
430
  class NoAliasRuby < ToRuby
401
431
  def visit_Psych_Nodes_Alias o
402
- raise BadAlias, "Unknown alias: #{o.anchor}"
432
+ raise AliasesNotEnabled
403
433
  end
404
434
  end
405
435
  end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  module Psych
3
3
  module Visitors
4
4
  class Visitor
@@ -8,12 +8,26 @@ module Psych
8
8
 
9
9
  private
10
10
 
11
- DISPATCH = Hash.new do |hash, klass|
12
- hash[klass] = "visit_#{klass.name.gsub('::', '_')}"
11
+ # @api private
12
+ def self.dispatch_cache
13
+ Hash.new do |hash, klass|
14
+ hash[klass] = :"visit_#{klass.name.gsub('::', '_')}"
15
+ end.compare_by_identity
16
+ end
17
+
18
+ if defined?(Ractor)
19
+ def dispatch
20
+ @dispatch_cache ||= (Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache)
21
+ end
22
+ else
23
+ DISPATCH = dispatch_cache
24
+ def dispatch
25
+ DISPATCH
26
+ end
13
27
  end
14
28
 
15
29
  def visit target
16
- send DISPATCH[target.class], target
30
+ send dispatch[target.class], target
17
31
  end
18
32
  end
19
33
  end