psych 3.1.0 → 3.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)
16
16
  class_loader = ClassLoader.new
17
17
  scanner = ScalarScanner.new class_loader
18
- new(scanner, class_loader)
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)
@@ -124,7 +129,7 @@ module Psych
124
129
  end
125
130
 
126
131
  def visit_Psych_Nodes_Sequence o
127
- if klass = resolve_class(Psych.load_tags[o.tag])
132
+ if klass = resolve_class(@load_tags[o.tag])
128
133
  instance = klass.allocate
129
134
 
130
135
  if instance.respond_to?(:init_with)
@@ -156,8 +161,8 @@ module Psych
156
161
  end
157
162
 
158
163
  def visit_Psych_Nodes_Mapping o
159
- if Psych.load_tags[o.tag]
160
- return revive(resolve_class(Psych.load_tags[o.tag]), o)
164
+ if @load_tags[o.tag]
165
+ return revive(resolve_class(@load_tags[o.tag]), o)
161
166
  end
162
167
  return revive_hash(register(o, {}), o) unless o.tag
163
168
 
@@ -252,6 +257,8 @@ module Psych
252
257
 
253
258
  e = build_exception((resolve_class($1) || class_loader.exception),
254
259
  h.delete('message'))
260
+
261
+ e.set_backtrace h.delete('backtrace') if h.key? 'backtrace'
255
262
  init_with(e, h, o)
256
263
 
257
264
  when '!set', 'tag:yaml.org,2002:set'
@@ -320,6 +327,7 @@ module Psych
320
327
  end
321
328
 
322
329
  private
330
+
323
331
  def register node, object
324
332
  @st[node.anchor] = object if node.anchor
325
333
  object
@@ -331,13 +339,12 @@ module Psych
331
339
  list
332
340
  end
333
341
 
334
- SHOVEL = '<<'
335
- def revive_hash hash, o
342
+ def revive_hash hash, o, tagged= false
336
343
  o.children.each_slice(2) { |k,v|
337
344
  key = accept(k)
338
345
  val = accept(v)
339
346
 
340
- if key == SHOVEL && k.tag != "tag:yaml.org,2002:str"
347
+ if key == '<<' && k.tag != "tag:yaml.org,2002:str"
341
348
  case v
342
349
  when Nodes::Alias, Nodes::Mapping
343
350
  begin
@@ -359,6 +366,12 @@ module Psych
359
366
  hash[key] = val
360
367
  end
361
368
  else
369
+ if !tagged && @symbolize_names && key.is_a?(String)
370
+ key = key.to_sym
371
+ elsif !@freeze
372
+ key = deduplicate(key)
373
+ end
374
+
362
375
  hash[key] = val
363
376
  end
364
377
 
@@ -366,12 +379,32 @@ module Psych
366
379
  hash
367
380
  end
368
381
 
382
+ if RUBY_VERSION < '2.7'
383
+ def deduplicate key
384
+ if key.is_a?(String)
385
+ # It is important to untaint the string, otherwise it won't
386
+ # be deduplicated into an fstring, but simply frozen.
387
+ -(key.untaint)
388
+ else
389
+ key
390
+ end
391
+ end
392
+ else
393
+ def deduplicate key
394
+ if key.is_a?(String)
395
+ -key
396
+ else
397
+ key
398
+ end
399
+ end
400
+ end
401
+
369
402
  def merge_key hash, key, val
370
403
  end
371
404
 
372
405
  def revive klass, node
373
406
  s = register(node, klass.allocate)
374
- init_with(s, revive_hash({}, node), node)
407
+ init_with(s, revive_hash({}, node, true), node)
375
408
  end
376
409
 
377
410
  def init_with o, h, node
@@ -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
@@ -80,7 +80,7 @@ module Psych
80
80
  raise(TypeError, "Can't dump #{target.class}") unless method
81
81
 
82
82
  h[klass] = method
83
- end
83
+ end.compare_by_identity
84
84
  end
85
85
 
86
86
  def start encoding = Nodes::Stream::UTF8
@@ -181,41 +181,11 @@ module Psych
181
181
  end
182
182
 
183
183
  def visit_Exception o
184
- tag = ['!ruby/exception', o.class.name].join ':'
185
-
186
- @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
187
-
188
- {
189
- 'message' => private_iv_get(o, 'mesg'),
190
- 'backtrace' => private_iv_get(o, 'backtrace'),
191
- }.each do |k,v|
192
- next unless v
193
- @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
194
- accept v
195
- end
196
-
197
- dump_ivars o
198
-
199
- @emitter.end_mapping
184
+ dump_exception o, o.message.to_s
200
185
  end
201
186
 
202
187
  def visit_NameError o
203
- tag = ['!ruby/exception', o.class.name].join ':'
204
-
205
- @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
206
-
207
- {
208
- 'message' => o.message.to_s,
209
- 'backtrace' => private_iv_get(o, 'backtrace'),
210
- }.each do |k,v|
211
- next unless v
212
- @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY
213
- accept v
214
- end
215
-
216
- dump_ivars o
217
-
218
- @emitter.end_mapping
188
+ dump_exception o, o.message.to_s
219
189
  end
220
190
 
221
191
  def visit_Regexp o
@@ -458,15 +428,6 @@ module Psych
458
428
  node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)
459
429
  register(o, node)
460
430
 
461
- # Dump the elements
462
- accept 'elements'
463
- @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
464
- o.each do |k,v|
465
- accept k
466
- accept v
467
- end
468
- @emitter.end_mapping
469
-
470
431
  # Dump the ivars
471
432
  accept 'ivars'
472
433
  @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
@@ -476,6 +437,15 @@ module Psych
476
437
  end
477
438
  @emitter.end_mapping
478
439
 
440
+ # Dump the elements
441
+ accept 'elements'
442
+ @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
443
+ o.each do |k,v|
444
+ accept k
445
+ accept v
446
+ end
447
+ @emitter.end_mapping
448
+
479
449
  @emitter.end_mapping
480
450
  else
481
451
  tag = "!ruby/hash:#{o.class}"
@@ -492,6 +462,24 @@ module Psych
492
462
  def dump_list o
493
463
  end
494
464
 
465
+ def dump_exception o, msg
466
+ tag = ['!ruby/exception', o.class.name].join ':'
467
+
468
+ @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK
469
+
470
+ if msg
471
+ @emitter.scalar 'message', nil, nil, true, false, Nodes::Scalar::ANY
472
+ accept msg
473
+ end
474
+
475
+ @emitter.scalar 'backtrace', nil, nil, true, false, Nodes::Scalar::ANY
476
+ accept o.backtrace
477
+
478
+ dump_ivars o
479
+
480
+ @emitter.end_mapping
481
+ end
482
+
495
483
  def format_time time
496
484
  if time.utc?
497
485
  time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
@@ -521,9 +509,9 @@ module Psych
521
509
  def emit_coder c, o
522
510
  case c.type
523
511
  when :scalar
524
- @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, Nodes::Scalar::ANY
512
+ @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, c.style
525
513
  when :seq
526
- @emitter.start_sequence nil, c.tag, c.tag.nil?, Nodes::Sequence::BLOCK
514
+ @emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
527
515
  c.seq.each do |thing|
528
516
  accept thing
529
517
  end
data/psych.gemspec CHANGED
@@ -1,16 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  # frozen_string_literal: true
3
3
 
4
- begin
5
- require_relative 'lib/psych/versions'
6
- rescue LoadError
7
- # for Ruby core repository
8
- require_relative 'versions'
4
+ version_module = Module.new do
5
+ version_rb = File.join(__dir__, "lib/psych/versions.rb")
6
+ module_eval(File.read(version_rb), version_rb)
9
7
  end
10
8
 
11
9
  Gem::Specification.new do |s|
12
10
  s.name = "psych"
13
- s.version = Psych::VERSION
11
+ s.version = version_module::Psych::VERSION
14
12
  s.authors = ["Aaron Patterson", "SHIBATA Hiroshi", "Charles Oliver Nutter"]
15
13
  s.email = ["aaron@tenderlovemaking.com", "hsbt@ruby-lang.org", "headius@headius.com"]
16
14
  s.summary = "Psych is a YAML parser and emitter"
@@ -25,7 +23,7 @@ DESCRIPTION
25
23
 
26
24
  # for ruby core repository. It was generated by `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
25
  s.files = [
28
- ".gitignore", ".travis.yml", "CHANGELOG.rdoc", "Gemfile", "Mavenfile", "README.md", "Rakefile", "bin/console",
26
+ ".gitignore", "Gemfile", "LICENSE", "Mavenfile", "README.md", "Rakefile", "bin/console",
29
27
  "bin/setup", "ext/psych/depend", "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h",
30
28
  "ext/psych/psych_emitter.c", "ext/psych/psych_emitter.h", "ext/psych/psych_parser.c", "ext/psych/psych_parser.h",
31
29
  "ext/psych/psych_to_ruby.c", "ext/psych/psych_to_ruby.h", "ext/psych/psych_yaml_tree.c", "ext/psych/psych_yaml_tree.h",
@@ -45,15 +43,11 @@ DESCRIPTION
45
43
  ]
46
44
 
47
45
  s.rdoc_options = ["--main", "README.md"]
48
- s.extra_rdoc_files = ["CHANGELOG.rdoc", "README.md"]
46
+ s.extra_rdoc_files = ["README.md"]
49
47
 
50
- s.required_ruby_version = Gem::Requirement.new(">= 2.2.2")
51
- s.rubygems_version = "2.5.1"
48
+ s.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
52
49
  s.required_rubygems_version = Gem::Requirement.new(">= 0")
53
50
 
54
- s.add_development_dependency 'rake-compiler', ">= 0.4.1"
55
- s.add_development_dependency 'minitest', "~> 5.0"
56
-
57
51
  if RUBY_ENGINE == 'jruby'
58
52
  s.platform = 'java'
59
53
  s.files.concat [
@@ -65,11 +59,9 @@ DESCRIPTION
65
59
  "lib/psych_jars.rb",
66
60
  "lib/psych.jar"
67
61
  ]
68
- s.requirements = "jar org.yaml:snakeyaml, #{Psych::DEFAULT_SNAKEYAML_VERSION}"
62
+ s.requirements = "jar org.yaml:snakeyaml, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}"
69
63
  s.add_dependency 'jar-dependencies', '>= 0.1.7'
70
- s.add_development_dependency 'ruby-maven'
71
64
  else
72
65
  s.extensions = ["ext/psych/extconf.rb"]
73
- s.add_development_dependency 'rake-compiler-dock', ">= 0.6.3"
74
66
  end
75
67
  end
metadata CHANGED
@@ -1,59 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: psych
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
8
8
  - SHIBATA Hiroshi
9
9
  - Charles Oliver Nutter
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-12-18 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: rake-compiler
17
- requirement: !ruby/object:Gem::Requirement
18
- requirements:
19
- - - ">="
20
- - !ruby/object:Gem::Version
21
- version: 0.4.1
22
- type: :development
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- version: 0.4.1
29
- - !ruby/object:Gem::Dependency
30
- name: minitest
31
- requirement: !ruby/object:Gem::Requirement
32
- requirements:
33
- - - "~>"
34
- - !ruby/object:Gem::Version
35
- version: '5.0'
36
- type: :development
37
- prerelease: false
38
- version_requirements: !ruby/object:Gem::Requirement
39
- requirements:
40
- - - "~>"
41
- - !ruby/object:Gem::Version
42
- version: '5.0'
43
- - !ruby/object:Gem::Dependency
44
- name: rake-compiler-dock
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: 0.6.3
50
- type: :development
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: 0.6.3
13
+ date: 2021-05-13 00:00:00.000000000 Z
14
+ dependencies: []
57
15
  description: |
58
16
  Psych is a YAML parser and emitter. Psych leverages libyaml[https://pyyaml.org/wiki/LibYAML]
59
17
  for its YAML parsing and emitting capabilities. In addition to wrapping libyaml,
@@ -66,13 +24,11 @@ executables: []
66
24
  extensions:
67
25
  - ext/psych/extconf.rb
68
26
  extra_rdoc_files:
69
- - CHANGELOG.rdoc
70
27
  - README.md
71
28
  files:
72
29
  - ".gitignore"
73
- - ".travis.yml"
74
- - CHANGELOG.rdoc
75
30
  - Gemfile
31
+ - LICENSE
76
32
  - Mavenfile
77
33
  - README.md
78
34
  - Rakefile
@@ -144,7 +100,7 @@ homepage: https://github.com/ruby/psych
144
100
  licenses:
145
101
  - MIT
146
102
  metadata: {}
147
- post_install_message:
103
+ post_install_message:
148
104
  rdoc_options:
149
105
  - "--main"
150
106
  - README.md
@@ -154,16 +110,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
154
110
  requirements:
155
111
  - - ">="
156
112
  - !ruby/object:Gem::Version
157
- version: 2.2.2
113
+ version: 2.4.0
158
114
  required_rubygems_version: !ruby/object:Gem::Requirement
159
115
  requirements:
160
116
  - - ">="
161
117
  - !ruby/object:Gem::Version
162
118
  version: '0'
163
119
  requirements: []
164
- rubyforge_project:
165
- rubygems_version: 2.7.6
166
- signing_key:
120
+ rubygems_version: 3.3.0.dev
121
+ signing_key:
167
122
  specification_version: 4
168
123
  summary: Psych is a YAML parser and emitter
169
124
  test_files: []