diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2015-01-08 14:21:34 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2015-01-08 14:21:34 -0800 |
commit | e3b2c1c9f5c3a6144a4b02d46a3677df9826a1ab (patch) | |
tree | 8976c31dc44648187f2bcceec3c69297df658d67 /lib | |
parent | 010d0c37bde30c5f347ebfd69087a487ff8b8bbb (diff) | |
parent | af308f8307899cb9e1c0fffea4bce3110a1c3926 (diff) | |
download | psych-e3b2c1c9f5c3a6144a4b02d46a3677df9826a1ab.zip |
Merge branch 'master' into jirutka-patch-1
* master: (21 commits)
* ext/psych/lib/psych/visitors/to_ruby.rb: call `allocate` on hash subclasses. Fixes github.com/tenderlove/psych/issues/196
* ext/psych/lib/psych/visitors/to_ruby.rb: revive hashes with ivars
removed isolate task
removed isolate plugin
added minitest dependency into gemspec
added install task into travis
added ruby-head env
bumping version to 2.0.8
fixed build error caused by trunk changes
bumping version to 2.0.7
merging from ruby trunk
backport r48512 from ruby/ruby trunk.
Add changelog for 2a4d9568f7d5d19c00231cf48eb855cc45ec3394
backport r48214 from ruby/ruby trunk.
Allow dumping any BasicObject that defines #marshal_dump or #marshal_load
bumping version
* ext/psych/lib/psych/visitors/yaml_tree.rb: fix NameError dumping and loading. Fixes GH #85. Thanks @brentdax for the patch! * test/psych/test_exception.rb: test for fix
* ext/psych/lib/psych/scalar_scanner.rb: fix loading strings that look like integers but have a newline. Fixes GH #189 * test/psych/test_string.rb: test for fix
* ext/psych/lib/psych/visitors/to_ruby.rb: merge keys with a hash should merge the hash in to the parent. * test/psych/test_merge_keys.rb: test for change. Fixes GH #202
* ext/psych/lib/psych/visitors/to_ruby.rb: quoted "<<" strings should not be treated as merge keys. * ext/psych/lib/psych/visitors/yaml_tree.rb: hashes with keys containing "<<" should roundtrip. * test/psych/test_merge_keys.rb: test for change. Fixes GH #203
...
Conflicts:
lib/psych/visitors/yaml_tree.rb
Diffstat (limited to 'lib')
-rw-r--r-- | lib/psych.rb | 2 | ||||
-rw-r--r-- | lib/psych/scalar_scanner.rb | 2 | ||||
-rw-r--r-- | lib/psych/visitors/to_ruby.rb | 35 | ||||
-rw-r--r-- | lib/psych/visitors/yaml_tree.rb | 83 |
4 files changed, 109 insertions, 13 deletions
diff --git a/lib/psych.rb b/lib/psych.rb index 41d40a5..1933437 100644 --- a/lib/psych.rb +++ b/lib/psych.rb @@ -217,7 +217,7 @@ require 'psych/class_loader' module Psych # The version is Psych you're using - VERSION = '2.0.5' + VERSION = '2.0.8' # The version of libyaml Psych is using LIBYAML_VERSION = Psych.libyaml_version.join '.' diff --git a/lib/psych/scalar_scanner.rb b/lib/psych/scalar_scanner.rb index 3fc9edd..9300790 100644 --- a/lib/psych/scalar_scanner.rb +++ b/lib/psych/scalar_scanner.rb @@ -37,7 +37,7 @@ module Psych case string # Check for a String type, being careful not to get caught by hash keys, hex values, and # special floats (e.g., -.inf). - when /^[^\d\.:-]?[A-Za-z_\s!@#\$%\^&\*\(\)\{\}\<\>\|\/\\~;=]+/ + when /^[^\d\.:-]?[A-Za-z_\s!@#\$%\^&\*\(\)\{\}\<\>\|\/\\~;=]+/, /\n/ if string.length > 5 @string_cache[string] = true return string diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb index 234cabc..f353e9c 100644 --- a/lib/psych/visitors/to_ruby.rb +++ b/lib/psych/visitors/to_ruby.rb @@ -261,8 +261,22 @@ module Psych end set + when /^!ruby\/hash-with-ivars(?::(.*))?$/ + hash = $1 ? resolve_class($1).allocate : {} + o.children.each_slice(2) do |key, value| + case key.value + when 'elements' + revive_hash hash, value + when 'ivars' + value.children.each_slice(2) do |k,v| + hash.instance_variable_set accept(k), accept(v) + end + end + end + hash + when /^!map:(.*)$/, /^!ruby\/hash:(.*)$/ - revive_hash register(o, resolve_class($1).new), o + revive_hash register(o, resolve_class($1).allocate), o when '!omap', 'tag:yaml.org,2002:omap' map = register(o, class_loader.psych_omap.new) @@ -271,6 +285,21 @@ module Psych end map + when /^!ruby\/marshalable:(.*)$/ + name = $1 + klass = resolve_class(name) + obj = register(o, klass.allocate) + + if obj.respond_to?(:init_with) + init_with(obj, revive_hash({}, o), o) + elsif obj.respond_to?(:marshal_load) + marshal_data = o.children.map(&method(:accept)) + obj.marshal_load(marshal_data) + obj + else + raise ArgumentError, "Cannot deserialize #{name}" + end + else revive_hash(register(o, {}), o) end @@ -305,9 +334,9 @@ module Psych key = accept(k) val = accept(v) - if key == '<<' + if key == '<<' && k.tag != "tag:yaml.org,2002:str" case v - when Nodes::Alias + when Nodes::Alias, Nodes::Mapping begin hash.merge! val rescue TypeError diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb index f40538a..3a6bd1d 100644 --- a/lib/psych/visitors/yaml_tree.rb +++ b/lib/psych/visitors/yaml_tree.rb @@ -27,6 +27,8 @@ module Psych def key? target @obj_to_node.key? target.object_id + rescue NoMethodError + false end def id_for target @@ -211,6 +213,25 @@ module Psych @emitter.end_mapping end + def visit_NameError o + tag = ['!ruby/exception', o.class.name].join ':' + + @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK + + { + 'message' => o.message.to_s, + 'backtrace' => private_iv_get(o, 'backtrace'), + }.each do |k,v| + next unless v + @emitter.scalar k, nil, nil, true, false, Nodes::Scalar::ANY + accept v + end + + dump_ivars o + + @emitter.end_mapping + end + def visit_Regexp o register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY) end @@ -291,6 +312,11 @@ module Psych quote = false elsif o =~ /\n/ style = Nodes::Scalar::LITERAL + elsif o == '<<' + style = Nodes::Scalar::SINGLE_QUOTED + tag = 'tag:yaml.org,2002:str' + plain = false + quote = false elsif o =~ /^[^[:word:]][^"]*$/ style = Nodes::Scalar::DOUBLE_QUOTED else @@ -341,17 +367,46 @@ module Psych end def visit_Hash o - tag = o.class == ::Hash ? nil : "!ruby/hash:#{o.class}" - implicit = !tag + ivars = o.instance_variables - register(o, @emitter.start_mapping(nil, tag, implicit, Psych::Nodes::Mapping::BLOCK)) + if ivars.any? + tag = "!ruby/hash-with-ivars" + tag << ":#{o.class}" unless o.class == ::Hash - o.each do |k,v| - accept k - accept v - end + register(o, @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK)) - @emitter.end_mapping + @emitter.scalar 'elements', nil, nil, true, false, Nodes::Scalar::ANY + + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + o.each do |k,v| + accept k + accept v + end + @emitter.end_mapping + + @emitter.scalar 'ivars', nil, nil, true, false, Nodes::Scalar::ANY + + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + o.instance_variables.each do |ivar| + accept ivar + accept o.instance_variable_get ivar + end + @emitter.end_mapping + + @emitter.end_mapping + else + tag = o.class == ::Hash ? nil : "!ruby/hash:#{o.class}" + implicit = !tag + + register(o, @emitter.start_mapping(nil, tag, implicit, Psych::Nodes::Mapping::BLOCK)) + + o.each do |k,v| + accept k + accept v + end + + @emitter.end_mapping + end end def visit_Psych_Set o @@ -387,6 +442,18 @@ module Psych end end + def visit_BasicObject o + tag = Psych.dump_tags[o.class] + tag ||= "!ruby/marshalable:#{o.class.name}" + + map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + register(o, map) + + o.marshal_dump.each(&method(:accept)) + + @emitter.end_mapping + end + private # FIXME: Remove the index and count checks in Psych 3.0 NULL = "\x00" |