def onEnterNode(self, node): if node.isExpressionVariableNameRef(): provider = node.provider try: variable = self._attachVariable(node, provider) except MaybeLocalVariableUsage: variable_name = node.getVariableName() new_node = ExpressionLocalsVariableRefOrFallback( locals_scope=provider.getFunctionLocalsScope(), variable_name=variable_name, fallback=ExpressionVariableRef( variable=node.getParentModule(). getVariableForReference(variable_name), source_ref=node.source_ref, ), source_ref=node.source_ref, ) else: new_node = ExpressionVariableRef(variable=variable, source_ref=node.source_ref) variable.addVariableUser(provider) parent = node.parent node.finalize() parent.replaceChild(node, new_node)
def wrapSuperBuiltin(type_arg, object_arg, source_ref): if type_arg is None and python_version >= 300: type_arg = ExpressionVariableRef(variable_name="__class__", source_ref=source_ref) # Ought to be already closure taken. type_arg.setVariable( provider.getVariableForReference(variable_name="__class__")) # If we already have this as a local variable, then use that # instead. type_arg_owner = type_arg.getVariable().getOwner() if type_arg_owner is provider or \ not (type_arg_owner.isExpressionFunctionBody() or \ type_arg_owner.isExpressionClassBody()): type_arg = None if type_arg is None: return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 331 else "RuntimeError", exception_value="super(): __class__ cell not found", ) if object_arg is None: if provider.isExpressionGeneratorObjectBody() or \ provider.isExpressionCoroutineObjectBody() or \ provider.isExpressionAsyncgenObjectBody(): parameter_provider = provider.getParentVariableProvider() else: parameter_provider = provider if parameter_provider.getParameters().getArgumentCount() > 0: par1_name = parameter_provider.getParameters( ).getArgumentNames()[0] object_arg = ExpressionVariableRef(variable_name=par1_name, source_ref=source_ref) object_arg.setVariable( provider.getVariableForReference( variable_name=par1_name)) if not object_arg.getVariable().isParameterVariable(): return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 330 else "RuntimeError", exception_value="super(): __class__ cell not found", ) else: return makeRaiseExceptionReplacementExpression( expression=node, exception_type="RuntimeError", exception_value="super(): no arguments") return ExpressionBuiltinSuper(super_type=type_arg, super_object=object_arg, source_ref=source_ref)
def wrapSuperBuiltin( type, object, source_ref ): if type is None and python_version >= 300: provider = node.getParentVariableProvider() type = ExpressionVariableRef( variable_name = "__class__", source_ref = source_ref ) # Ought to be already closure taken. type.setVariable( provider.getVariableForReference( variable_name = "__class__" ) ) from nuitka.nodes.NodeMakingHelpers import makeRaiseExceptionReplacementExpression if not type.getVariable().isClosureReference(): return makeRaiseExceptionReplacementExpression( expression = node, exception_type = "SystemError" if python_version < 331 else "RuntimeError", exception_value = "super(): __class__ cell not found", ) if object is None and provider.getParameters().getArgumentCount() > 0: par1_name = provider.getParameters().getArgumentNames()[0] # TODO: Nested first argument would kill us here, need a test # for that. object = ExpressionVariableRef( variable_name = par1_name, source_ref = source_ref ) object.setVariable( node.getParentVariableProvider().getVariableForReference( variable_name = par1_name ) ) if not object.getVariable().isParameterVariable(): return makeRaiseExceptionReplacementExpression( expression = node, exception_type = "SystemError" if python_version < 330 else "RuntimeError", exception_value = "super(): __class__ cell not found", ) return ExpressionBuiltinSuper( super_type = type, super_object = object, source_ref = source_ref )
def _buildInplaceAssignVariableNode(variable_ref, operator, expression, source_ref): assert variable_ref.isExpressionTargetVariableRef(), variable_ref inplace_node = ExpressionOperationBinaryInplace( operator = operator, left = ExpressionVariableRef( variable_name = variable_ref.getVariableName(), source_ref = source_ref ), right = expression, source_ref = source_ref ) inplace_node.markAsInplaceSuspect() result = ( StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = variable_ref.getVariableName(), source_ref = source_ref ), source = inplace_node, source_ref = source_ref ), ) return result
def _buildInplaceAssignVariableNode(variable_ref, tmp_variable1, tmp_variable2, operator, expression, source_ref): assert variable_ref.isExpressionTargetVariableRef(), variable_ref # First assign the target value to a temporary variable. preserve_to_tmp = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable1, source_ref=source_ref), source=ExpressionVariableRef( variable_name=variable_ref.getVariableName(), source_ref=source_ref), source_ref=source_ref) # Second assign the inplace result to a temporary variable inplace_to_tmp = StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source=ExpressionOperationBinaryInplace(operator=operator, left=ExpressionTempVariableRef( variable=tmp_variable1, source_ref=source_ref), right=expression, source_ref=source_ref), source_ref=source_ref) # Third, copy it over, if the reference values change, i.e. IsNot is true. copy_back_from_tmp = StatementConditional( condition=ExpressionComparisonIsNOT( left=ExpressionTempVariableRef(variable=tmp_variable1, source_ref=source_ref), right=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=variable_ref.makeCloneAt(source_ref), source=ExpressionTempVariableRef(variable=tmp_variable2, source_ref=source_ref), source_ref=source_ref)), no_branch=None, source_ref=source_ref) return ( preserve_to_tmp, # making sure the above temporary variable is deleted in any case. makeTryFinallyStatement( tried=(inplace_to_tmp, copy_back_from_tmp), final=( StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable1, source_ref=source_ref), tolerant=False, source_ref=source_ref), StatementDelVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable2, source_ref=source_ref), tolerant=True, source_ref=source_ref), ), source_ref=source_ref))
def buildAnnAssignNode(provider, node, source_ref): """ Python3.6 annotation assignment. """ if provider.isCompiledPythonModule() or provider.isExpressionClassBody(): provider.markAsNeedsAnnotationsDictionary() # Evaluate the right hand side first, so it can get names provided # before the left hand side exists. statements = [] if node.value is not None: source = buildNode(provider, node.value, source_ref) statements.append( buildAssignmentStatements(provider=provider, node=node.target, source=source, source_ref=source_ref)) # Only name referencing annotations are effective right now. if statements[-1].isStatementAssignmentVariable(): variable_name = statements[-1].getVariableName() else: variable_name = None else: # Only name referencing annotations are effective right now. kind, detail = decodeAssignTarget(provider=provider, node=node.target, source_ref=source_ref) if kind == "Name": variable_name = detail else: variable_name = None # Only annotations for modules and classes are really made, for functions # they are ignored like comments. if variable_name is not None: if provider.isExpressionFunctionBody(): provider.getVariableForAssignment(variable_name) else: annotation = buildNode(provider, node.annotation, source_ref) statements.append( StatementAssignmentSubscript(expression=ExpressionVariableRef( variable=provider.getVariableForAssignment( "__annotations__"), source_ref=source_ref), subscript=makeConstantRefNode( constant=variable_name, source_ref=source_ref), source=annotation, source_ref=source_ref)) return makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref)
def buildVariableReferenceNode(provider, node, source_ref): # Python3 is influenced by the mere use of a variable name. So we need to remember it, # esp. for cases, where it is optimized away. if Utils.python_version >= 300 and node.id == "super" and provider.isExpressionFunctionBody( ): provider.markAsClassClosureTaker() return ExpressionVariableRef(variable_name=node.id, source_ref=source_ref)
def unpackFrom(source, arg_names): accesses = [] sub_special_index = 0 iter_var = outer_body.allocateTempVariable( None, "arg_iter_%d" % len(iter_vars)) iter_vars.append(iter_var) statements.append( StatementAssignmentVariable(variable=iter_var, source=ExpressionBuiltinIter1( value=source, source_ref=source_ref), source_ref=source_ref)) for element_index, arg_name in enumerate(arg_names): if getKind(arg_name) == "Name": arg_var = outer_body.createProvidedVariable(arg_name.id) outer_body.registerProvidedVariable(arg_var) statements.append( StatementAssignmentVariable( variable=arg_var, source=ExpressionSpecialUnpack( value=ExpressionTempVariableRef( variable=iter_var, source_ref=source_ref), count=element_index + 1, expected=len(arg_names), starred=False, source_ref=source_ref), source_ref=source_ref)) accesses.append( ExpressionVariableRef(variable=arg_var, source_ref=source_ref)) elif getKind(arg_name) == "Tuple": accesses.extend( unpackFrom(source=ExpressionSpecialUnpack( value=ExpressionTempVariableRef(variable=iter_var, source_ref=source_ref), count=element_index + 1, expected=len(arg_names), starred=False, source_ref=source_ref), arg_names=arg_name.elts)) sub_special_index += 1 else: assert False, arg_name statements.append( StatementSpecialUnpackCheck(iterator=ExpressionTempVariableRef( variable=iter_var, source_ref=source_ref), count=len(arg_names), source_ref=source_ref)) return accesses
def wrapSuperBuiltin(type, object, source_ref): if type is None and python_version >= 300: provider = node.getParentVariableProvider() type = ExpressionVariableRef(variable_name="__class__", source_ref=source_ref) # Ought to be already closure taken. type.setVariable( provider.getVariableForReference(variable_name="__class__")) from nuitka.nodes.NodeMakingHelpers import makeRaiseExceptionReplacementExpression if not type.getVariable().isClosureReference(): return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 331 else "RuntimeError", exception_value="super(): __class__ cell not found", ) if object is None and provider.getParameters().getArgumentCount( ) > 0: par1_name = provider.getParameters().getArgumentNames()[0] # TODO: Nested first argument would kill us here, need a test # for that. object = ExpressionVariableRef(variable_name=par1_name, source_ref=source_ref) object.setVariable( node.getParentVariableProvider().getVariableForReference( variable_name=par1_name)) if not object.getVariable().isParameterVariable(): return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 330 else "RuntimeError", exception_value="super(): __class__ cell not found", ) return ExpressionBuiltinSuper(super_type=type, super_object=object, source_ref=source_ref)
def onEnterNode(self, node): if node.isExpressionVariableNameRef(): provider = node.provider try: variable = self._attachVariable(node, provider) except MaybeLocalVariableUsage: variable_name = node.getVariableName() node.replaceWith( ExpressionLocalsVariableRefORFallback( locals_scope=provider.getLocalsScope(), variable_name=variable_name, fallback_node=ExpressionVariableRef( variable=node.getParentModule( ).getVariableForReference(variable_name), source_ref=node.source_ref), source_ref=node.source_ref)) else: node.replaceWith( ExpressionVariableRef(variable=variable, source_ref=node.source_ref)) variable.addVariableUser(provider)
def _buildInplaceAssignVariableNode(provider, variable_ref, tmp_variable1, tmp_variable2, operator, expression, source_ref): assert variable_ref.isExpressionTargetVariableRef(), variable_ref return ( # First assign the target value to a temporary variable. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable1.makeReference(provider), source_ref=source_ref), source=ExpressionVariableRef( variable_name=variable_ref.getVariableName(), source_ref=source_ref), source_ref=source_ref), # Second assign the inplace result to a temporary variable. StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_variable2.makeReference(provider), source_ref=source_ref), source=ExpressionOperationBinaryInplace( operator=operator, left=ExpressionTempVariableRef( variable=tmp_variable1.makeReference(provider), source_ref=source_ref), right=expression, source_ref=source_ref), source_ref=source_ref), # Copy it over, if the reference values change, i.e. IsNot is true. StatementConditional( condition=ExpressionComparisonIsNOT( left=ExpressionTempVariableRef( variable=tmp_variable1.makeReference(provider), source_ref=source_ref), right=ExpressionTempVariableRef( variable=tmp_variable2.makeReference(provider), source_ref=source_ref), source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=variable_ref.makeCloneAt(source_ref), source=ExpressionTempVariableRef( variable=tmp_variable2.makeReference(provider), source_ref=source_ref), source_ref=source_ref)), no_branch=None, source_ref=source_ref))
def onEnterNode(self, node): if node.isExpressionVariableNameRef(): provider = node.getParentVariableProvider() try: variable = self._attachVariable(node, provider) except MaybeLocalVariableUsage: variable_name = node.getVariableName() node.replaceWith( ExpressionLocalsVariableRef( variable_name=variable_name, fallback_variable=node.getParentModule( ).getVariableForReference(variable_name), source_ref=node.getSourceReference())) else: node.replaceWith( ExpressionVariableRef(variable=variable, source_ref=node.source_ref)) variable.addVariableUser(provider) elif node.isExpressionVariableRef(): provider = node.getParentVariableProvider() variable = node.getVariable() if variable is None: try: variable = self._attachVariable(node, provider) except MaybeLocalVariableUsage: variable_name = node.getVariableName() node.replaceWith( ExpressionLocalsVariableRef( variable_name=variable_name, fallback_variable=node.getParentModule( ).getVariableForReference(variable_name), source_ref=node.getSourceReference())) else: node.setVariable(variable) variable.addVariableUser(provider) else: variable.addVariableUser(provider)
def _buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity, pylint: disable=R0914,R0915 # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statement_nodes, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope(name="class_creation", allow_closure=True) tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases") tmp_class_decl_dict = provider.allocateTempVariable(temp_scope=temp_scope, name="class_decl_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope=temp_scope, name="metaclass") tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared") class_creation_function = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, flags=set(), source_ref=source_ref) if python_version >= 340 and False: # TODO: Temporarily reverted: tmp_class = class_creation_function.allocateTempVariable( temp_scope=None, name="__class__") class_target_variable_ref = ExpressionTargetTempVariableRef( variable=tmp_class, source_ref=source_ref) class_variable_ref = ExpressionTempVariableRef(variable=tmp_class, source_ref=source_ref) else: class_variable = class_creation_function.getVariableForAssignment( "__class__") class_target_variable_ref = ExpressionTargetVariableRef( variable_name="__class__", variable=class_variable, source_ref=source_ref) class_variable_ref = ExpressionVariableRef(variable_name="__class__", variable=class_variable, source_ref=source_ref) code_object = CodeObjectSpec(co_name=node.name, co_kind="Class", co_varnames=(), co_argcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False) body = buildFrameNode(provider=class_creation_function, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref module_variable = class_creation_function.getVariableForAssignment( "__module__") statements = [ StatementSetLocals(new_locals=ExpressionTempVariableRef( variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", variable=module_variable, source_ref=source_ref), source=makeConstantRefNode( constant=provider.getParentModule().getFullName(), source_ref=source_ref, user_provided=True), source_ref=source_ref) ] if class_doc is not None: doc_variable = class_creation_function.getVariableForAssignment( "__doc__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", variable=doc_variable, source_ref=source_ref), source=makeConstantRefNode(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref)) # The "__qualname__" attribute is new in Python 3.3. if python_version >= 330: qualname = class_creation_function.getFunctionQualname() qualname_variable = class_creation_function.getVariableForAssignment( "__qualname__") if python_version < 340: qualname_ref = makeConstantRefNode(constant=qualname, source_ref=source_ref, user_provided=True) else: qualname_ref = ExpressionFunctionQualnameRef( function_body=class_creation_function, source_ref=source_ref, ) statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__qualname__", variable=qualname_variable, source_ref=source_ref), source=qualname_ref, source_ref=source_ref)) if python_version >= 340: qualname_assign = statements[-1] if python_version >= 360 and \ class_creation_function.needsAnnotationsDictionary(): annotations_variable = class_creation_function.getVariableForAssignment( "__annotations__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__annotations__", variable=annotations_variable, source_ref=source_ref), source=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref)) statements.append(body) statements += [ StatementAssignmentVariable( variable_ref=class_target_variable_ref, source=ExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=(makeConstantRefNode(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), ExpressionBuiltinLocals(source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementReturn(expression=class_variable_ref, source_ref=source_ref) ] body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained. class_creation_function.setBody(body) class_creation_function.registerProvidedVariable(tmp_bases) class_creation_function.registerProvidedVariable(tmp_class_decl_dict) class_creation_function.registerProvidedVariable(tmp_metaclass) class_creation_function.registerProvidedVariable(tmp_prepared) # The class body is basically a function that implicitly, at the end # returns its created class and cannot have other return statements # contained. decorated_body = ExpressionFunctionCall( function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef( function_body=class_creation_function, source_ref=source_ref), code_object=code_object, defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref) for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) statements = ( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases, source_ref=source_ref), source=makeSequenceCreationOrConstant(sequence_kind="tuple", elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source=makeDictCreationOrConstant(keys=[ makeConstantRefNode(constant=keyword.arg, source_ref=source_ref, user_provided=True) for keyword in node.keywords ], values=[ buildNode( provider, keyword.value, source_ref) for keyword in node.keywords ], source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), source=ExpressionSelectMetaclass(metaclass=ExpressionConditional( condition=ExpressionComparisonIn( left=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=ExpressionConditional( condition=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), expression_no=ExpressionBuiltinRef(builtin_name="type", source_ref=source_ref), expression_yes=ExpressionBuiltinType1( value=ExpressionSubscriptLookup( subscribed=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), subscript=makeConstantRefNode( constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), bases=ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref_orig), StatementConditional( condition=ExpressionComparisonIn( left=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), no_branch=None, yes_branch=makeStatementsSequenceFromStatement( statement=StatementDictOperationRemove( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref)), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_prepared, source_ref=source_ref), source=ExpressionConditional( condition=ExpressionBuiltinHasattr( # pylint: disable=E1120,E1123 object=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), name=makeConstantRefNode(constant="__prepare__", source_ref=source_ref, user_provided=True), source_ref=source_ref), expression_no=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), expression_yes=ExpressionCall( called=ExpressionAttributeLookup( source=ExpressionTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref), args=ExpressionMakeTuple( elements=(makeConstantRefNode(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef( variable=tmp_bases, source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable(variable_ref=ExpressionTargetVariableRef( variable_name=node.name, source_ref=source_ref), source=decorated_body, source_ref=source_ref), ) if python_version >= 340: class_assign = statements[-1] class_creation_function.qualname_setup = class_assign, qualname_assign final = (StatementReleaseVariable(variable=tmp_bases, source_ref=source_ref), StatementReleaseVariable(variable=tmp_class_decl_dict, source_ref=source_ref), StatementReleaseVariable(variable=tmp_metaclass, source_ref=source_ref), StatementReleaseVariable(variable=tmp_prepared, source_ref=source_ref)) return makeTryFinallyStatement(provider=provider, tried=statements, final=final, source_ref=source_ref)
def wrapSuperBuiltin(type_arg, object_arg, source_ref): if type_arg is None and python_version >= 300: if provider.isCompiledPythonModule(): return makeRaiseExceptionReplacementExpression( expression=node, exception_type="RuntimeError", exception_value="super(): no arguments", ) class_variable = provider.getVariableForReference( variable_name="__class__") provider.trace_collection.getVariableCurrentTrace( class_variable).addUsage() type_arg = ExpressionVariableRef( # Ought to be already closure taken due to "super" flag in # tree building. variable=class_variable, source_ref=source_ref, ) # If we already have this as a local variable, then use that # instead. type_arg_owner = type_arg.getVariable().getOwner() if type_arg_owner is provider or not ( type_arg_owner.isExpressionFunctionBody() or type_arg_owner.isExpressionClassBody()): type_arg = None if type_arg is None: return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 331 else "RuntimeError", exception_value="super(): __class__ cell not found", ) if object_arg is None: if (provider.isExpressionGeneratorObjectBody() or provider.isExpressionCoroutineObjectBody() or provider.isExpressionAsyncgenObjectBody()): parameter_provider = provider.getParentVariableProvider() else: parameter_provider = provider if parameter_provider.getParameters().getArgumentCount() > 0: par1_name = parameter_provider.getParameters( ).getArgumentNames()[0] object_variable = provider.getVariableForReference( variable_name=par1_name) provider.trace_collection.getVariableCurrentTrace( object_variable).addUsage() object_arg = ExpressionVariableRef( variable=object_variable, source_ref=source_ref) if not object_arg.getVariable().isParameterVariable(): return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 300 else "RuntimeError", exception_value="super(): __class__ cell not found", ) else: return makeRaiseExceptionReplacementExpression( expression=node, exception_type="RuntimeError", exception_value="super(): no arguments", ) return ExpressionBuiltinSuper(super_type=type_arg, super_object=object_arg, source_ref=source_ref)
def buildFunctionWithParsing(provider, function_kind, name, function_doc, flags, node, source_ref): # This contains a complex re-formulation for nested parameter functions. # pylint: disable=R0914 kind = getKind(node) assert kind in ("FunctionDef", "Lambda", "AsyncFunctionDef"), "unsupported for kind " + kind def extractArg(arg): if arg is None: return None elif type(arg) is str: return mangleName(arg, provider) elif getKind(arg) == "Name": return mangleName(arg.id, provider) elif getKind(arg) == "arg": return mangleName(arg.arg, provider) elif getKind(arg) == "Tuple": # These are to be re-formulated on the outside. assert False else: assert False, getKind(arg) special_args = {} def extractNormalArgs(args): normal_args = [] for arg in args: if type(arg) is not str and getKind(arg) == "Tuple": special_arg_name = ".%d" % (len(special_args) + 1) special_args[special_arg_name] = arg.elts normal_args.append(special_arg_name) else: normal_args.append(extractArg(arg)) return normal_args normal_args = extractNormalArgs(node.args.args) parameters = ParameterSpec( ps_name=name, ps_normal_args=normal_args, ps_kw_only_args=[extractArg(arg) for arg in node.args.kwonlyargs] if python_version >= 300 else [], ps_list_star_arg=extractArg(node.args.vararg), ps_dict_star_arg=extractArg(node.args.kwarg), ps_default_count=len(node.args.defaults)) message = parameters.checkValid() if message is not None: SyntaxErrors.raiseSyntaxError(message, source_ref) code_object = CodeObjectSpec( co_name=name, co_kind=function_kind, co_varnames=parameters.getParameterNames(), co_argcount=parameters.getArgumentCount(), co_kwonlyargcount=parameters.getKwOnlyParameterCount(), co_has_starlist=parameters.getStarListArgumentName() is not None, co_has_stardict=parameters.getStarDictArgumentName() is not None) outer_body = ExpressionFunctionBody(provider=provider, name=name, flags=flags, doc=function_doc, parameters=parameters, source_ref=source_ref) if special_args: inner_name = name.strip("<>") + "$inner" inner_arg_names = [] iter_vars = [] values = [] statements = [] def unpackFrom(source, arg_names): accesses = [] sub_special_index = 0 iter_var = outer_body.allocateTempVariable( None, "arg_iter_%d" % len(iter_vars)) iter_vars.append(iter_var) statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=iter_var, source_ref=source_ref), source=ExpressionBuiltinIter1(value=source, source_ref=source_ref), source_ref=source_ref)) for element_index, arg_name in enumerate(arg_names): if getKind(arg_name) == "Name": inner_arg_names.append(arg_name.id) arg_var = outer_body.allocateTempVariable( None, "tmp_" + arg_name.id) statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=arg_var, source_ref=source_ref), source=ExpressionSpecialUnpack( value=ExpressionTempVariableRef( variable=iter_var, source_ref=source_ref), count=element_index + 1, expected=len(arg_names), source_ref=source_ref), source_ref=source_ref)) accesses.append( ExpressionTempVariableRef(variable=arg_var, source_ref=source_ref)) elif getKind(arg_name) == "Tuple": accesses.extend( unpackFrom(source=ExpressionSpecialUnpack( value=ExpressionTempVariableRef( variable=iter_var, source_ref=source_ref), count=element_index + 1, expected=len(arg_names), source_ref=source_ref), arg_names=arg_name.elts)) sub_special_index += 1 else: assert False, arg_name statements.append( StatementSpecialUnpackCheck(iterator=ExpressionTempVariableRef( variable=iter_var, source_ref=source_ref), count=len(arg_names), source_ref=source_ref)) return accesses for arg_name in parameters.getParameterNames(): if arg_name.startswith('.'): source = ExpressionVariableRef(variable_name=arg_name, source_ref=source_ref) values.extend(unpackFrom(source, special_args[arg_name])) else: values.append( ExpressionVariableRef(variable_name=arg_name, source_ref=source_ref)) inner_arg_names.append(arg_name) inner_parameters = ParameterSpec(ps_name=inner_name, ps_normal_args=inner_arg_names, ps_kw_only_args=(), ps_list_star_arg=None, ps_dict_star_arg=None, ps_default_count=None) function_body = ExpressionFunctionBody(provider=outer_body, name=inner_name, flags=flags, doc=function_doc, parameters=inner_parameters, source_ref=source_ref) statements.append( StatementReturn(ExpressionFunctionCall( function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef( function_body=function_body, source_ref=source_ref), code_object=code_object, defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=values, source_ref=source_ref), source_ref=source_ref)) outer_body.setBody( makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider, tried=statements, final=[ StatementReleaseVariable(variable=variable, source_ref=source_ref) for variable in outer_body.getTempVariables() ], source_ref=source_ref, public_exc=False))) else: function_body = outer_body return outer_body, function_body, code_object
def getDictUnpackingHelper(): helper_name = "_unpack_dict" result = ExpressionFunctionBody( provider = getInternalModule(), name = helper_name, doc = None, parameters = ParameterSpec( ps_name = helper_name, ps_normal_args = (), ps_list_star_arg = "args", ps_dict_star_arg = None, ps_default_count = 0, ps_kw_only_args = () ), flags = set(), source_ref = internal_source_ref ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "dict") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried = StatementAssignmentVariable( variable = tmp_item_variable, source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "StopIteration", handler_body = StatementLoopBreak( source_ref = internal_source_ref ), source_ref = internal_source_ref ), makeTryExceptSingleHandlerNode( tried = StatementDictOperationUpdate( dict_arg = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "AttributeError", handler_body = StatementRaiseException( exception_type = ExpressionBuiltinMakeException( exception_name = "TypeError", args = ( makeBinaryOperationNode( operator = "Mod", left = makeConstantRefNode( constant = """\ '%s' object is not a mapping""", source_ref = internal_source_ref, user_provided = True ), right = ExpressionMakeTuple( elements = ( ExpressionAttributeLookup( source = ExpressionBuiltinType1( value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), attribute_name = "__name__", source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), ), source_ref = internal_source_ref ), exception_value = None, exception_trace = None, exception_cause = None, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) args_variable = result.getVariableForAssignment( variable_name = "args" ) final = ( StatementReleaseVariable( variable = tmp_result_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_iter_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_item_variable, source_ref = internal_source_ref ), # We get handed our args responsibility. StatementDelVariable( variable = args_variable, tolerant = False, source_ref = internal_source_ref ) ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable = tmp_iter_variable, source = ExpressionBuiltinIter1( value = ExpressionVariableRef( variable = args_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementAssignmentVariable( variable = tmp_result_variable, source = makeConstantRefNode( constant = {}, source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementLoop( body = loop_body, source_ref = internal_source_ref ), StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider = result, tried = tried, final = final, source_ref = internal_source_ref ) ) ) return result
def _buildContractionNode(provider, node, name, emit_class, start_value, assign_provider, source_ref): # The contraction nodes are reformulated to function bodies, with loops as # described in the developer manual. They use a lot of temporary names, # nested blocks, etc. and so a lot of variable names. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=R0912,R0914 # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. assert provider.isParentVariableProvider(), provider function_body = ExpressionFunctionBody(provider=provider, name=name, doc=None, parameters=ParameterSpec( name="contraction", normal_args=("__iterator", ), list_star_arg=None, dict_star_arg=None, default_count=0, kw_only_args=()), source_ref=source_ref) if start_value is not None: container_tmp = function_body.allocateTempVariable( temp_scope=None, name="contraction_result") else: container_tmp = None outer_iter_ref = ExpressionVariableRef(variable_name="__iterator", source_ref=source_ref) statements, del_statements = _buildContractionBodyNode( function_body=function_body, assign_provider=assign_provider, provider=provider, node=node, emit_class=emit_class, outer_iter_ref=outer_iter_ref, temp_scope=None, start_value=start_value, container_tmp=container_tmp, source_ref=source_ref, ) if start_value is not None: statements.append( StatementReturn(expression=ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), source_ref=source_ref)) statements = (makeTryFinallyStatement( tried=statements, final=del_statements, source_ref=source_ref.atInternal()), ) function_body.setBody( StatementsFrame(statements=statements, guard_mode="pass_through" if emit_class is not ExpressionYield else "generator", var_names=(), arg_count=0, kw_only_count=0, has_starlist=False, has_stardict=False, code_name="contraction", source_ref=source_ref)) return ExpressionFunctionCall(function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(ExpressionBuiltinIter1( value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), ), source_ref=source_ref)
def getClassBasesMroConversionHelper(): helper_name = "_mro_entries_conversion" result = makeInternalHelperFunctionBody( name=helper_name, parameters=ParameterSpec( ps_name=helper_name, ps_normal_args=("bases", ), ps_pos_only_args=(), ps_list_star_arg=None, ps_dict_star_arg=None, ps_default_count=0, ps_kw_only_args=(), ), inline_const_args=False, # TODO: Allow this. ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "list") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "base") args_variable = result.getVariableForAssignment(variable_name="bases") non_type_case = makeStatementConditional( condition=ExpressionAttributeCheck( expression=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), attribute_name="__mro_entries__", source_ref=internal_source_ref, ), yes_branch=StatementExpressionOnly( expression=ExpressionListOperationExtend( list_arg=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), value=makeExpressionCall( called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), attribute_name="__mro_entries__", source_ref=internal_source_ref, ), args=makeExpressionMakeTuple( elements=(ExpressionVariableRef( variable=args_variable, source_ref=internal_source_ref), ), source_ref=internal_source_ref, ), kw=None, source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), no_branch=StatementListOperationAppend( list_arg=ExpressionTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef(variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ) type_case = StatementListOperationAppend( list_arg=ExpressionTempVariableRef(variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef(variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ) loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable=tmp_item_variable, source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), exception_name="StopIteration", handler_body=StatementLoopBreak(source_ref=internal_source_ref), source_ref=internal_source_ref, ), makeStatementConditional( condition=ExpressionConditionalAnd( left=ExpressionBuiltinIsinstance( instance=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), classes=makeConstantRefNode( constant=type, source_ref=internal_source_ref), source_ref=internal_source_ref, ), right=ExpressionBuiltinIssubclass( cls=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), classes=makeConstantRefNode( constant=type, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), yes_branch=type_case, no_branch=non_type_case, source_ref=internal_source_ref, ), ) final = ( StatementReleaseVariable(variable=args_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_result_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_iter_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_item_variable, source_ref=internal_source_ref), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=tmp_iter_variable, source=ExpressionBuiltinIter1( value=ExpressionVariableRef(variable=args_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), StatementAssignmentVariable( variable=tmp_result_variable, source=makeConstantRefNode(constant=[], source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementLoop(loop_body=loop_body, source_ref=internal_source_ref), StatementReturn( expression=ExpressionBuiltinTuple( value=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), ) result.setChild( "body", makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider=result, tried=tried, final=final, source_ref=internal_source_ref, )), ) return result
def getListUnpackingHelper(): helper_name = "_unpack_list" result = ExpressionFunctionBody( provider = getInternalModule(), name = helper_name, doc = None, parameters = ParameterSpec( name = helper_name, normal_args = (), list_star_arg = "args", dict_star_arg = None, default_count = 0, kw_only_args = () ), flags = set(), source_ref = internal_source_ref ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "list") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source = ExpressionBuiltinNext1( value = ExpressionTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), exception_name = "StopIteration", handler_body = StatementLoopBreak( source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementExpressionOnly( expression = ExpressionListOperationExtend( list_arg = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), value = ExpressionTempVariableRef( variable = tmp_item_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) args_variable = result.getVariableForAssignment( variable_name = "args" ) final = ( StatementReleaseVariable( variable = tmp_result_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_iter_variable, source_ref = internal_source_ref ), StatementReleaseVariable( variable = tmp_item_variable, source_ref = internal_source_ref ), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_iter_variable, source_ref = internal_source_ref ), source = ExpressionBuiltinIter1( value = ExpressionVariableRef( variable_name = "args", variable = args_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source = ExpressionConstantRef( constant = [], source_ref = internal_source_ref ), source_ref = internal_source_ref ), StatementLoop( body = loop_body, source_ref = internal_source_ref ), StatementReturn( expression = ExpressionTempVariableRef( variable = tmp_result_variable, source_ref = internal_source_ref ), source_ref = internal_source_ref ) ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider = result, tried = tried, final = final, source_ref = internal_source_ref ) ) ) return result
def wrapSuperBuiltin(type, object, source_ref): if type is None and python_version >= 300: provider = node.getParentVariableProvider() if python_version < 340 or True: # TODO: Temporarily reverted: type = ExpressionVariableRef( variable_name = "__class__", source_ref = source_ref ) # Ought to be already closure taken. type.setVariable( provider.getVariableForClosure( variable_name = "__class__" ) ) # If we already have this as a local variable, then use that # instead. if not type.getVariable().isClosureReference(): type = None else: from nuitka.VariableRegistry import addVariableUsage addVariableUsage(type.getVariable(), provider) else: parent_provider = provider.getParentVariableProvider() class_var = parent_provider.getTempVariable( temp_scope = None, name = "__class__" ) type = ExpressionTempVariableRef( variable = class_var.makeReference(parent_provider).makeReference(provider), source_ref = source_ref ) from nuitka.VariableRegistry import addVariableUsage addVariableUsage(type.getVariable(), provider) from nuitka.nodes.NodeMakingHelpers import \ makeRaiseExceptionReplacementExpression if type is None: return makeRaiseExceptionReplacementExpression( expression = node, exception_type = "SystemError" if python_version < 331 else "RuntimeError", exception_value = "super(): __class__ cell not found", ) if object is None: if provider.getParameters().getArgumentCount() > 0: par1_name = provider.getParameters().getArgumentNames()[0] # TODO: Nested first argument would kill us here, need a # test for that. object = ExpressionVariableRef( variable_name = par1_name, source_ref = source_ref ) object.setVariable( provider.getVariableForReference( variable_name = par1_name ) ) if not object.getVariable().isParameterVariable(): return makeRaiseExceptionReplacementExpression( expression = node, exception_type = "SystemError" if python_version < 330 else "RuntimeError", exception_value = "super(): __class__ cell not found", ) else: return makeRaiseExceptionReplacementExpression( expression = node, exception_type = "RuntimeError", exception_value = "super(): no arguments" ) return ExpressionBuiltinSuper( super_type = type, super_object = object, source_ref = source_ref )
def buildVariableReferenceNode(provider, node, source_ref): return ExpressionVariableRef( variable_name = mangleName(node.id, provider), source_ref = source_ref )
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=too-many-branches,too-many-statements if node.isExpressionVariableNameRef(): provider = node.provider if provider.isExpressionClassBody(): if node.needsFallback(): variable = provider.getVariableForReference( variable_name=node.getVariableName()) new_node = ExpressionLocalsVariableRefOrFallback( locals_scope=provider.getFunctionLocalsScope(), variable_name=node.getVariableName(), fallback=ExpressionVariableRef( variable=variable, source_ref=node.source_ref), source_ref=node.source_ref, ) variable.addVariableUser(provider) else: new_node = ExpressionLocalsVariableRef( locals_scope=provider.getFunctionLocalsScope(), variable_name=node.getVariableName(), source_ref=node.source_ref, ) parent = node.parent node.finalize() parent.replaceChild(node, new_node) elif node.isExpressionTempVariableRef(): if node.getVariable().getOwner() != node.getParentVariableProvider( ): node.getParentVariableProvider().addClosureVariable( node.getVariable()) elif node.isExpressionGeneratorObjectBody(): if python_version >= 300: self._handleNonLocal(node) # Only Python3.4 or later allows for generators to have qualname. if python_version >= 340: self._handleQualnameSetup(node) elif node.isExpressionCoroutineObjectBody(): self._handleNonLocal(node) self._handleQualnameSetup(node) elif node.isExpressionAsyncgenObjectBody(): self._handleNonLocal(node) self._handleQualnameSetup(node) elif node.isExpressionClassBody(): if python_version >= 300: self._handleNonLocal(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) elif node.isExpressionFunctionBody(): if python_version >= 300: self._handleNonLocal(node) # Python 3.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.isCompiledPythonModule(): break if current.isExpressionClassBody(): if seen_function: node.setAttributeName( "_%s%s" % (current.getName().lstrip("_"), attribute_name)) break seen_function = True # Check if continue and break are properly in loops. If not, raise a # syntax error. elif node.isStatementLoopBreak() or node.isStatementLoopContinue(): current = node while True: current = current.getParent() if current.isStatementLoop(): break if current.isParentVariableProvider(): if node.isStatementLoopContinue(): message = "'continue' not properly in loop" else: message = "'break' outside loop" raiseSyntaxError(message, node.getSourceReference())
def _buildContractionNode(provider, node, name, emit_class, start_value, assign_provider, source_ref): # The contraction nodes are reformulated to function bodies, with loops as # described in the developer manual. They use a lot of temporary names, # nested blocks, etc. and so a lot of variable names. There is no good way # around that, and we deal with many cases, due to having generator # expressions sharing this code, pylint: disable=R0912,R0914 # Note: The assign_provider is only to cover Python2 list contractions, # assigning one of the loop variables to the outside scope. assert provider.isParentVariableProvider(), provider function_body = ExpressionFunctionBody( provider=provider, name=name, doc=None, parameters=make_contraction_parameters, source_ref=source_ref) if start_value is not None: container_tmp = function_body.allocateTempVariable(None, "result") statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), source=start_value, source_ref=source_ref.atInternal()) ] else: statements = [] if hasattr(node, "elt"): if start_value is not None: current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionYield function_body.markAsGenerator() current_body = emit_class(buildNode(provider=function_body, node=node.elt, source_ref=source_ref), source_ref=source_ref) else: assert emit_class is ExpressionDictOperationSet current_body = emit_class(ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), key=buildNode( provider=function_body, node=node.key, source_ref=source_ref, ), value=buildNode( provider=function_body, node=node.value, source_ref=source_ref, ), source_ref=source_ref) current_body = StatementExpressionOnly(expression=current_body, source_ref=source_ref) for count, qual in enumerate(reversed(node.generators)): tmp_iter_variable = function_body.allocateTempVariable( temp_scope=None, name="contraction_iter_%d" % count) tmp_value_variable = function_body.allocateTempVariable( temp_scope=None, name="iter_value_%d" % count) # The first iterated value is to be calculated outside of the function # and will be given as a parameter "_iterated", the others are built # inside the function. if qual is node.generators[0]: value_iterator = ExpressionVariableRef(variable_name="__iterator", source_ref=source_ref) else: value_iterator = ExpressionBuiltinIter1(value=buildNode( provider=function_body, node=qual.iter, source_ref=source_ref), source_ref=source_ref) # First create the iterator and store it, next should be loop body nested_statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference(function_body), source_ref=source_ref), source=value_iterator, source_ref=source_ref) ] loop_statements = [ makeTryExceptSingleHandlerNode( tried=makeStatementsSequenceFromStatement( statement=StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_value_variable.makeReference( function_body), source_ref=source_ref), source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable.makeReference( function_body), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref)), exception_name="StopIteration", handler_body=makeStatementsSequenceFromStatement( statement=StatementBreakLoop( source_ref=source_ref.atInternal())), source_ref=source_ref), buildAssignmentStatements( provider=provider if assign_provider else function_body, temp_provider=function_body, node=qual.target, source=ExpressionTempVariableRef( variable=tmp_value_variable.makeReference(function_body), source_ref=source_ref), source_ref=source_ref) ] conditions = buildNodeList(provider=function_body, nodes=qual.ifs, source_ref=source_ref) if len(conditions) == 1: loop_statements.append( StatementConditional( condition=conditions[0], yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) elif len(conditions) > 1: loop_statements.append( StatementConditional( condition=buildAndNode(provider=function_body, values=conditions, source_ref=source_ref), yes_branch=makeStatementsSequenceFromStatement( statement=current_body), no_branch=None, source_ref=source_ref)) else: loop_statements.append(current_body) nested_statements.append( StatementLoop(body=StatementsSequence( statements=mergeStatements(loop_statements), source_ref=source_ref), source_ref=source_ref)) nested_statements.append( StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_iter_variable.makeReference(function_body), source_ref=source_ref), tolerant=False, source_ref=source_ref)) current_body = StatementsSequence(statements=nested_statements, source_ref=source_ref) statements.append(current_body) if start_value is not None: statements.append( StatementReturn(expression=ExpressionTempVariableRef( variable=container_tmp.makeReference(function_body), source_ref=source_ref), source_ref=source_ref)) function_body.setBody( StatementsFrame(statements=mergeStatements(statements), guard_mode="pass_through" if emit_class is not ExpressionYield else "generator", var_names=(), arg_count=0, kw_only_count=0, has_starlist=False, has_stardict=False, code_name="contraction", source_ref=source_ref)) return ExpressionFunctionCall(function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(ExpressionBuiltinIter1( value=buildNode( provider=provider, node=node.generators[0].iter, source_ref=source_ref), source_ref=source_ref), ), source_ref=source_ref)
def _buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, which just has # the complexity, pylint: disable=R0914 # This function is the Python3 special case with special re-formulation as according # to developer manual. class_statements, class_doc = extractDocFromBody(node) # The result will be a temp block that holds the temporary variables. result = StatementTempBlock(source_ref=source_ref) tmp_bases = result.getTempVariable("bases") tmp_class_decl_dict = result.getTempVariable("class_decl_dict") tmp_metaclass = result.getTempVariable("metaclass") tmp_prepared = result.getTempVariable("prepared") class_creation_function = ExpressionFunctionBody( provider=provider, is_class=True, parameters=make_class_parameters, name=node.name, doc=class_doc, source_ref=source_ref) # Hack: class_creation_function.parent = provider body = buildStatementsNode(provider=class_creation_function, nodes=class_statements, frame=True, source_ref=source_ref) if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref.atInternal() statements = [ StatementSetLocals(new_locals=ExpressionTempVariableRef( variable=tmp_prepared.makeReference(result), source_ref=source_ref), source_ref=source_ref.atInternal()), StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", source_ref=source_ref), source=ExpressionConstantRef( constant=provider.getParentModule().getName(), source_ref=source_ref), source_ref=source_ref.atInternal()) ] if class_doc is not None: statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", source_ref=source_ref), source=ExpressionConstantRef(constant=class_doc, source_ref=source_ref), source_ref=source_ref.atInternal())) if Utils.python_version >= 330: if provider.isExpressionFunctionBody(): qualname = provider.getName() + ".<locals>." + node.name else: qualname = node.name statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__qualname__", source_ref=source_ref), source=ExpressionConstantRef(constant=qualname, source_ref=source_ref), source_ref=source_ref.atInternal())) statements += [ body, StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name="__class__", source_ref=source_ref), source=ExpressionCall( called=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), args=ExpressionMakeTuple( elements=(ExpressionConstantRef(constant=node.name, source_ref=source_ref), ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), ExpressionBuiltinLocals(source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref.atInternal()), StatementReturn(expression=ExpressionVariableRef( variable_name="__class__", source_ref=source_ref), source_ref=source_ref.atInternal()) ] body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) # The class body is basically a function that implicitely, at the end returns its # locals and cannot have other return statements contained. class_creation_function.setBody(body) # The class body is basically a function that implicitely, at the end returns its # created class and cannot have other return statements contained. decorated_body = ExpressionFunctionCall( function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef( function_body=class_creation_function, source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref) for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) statements = [ StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), source=ExpressionMakeTuple(elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source=ExpressionMakeDict(pairs=[ ExpressionKeyValuePair( key=ExpressionConstantRef(constant=keyword.arg, source_ref=source_ref), value=buildNode(provider, keyword.value, source_ref), source_ref=source_ref) for keyword in node.keywords ], source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), source=ExpressionSelectMetaclass( metaclass=ExpressionConditional( condition=ExpressionComparison( comparator="In", left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source_ref=source_ref), yes_expression=ExpressionDictOperationGet( dicte=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref), source_ref=source_ref), no_expression=ExpressionConditional( condition=ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), no_expression=ExpressionBuiltinRef( builtin_name="type", source_ref=source_ref), yes_expression=ExpressionBuiltinType1( value=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), subscript=ExpressionConstantRef( constant=0, source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), bases=ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementConditional( condition=ExpressionComparison( comparator="In", left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source_ref=source_ref), no_branch=None, yes_branch=makeStatementsSequenceFromStatement( statement=StatementDictOperationRemove( dicte=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref), source_ref=source_ref)), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_prepared.makeReference(result), source_ref=source_ref), source=ExpressionConditional( condition=ExpressionBuiltinHasattr( object=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), name=ExpressionConstantRef(constant="__prepare__", source_ref=source_ref), source_ref=source_ref), no_expression=ExpressionConstantRef(constant={}, source_ref=source_ref), yes_expression=ExpressionCall( called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(result), source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref), args=ExpressionMakeTuple( elements=(ExpressionConstantRef(constant=node.name, source_ref=source_ref), ExpressionTempVariableRef( variable=tmp_bases.makeReference(result), source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(result), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable(variable_ref=ExpressionTargetVariableRef( variable_name=node.name, source_ref=source_ref), source=decorated_body, source_ref=source_ref) ] result.setBody( StatementsSequence(statements=statements, source_ref=source_ref)) return result
def _buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity, pylint: disable=R0914 # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statements, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope(name="class_creation", allow_closure=True) tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases") tmp_class_decl_dict = provider.allocateTempVariable(temp_scope=temp_scope, name="class_decl_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope=temp_scope, name="metaclass") tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared") class_creation_function = ExpressionFunctionBody( provider=provider, is_class=True, parameters=make_class_parameters, name=node.name, doc=class_doc, source_ref=source_ref) # Hack: This allows some APIs to work although this is not yet officially a # child yet. class_creation_function.parent = provider body = buildStatementsNode(provider=class_creation_function, nodes=class_statements, frame=True, source_ref=source_ref) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref module_variable = class_creation_function.getVariableForAssignment( "__module__") statements = [ StatementSetLocals(new_locals=ExpressionTempVariableRef( variable=tmp_prepared.makeReference(provider), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__module__", variable=module_variable, source_ref=source_ref), source=ExpressionConstantRef( constant=provider.getParentModule().getFullName(), source_ref=source_ref, user_provided=True), source_ref=source_ref) ] if class_doc is not None: doc_variable = class_creation_function.getVariableForAssignment( "__doc__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__doc__", variable=doc_variable, source_ref=source_ref), source=ExpressionConstantRef(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref)) # The "__qualname__" attribute is new in Python 3.3. if Utils.python_version >= 330: qualname = class_creation_function.getFunctionQualname() qualname_variable = class_creation_function.getVariableForAssignment( "__qualname__") statements.append( StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef( variable_name="__qualname__", variable=qualname_variable, source_ref=source_ref), source=ExpressionConstantRef(constant=qualname, source_ref=source_ref, user_provided=True), source_ref=source_ref)) if Utils.python_version >= 340 and False: # TODO: Temporarily reverted: tmp_class = class_creation_function.allocateTempVariable( temp_scope=None, name="__class__") class_target_variable_ref = ExpressionTargetTempVariableRef( variable=tmp_class.makeReference(class_creation_function), source_ref=source_ref) class_variable_ref = ExpressionTempVariableRef( variable=tmp_class.makeReference(class_creation_function), source_ref=source_ref) else: class_variable = class_creation_function.getVariableForAssignment( "__class__") class_target_variable_ref = ExpressionTargetVariableRef( variable_name="__class__", variable=class_variable, source_ref=source_ref) class_variable_ref = ExpressionVariableRef(variable_name="__class__", variable=class_variable, source_ref=source_ref) statements += [ body, StatementAssignmentVariable( variable_ref=class_target_variable_ref, source=ExpressionCall( called=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), args=makeSequenceCreationOrConstant( sequence_kind="tuple", elements=(ExpressionConstantRef(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), ExpressionBuiltinLocals(source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementReturn(expression=class_variable_ref, source_ref=source_ref) ] body = makeStatementsSequence(statements=statements, allow_none=True, source_ref=source_ref) # The class body is basically a function that implicitely, at the end # returns its locals and cannot have other return statements contained. class_creation_function.setBody(body) # The class body is basically a function that implicitely, at the end # returns its created class and cannot have other return statements # contained. decorated_body = ExpressionFunctionCall( function=ExpressionFunctionCreation(function_ref=ExpressionFunctionRef( function_body=class_creation_function, source_ref=source_ref), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref), values=(), source_ref=source_ref) for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) statements = ( StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), source=makeSequenceCreationOrConstant(sequence_kind="tuple", elements=buildNodeList( provider, node.bases, source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source=makeDictCreationOrConstant(keys=[ ExpressionConstantRef(constant=keyword.arg, source_ref=source_ref, user_provided=True) for keyword in node.keywords ], values=[ buildNode( provider, keyword.value, source_ref) for keyword in node.keywords ], lazy_order=False, source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), source=ExpressionSelectMetaclass(metaclass=ExpressionConditional( condition=ExpressionComparison( comparator="In", left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source_ref=source_ref), yes_expression=ExpressionDictOperationGet( dicte=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref), no_expression=ExpressionConditional( condition=ExpressionTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), no_expression=ExpressionBuiltinRef(builtin_name="type", source_ref=source_ref), yes_expression=ExpressionBuiltinType1( value=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), subscript=ExpressionConstantRef( constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), bases=ExpressionTempVariableRef( variable=tmp_bases. makeReference(provider), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref_orig), StatementConditional( condition=ExpressionComparison( comparator="In", left=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), right=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source_ref=source_ref), no_branch=None, yes_branch=makeStatementsSequenceFromStatement( statement=StatementDictOperationRemove( dicte=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), key=ExpressionConstantRef(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref)), source_ref=source_ref), StatementAssignmentVariable( variable_ref=ExpressionTargetTempVariableRef( variable=tmp_prepared.makeReference(provider), source_ref=source_ref), source=ExpressionConditional( condition=ExpressionBuiltinHasattr( object=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), name=ExpressionConstantRef(constant="__prepare__", source_ref=source_ref, user_provided=True), source_ref=source_ref), no_expression=ExpressionConstantRef(constant={}, source_ref=source_ref, user_provided=True), yes_expression=ExpressionCall( called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref), args=ExpressionMakeTuple(elements=( ExpressionConstantRef(constant=node.name, source_ref=source_ref, user_provided=True), ExpressionTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref)), source_ref=source_ref), kw=ExpressionTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), source_ref=source_ref), StatementAssignmentVariable(variable_ref=ExpressionTargetVariableRef( variable_name=node.name, source_ref=source_ref), source=decorated_body, source_ref=source_ref), ) final = (StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_bases.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_class_decl_dict.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_metaclass.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref), StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef( variable=tmp_prepared.makeReference(provider), source_ref=source_ref), tolerant=True, source_ref=source_ref)) return makeTryFinallyStatement(tried=statements, final=final, source_ref=source_ref)
def wrapSuperBuiltin(type_arg, object_arg, source_ref): if type_arg is None and python_version >= 300: provider = node.getParentVariableProvider() if python_version < 340 or True: # TODO: Temporarily reverted: type_arg = ExpressionVariableRef(variable_name="__class__", source_ref=source_ref) # Ought to be already closure taken. type_arg.setVariable(provider.getVariableForClosure(variable_name="__class__")) # If we already have this as a local variable, then use that # instead. if type_arg.getVariable().getOwner() is provider: type_arg = None else: addVariableUsage(type_arg.getVariable(), provider) else: parent_provider = provider.getParentVariableProvider() class_var = parent_provider.getTempVariable(temp_scope=None, name="__class__") type_arg = ExpressionTempVariableRef(variable=class_var, source_ref=source_ref) addVariableUsage(type_arg.getVariable(), provider) if type_arg is None: return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 331 else "RuntimeError", exception_value="super(): __class__ cell not found", ) if object_arg is None: if provider.getParameters().getArgumentCount() > 0: par1_name = provider.getParameters().getArgumentNames()[0] # TODO: Nested first argument would kill us here, need a # test for that. object_arg = ExpressionVariableRef(variable_name=par1_name, source_ref=source_ref) object_arg.setVariable(provider.getVariableForReference(variable_name=par1_name)) if not object_arg.getVariable().isParameterVariable(): return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 330 else "RuntimeError", exception_value="super(): __class__ cell not found", ) else: return makeRaiseExceptionReplacementExpression( expression=node, exception_type="RuntimeError", exception_value="super(): no arguments" ) return ExpressionBuiltinSuper(super_type=type_arg, super_object=object_arg, source_ref=source_ref)
def wrapSuperBuiltin(type_arg, object_arg, source_ref): if type_arg is None and python_version >= 300: if provider.isCompiledPythonModule(): return makeRaiseExceptionReplacementExpression( expression=node, exception_type="RuntimeError", exception_value="super(): no arguments", ) class_variable = provider.getVariableForReference(variable_name="__class__") provider.trace_collection.getVariableCurrentTrace(class_variable).addUsage() type_arg = ExpressionVariableRef( # Ought to be already closure taken due to "super" flag in # tree building. variable=class_variable, source_ref=source_ref, ) # If we already have this as a local variable, then use that # instead. type_arg_owner = type_arg.getVariable().getOwner() if type_arg_owner is provider or not ( type_arg_owner.isExpressionFunctionBody() or type_arg_owner.isExpressionClassBody() ): type_arg = None if type_arg is None: return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 331 else "RuntimeError", exception_value="super(): __class__ cell not found", ) if object_arg is None: if ( provider.isExpressionGeneratorObjectBody() or provider.isExpressionCoroutineObjectBody() or provider.isExpressionAsyncgenObjectBody() ): parameter_provider = provider.getParentVariableProvider() else: parameter_provider = provider if parameter_provider.getParameters().getArgumentCount() > 0: par1_name = parameter_provider.getParameters().getArgumentNames()[0] object_variable = provider.getVariableForReference( variable_name=par1_name ) provider.trace_collection.getVariableCurrentTrace( object_variable ).addUsage() object_arg = ExpressionVariableRef( variable=object_variable, source_ref=source_ref ) if not object_arg.getVariable().isParameterVariable(): return makeRaiseExceptionReplacementExpression( expression=node, exception_type="SystemError" if python_version < 300 else "RuntimeError", exception_value="super(): __class__ cell not found", ) else: return makeRaiseExceptionReplacementExpression( expression=node, exception_type="RuntimeError", exception_value="super(): no arguments", ) return ExpressionBuiltinSuper( super_type=type_arg, super_object=object_arg, source_ref=source_ref )
def buildClassNode3(provider, node, source_ref): # Many variables, due to the huge re-formulation that is going on here, # which just has the complexity and optimization checks: # pylint: disable=I0021,too-many-branches,too-many-locals,too-many-statements # This function is the Python3 special case with special re-formulation as # according to developer manual. class_statement_nodes, class_doc = extractDocFromBody(node) # We need a scope for the temporary variables, and they might be closured. temp_scope = provider.allocateTempScope(name="class_creation") tmp_class_decl_dict = provider.allocateTempVariable(temp_scope=temp_scope, name="class_decl_dict") tmp_metaclass = provider.allocateTempVariable(temp_scope=temp_scope, name="metaclass") tmp_prepared = provider.allocateTempVariable(temp_scope=temp_scope, name="prepared") class_creation_function = ExpressionClassBody(provider=provider, name=node.name, doc=class_doc, source_ref=source_ref) class_locals_scope = class_creation_function.getLocalsScope() # Only local variable, for provision to methods. class_variable = class_locals_scope.getLocalVariable( owner=class_creation_function, variable_name="__class__") class_locals_scope.registerProvidedVariable(class_variable) class_variable_ref = ExpressionVariableRef(variable=class_variable, source_ref=source_ref) parent_module = provider.getParentModule() code_object = CodeObjectSpec( co_name=node.name, co_kind="Class", co_varnames=(), co_freevars=(), co_argcount=0, co_posonlyargcount=0, co_kwonlyargcount=0, co_has_starlist=False, co_has_stardict=False, co_filename=parent_module.getRunTimeFilename(), co_lineno=source_ref.getLineNumber(), future_spec=parent_module.getFutureSpec(), ) body = buildFrameNode( provider=class_creation_function, nodes=class_statement_nodes, code_object=code_object, source_ref=source_ref, ) source_ref_orig = source_ref if body is not None: # The frame guard has nothing to tell its line number to. body.source_ref = source_ref locals_scope = class_creation_function.getLocalsScope() statements = [ StatementSetLocals( locals_scope=locals_scope, new_locals=ExpressionTempVariableRef(variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref, ), StatementAssignmentVariableName( provider=class_creation_function, variable_name="__module__", source=ExpressionModuleAttributeNameRef( variable=provider.getParentModule().getVariableForReference( "__name__"), source_ref=source_ref, ), source_ref=source_ref, ), ] if class_doc is not None: statements.append( StatementAssignmentVariableName( provider=class_creation_function, variable_name="__doc__", source=makeConstantRefNode(constant=class_doc, source_ref=source_ref, user_provided=True), source_ref=source_ref, )) # The "__qualname__" attribute is new in Python3. qualname = class_creation_function.getFunctionQualname() if python_version < 0x340: qualname_ref = makeConstantRefNode(constant=qualname, source_ref=source_ref, user_provided=True) else: qualname_ref = ExpressionFunctionQualnameRef( function_body=class_creation_function, source_ref=source_ref) statements.append( StatementLocalsDictOperationSet( locals_scope=locals_scope, variable_name="__qualname__", value=qualname_ref, source_ref=source_ref, )) if python_version >= 0x340: qualname_assign = statements[-1] if python_version >= 0x360 and class_creation_function.needsAnnotationsDictionary( ): statements.append( StatementLocalsDictOperationSet( locals_scope=locals_scope, variable_name="__annotations__", value=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref, )) statements.append(body) if node.bases: tmp_bases = provider.allocateTempVariable(temp_scope=temp_scope, name="bases") if python_version >= 0x370: tmp_bases_orig = provider.allocateTempVariable( temp_scope=temp_scope, name="bases_orig") def makeBasesRef(): return ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref) else: def makeBasesRef(): return makeConstantRefNode(constant=(), source_ref=source_ref) if python_version >= 0x370 and node.bases: statements.append( makeStatementConditional( condition=makeComparisonExpression( comparator="NotEq", left=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), right=ExpressionTempVariableRef(variable=tmp_bases_orig, source_ref=source_ref), source_ref=source_ref, ), yes_branch=StatementLocalsDictOperationSet( locals_scope=locals_scope, variable_name="__orig_bases__", value=ExpressionTempVariableRef(variable=tmp_bases_orig, source_ref=source_ref), source_ref=source_ref, ), no_branch=None, source_ref=source_ref, )) statements += ( StatementAssignmentVariable( variable=class_variable, source=makeExpressionCall( called=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), args=makeExpressionMakeTuple( elements=( makeConstantRefNode( constant=node.name, source_ref=source_ref, user_provided=True, ), makeBasesRef(), ExpressionBuiltinLocalsRef(locals_scope=locals_scope, source_ref=source_ref), ), source_ref=source_ref, ), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), StatementReturn(expression=class_variable_ref, source_ref=source_ref), ) body = makeStatementsSequenceFromStatement( statement=makeTryFinallyStatement( provider=class_creation_function, tried=mergeStatements(statements, True), final=StatementReleaseLocals(locals_scope=locals_scope, source_ref=source_ref), source_ref=source_ref, )) # The class body is basically a function that implicitly, at the end # returns its locals and cannot have other return statements contained. class_creation_function.setChild("body", body) # The class body is basically a function that implicitly, at the end # returns its created class and cannot have other return statements # contained. decorated_body = class_creation_function for decorator in buildNodeList(provider, reversed(node.decorator_list), source_ref): decorated_body = makeExpressionCall( called=decorator, args=makeExpressionMakeTuple(elements=(decorated_body, ), source_ref=source_ref), kw=None, source_ref=decorator.getSourceReference(), ) if node.keywords and node.keywords[-1].arg is None: keywords = node.keywords[:-1] else: keywords = node.keywords statements = [] if node.bases: statements.append( StatementAssignmentVariable( variable=tmp_bases if python_version < 0x370 else tmp_bases_orig, source=_buildBasesTupleCreationNode(provider=provider, elements=node.bases, source_ref=source_ref), source_ref=source_ref, )) if python_version >= 0x370: bases_conversion = ExpressionFunctionCall( function=ExpressionFunctionCreation( function_ref=ExpressionFunctionRef( function_body=getClassBasesMroConversionHelper(), source_ref=source_ref, ), defaults=(), kw_defaults=None, annotations=None, source_ref=source_ref, ), values=(ExpressionTempVariableRef(variable=tmp_bases_orig, source_ref=source_ref), ), source_ref=source_ref, ) statements.append( StatementAssignmentVariable(variable=tmp_bases, source=bases_conversion, source_ref=source_ref)) statements.append( StatementAssignmentVariable( variable=tmp_class_decl_dict, source=makeDictCreationOrConstant2( keys=[keyword.arg for keyword in keywords], values=[ buildNode(provider, keyword.value, source_ref) for keyword in keywords ], source_ref=source_ref, ), source_ref=source_ref, )) if node.keywords and node.keywords[-1].arg is None: statements.append( StatementDictOperationUpdate( dict_arg=ExpressionVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), value=buildNode(provider, node.keywords[-1].value, source_ref), source_ref=source_ref, )) # Check if there are bases, and if there are, go with the type of the # first base class as a metaclass unless it was specified in the class # decl dict of course. if node.bases: unspecified_metaclass_expression = ExpressionBuiltinType1( value=ExpressionSubscriptLookup( expression=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), subscript=makeConstantRefNode(constant=0, source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ) # Might become empty behind our back during conversion, therefore make the # check at run time for 3.7 or higher. if python_version >= 0x370: unspecified_metaclass_expression = ExpressionConditional( condition=ExpressionTempVariableRef(variable=tmp_bases, source_ref=source_ref), expression_yes=unspecified_metaclass_expression, expression_no=makeExpressionBuiltinTypeRef( builtin_name="type", source_ref=source_ref), source_ref=source_ref, ) else: unspecified_metaclass_expression = makeExpressionBuiltinTypeRef( builtin_name="type", source_ref=source_ref) call_prepare = StatementAssignmentVariable( variable=tmp_prepared, source=makeExpressionCall( called=ExpressionAttributeLookup( expression=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref, ), args=makeExpressionMakeTuple( elements=( makeConstantRefNode(constant=node.name, source_ref=source_ref, user_provided=True), makeBasesRef(), ), source_ref=source_ref, ), kw=ExpressionTempVariableRef(variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ) if python_version >= 0x364: call_prepare = makeStatementsSequenceFromStatements( call_prepare, makeStatementConditional( condition=ExpressionAttributeCheck( expression=ExpressionTempVariableRef( variable=tmp_prepared, source_ref=source_ref), attribute_name="__getitem__", source_ref=source_ref, ), yes_branch=None, no_branch=makeRaiseExceptionExpressionFromTemplate( exception_type="TypeError", template="%s.__prepare__() must return a mapping, not %s", template_args=( ExpressionBuiltinGetattr( expression=ExpressionTempVariableRef( variable=tmp_metaclass, source_ref=source_ref), name=makeConstantRefNode(constant="__name__", source_ref=source_ref), default=makeConstantRefNode(constant="<metaclass>", source_ref=source_ref), source_ref=source_ref, ), ExpressionAttributeLookup( expression=ExpressionBuiltinType1( value=ExpressionTempVariableRef( variable=tmp_prepared, source_ref=source_ref), source_ref=source_ref, ), attribute_name="__name__", source_ref=source_ref, ), ), source_ref=source_ref, ).asStatement(), source_ref=source_ref, ), ) statements += ( StatementAssignmentVariable( variable=tmp_metaclass, source=ExpressionSelectMetaclass( metaclass=ExpressionConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode( constant="metaclass", source_ref=source_ref, user_provided=True, ), dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), expression_yes=ExpressionDictOperationGet( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode( constant="metaclass", source_ref=source_ref, user_provided=True, ), source_ref=source_ref, ), expression_no=unspecified_metaclass_expression, source_ref=source_ref, ), bases=makeBasesRef(), source_ref=source_ref, ), source_ref=source_ref_orig, ), makeStatementConditional( condition=ExpressionDictOperationIn( key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), source_ref=source_ref, ), no_branch=None, yes_branch=StatementDictOperationRemove( dict_arg=ExpressionTempVariableRef( variable=tmp_class_decl_dict, source_ref=source_ref), key=makeConstantRefNode(constant="metaclass", source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ), makeStatementConditional( condition=ExpressionAttributeCheck( expression=ExpressionTempVariableRef(variable=tmp_metaclass, source_ref=source_ref), attribute_name="__prepare__", source_ref=source_ref, ), yes_branch=call_prepare, no_branch=StatementAssignmentVariable( variable=tmp_prepared, source=makeConstantRefNode(constant={}, source_ref=source_ref, user_provided=True), source_ref=source_ref, ), source_ref=source_ref, ), StatementAssignmentVariableName( provider=provider, variable_name=mangleName(node.name, provider), source=decorated_body, source_ref=source_ref, ), ) if python_version >= 0x340: class_creation_function.qualname_setup = node.name, qualname_assign final = [tmp_class_decl_dict, tmp_metaclass, tmp_prepared] if node.bases: final.insert(0, tmp_bases) if python_version >= 0x370: final.insert(0, tmp_bases_orig) return makeTryFinallyStatement( provider=provider, tried=statements, final=tuple( StatementReleaseVariable(variable=variable, source_ref=source_ref) for variable in final), source_ref=source_ref, )
def wrapSuperBuiltin(type_arg, object_arg, source_ref): if type_arg is None and python_version >= 300: provider = node.getParentVariableProvider() type_arg = ExpressionVariableRef( variable_name = "__class__", source_ref = source_ref ) # Ought to be already closure taken. type_arg.setVariable( provider.getVariableForReference( variable_name = "__class__" ) ) # If we already have this as a local variable, then use that # instead. type_arg_owner = type_arg.getVariable().getOwner() if type_arg_owner is provider or \ not (type_arg_owner.isExpressionFunctionBody() or \ type_arg_owner.isExpressionClassBody()): type_arg = None else: addVariableUsage(type_arg.getVariable(), provider) if type_arg is None: return makeRaiseExceptionReplacementExpression( expression = node, exception_type = "SystemError" if python_version < 331 else "RuntimeError", exception_value = "super(): __class__ cell not found", ) if object_arg is None: if provider.isExpressionGeneratorObjectBody(): parameter_provider = provider.getParentVariableProvider() else: parameter_provider = provider if parameter_provider.getParameters().getArgumentCount() > 0: par1_name = parameter_provider.getParameters().getArgumentNames()[0] object_arg = ExpressionVariableRef( variable_name = par1_name, source_ref = source_ref ) object_arg.setVariable( provider.getVariableForReference( variable_name = par1_name ) ) if not object_arg.getVariable().isParameterVariable(): return makeRaiseExceptionReplacementExpression( expression = node, exception_type = "SystemError" if python_version < 330 else "RuntimeError", exception_value = "super(): __class__ cell not found", ) else: return makeRaiseExceptionReplacementExpression( expression = node, exception_type = "RuntimeError", exception_value = "super(): no arguments" ) return ExpressionBuiltinSuper( super_type = type_arg, super_object = object_arg, source_ref = source_ref )
def getSetUnpackingHelper(): helper_name = "_unpack_set" result = makeInternalHelperFunctionBody( name=helper_name, parameters=ParameterSpec( ps_name=helper_name, ps_normal_args=(), ps_list_star_arg="args", ps_dict_star_arg=None, ps_default_count=0, ps_kw_only_args=(), ps_pos_only_args=(), ), ) temp_scope = None tmp_result_variable = result.allocateTempVariable(temp_scope, "set") tmp_iter_variable = result.allocateTempVariable(temp_scope, "iter") tmp_item_variable = result.allocateTempVariable(temp_scope, "keys") loop_body = makeStatementsSequenceFromStatements( makeTryExceptSingleHandlerNode( tried=StatementAssignmentVariable( variable=tmp_item_variable, source=ExpressionBuiltinNext1( value=ExpressionTempVariableRef( variable=tmp_iter_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), exception_name="StopIteration", handler_body=StatementLoopBreak(source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementExpressionOnly( expression=ExpressionSetOperationUpdate( set_arg=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), value=ExpressionTempVariableRef( variable=tmp_item_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), ) args_variable = result.getVariableForAssignment(variable_name="args") final = ( StatementReleaseVariable(variable=tmp_result_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_iter_variable, source_ref=internal_source_ref), StatementReleaseVariable(variable=tmp_item_variable, source_ref=internal_source_ref), ) tried = makeStatementsSequenceFromStatements( StatementAssignmentVariable( variable=tmp_iter_variable, source=ExpressionBuiltinIter1( value=ExpressionVariableRef(variable=args_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), source_ref=internal_source_ref, ), StatementAssignmentVariable( variable=tmp_result_variable, source=makeConstantRefNode(constant=set(), source_ref=internal_source_ref), source_ref=internal_source_ref, ), StatementLoop(body=loop_body, source_ref=internal_source_ref), StatementReturn( expression=ExpressionTempVariableRef( variable=tmp_result_variable, source_ref=internal_source_ref), source_ref=internal_source_ref, ), ) result.setBody( makeStatementsSequenceFromStatement( makeTryFinallyStatement( provider=result, tried=tried, final=final, source_ref=internal_source_ref, ))) 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=too-many-branches,too-many-statements if node.isExpressionVariableNameRef(): 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. owner = variable.getOwner() user = provider while user is not owner: if user.isExpressionFunctionBody() or \ user.isExpressionClassBody(): break user = user.getParentVariableProvider() if owner is not user: if python_version >= 340 or \ (python_version >= 300 and \ variable.isModuleVariable()): node.replaceWith( ExpressionLocalsVariableRef( variable_name=node.getVariableName(), fallback_variable=variable, source_ref=node.getSourceReference())) else: node.replaceWith( ExpressionVariableRef(variable=variable, source_ref=node.source_ref)) else: node.replaceWith( ExpressionVariableRef(variable=variable, source_ref=node.source_ref)) variable.addVariableUser(provider) elif node.isExpressionTempVariableRef(): if node.getVariable().getOwner() != node.getParentVariableProvider( ): node.getParentVariableProvider().addClosureVariable( node.getVariable()) elif node.isExpressionGeneratorObjectBody(): self._handleNonLocal(node) # Only Python3.4 or later allows for generators to have qualname. if python_version >= 340: self._handleQualnameSetup(node) elif node.isExpressionCoroutineObjectBody(): self._handleNonLocal(node) self._handleQualnameSetup(node) elif node.isExpressionAsyncgenObjectBody(): self._handleNonLocal(node) self._handleQualnameSetup(node) elif node.isExpressionClassBody(): self._handleNonLocal(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) elif node.isExpressionFunctionBody(): self._handleNonLocal(node) # Python 3.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.isCompiledPythonModule(): break if current.isExpressionClassBody(): 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.isStatementLoopBreak() or node.isStatementLoopContinue(): current = node while True: current = current.getParent() if current.isStatementLoop(): break if current.isParentVariableProvider(): if node.isStatementLoopContinue(): message = "'continue' not properly in loop" else: message = "'break' outside loop" raiseSyntaxError( message, node.getSourceReference(), )