psych 5.2.4 → 5.2.5

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: 459c567be3d6ef6cb06cab52abb277a79f2f631da2944bd15622f23fdd3b1dec
4
- data.tar.gz: 72aff05916df6027d69d9fe22562c5f5b700066f9d00670445450cdd2939ce4d
3
+ metadata.gz: b96aafb2908bc47d791319d79b9dbf2ae5fa68001abf115afbe6366bcf27597e
4
+ data.tar.gz: c9d309b97bdc0355bbe43b9bee36baa06f8562ada6d906e1e5706606cb077a30
5
5
  SHA512:
6
- metadata.gz: 87e6d5b1fa471069209207f4bca47d5b3158ce4d2909f18a497cb0b7b9b6d76e086553dc905e5b9fc92e5f620c1571db1db87531f8ba9fcbb2b685c12774d3df
7
- data.tar.gz: d837ad140affbd97a8a6d4c6d7088d30f907cc0c5c7743367801b2fd8d2e8f0683f53a0e187541e6eee296b0c3fd5a69ad758b841e88548265e39a550eef29ef
6
+ metadata.gz: '0988012dbedddbf185d5760497e3bf5b283aa0cf57967b67104c1719fe260371139200ee826e6ee78d6b18f5dc9f3a9f5c76f5d4201db4e15e45ae1deee44082'
7
+ data.tar.gz: 6d2ed9e723c945078cf75aa7862d833086e9161336379d5a636da385955c8106e147f68a4bf76ee590cea4be9ed48e1b2ba9a08f02ff2aac6c04f113abce4ae9
@@ -24,6 +24,15 @@ static VALUE path2class(VALUE self, VALUE path)
24
24
  return rb_path_to_class(path);
25
25
  }
26
26
 
27
+ static VALUE init_struct(VALUE self, VALUE data, VALUE attrs)
28
+ {
29
+ VALUE args = rb_ary_new2(1);
30
+ rb_ary_push(args, attrs);
31
+ rb_struct_initialize(data, args);
32
+
33
+ return data;
34
+ }
35
+
27
36
  void Init_psych_to_ruby(void)
28
37
  {
29
38
  VALUE psych = rb_define_module("Psych");
@@ -33,6 +42,7 @@ void Init_psych_to_ruby(void)
33
42
  VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject);
34
43
  cPsychVisitorsToRuby = rb_define_class_under(visitors, "ToRuby", visitor);
35
44
 
45
+ rb_define_private_method(cPsychVisitorsToRuby, "init_struct", init_struct, 2);
36
46
  rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2);
37
47
  rb_define_private_method(class_loader, "path2class", path2class, 1);
38
48
  }
@@ -6,6 +6,7 @@ module Psych
6
6
  class ClassLoader # :nodoc:
7
7
  BIG_DECIMAL = 'BigDecimal'
8
8
  COMPLEX = 'Complex'
9
+ DATA = 'Data' unless RUBY_VERSION < "3.2"
9
10
  DATE = 'Date'
10
11
  DATE_TIME = 'DateTime'
11
12
  EXCEPTION = 'Exception'
@@ -18,12 +18,19 @@ if defined?(::IRB)
18
18
  require_relative 'y'
19
19
  end
20
20
 
21
-
22
- # TODO: how best to check for builtin Set?
23
- if defined?(::Set) && Object.const_source_location(:Set) == ["ruby", 0]
21
+ # Up to Ruby 3.4, Set was a regular object and was dumped as such
22
+ # by Pysch.
23
+ # Starting from Ruby 3.5 it's a core class written in C, so we have to implement
24
+ # #encode_with / #init_with to preserve backward compatibility.
25
+ if defined?(::Set) && Set.new.instance_variables.empty?
24
26
  class Set
25
27
  def encode_with(coder)
26
- coder["hash"] = to_h
28
+ hash = {}
29
+ each do |m|
30
+ hash[m] = true
31
+ end
32
+ coder["hash"] = hash
33
+ coder
27
34
  end
28
35
 
29
36
  def init_with(coder)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Psych
4
4
  # The version of Psych you are using
5
- VERSION = '5.2.4'
5
+ VERSION = '5.2.5'
6
6
 
7
7
  if RUBY_ENGINE == 'jruby'
8
8
  DEFAULT_SNAKEYAML_VERSION = '2.9'.freeze
@@ -96,11 +96,11 @@ module Psych
96
96
  Float(@ss.tokenize(o.value))
97
97
  when "!ruby/regexp"
98
98
  klass = class_loader.regexp
99
- o.value =~ /^\/(.*)\/([mixn]*)$/m
100
- source = $1
99
+ matches = /^\/(?<string>.*)\/(?<options>[mixn]*)$/m.match(o.value)
100
+ source = matches[:string].gsub('\/', '/')
101
101
  options = 0
102
102
  lang = nil
103
- $2&.each_char do |option|
103
+ matches[:options].each_char do |option|
104
104
  case option
105
105
  when 'x' then options |= Regexp::EXTENDED
106
106
  when 'i' then options |= Regexp::IGNORECASE
@@ -197,6 +197,32 @@ module Psych
197
197
  s
198
198
  end
199
199
 
200
+ when /^!ruby\/data(-with-ivars)?(?::(.*))?$/
201
+ data = register(o, resolve_class($2).allocate) if $2
202
+ members = {}
203
+
204
+ if $1 # data-with-ivars
205
+ ivars = {}
206
+ o.children.each_slice(2) do |type, vars|
207
+ case accept(type)
208
+ when 'members'
209
+ revive_data_members(members, vars)
210
+ data ||= allocate_anon_data(o, members)
211
+ when 'ivars'
212
+ revive_hash(ivars, vars)
213
+ end
214
+ end
215
+ ivars.each do |ivar, v|
216
+ data.instance_variable_set ivar, v
217
+ end
218
+ else
219
+ revive_data_members(members, o)
220
+ end
221
+ data ||= allocate_anon_data(o, members)
222
+ init_struct(data, **members)
223
+ data.freeze
224
+ data
225
+
200
226
  when /^!ruby\/object:?(.*)?$/
201
227
  name = $1 || 'Object'
202
228
 
@@ -340,6 +366,20 @@ module Psych
340
366
  list
341
367
  end
342
368
 
369
+ def allocate_anon_data node, members
370
+ klass = class_loader.data.define(*members.keys)
371
+ register(node, klass.allocate)
372
+ end
373
+
374
+ def revive_data_members hash, o
375
+ o.children.each_slice(2) do |k,v|
376
+ name = accept(k)
377
+ value = accept(v)
378
+ hash[class_loader.symbolize(name)] = value
379
+ end
380
+ hash
381
+ end
382
+
343
383
  def revive_hash hash, o, tagged= false
344
384
  o.children.each_slice(2) { |k,v|
345
385
  key = accept(k)
@@ -73,7 +73,7 @@ module Psych
73
73
 
74
74
  method = respond_to?(method) ? method : h[klass.superclass]
75
75
 
76
- raise(TypeError, "Can't dump #{target.class}") unless method
76
+ raise(TypeError, "can't dump #{klass.name}") unless method
77
77
 
78
78
  h[klass] = method
79
79
  end.compare_by_identity
@@ -162,6 +162,44 @@ module Psych
162
162
 
163
163
  alias :visit_Delegator :visit_Object
164
164
 
165
+ def visit_Data o
166
+ ivars = o.instance_variables
167
+ if ivars.empty?
168
+ tag = ['!ruby/data', o.class.name].compact.join(':')
169
+ register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK)
170
+ o.members.each do |member|
171
+ @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY
172
+ accept o.send member
173
+ end
174
+ @emitter.end_mapping
175
+
176
+ else
177
+ tag = ['!ruby/data-with-ivars', o.class.name].compact.join(':')
178
+ node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)
179
+ register(o, node)
180
+
181
+ # Dump the members
182
+ accept 'members'
183
+ @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
184
+ o.members.each do |member|
185
+ @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY
186
+ accept o.send member
187
+ end
188
+ @emitter.end_mapping
189
+
190
+ # Dump the ivars
191
+ accept 'ivars'
192
+ @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK
193
+ ivars.each do |ivar|
194
+ accept ivar.to_s
195
+ accept o.instance_variable_get ivar
196
+ end
197
+ @emitter.end_mapping
198
+
199
+ @emitter.end_mapping
200
+ end
201
+ end
202
+
165
203
  def visit_Struct o
166
204
  tag = ['!ruby/struct', o.class.name].compact.join(':')
167
205
 
data/lib/psych.rb CHANGED
@@ -23,7 +23,6 @@ require_relative 'psych/parser'
23
23
  require_relative 'psych/omap'
24
24
  require_relative 'psych/set'
25
25
  require_relative 'psych/coder'
26
- require_relative 'psych/core_ext'
27
26
  require_relative 'psych/stream'
28
27
  require_relative 'psych/json/tree_builder'
29
28
  require_relative 'psych/json/stream'
@@ -654,6 +653,35 @@ module Psych
654
653
  result
655
654
  end
656
655
 
656
+ ###
657
+ # Load multiple documents given in +yaml+. Returns the parsed documents
658
+ # as a list.
659
+ #
660
+ # Example:
661
+ #
662
+ # Psych.safe_load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar']
663
+ #
664
+ # list = []
665
+ # Psych.safe_load_stream("--- foo\n...\n--- bar\n...") do |ruby|
666
+ # list << ruby
667
+ # end
668
+ # list # => ['foo', 'bar']
669
+ #
670
+ def self.safe_load_stream yaml, filename: nil, permitted_classes: [], aliases: false
671
+ documents = parse_stream(yaml, filename: filename).children.map do |child|
672
+ stream = Psych::Nodes::Stream.new
673
+ stream.children << child
674
+ safe_load(stream.to_yaml, permitted_classes: permitted_classes, aliases: aliases)
675
+ end
676
+
677
+ if block_given?
678
+ documents.each { |doc| yield doc }
679
+ nil
680
+ else
681
+ documents
682
+ end
683
+ end
684
+
657
685
  ###
658
686
  # Load the document contained in +filename+. Returns the yaml contained in
659
687
  # +filename+ as a Ruby object, or if the file is empty, it returns
@@ -761,3 +789,5 @@ module Psych
761
789
  self.domain_types = {}
762
790
  # :startdoc:
763
791
  end
792
+
793
+ require_relative 'psych/core_ext'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: psych
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.4
4
+ version: 5.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2025-05-01 00:00:00.000000000 Z
13
+ date: 2025-05-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: stringio
@@ -129,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
129
  - !ruby/object:Gem::Version
130
130
  version: '0'
131
131
  requirements: []
132
- rubygems_version: 3.5.11
132
+ rubygems_version: 3.5.22
133
133
  signing_key:
134
134
  specification_version: 4
135
135
  summary: Psych is a YAML parser and emitter