Fix safe_eval() of set literals

There was code to support set literals (on Python 2.7 and newer), but it
was buggy: SAFE_NODES.union() doesn't modify SAFE_NODES in place,
instead it returns a new set object that is then silently discarded.

I added a unit test and fixed the code.  I also changed the version
check to use sys.version_tuple instead of a string comparison, for
consistency with the subsequent Python 3.4 version check that I added in
the previous commit.
This commit is contained in:
Marius Gedminas 2015-09-11 09:41:05 +03:00
parent 2b73002044
commit f91b28ef23
2 changed files with 6 additions and 2 deletions

View file

@ -67,8 +67,8 @@ def safe_eval(expr, locals={}, include_exceptions=False):
) )
# AST node types were expanded after 2.6 # AST node types were expanded after 2.6
if not sys.version.startswith('2.6'): if sys.version_info[:2] >= (2, 7):
SAFE_NODES.union( SAFE_NODES.update(
set( set(
(ast.Set,) (ast.Set,)
) )

View file

@ -19,6 +19,7 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import sys
from collections import defaultdict from collections import defaultdict
from ansible.compat.tests import unittest from ansible.compat.tests import unittest
@ -45,3 +46,6 @@ class TestSafeEval(unittest.TestCase):
self.assertEqual(safe_eval('[]', locals=locals_vars), []) self.assertEqual(safe_eval('[]', locals=locals_vars), [])
self.assertEqual(safe_eval('{}', locals=locals_vars), {}) self.assertEqual(safe_eval('{}', locals=locals_vars), {})
@unittest.skipUnless(sys.version_info[:2] >= (2, 7), "Python 2.6 has no set literals")
def test_set_literals(self):
self.assertEqual(safe_eval('{0}'), set([0]))