From fc914d52c43f499224f7fb4c2d4c47623adc5b33 Mon Sep 17 00:00:00 2001 From: Phil Sphicas Date: Fri, 18 Sep 2020 00:29:02 -0700 Subject: [PATCH] Avoid repeatedly appending to yaml_implicit_resolvers Repeated calls to `resolve` can experience performance degredation, if `add_implicit_resolver` has been called with `first=None` (to add an implicit resolver with an unspecified first character). For example, every time `foo` is encountered, the "wildcard implicit resolvers" (with `first=None`) will be appended to the list of implicit resolvers for strings starting with `f`, which will normally be the resolver for booleans. The list `yaml_implicit_resolvers['f']` will keep getting longer. The same behavior applies for any first-letter matches with existing implicit resolvers. This change avoids unintentionally mutating the lists in the class-level dict `yaml_implicit_resolvers` by looping through a temporary copy. Fixes: #439 --- lib/yaml/resolver.py | 4 ++-- lib3/yaml/resolver.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/yaml/resolver.py b/lib/yaml/resolver.py index 528fbc0e..ba9aeab2 100644 --- a/lib/yaml/resolver.py +++ b/lib/yaml/resolver.py @@ -146,8 +146,8 @@ def resolve(self, kind, value, implicit): resolvers = self.yaml_implicit_resolvers.get(u'', []) else: resolvers = self.yaml_implicit_resolvers.get(value[0], []) - resolvers += self.yaml_implicit_resolvers.get(None, []) - for tag, regexp in resolvers: + wildcard_resolvers = self.yaml_implicit_resolvers.get(None, []) + for tag, regexp in resolvers + wildcard_resolvers: if regexp.match(value): return tag implicit = implicit[1] diff --git a/lib3/yaml/resolver.py b/lib3/yaml/resolver.py index 02b82e73..013896d2 100644 --- a/lib3/yaml/resolver.py +++ b/lib3/yaml/resolver.py @@ -146,8 +146,8 @@ def resolve(self, kind, value, implicit): resolvers = self.yaml_implicit_resolvers.get('', []) else: resolvers = self.yaml_implicit_resolvers.get(value[0], []) - resolvers += self.yaml_implicit_resolvers.get(None, []) - for tag, regexp in resolvers: + wildcard_resolvers = self.yaml_implicit_resolvers.get(None, []) + for tag, regexp in resolvers + wildcard_resolvers: if regexp.match(value): return tag implicit = implicit[1]