summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--_test/roundtrip.py2
-rw-r--r--_test/test_yamlobject.py40
-rw-r--r--constructor.py36
-rw-r--r--representer.py6
4 files changed, 72 insertions, 12 deletions
diff --git a/_test/roundtrip.py b/_test/roundtrip.py
index 86e4862..c9b4ffb 100644
--- a/_test/roundtrip.py
+++ b/_test/roundtrip.py
@@ -228,7 +228,7 @@ def save_and_run(program, base_dir=None, file_name=None):
print('running:', *cmd)
check_output(cmd, stderr=STDOUT, universal_newlines=True)
except CalledProcessError as exception:
- print("##### Running '{} {}' FAILED #####".format(sys.exeutable, file_name))
+ print("##### Running '{} {}' FAILED #####".format(sys.executable, file_name))
print(exception.output)
return exception.returncode
return 0
diff --git a/_test/test_yamlobject.py b/_test/test_yamlobject.py
index 1d730b5..2cb7b11 100644
--- a/_test/test_yamlobject.py
+++ b/_test/test_yamlobject.py
@@ -2,6 +2,7 @@
from __future__ import print_function
+import sys
import pytest # NOQA
from roundtrip import save_and_run # NOQA
@@ -42,3 +43,42 @@ def test_monster(tmpdir):
""")
'''
assert save_and_run(program_src, tmpdir) == 0
+
+
+
+@pytest.mark.skipif(sys.version_info < (3, 0), reason='no __qualname__')
+def test_qualified_name00(tmpdir):
+ """issue 214"""
+ program_src = u'''\
+ from ruamel.yaml import YAML
+ from ruamel.yaml.compat import StringIO
+
+ class A:
+ def f(self):
+ pass
+
+ yaml = YAML(typ='unsafe')
+ buf = StringIO()
+ yaml.dump(A.f, buf)
+ res = buf.getvalue()
+ assert res == '!!python/name:__main__.A.f \\n...\\n'
+ x = yaml.load(res)
+ assert x == A.f
+ '''
+ assert save_and_run(program_src, tmpdir) == 0
+
+
+@pytest.mark.skipif(sys.version_info < (3, 0), reason='no __qualname__')
+def test_qualified_name01(tmpdir):
+ """issue 214"""
+ from ruamel.yaml import YAML
+ import ruamel.yaml.comments
+ from ruamel.yaml.compat import StringIO
+
+ yaml = YAML(typ='unsafe')
+ buf = StringIO()
+ yaml.dump(ruamel.yaml.comments.CommentedBase.yaml_anchor, buf)
+ res = buf.getvalue()
+ assert res == '!!python/name:ruamel.yaml.comments.CommentedBase.yaml_anchor \n...\n'
+ x = yaml.load(res)
+ assert x == ruamel.yaml.comments.CommentedBase.yaml_anchor
diff --git a/constructor.py b/constructor.py
index 6de5181..ab3ebf5 100644
--- a/constructor.py
+++ b/constructor.py
@@ -773,10 +773,20 @@ class Constructor(SafeConstructor):
mark,
)
if u'.' in name:
- module_name, object_name = name.rsplit('.', 1)
+ lname = name.split('.')
+ lmodule_name, lobject_name = lname, []
+ while len(lmodule_name) > 1:
+ lobject_name.insert(0, lmodule_name.pop())
+ module_name = '.'.join(lmodule_name)
+ try:
+ __import__(module_name)
+ # object_name = '.'.join(object_name)
+ break
+ except ImportError as exc:
+ continue
else:
module_name = builtins_module
- object_name = name
+ object_name = [name]
try:
__import__(module_name)
except ImportError as exc:
@@ -787,14 +797,20 @@ class Constructor(SafeConstructor):
mark,
)
module = sys.modules[module_name]
- if not hasattr(module, object_name):
- raise ConstructorError(
- 'while constructing a Python object',
- mark,
- 'cannot find %r in the module %r' % (utf8(object_name), module.__name__),
- mark,
- )
- return getattr(module, object_name)
+ object_name = '.'.join(lobject_name)
+ obj = module
+ while lobject_name:
+ if not hasattr(obj, lobject_name[0]):
+
+ raise ConstructorError(
+ 'while constructing a Python object',
+ mark,
+ 'cannot find %r in the module %r' % (
+ utf8(object_name), module.__name__),
+ mark,
+ )
+ obj = getattr(obj, lobject_name.pop(0))
+ return obj
def construct_python_name(self, suffix, node):
# type: (Any, Any) -> Any
diff --git a/representer.py b/representer.py
index a659977..c663397 100644
--- a/representer.py
+++ b/representer.py
@@ -483,7 +483,11 @@ class Representer(SafeRepresenter):
def represent_name(self, data):
# type: (Any) -> Any
- name = u'%s.%s' % (data.__module__, data.__name__)
+ try:
+ name = u'%s.%s' % (data.__module__, data.__qualname__)
+ except AttributeError:
+ # probably PY2
+ name = u'%s.%s' % (data.__module__, data.__name__)
return self.represent_scalar(u'tag:yaml.org,2002:python/name:' + name, "")
def represent_module(self, data):