Merge pull request #617 from rwtolbert/bugfix/assign_to_None

Adding code to prevent assignment to some core builtin names
This commit is contained in:
Berker Peksag 2014-07-05 07:48:15 +03:00
commit fa1c5d851e
2 changed files with 44 additions and 0 deletions

View File

@ -47,6 +47,7 @@ import importlib
import codecs import codecs
import ast import ast
import sys import sys
import keyword
from collections import defaultdict from collections import defaultdict
@ -73,6 +74,21 @@ def load_stdlib():
_stdlib[e] = module _stdlib[e] = module
# True, False and None included here since they
# are assignable in Python 2.* but become
# keywords in Python 3.*
def _is_hy_builtin(name, module_name):
extras = ['True', 'False', 'None',
'true', 'false', 'nil', 'null']
if name in extras or keyword.iskeyword(name):
return True
# for non-Hy modules, check for pre-existing name in
# _compile_table
if not module_name.startswith("hy."):
return name in _compile_table
return False
_compile_table = {} _compile_table = {}
@ -1751,6 +1767,12 @@ class HyASTCompiler(object):
def _compile_assign(self, name, result, def _compile_assign(self, name, result,
start_line, start_column): start_line, start_column):
str_name = "%s" % name
if _is_hy_builtin(str_name, self.module_name):
raise HyTypeError(name,
"Can't assign to a builtin: `%s'" % str_name)
result = self.compile(result) result = self.compile(result)
ld_name = self.compile(name) ld_name = self.compile(name)

View File

@ -28,6 +28,28 @@
(setv (get foo 0) 12) (setv (get foo 0) 12)
(assert (= (get foo 0) 12))) (assert (= (get foo 0) 12)))
(defn test-setv-builtin []
"NATIVE: test that setv doesn't work on builtins"
(try (eval '(setv False 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv True 0))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv None 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv false 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv true 0))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv nil 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv null 1))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn defclass [] (print "hello")))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn get [] (print "hello")))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn lambda [] (print "hello")))
(catch [e [TypeError]] (assert (in "Can't assign to a builtin" (str e))))))
(defn test-for-loop [] (defn test-for-loop []
"NATIVE: test for loops" "NATIVE: test for loops"