Skip to content

Commit

Permalink
Fix PyYAML 5.1 Loader= warnings
Browse files Browse the repository at this point in the history
Per [1] upstream docs, we should use safe loader where we can.
For parsing '!eval' we need full loader though.  So use Loaders
appropriately.

Slightly inconvenient is to write this thing portably because
FullLoader isn't available in old PyYAML versions.

[1] https://msg.pyyaml.org/load

Fixes: #93
  • Loading branch information
praiskup authored and pkubatrh committed Mar 21, 2019
1 parent 525f2a7 commit 198b193
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 22 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ New in 1.3:

- Added 'fedora-30' config, and rawhide moved to 'fedora-31'.

- Compatibility fixes for new PyYAML 5.1.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

New in 1.2:
Expand Down
13 changes: 8 additions & 5 deletions distgen/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ def __recursive_load(pm, stack, filename):

import yaml
try:
yaml_data = yaml.load(pm.open_file(
filename,
fail=True,
file_desc="configuration file",
))
yaml_data = yaml.load(
pm.open_file(
filename,
fail=True,
file_desc="configuration file",
),
Loader=yaml.SafeLoader,
)
except yaml.YAMLError as exc:
fatal("Error in configuration file: {0}".format(exc))

Expand Down
44 changes: 29 additions & 15 deletions distgen/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import sys
import imp
import jinja2
import functools

from distgen.err import fatal
from distgen.pathmanager import PathManager
Expand Down Expand Up @@ -195,6 +196,32 @@ def _recursive_render_spec(self, s, max_passes=25, **kwargs):

return s

def _enhanced_yaml_module(self, sysconfig):

# NOTE: This is soo ugly, sorry for that, in future we need to modify
# PyYAML to let us specify callbacks, somehow. But for now, import
# yaml right here (local import) to be able to add the
# constructors/representers **only** locally (don't modify global
# context).
def _eval_node(loader, node):
return str(eval(str(loader.construct_scalar(node)), {
'project': self.project,
'config': sysconfig,
'macros': sysconfig['macros'],
}))

import yaml
try:
yaml.add_constructor(u'!eval', _eval_node, yaml.FullLoader)
yaml.dg_load = functools.partial(yaml.load, Loader=yaml.FullLoader)
except AttributeError:
# Older versions of PyYAML don't have yaml.FullLoader, remove this
# once we don't have to deal with those.
yaml.add_constructor(u'!eval', _eval_node)
yaml.dg_load = yaml.load

return yaml

def render(self, specfiles, multispec, multispec_selectors, template,
config, cmd_cfg, output, confdirs=None,
explicit_macros={}, max_passes=1):
Expand Down Expand Up @@ -227,20 +254,7 @@ def render(self, specfiles, multispec, multispec_selectors, template,
self.vars_fill_variables(explicit_macros, sysconfig)
sysconfig = merge_yaml(sysconfig, explicit_macros)

# NOTE: This is soo ugly, sorry for that, in future we need to modify
# PyYAML to let us specify callbacks, somehow. But for now, import
# yaml right here to be able to add the constructors/representers
# "locally".
import yaml

def _eval_node(loader, node):
return str(eval(str(loader.construct_scalar(node)), {
'project': self.project,
'config': sysconfig,
'macros': sysconfig['macros'],
}))

yaml.add_constructor(u'!eval', _eval_node)
yaml = self._enhanced_yaml_module(sysconfig)

spec = {}
for specfile in specfiles or []:
Expand All @@ -253,7 +267,7 @@ def _eval_node(loader, node):
fatal("Spec file {0} not found".format(specfile))

try:
specdata = yaml.load(specfd)
specdata = yaml.dg_load(specfd)
spec = merge_yaml(spec, specdata)
except yaml.YAMLError as exc:
fatal("Error in spec file: {0}".format(exc))
Expand Down
2 changes: 1 addition & 1 deletion distgen/multispec.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(self, data):
def from_path(cls, project_dir, path):
pm = PathManager([])
fd = pm.open_file(path, [project_dir], fail=True)
data = yaml.load(fd)
data = yaml.load(fd, Loader=yaml.SafeLoader)
return cls(data)

def _process(self):
Expand Down
2 changes: 1 addition & 1 deletion tests/unittests/test_multispec.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def test_from_path_nok(self):

def test_validate(self):
with open(os.path.join(ms_fixtures, 'complex.yaml')) as f:
Multispec(yaml.load(f))._validate()
Multispec(yaml.load(f, Loader=yaml.SafeLoader))._validate()

def test_has_spec_group(self):
ms = Multispec.from_path(ms_fixtures, 'complex.yaml')
Expand Down

0 comments on commit 198b193

Please sign in to comment.