mirror of
https://github.com/yaml/pyyaml.git
synced 2025-10-19 19:13:19 +00:00
Allow add_multi_constructor with None (#358)
Loader.add_multi_constructor(None, myconstructor) Also add test for add_multi_constructor('!', ...) etc. See issue #317
This commit is contained in:
parent
5a0cfab86f
commit
03b378d039
8 changed files with 137 additions and 2 deletions
|
@ -74,7 +74,7 @@ class BaseConstructor(object):
|
||||||
constructor = self.yaml_constructors[node.tag]
|
constructor = self.yaml_constructors[node.tag]
|
||||||
else:
|
else:
|
||||||
for tag_prefix in self.yaml_multi_constructors:
|
for tag_prefix in self.yaml_multi_constructors:
|
||||||
if node.tag.startswith(tag_prefix):
|
if tag_prefix is not None and node.tag.startswith(tag_prefix):
|
||||||
tag_suffix = node.tag[len(tag_prefix):]
|
tag_suffix = node.tag[len(tag_prefix):]
|
||||||
constructor = self.yaml_multi_constructors[tag_prefix]
|
constructor = self.yaml_multi_constructors[tag_prefix]
|
||||||
break
|
break
|
||||||
|
|
|
@ -72,7 +72,7 @@ class BaseConstructor:
|
||||||
constructor = self.yaml_constructors[node.tag]
|
constructor = self.yaml_constructors[node.tag]
|
||||||
else:
|
else:
|
||||||
for tag_prefix in self.yaml_multi_constructors:
|
for tag_prefix in self.yaml_multi_constructors:
|
||||||
if node.tag.startswith(tag_prefix):
|
if tag_prefix is not None and node.tag.startswith(tag_prefix):
|
||||||
tag_suffix = node.tag[len(tag_prefix):]
|
tag_suffix = node.tag[len(tag_prefix):]
|
||||||
constructor = self.yaml_multi_constructors[tag_prefix]
|
constructor = self.yaml_multi_constructors[tag_prefix]
|
||||||
break
|
break
|
||||||
|
|
4
tests/data/multi-constructor.code
Normal file
4
tests/data/multi-constructor.code
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[
|
||||||
|
{'Tag1': ['a', 1, 'b', 2]},
|
||||||
|
{'Tag2': ['a', 1, 'b', 2]},
|
||||||
|
]
|
3
tests/data/multi-constructor.multi
Normal file
3
tests/data/multi-constructor.multi
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
- !Tag1 [a, 1, b, 2]
|
||||||
|
- !!Tag2 [a, 1, b, 2]
|
63
tests/lib/test_multi_constructor.py
Normal file
63
tests/lib/test_multi_constructor.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import yaml
|
||||||
|
import pprint
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def _load_code(expression):
|
||||||
|
return eval(expression)
|
||||||
|
|
||||||
|
def myconstructor1(constructor, tag, node):
|
||||||
|
seq = constructor.construct_sequence(node)
|
||||||
|
return {tag: seq }
|
||||||
|
|
||||||
|
def myconstructor2(constructor, tag, node):
|
||||||
|
seq = constructor.construct_sequence(node)
|
||||||
|
string = ''
|
||||||
|
try:
|
||||||
|
i = tag.index('!') + 1
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
i = tag.rindex(':') + 1
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if i >= 0:
|
||||||
|
tag = tag[i:]
|
||||||
|
return { tag: seq }
|
||||||
|
|
||||||
|
class Multi1(yaml.FullLoader):
|
||||||
|
pass
|
||||||
|
class Multi2(yaml.FullLoader):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_multi_constructor(input_filename, code_filename, verbose=False):
|
||||||
|
input = open(input_filename, 'rb').read().decode('utf-8')
|
||||||
|
native = _load_code(open(code_filename, 'rb').read())
|
||||||
|
|
||||||
|
# default multi constructor for ! and !! tags
|
||||||
|
Multi1.add_multi_constructor('!', myconstructor1)
|
||||||
|
Multi1.add_multi_constructor('tag:yaml.org,2002:', myconstructor1)
|
||||||
|
|
||||||
|
data = yaml.load(input, Loader=Multi1)
|
||||||
|
if verbose:
|
||||||
|
print('Multi1:')
|
||||||
|
print(data)
|
||||||
|
print(native)
|
||||||
|
assert(data == native)
|
||||||
|
|
||||||
|
|
||||||
|
# default multi constructor for all tags
|
||||||
|
Multi2.add_multi_constructor(None, myconstructor2)
|
||||||
|
|
||||||
|
data = yaml.load(input, Loader=Multi2)
|
||||||
|
if verbose:
|
||||||
|
print('Multi2:')
|
||||||
|
print(data)
|
||||||
|
print(native)
|
||||||
|
assert(data == native)
|
||||||
|
|
||||||
|
|
||||||
|
test_multi_constructor.unittest = ['.multi', '.code']
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import test_appliance
|
||||||
|
test_appliance.run(globals())
|
||||||
|
|
|
@ -12,6 +12,7 @@ from test_representer import *
|
||||||
from test_recursive import *
|
from test_recursive import *
|
||||||
from test_input_output import *
|
from test_input_output import *
|
||||||
from test_sort_keys import *
|
from test_sort_keys import *
|
||||||
|
from test_multi_constructor import *
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import test_appliance
|
import test_appliance
|
||||||
|
|
63
tests/lib3/test_multi_constructor.py
Normal file
63
tests/lib3/test_multi_constructor.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import yaml
|
||||||
|
import pprint
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def _load_code(expression):
|
||||||
|
return eval(expression)
|
||||||
|
|
||||||
|
def myconstructor1(constructor, tag, node):
|
||||||
|
seq = constructor.construct_sequence(node)
|
||||||
|
return {tag: seq }
|
||||||
|
|
||||||
|
def myconstructor2(constructor, tag, node):
|
||||||
|
seq = constructor.construct_sequence(node)
|
||||||
|
string = ''
|
||||||
|
try:
|
||||||
|
i = tag.index('!') + 1
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
i = tag.rindex(':') + 1
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if i >= 0:
|
||||||
|
tag = tag[i:]
|
||||||
|
return { tag: seq }
|
||||||
|
|
||||||
|
class Multi1(yaml.FullLoader):
|
||||||
|
pass
|
||||||
|
class Multi2(yaml.FullLoader):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_multi_constructor(input_filename, code_filename, verbose=False):
|
||||||
|
input = open(input_filename, 'rb').read().decode('utf-8')
|
||||||
|
native = _load_code(open(code_filename, 'rb').read())
|
||||||
|
|
||||||
|
# default multi constructor for ! and !! tags
|
||||||
|
Multi1.add_multi_constructor('!', myconstructor1)
|
||||||
|
Multi1.add_multi_constructor('tag:yaml.org,2002:', myconstructor1)
|
||||||
|
|
||||||
|
data = yaml.load(input, Loader=Multi1)
|
||||||
|
if verbose:
|
||||||
|
print('Multi1:')
|
||||||
|
print(data)
|
||||||
|
print(native)
|
||||||
|
assert(data == native)
|
||||||
|
|
||||||
|
|
||||||
|
# default multi constructor for all tags
|
||||||
|
Multi2.add_multi_constructor(None, myconstructor2)
|
||||||
|
|
||||||
|
data = yaml.load(input, Loader=Multi2)
|
||||||
|
if verbose:
|
||||||
|
print('Multi2:')
|
||||||
|
print(data)
|
||||||
|
print(native)
|
||||||
|
assert(data == native)
|
||||||
|
|
||||||
|
|
||||||
|
test_multi_constructor.unittest = ['.multi', '.code']
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import test_appliance
|
||||||
|
test_appliance.run(globals())
|
||||||
|
|
|
@ -12,6 +12,7 @@ from test_representer import *
|
||||||
from test_recursive import *
|
from test_recursive import *
|
||||||
from test_input_output import *
|
from test_input_output import *
|
||||||
from test_sort_keys import *
|
from test_sort_keys import *
|
||||||
|
from test_multi_constructor import *
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import test_appliance
|
import test_appliance
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue