diff --git a/conda_build/metadata.py b/conda_build/metadata.py index 56f8a8cfea..55c168af03 100644 --- a/conda_build/metadata.py +++ b/conda_build/metadata.py @@ -1,7 +1,6 @@ from __future__ import absolute_import, division, print_function from collections import OrderedDict -import contextlib import copy import hashlib import json @@ -35,9 +34,42 @@ 'files of conda recipes)') try: - loader = yaml.CLoader -except: - loader = yaml.Loader + Loader = yaml.CLoader +except AttributeError: + Loader = yaml.Loader + + +class StringifyNumbersLoader(Loader): + @classmethod + def remove_implicit_resolver(cls, tag): + if 'yaml_implicit_resolvers' not in cls.__dict__: + cls.yaml_implicit_resolvers = { + k: v[:] + for k, v in cls.yaml_implicit_resolvers.items() + } + for ch in tuple(cls.yaml_implicit_resolvers): + resolvers = [ + (t, r) + for t, r in cls.yaml_implicit_resolvers[ch] + if t != tag + ] + if resolvers: + cls.yaml_implicit_resolvers[ch] = resolvers + else: + del cls.yaml_implicit_resolvers[ch] + + @classmethod + def remove_constructor(cls, tag): + if 'yaml_constructors' not in cls.__dict__: + cls.yaml_constructors = cls.yaml_constructors.copy() + if tag in cls.yaml_constructors: + del cls.yaml_constructors[tag] + + +StringifyNumbersLoader.remove_implicit_resolver('tag:yaml.org,2002:float') +StringifyNumbersLoader.remove_implicit_resolver('tag:yaml.org,2002:int') +StringifyNumbersLoader.remove_constructor('tag:yaml.org,2002:float') +StringifyNumbersLoader.remove_constructor('tag:yaml.org,2002:int') on_win = (sys.platform == 'win32') @@ -222,9 +254,7 @@ def select_lines(data, namespace, variants_in_place): def yamlize(data): try: - with stringify_numbers(): - loaded_data = yaml.load(data, Loader=loader) - return loaded_data + return yaml.load(data, Loader=StringifyNumbersLoader) except yaml.error.YAMLError as e: if '{{' in data: try: @@ -884,20 +914,6 @@ def _hash_dependencies(hashing_dependencies, hash_length): return 'h{0}'.format(hash_.hexdigest())[:hash_length + 1] -@contextlib.contextmanager -def stringify_numbers(): - # ensure that numbers are not interpreted as ints or floats. That trips up versions - # with trailing zeros. - implicit_resolver_backup = loader.yaml_implicit_resolvers.copy() - for ch in list(u'0123456789'): - if ch in loader.yaml_implicit_resolvers: - del loader.yaml_implicit_resolvers[ch] - yield - for ch in list(u'0123456789'): - if ch in implicit_resolver_backup: - loader.yaml_implicit_resolvers[ch] = implicit_resolver_backup[ch] - - class MetaData(object): def __init__(self, path, config=None, variant=None):