psych 3.3.0 → 5.1.0
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 +4 -4
- data/Gemfile +1 -1
- data/Mavenfile +1 -1
- data/README.md +6 -5
- data/Rakefile +11 -4
- data/ext/psych/depend +13 -1
- data/ext/psych/extconf.rb +40 -30
- data/ext/psych/psych_parser.c +19 -33
- data/lib/psych/class_loader.rb +5 -5
- data/lib/psych/core_ext.rb +1 -1
- data/lib/psych/exception.rb +16 -2
- data/lib/psych/handler.rb +1 -1
- data/lib/psych/handlers/document_stream.rb +1 -1
- data/lib/psych/handlers/recorder.rb +1 -1
- data/lib/psych/json/stream.rb +2 -2
- data/lib/psych/json/tree_builder.rb +1 -1
- data/lib/psych/nodes/node.rb +4 -4
- data/lib/psych/nodes/scalar.rb +1 -1
- data/lib/psych/nodes.rb +7 -7
- data/lib/psych/parser.rb +13 -0
- data/lib/psych/scalar_scanner.rb +22 -16
- data/lib/psych/syntax_error.rb +1 -1
- data/lib/psych/tree_builder.rb +3 -3
- data/lib/psych/versions.rb +3 -3
- data/lib/psych/visitors/json_tree.rb +1 -1
- data/lib/psych/visitors/to_ruby.rb +19 -15
- data/lib/psych/visitors/visitor.rb +1 -1
- data/lib/psych/visitors/yaml_tree.rb +61 -13
- data/lib/psych/visitors.rb +6 -6
- data/lib/psych.rb +162 -84
- data/psych.gemspec +5 -5
- metadata +20 -17
- data/ext/psych/yaml/LICENSE +0 -19
- data/ext/psych/yaml/api.c +0 -1393
- data/ext/psych/yaml/config.h +0 -80
- data/ext/psych/yaml/dumper.c +0 -394
- data/ext/psych/yaml/emitter.c +0 -2358
- data/ext/psych/yaml/loader.c +0 -544
- data/ext/psych/yaml/parser.c +0 -1375
- data/ext/psych/yaml/reader.c +0 -469
- data/ext/psych/yaml/scanner.c +0 -3598
- data/ext/psych/yaml/writer.c +0 -141
- data/ext/psych/yaml/yaml.h +0 -1985
- data/ext/psych/yaml/yaml_private.h +0 -688
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
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,9 +12,9 @@ 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(symbolize_names: false, freeze: false)
|
15
|
+
def self.create(symbolize_names: false, freeze: false, strict_integer: false)
|
16
16
|
class_loader = ClassLoader.new
|
17
|
-
scanner = ScalarScanner.new class_loader
|
17
|
+
scanner = ScalarScanner.new class_loader, strict_integer: strict_integer
|
18
18
|
new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze)
|
19
19
|
end
|
20
20
|
|
@@ -24,6 +24,7 @@ module Psych
|
|
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
|
29
30
|
@symbolize_names = symbolize_names
|
@@ -48,7 +49,7 @@ module Psych
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def deserialize o
|
51
|
-
if klass = resolve_class(
|
52
|
+
if klass = resolve_class(@load_tags[o.tag])
|
52
53
|
instance = klass.allocate
|
53
54
|
|
54
55
|
if instance.respond_to?(:init_with)
|
@@ -79,7 +80,9 @@ module Psych
|
|
79
80
|
when "!ruby/object:DateTime"
|
80
81
|
class_loader.date_time
|
81
82
|
require 'date' unless defined? DateTime
|
82
|
-
@ss.parse_time(o.value)
|
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)
|
83
86
|
when '!ruby/encoding'
|
84
87
|
::Encoding.find o.value
|
85
88
|
when "!ruby/object:Complex"
|
@@ -128,7 +131,7 @@ module Psych
|
|
128
131
|
end
|
129
132
|
|
130
133
|
def visit_Psych_Nodes_Sequence o
|
131
|
-
if klass = resolve_class(
|
134
|
+
if klass = resolve_class(@load_tags[o.tag])
|
132
135
|
instance = klass.allocate
|
133
136
|
|
134
137
|
if instance.respond_to?(:init_with)
|
@@ -160,8 +163,8 @@ module Psych
|
|
160
163
|
end
|
161
164
|
|
162
165
|
def visit_Psych_Nodes_Mapping o
|
163
|
-
if
|
164
|
-
return revive(resolve_class(
|
166
|
+
if @load_tags[o.tag]
|
167
|
+
return revive(resolve_class(@load_tags[o.tag]), o)
|
165
168
|
end
|
166
169
|
return revive_hash(register(o, {}), o) unless o.tag
|
167
170
|
|
@@ -322,10 +325,11 @@ module Psych
|
|
322
325
|
end
|
323
326
|
|
324
327
|
def visit_Psych_Nodes_Alias o
|
325
|
-
@st.fetch(o.anchor) { raise
|
328
|
+
@st.fetch(o.anchor) { raise AnchorNotDefined, o.anchor }
|
326
329
|
end
|
327
330
|
|
328
331
|
private
|
332
|
+
|
329
333
|
def register node, object
|
330
334
|
@st[node.anchor] = object if node.anchor
|
331
335
|
object
|
@@ -337,7 +341,7 @@ module Psych
|
|
337
341
|
list
|
338
342
|
end
|
339
343
|
|
340
|
-
def revive_hash hash, o
|
344
|
+
def revive_hash hash, o, tagged= false
|
341
345
|
o.children.each_slice(2) { |k,v|
|
342
346
|
key = accept(k)
|
343
347
|
val = accept(v)
|
@@ -364,7 +368,7 @@ module Psych
|
|
364
368
|
hash[key] = val
|
365
369
|
end
|
366
370
|
else
|
367
|
-
if @symbolize_names
|
371
|
+
if !tagged && @symbolize_names && key.is_a?(String)
|
368
372
|
key = key.to_sym
|
369
373
|
elsif !@freeze
|
370
374
|
key = deduplicate(key)
|
@@ -402,7 +406,7 @@ module Psych
|
|
402
406
|
|
403
407
|
def revive klass, node
|
404
408
|
s = register(node, klass.allocate)
|
405
|
-
init_with(s, revive_hash({}, node), node)
|
409
|
+
init_with(s, revive_hash({}, node, true), node)
|
406
410
|
end
|
407
411
|
|
408
412
|
def init_with o, h, node
|
@@ -425,7 +429,7 @@ module Psych
|
|
425
429
|
|
426
430
|
class NoAliasRuby < ToRuby
|
427
431
|
def visit_Psych_Nodes_Alias o
|
428
|
-
raise
|
432
|
+
raise AliasesNotEnabled
|
429
433
|
end
|
430
434
|
end
|
431
435
|
end
|
@@ -17,7 +17,7 @@ module Psych
|
|
17
17
|
|
18
18
|
if defined?(Ractor)
|
19
19
|
def dispatch
|
20
|
-
Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache
|
20
|
+
@dispatch_cache ||= (Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache)
|
21
21
|
end
|
22
22
|
else
|
23
23
|
DISPATCH = dispatch_cache
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
require_relative '../tree_builder'
|
3
|
+
require_relative '../scalar_scanner'
|
4
|
+
require_relative '../class_loader'
|
5
5
|
|
6
6
|
module Psych
|
7
7
|
module Visitors
|
@@ -192,12 +192,13 @@ module Psych
|
|
192
192
|
register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY)
|
193
193
|
end
|
194
194
|
|
195
|
+
def visit_Date o
|
196
|
+
register o, visit_Integer(o.gregorian)
|
197
|
+
end
|
198
|
+
|
195
199
|
def visit_DateTime o
|
196
|
-
|
197
|
-
|
198
|
-
else
|
199
|
-
o.strftime("%Y-%m-%d %H:%M:%S.%9N %:z".freeze)
|
200
|
-
end
|
200
|
+
t = o.italy
|
201
|
+
formatted = format_time t, t.offset.zero?
|
201
202
|
tag = '!ruby/object:DateTime'
|
202
203
|
register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY)
|
203
204
|
end
|
@@ -235,7 +236,6 @@ module Psych
|
|
235
236
|
end
|
236
237
|
alias :visit_TrueClass :visit_Integer
|
237
238
|
alias :visit_FalseClass :visit_Integer
|
238
|
-
alias :visit_Date :visit_Integer
|
239
239
|
|
240
240
|
def visit_Float o
|
241
241
|
if o.nan?
|
@@ -272,6 +272,8 @@ module Psych
|
|
272
272
|
tag = 'tag:yaml.org,2002:str'
|
273
273
|
plain = false
|
274
274
|
quote = false
|
275
|
+
elsif o == 'y' || o == 'n'
|
276
|
+
style = Nodes::Scalar::DOUBLE_QUOTED
|
275
277
|
elsif @line_width && o.length > @line_width
|
276
278
|
style = Nodes::Scalar::FOLDED
|
277
279
|
elsif o =~ /^[^[:word:]][^"]*$/
|
@@ -480,8 +482,8 @@ module Psych
|
|
480
482
|
@emitter.end_mapping
|
481
483
|
end
|
482
484
|
|
483
|
-
def format_time time
|
484
|
-
if
|
485
|
+
def format_time time, utc = time.utc?
|
486
|
+
if utc
|
485
487
|
time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
|
486
488
|
else
|
487
489
|
time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z")
|
@@ -509,9 +511,9 @@ module Psych
|
|
509
511
|
def emit_coder c, o
|
510
512
|
case c.type
|
511
513
|
when :scalar
|
512
|
-
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false,
|
514
|
+
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, c.style
|
513
515
|
when :seq
|
514
|
-
@emitter.start_sequence nil, c.tag, c.tag.nil?,
|
516
|
+
@emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
|
515
517
|
c.seq.each do |thing|
|
516
518
|
accept thing
|
517
519
|
end
|
@@ -535,5 +537,51 @@ module Psych
|
|
535
537
|
end
|
536
538
|
end
|
537
539
|
end
|
540
|
+
|
541
|
+
class RestrictedYAMLTree < YAMLTree
|
542
|
+
DEFAULT_PERMITTED_CLASSES = {
|
543
|
+
TrueClass => true,
|
544
|
+
FalseClass => true,
|
545
|
+
NilClass => true,
|
546
|
+
Integer => true,
|
547
|
+
Float => true,
|
548
|
+
String => true,
|
549
|
+
Array => true,
|
550
|
+
Hash => true,
|
551
|
+
}.compare_by_identity.freeze
|
552
|
+
|
553
|
+
def initialize emitter, ss, options
|
554
|
+
super
|
555
|
+
@permitted_classes = DEFAULT_PERMITTED_CLASSES.dup
|
556
|
+
Array(options[:permitted_classes]).each do |klass|
|
557
|
+
@permitted_classes[klass] = true
|
558
|
+
end
|
559
|
+
@permitted_symbols = {}.compare_by_identity
|
560
|
+
Array(options[:permitted_symbols]).each do |symbol|
|
561
|
+
@permitted_symbols[symbol] = true
|
562
|
+
end
|
563
|
+
@aliases = options.fetch(:aliases, false)
|
564
|
+
end
|
565
|
+
|
566
|
+
def accept target
|
567
|
+
if !@aliases && @st.key?(target)
|
568
|
+
raise BadAlias, "Tried to dump an aliased object"
|
569
|
+
end
|
570
|
+
|
571
|
+
unless Symbol === target || @permitted_classes[target.class]
|
572
|
+
raise DisallowedClass.new('dump', target.class.name || target.class.inspect)
|
573
|
+
end
|
574
|
+
|
575
|
+
super
|
576
|
+
end
|
577
|
+
|
578
|
+
def visit_Symbol sym
|
579
|
+
unless @permitted_classes[Symbol] || @permitted_symbols[sym]
|
580
|
+
raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})")
|
581
|
+
end
|
582
|
+
|
583
|
+
super
|
584
|
+
end
|
585
|
+
end
|
538
586
|
end
|
539
587
|
end
|
data/lib/psych/visitors.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
require_relative 'visitors/visitor'
|
3
|
+
require_relative 'visitors/to_ruby'
|
4
|
+
require_relative 'visitors/emitter'
|
5
|
+
require_relative 'visitors/yaml_tree'
|
6
|
+
require_relative 'visitors/json_tree'
|
7
|
+
require_relative 'visitors/depth_first'
|
data/lib/psych.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
require_relative 'psych/versions'
|
3
3
|
case RUBY_ENGINE
|
4
4
|
when 'jruby'
|
5
|
-
|
5
|
+
require_relative 'psych_jars'
|
6
6
|
if JRuby::Util.respond_to?(:load_ext)
|
7
7
|
JRuby::Util.load_ext('org.jruby.ext.psych.PsychLibrary')
|
8
8
|
else
|
@@ -12,28 +12,28 @@ when 'jruby'
|
|
12
12
|
else
|
13
13
|
require 'psych.so'
|
14
14
|
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
15
|
+
require_relative 'psych/nodes'
|
16
|
+
require_relative 'psych/streaming'
|
17
|
+
require_relative 'psych/visitors'
|
18
|
+
require_relative 'psych/handler'
|
19
|
+
require_relative 'psych/tree_builder'
|
20
|
+
require_relative 'psych/parser'
|
21
|
+
require_relative 'psych/omap'
|
22
|
+
require_relative 'psych/set'
|
23
|
+
require_relative 'psych/coder'
|
24
|
+
require_relative 'psych/core_ext'
|
25
|
+
require_relative 'psych/stream'
|
26
|
+
require_relative 'psych/json/tree_builder'
|
27
|
+
require_relative 'psych/json/stream'
|
28
|
+
require_relative 'psych/handlers/document_stream'
|
29
|
+
require_relative 'psych/class_loader'
|
30
30
|
|
31
31
|
###
|
32
32
|
# = Overview
|
33
33
|
#
|
34
34
|
# Psych is a YAML parser and emitter.
|
35
35
|
# Psych leverages libyaml [Home page: https://pyyaml.org/wiki/LibYAML]
|
36
|
-
# or [
|
36
|
+
# or [git repo: https://github.com/yaml/libyaml] for its YAML parsing
|
37
37
|
# and emitting capabilities. In addition to wrapping libyaml, Psych also
|
38
38
|
# knows how to serialize and de-serialize most Ruby objects to and from
|
39
39
|
# the YAML format.
|
@@ -234,9 +234,6 @@ require 'psych/class_loader'
|
|
234
234
|
module Psych
|
235
235
|
# The version of libyaml Psych is using
|
236
236
|
LIBYAML_VERSION = Psych.libyaml_version.join('.').freeze
|
237
|
-
# Deprecation guard
|
238
|
-
NOT_GIVEN = Object.new.freeze
|
239
|
-
private_constant :NOT_GIVEN
|
240
237
|
|
241
238
|
###
|
242
239
|
# Load +yaml+ in to a Ruby data structure. If multiple documents are
|
@@ -249,11 +246,11 @@ module Psych
|
|
249
246
|
#
|
250
247
|
# Example:
|
251
248
|
#
|
252
|
-
# Psych.
|
253
|
-
# Psych.
|
249
|
+
# Psych.unsafe_load("--- a") # => 'a'
|
250
|
+
# Psych.unsafe_load("---\n - a\n - b") # => ['a', 'b']
|
254
251
|
#
|
255
252
|
# begin
|
256
|
-
# Psych.
|
253
|
+
# Psych.unsafe_load("--- `", filename: "file.txt")
|
257
254
|
# rescue Psych::SyntaxError => ex
|
258
255
|
# ex.file # => 'file.txt'
|
259
256
|
# ex.message # => "(file.txt): found character that cannot start any token"
|
@@ -262,24 +259,19 @@ module Psych
|
|
262
259
|
# When the optional +symbolize_names+ keyword argument is set to a
|
263
260
|
# true value, returns symbols for keys in Hash objects (default: strings).
|
264
261
|
#
|
265
|
-
# Psych.
|
266
|
-
# Psych.
|
262
|
+
# Psych.unsafe_load("---\n foo: bar") # => {"foo"=>"bar"}
|
263
|
+
# Psych.unsafe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
267
264
|
#
|
268
265
|
# Raises a TypeError when `yaml` parameter is NilClass
|
269
266
|
#
|
270
267
|
# NOTE: This method *should not* be used to parse untrusted documents, such as
|
271
268
|
# YAML documents that are supplied via user input. Instead, please use the
|
272
|
-
# safe_load method.
|
269
|
+
# load method or the safe_load method.
|
273
270
|
#
|
274
|
-
def self.
|
275
|
-
if legacy_filename != NOT_GIVEN
|
276
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load is deprecated. Use keyword argument like Psych.load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
277
|
-
filename = legacy_filename
|
278
|
-
end
|
279
|
-
|
271
|
+
def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false, strict_integer: false
|
280
272
|
result = parse(yaml, filename: filename)
|
281
273
|
return fallback unless result
|
282
|
-
result.to_ruby(symbolize_names: symbolize_names, freeze: freeze)
|
274
|
+
result.to_ruby(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer)
|
283
275
|
end
|
284
276
|
|
285
277
|
###
|
@@ -289,7 +281,8 @@ module Psych
|
|
289
281
|
# * TrueClass
|
290
282
|
# * FalseClass
|
291
283
|
# * NilClass
|
292
|
-
# *
|
284
|
+
# * Integer
|
285
|
+
# * Float
|
293
286
|
# * String
|
294
287
|
# * Array
|
295
288
|
# * Hash
|
@@ -314,7 +307,7 @@ module Psych
|
|
314
307
|
# A Psych::DisallowedClass exception will be raised if the yaml contains a
|
315
308
|
# class that isn't in the +permitted_classes+ list.
|
316
309
|
#
|
317
|
-
# A Psych::
|
310
|
+
# A Psych::AliasesNotEnabled exception will be raised if the yaml contains aliases
|
318
311
|
# but the +aliases+ keyword argument is set to false.
|
319
312
|
#
|
320
313
|
# +filename+ will be used in the exception message if any exception is raised
|
@@ -326,33 +319,13 @@ module Psych
|
|
326
319
|
# Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"}
|
327
320
|
# Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
328
321
|
#
|
329
|
-
def self.safe_load yaml,
|
330
|
-
if legacy_permitted_classes != NOT_GIVEN
|
331
|
-
warn_with_uplevel 'Passing permitted_classes with the 2nd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_classes: ...) instead.', uplevel: 1 if $VERBOSE
|
332
|
-
permitted_classes = legacy_permitted_classes
|
333
|
-
end
|
334
|
-
|
335
|
-
if legacy_permitted_symbols != NOT_GIVEN
|
336
|
-
warn_with_uplevel 'Passing permitted_symbols with the 3rd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_symbols: ...) instead.', uplevel: 1 if $VERBOSE
|
337
|
-
permitted_symbols = legacy_permitted_symbols
|
338
|
-
end
|
339
|
-
|
340
|
-
if legacy_aliases != NOT_GIVEN
|
341
|
-
warn_with_uplevel 'Passing aliases with the 4th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, aliases: ...) instead.', uplevel: 1 if $VERBOSE
|
342
|
-
aliases = legacy_aliases
|
343
|
-
end
|
344
|
-
|
345
|
-
if legacy_filename != NOT_GIVEN
|
346
|
-
warn_with_uplevel 'Passing filename with the 5th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
347
|
-
filename = legacy_filename
|
348
|
-
end
|
349
|
-
|
322
|
+
def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
|
350
323
|
result = parse(yaml, filename: filename)
|
351
324
|
return fallback unless result
|
352
325
|
|
353
326
|
class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s),
|
354
327
|
permitted_symbols.map(&:to_s))
|
355
|
-
scanner = ScalarScanner.new class_loader
|
328
|
+
scanner = ScalarScanner.new class_loader, strict_integer: strict_integer
|
356
329
|
visitor = if aliases
|
357
330
|
Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
|
358
331
|
else
|
@@ -362,6 +335,47 @@ module Psych
|
|
362
335
|
result
|
363
336
|
end
|
364
337
|
|
338
|
+
###
|
339
|
+
# Load +yaml+ in to a Ruby data structure. If multiple documents are
|
340
|
+
# provided, the object contained in the first document will be returned.
|
341
|
+
# +filename+ will be used in the exception message if any exception
|
342
|
+
# is raised while parsing. If +yaml+ is empty, it returns
|
343
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
344
|
+
#
|
345
|
+
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
|
346
|
+
#
|
347
|
+
# Example:
|
348
|
+
#
|
349
|
+
# Psych.load("--- a") # => 'a'
|
350
|
+
# Psych.load("---\n - a\n - b") # => ['a', 'b']
|
351
|
+
#
|
352
|
+
# begin
|
353
|
+
# Psych.load("--- `", filename: "file.txt")
|
354
|
+
# rescue Psych::SyntaxError => ex
|
355
|
+
# ex.file # => 'file.txt'
|
356
|
+
# ex.message # => "(file.txt): found character that cannot start any token"
|
357
|
+
# end
|
358
|
+
#
|
359
|
+
# When the optional +symbolize_names+ keyword argument is set to a
|
360
|
+
# true value, returns symbols for keys in Hash objects (default: strings).
|
361
|
+
#
|
362
|
+
# Psych.load("---\n foo: bar") # => {"foo"=>"bar"}
|
363
|
+
# Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
364
|
+
#
|
365
|
+
# Raises a TypeError when `yaml` parameter is NilClass. This method is
|
366
|
+
# similar to `safe_load` except that `Symbol` objects are allowed by default.
|
367
|
+
#
|
368
|
+
def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
|
369
|
+
safe_load yaml, permitted_classes: permitted_classes,
|
370
|
+
permitted_symbols: permitted_symbols,
|
371
|
+
aliases: aliases,
|
372
|
+
filename: filename,
|
373
|
+
fallback: fallback,
|
374
|
+
symbolize_names: symbolize_names,
|
375
|
+
freeze: freeze,
|
376
|
+
strict_integer: strict_integer
|
377
|
+
end
|
378
|
+
|
365
379
|
###
|
366
380
|
# Parse a YAML string in +yaml+. Returns the Psych::Nodes::Document.
|
367
381
|
# +filename+ is used in the exception message if a Psych::SyntaxError is
|
@@ -381,22 +395,12 @@ module Psych
|
|
381
395
|
# end
|
382
396
|
#
|
383
397
|
# See Psych::Nodes for more information about YAML AST.
|
384
|
-
def self.parse yaml,
|
385
|
-
if legacy_filename != NOT_GIVEN
|
386
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse is deprecated. Use keyword argument like Psych.parse(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
387
|
-
filename = legacy_filename
|
388
|
-
end
|
389
|
-
|
398
|
+
def self.parse yaml, filename: nil
|
390
399
|
parse_stream(yaml, filename: filename) do |node|
|
391
400
|
return node
|
392
401
|
end
|
393
402
|
|
394
|
-
|
395
|
-
warn_with_uplevel 'Passing the `fallback` keyword argument of Psych.parse is deprecated.', uplevel: 1 if $VERBOSE
|
396
|
-
fallback
|
397
|
-
else
|
398
|
-
false
|
399
|
-
end
|
403
|
+
false
|
400
404
|
end
|
401
405
|
|
402
406
|
###
|
@@ -445,12 +449,7 @@ module Psych
|
|
445
449
|
# Raises a TypeError when NilClass is passed.
|
446
450
|
#
|
447
451
|
# See Psych::Nodes for more information about YAML AST.
|
448
|
-
def self.parse_stream yaml,
|
449
|
-
if legacy_filename != NOT_GIVEN
|
450
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse_stream is deprecated. Use keyword argument like Psych.parse_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
451
|
-
filename = legacy_filename
|
452
|
-
end
|
453
|
-
|
452
|
+
def self.parse_stream yaml, filename: nil, &block
|
454
453
|
if block_given?
|
455
454
|
parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
|
456
455
|
parser.parse yaml, filename
|
@@ -514,6 +513,79 @@ module Psych
|
|
514
513
|
visitor.tree.yaml io, options
|
515
514
|
end
|
516
515
|
|
516
|
+
###
|
517
|
+
# call-seq:
|
518
|
+
# Psych.safe_dump(o) -> string of yaml
|
519
|
+
# Psych.safe_dump(o, options) -> string of yaml
|
520
|
+
# Psych.safe_dump(o, io) -> io object passed in
|
521
|
+
# Psych.safe_dump(o, io, options) -> io object passed in
|
522
|
+
#
|
523
|
+
# Safely dump Ruby object +o+ to a YAML string. Optional +options+ may be passed in
|
524
|
+
# to control the output format. If an IO object is passed in, the YAML will
|
525
|
+
# be dumped to that IO object. By default, only the following
|
526
|
+
# classes are allowed to be serialized:
|
527
|
+
#
|
528
|
+
# * TrueClass
|
529
|
+
# * FalseClass
|
530
|
+
# * NilClass
|
531
|
+
# * Integer
|
532
|
+
# * Float
|
533
|
+
# * String
|
534
|
+
# * Array
|
535
|
+
# * Hash
|
536
|
+
#
|
537
|
+
# Arbitrary classes can be allowed by adding those classes to the +permitted_classes+
|
538
|
+
# keyword argument. They are additive. For example, to allow Date serialization:
|
539
|
+
#
|
540
|
+
# Psych.safe_dump(yaml, permitted_classes: [Date])
|
541
|
+
#
|
542
|
+
# Now the Date class can be dumped in addition to the classes listed above.
|
543
|
+
#
|
544
|
+
# A Psych::DisallowedClass exception will be raised if the object contains a
|
545
|
+
# class that isn't in the +permitted_classes+ list.
|
546
|
+
#
|
547
|
+
# Currently supported options are:
|
548
|
+
#
|
549
|
+
# [<tt>:indentation</tt>] Number of space characters used to indent.
|
550
|
+
# Acceptable value should be in <tt>0..9</tt> range,
|
551
|
+
# otherwise option is ignored.
|
552
|
+
#
|
553
|
+
# Default: <tt>2</tt>.
|
554
|
+
# [<tt>:line_width</tt>] Max character to wrap line at.
|
555
|
+
#
|
556
|
+
# Default: <tt>0</tt> (meaning "wrap at 81").
|
557
|
+
# [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet
|
558
|
+
# strictly formal).
|
559
|
+
#
|
560
|
+
# Default: <tt>false</tt>.
|
561
|
+
# [<tt>:header</tt>] Write <tt>%YAML [version]</tt> at the beginning of document.
|
562
|
+
#
|
563
|
+
# Default: <tt>false</tt>.
|
564
|
+
#
|
565
|
+
# Example:
|
566
|
+
#
|
567
|
+
# # Dump an array, get back a YAML string
|
568
|
+
# Psych.safe_dump(['a', 'b']) # => "---\n- a\n- b\n"
|
569
|
+
#
|
570
|
+
# # Dump an array to an IO object
|
571
|
+
# Psych.safe_dump(['a', 'b'], StringIO.new) # => #<StringIO:0x000001009d0890>
|
572
|
+
#
|
573
|
+
# # Dump an array with indentation set
|
574
|
+
# Psych.safe_dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n"
|
575
|
+
#
|
576
|
+
# # Dump an array to an IO with indentation set
|
577
|
+
# Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3)
|
578
|
+
def self.safe_dump o, io = nil, options = {}
|
579
|
+
if Hash === io
|
580
|
+
options = io
|
581
|
+
io = nil
|
582
|
+
end
|
583
|
+
|
584
|
+
visitor = Psych::Visitors::RestrictedYAMLTree.create options
|
585
|
+
visitor << o
|
586
|
+
visitor.tree.yaml io, options
|
587
|
+
end
|
588
|
+
|
517
589
|
###
|
518
590
|
# Dump a list of objects as separate documents to a document stream.
|
519
591
|
#
|
@@ -551,12 +623,7 @@ module Psych
|
|
551
623
|
# end
|
552
624
|
# list # => ['foo', 'bar']
|
553
625
|
#
|
554
|
-
def self.load_stream yaml,
|
555
|
-
if legacy_filename != NOT_GIVEN
|
556
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load_stream is deprecated. Use keyword argument like Psych.load_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
557
|
-
filename = legacy_filename
|
558
|
-
end
|
559
|
-
|
626
|
+
def self.load_stream yaml, filename: nil, fallback: [], **kwargs
|
560
627
|
result = if block_given?
|
561
628
|
parse_stream(yaml, filename: filename) do |node|
|
562
629
|
yield node.to_ruby(**kwargs)
|
@@ -577,9 +644,9 @@ module Psych
|
|
577
644
|
# NOTE: This method *should not* be used to parse untrusted documents, such as
|
578
645
|
# YAML documents that are supplied via user input. Instead, please use the
|
579
646
|
# safe_load_file method.
|
580
|
-
def self.
|
647
|
+
def self.unsafe_load_file filename, **kwargs
|
581
648
|
File.open(filename, 'r:bom|utf-8') { |f|
|
582
|
-
self.
|
649
|
+
self.unsafe_load f, filename: filename, **kwargs
|
583
650
|
}
|
584
651
|
end
|
585
652
|
|
@@ -594,6 +661,17 @@ module Psych
|
|
594
661
|
}
|
595
662
|
end
|
596
663
|
|
664
|
+
###
|
665
|
+
# Loads the document contained in +filename+. Returns the yaml contained in
|
666
|
+
# +filename+ as a Ruby object, or if the file is empty, it returns
|
667
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
668
|
+
# See load for options.
|
669
|
+
def self.load_file filename, **kwargs
|
670
|
+
File.open(filename, 'r:bom|utf-8') { |f|
|
671
|
+
self.load f, filename: filename, **kwargs
|
672
|
+
}
|
673
|
+
end
|
674
|
+
|
597
675
|
# :stopdoc:
|
598
676
|
def self.add_domain_type domain, type_tag, &block
|
599
677
|
key = ['tag', domain, type_tag].join ':'
|
data/psych.gemspec
CHANGED
@@ -27,9 +27,6 @@ DESCRIPTION
|
|
27
27
|
"bin/setup", "ext/psych/depend", "ext/psych/extconf.rb", "ext/psych/psych.c", "ext/psych/psych.h",
|
28
28
|
"ext/psych/psych_emitter.c", "ext/psych/psych_emitter.h", "ext/psych/psych_parser.c", "ext/psych/psych_parser.h",
|
29
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",
|
30
|
-
"ext/psych/yaml/LICENSE", "ext/psych/yaml/api.c", "ext/psych/yaml/config.h", "ext/psych/yaml/dumper.c",
|
31
|
-
"ext/psych/yaml/emitter.c", "ext/psych/yaml/loader.c", "ext/psych/yaml/parser.c", "ext/psych/yaml/reader.c",
|
32
|
-
"ext/psych/yaml/scanner.c", "ext/psych/yaml/writer.c", "ext/psych/yaml/yaml.h", "ext/psych/yaml/yaml_private.h",
|
33
30
|
"lib/psych.rb", "lib/psych/class_loader.rb", "lib/psych/coder.rb", "lib/psych/core_ext.rb", "lib/psych/exception.rb",
|
34
31
|
"lib/psych/handler.rb", "lib/psych/handlers/document_stream.rb", "lib/psych/handlers/recorder.rb",
|
35
32
|
"lib/psych/json/ruby_events.rb", "lib/psych/json/stream.rb", "lib/psych/json/tree_builder.rb",
|
@@ -55,13 +52,16 @@ DESCRIPTION
|
|
55
52
|
"ext/java/org/jruby/ext/psych/PsychLibrary.java",
|
56
53
|
"ext/java/org/jruby/ext/psych/PsychParser.java",
|
57
54
|
"ext/java/org/jruby/ext/psych/PsychToRuby.java",
|
58
|
-
"ext/java/org/jruby/ext/psych/PsychYamlTree.java",
|
59
55
|
"lib/psych_jars.rb",
|
60
56
|
"lib/psych.jar"
|
61
57
|
]
|
62
|
-
s.requirements = "jar org.
|
58
|
+
s.requirements = "jar org.snakeyaml:snakeyaml-engine, #{version_module::Psych::DEFAULT_SNAKEYAML_VERSION}"
|
63
59
|
s.add_dependency 'jar-dependencies', '>= 0.1.7'
|
64
60
|
else
|
65
61
|
s.extensions = ["ext/psych/extconf.rb"]
|
62
|
+
s.add_dependency 'stringio'
|
66
63
|
end
|
64
|
+
|
65
|
+
s.metadata['msys2_mingw_dependencies'] = 'libyaml'
|
66
|
+
|
67
67
|
end
|