From aa5da1b3126491d35c71db47c561cddc8077bfec Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 10 Feb 2018 19:35:03 +0100 Subject: [PATCH] Don't set up YAML constructors/resolvers for default loaders After reading https://pyyaml.org/wiki/PyYAMLDocumentation again, turns out Loader.add_constructor and .add_implicit_resolver are actually *class* methods. In other words, we've been adding dozens of constructors/resolvers to the default YAML loader object, causing it to slow down massively in other tests which call configdata.init(). Instead, create our own loader class and only add them once there. I'm still not sure why this caused the duration to increase with every YAML load though - that might still be some kind of bug in PyYAML. Fixes #2777 --- tests/end2end/fixtures/quteprocess.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py index c62de1dc9..0b5f683cc 100644 --- a/tests/end2end/fixtures/quteprocess.py +++ b/tests/end2end/fixtures/quteprocess.py @@ -784,13 +784,8 @@ class QuteProc(testprocess.Process): be compared. """ __tracebackhide__ = lambda e: e.errisinstance(pytest.fail.Exception) - # Translate ... to ellipsis in YAML. - loader = yaml.SafeLoader(expected) - loader.add_constructor('!ellipsis', lambda loader, node: ...) - loader.add_implicit_resolver('!ellipsis', re.compile(r'\.\.\.'), None) - data = self.get_session() - expected = loader.get_data() + expected = yaml.load(expected, Loader=YamlLoader) outcome = testutils.partial_compare(data, expected) if not outcome: msg = "Session comparison failed: {}".format(outcome.error) @@ -798,6 +793,18 @@ class QuteProc(testprocess.Process): pytest.fail(msg) +class YamlLoader(yaml.SafeLoader): + + """Custom YAML loader used in compare_session.""" + + pass + + +# Translate ... to ellipsis in YAML. +YamlLoader.add_constructor('!ellipsis', lambda loader, node: ...) +YamlLoader.add_implicit_resolver('!ellipsis', re.compile(r'\.\.\.'), None) + + def _xpath_escape(text): """Escape a string to be used in an XPath expression.