def getVariableForReference(self, variable_name): # print ( "REF func", self, variable_name ) if self.hasProvidedVariable(variable_name): result = self.getProvidedVariable(variable_name) else: result = self.getClosureVariable( variable_name = variable_name ) # Remember that we need that closure variable for something, so # we don't create it again all the time. if not result.isModuleVariable(): self.registerProvidedVariable(result) # For "exec" containing/star import containing, we get a # closure variable already, but if it is a module variable, # only then make it a maybe local variable. if self.isUnoptimized() and result.isModuleVariable(): result = Variables.MaybeLocalVariable( owner = self, maybe_variable = result ) self.registerProvidedVariable(result) return result
def getVariableForReference(self, variable_name): # print ( "REF func", self, variable_name ) if self.hasProvidedVariable(variable_name): result = self.getProvidedVariable(variable_name) else: # For exec containing/star import containing, get a closure variable # and if it is a module variable, only then make it a maybe local # variable. result = self.getClosureVariable(variable_name=variable_name) if self.isUnoptimized() and result.isModuleVariable(): result = Variables.MaybeLocalVariable( owner=self, variable_name=variable_name) # Remember that we need that closure for something. self.registerProvidedVariable(result) return result
def onEnterNode(self, node): # Mighty complex code with lots of branches and statements, but it # couldn't be less without making it more difficult. # pylint: disable=R0912,R0915 if node.isExpressionTargetVariableRef(): provider = node.getParentVariableProvider() if node.getVariable() is None: variable_name = node.getVariableName() variable = provider.getVariableForAssignment( variable_name=variable_name) node.setVariable(variable) addVariableUsage(node.getVariable(), provider) elif node.isExpressionTargetTempVariableRef(): provider = node.getParentVariableProvider() addVariableUsage(node.getVariable(), provider) elif node.isExpressionVariableRef(): if node.getVariable() is None: provider = node.getParentVariableProvider() if provider.isEarlyClosure(): variable = provider.getVariableForReference( variable_name=node.getVariableName()) # Python3.4 version respects closure variables taken can be # overridden by writes to locals. It should be done for # globals too, on all versions, but for Python2 the locals # dictionary is avoided unless "exec" appears, so it's not # done. if variable.getOwner() is not provider: if python_version >= 340 or \ (python_version >= 300 and \ variable.isModuleVariable()): variable = Variables.MaybeLocalVariable( owner=provider, maybe_variable=variable) node.setVariable(variable) elif node.isExpressionTempVariableRef(): if node.getVariable().getOwner() != node.getParentVariableProvider( ): node.setVariable( node.getParentVariableProvider().addClosureVariable( node.getVariable())) elif node.isExpressionFunctionBody(): if python_version >= 300: self._handleNonLocal(node) for variable in node.getParameters().getAllVariables(): addVariableUsage(variable, node) # Python3.4 allows for class declarations to be made global, even # after they were declared, so we need to fix this up. if python_version >= 340: self._handleQualnameSetup(node) # Attribute access of names of class functions should be mangled, if # they start with "__", but do not end in "__" as well. elif node.isExpressionAttributeLookup() or \ node.isStatementAssignmentAttribute() or \ node.isStatementDelAttribute(): attribute_name = node.getAttributeName() if attribute_name.startswith("__") and \ not attribute_name.endswith("__"): seen_function = False current = node while True: current = current.getParentVariableProvider() if current.isPythonModule(): break assert current.isExpressionFunctionBody() if current.isClassDictCreation(): if seen_function: node.setAttributeName( "_%s%s" % (current.getName().lstrip("_"), attribute_name)) break else: seen_function = True # Check if continue and break are properly in loops. If not, raise a # syntax error. elif node.isStatementBreakLoop() or node.isStatementContinueLoop(): current = node while True: if current.isPythonModule() or \ current.isExpressionFunctionBody(): if node.isStatementContinueLoop(): message = "'continue' not properly in loop" col_offset = 16 if python_version >= 300 else None display_line = True source_line = None else: message = "'break' outside loop" if isFullCompat(): col_offset = 2 if python_version >= 300 else None display_line = True source_line = "" if python_version >= 300 else None else: col_offset = 13 display_line = True source_line = None SyntaxErrors.raiseSyntaxError( message, source_ref=node.getSourceReference(), col_offset=col_offset, display_line=display_line, source_line=source_line) current = current.getParent() if current.isStatementLoop(): break