# HG changeset patch # User Paul Boddie # Date 1479071879 -3600 # Node ID fc5056a50cba44ef4520aa1f5c0413f6642287d5 # Parent 052e4264d8b7c34aa196e152bc5a70c3036ac07d Prevent redefinition of imported names and attempt to reference them correctly. diff -r 052e4264d8b7 -r fc5056a50cba inspector.py --- a/inspector.py Sat Nov 12 23:29:32 2016 +0100 +++ b/inspector.py Sun Nov 13 22:17:59 2016 +0100 @@ -343,9 +343,15 @@ # Names and attributes are assigned the entire expression. if isinstance(n, compiler.ast.AssName): - if n.name == "self": + + # Prevent redefinition of certain names. + + if self.in_class and self.in_function and n.name == "self": raise InspectError("Redefinition of self is not allowed.", self.get_namespace_path(), n) + if self.have_imported_name(n.name): + raise InspectError("Redefinition of an imported name is not allowed.", self.get_namespace_path(), n) + name_ref = expr and self.process_structure_node(expr) # Name assignments populate either function namespaces or the @@ -480,6 +486,11 @@ path = self.get_namespace_path() + # Prevent redefinition of imported names. + + if self.have_imported_name(n.name): + raise InspectError("Redefinition of an imported name is not allowed.", self.get_namespace_path(), n) + # To avoid notions of class "versions" where the same definition # might be parameterised with different state and be referenced # elsewhere (as base classes, for example), classes in functions or @@ -576,6 +587,11 @@ is_lambda = isinstance(n, compiler.ast.Lambda) + # Prevent redefinition of imported names. + + if not is_lambda and self.have_imported_name(name): + raise InspectError("Redefinition of an imported name is not allowed.", self.get_namespace_path(), n) + # Where a function is declared conditionally, use a separate name for # the definition, and assign the definition to the stated name. @@ -728,6 +744,11 @@ if name == self.name: raise InspectError("Cannot import the current module.", path, n) + # Prevent redefinition of imported names. + + if self.have_imported_name(alias or name): + raise InspectError("Redefinition of an imported name is not allowed.", self.get_namespace_path(), n) + self.set_module(alias or name.split(".")[-1], name) self.queue_module(name, True) diff -r 052e4264d8b7 -r fc5056a50cba modules.py --- a/modules.py Sat Nov 12 23:29:32 2016 +0100 +++ b/modules.py Sun Nov 13 22:17:59 2016 +0100 @@ -92,7 +92,7 @@ # Name resolution details. - self.name_references = {} # references to globals + self.name_references = {} # references to globals and imported names # Initialisation-related details. @@ -352,6 +352,13 @@ global_path = self.get_global_path(name) return self.imported.get(path) or self.imported.get(global_path) + def have_imported_name(self, name): + + "Return whether 'name' has been imported into the current namespace." + + path = self.get_object_path(name) + return self.imported.has_key(path) + def set_imported_name(self, name, ref): "Establish a reference for 'name' given by 'ref'." diff -r 052e4264d8b7 -r fc5056a50cba translator.py --- a/translator.py Sat Nov 12 23:29:32 2016 +0100 +++ b/translator.py Sun Nov 13 22:17:59 2016 +0100 @@ -625,7 +625,7 @@ # the complete access. name_ref = attr_expr and attr_expr.is_name() and attr_expr - name = name_ref and self.get_name_for_tracking(name_ref.name, name_ref and name_ref.final()) or None + 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 location = self.get_access_location(name) refs = self.get_referenced_attributes(location)