1.1 --- a/inspector.py Sat Nov 12 23:29:32 2016 +0100
1.2 +++ b/inspector.py Sun Nov 13 22:17:59 2016 +0100
1.3 @@ -343,9 +343,15 @@
1.4 # Names and attributes are assigned the entire expression.
1.5
1.6 if isinstance(n, compiler.ast.AssName):
1.7 - if n.name == "self":
1.8 +
1.9 + # Prevent redefinition of certain names.
1.10 +
1.11 + if self.in_class and self.in_function and n.name == "self":
1.12 raise InspectError("Redefinition of self is not allowed.", self.get_namespace_path(), n)
1.13
1.14 + if self.have_imported_name(n.name):
1.15 + raise InspectError("Redefinition of an imported name is not allowed.", self.get_namespace_path(), n)
1.16 +
1.17 name_ref = expr and self.process_structure_node(expr)
1.18
1.19 # Name assignments populate either function namespaces or the
1.20 @@ -480,6 +486,11 @@
1.21
1.22 path = self.get_namespace_path()
1.23
1.24 + # Prevent redefinition of imported names.
1.25 +
1.26 + if self.have_imported_name(n.name):
1.27 + raise InspectError("Redefinition of an imported name is not allowed.", self.get_namespace_path(), n)
1.28 +
1.29 # To avoid notions of class "versions" where the same definition
1.30 # might be parameterised with different state and be referenced
1.31 # elsewhere (as base classes, for example), classes in functions or
1.32 @@ -576,6 +587,11 @@
1.33
1.34 is_lambda = isinstance(n, compiler.ast.Lambda)
1.35
1.36 + # Prevent redefinition of imported names.
1.37 +
1.38 + if not is_lambda and self.have_imported_name(name):
1.39 + raise InspectError("Redefinition of an imported name is not allowed.", self.get_namespace_path(), n)
1.40 +
1.41 # Where a function is declared conditionally, use a separate name for
1.42 # the definition, and assign the definition to the stated name.
1.43
1.44 @@ -728,6 +744,11 @@
1.45 if name == self.name:
1.46 raise InspectError("Cannot import the current module.", path, n)
1.47
1.48 + # Prevent redefinition of imported names.
1.49 +
1.50 + if self.have_imported_name(alias or name):
1.51 + raise InspectError("Redefinition of an imported name is not allowed.", self.get_namespace_path(), n)
1.52 +
1.53 self.set_module(alias or name.split(".")[-1], name)
1.54 self.queue_module(name, True)
1.55
2.1 --- a/modules.py Sat Nov 12 23:29:32 2016 +0100
2.2 +++ b/modules.py Sun Nov 13 22:17:59 2016 +0100
2.3 @@ -92,7 +92,7 @@
2.4
2.5 # Name resolution details.
2.6
2.7 - self.name_references = {} # references to globals
2.8 + self.name_references = {} # references to globals and imported names
2.9
2.10 # Initialisation-related details.
2.11
2.12 @@ -352,6 +352,13 @@
2.13 global_path = self.get_global_path(name)
2.14 return self.imported.get(path) or self.imported.get(global_path)
2.15
2.16 + def have_imported_name(self, name):
2.17 +
2.18 + "Return whether 'name' has been imported into the current namespace."
2.19 +
2.20 + path = self.get_object_path(name)
2.21 + return self.imported.has_key(path)
2.22 +
2.23 def set_imported_name(self, name, ref):
2.24
2.25 "Establish a reference for 'name' given by 'ref'."
3.1 --- a/translator.py Sat Nov 12 23:29:32 2016 +0100
3.2 +++ b/translator.py Sun Nov 13 22:17:59 2016 +0100
3.3 @@ -625,7 +625,7 @@
3.4 # the complete access.
3.5
3.6 name_ref = attr_expr and attr_expr.is_name() and attr_expr
3.7 - name = name_ref and self.get_name_for_tracking(name_ref.name, name_ref and name_ref.final()) or None
3.8 + name = name_ref and self.get_name_for_tracking(name_ref.name, name_ref and name_ref.final() or name_ref.get_name()) or None
3.9
3.10 location = self.get_access_location(name)
3.11 refs = self.get_referenced_attributes(location)