def computeBuiltinCall(call_node, called): builtin_name = called.getBuiltinName() if builtin_name in _dispatch_dict: new_node = _dispatch_dict[builtin_name](call_node) if new_node is None: return call_node, None, None inspect_node = new_node if inspect_node.isExpressionSideEffects(): inspect_node = inspect_node.getExpression() if inspect_node.isExpressionBuiltinImport(): tags = "new_import" message = "Replaced dynamic builtin import %s with static module import." % inspect_node.kind elif inspect_node.isExpressionBuiltin( ) or inspect_node.isStatementExec(): tags = "new_builtin" message = "Replaced call to builtin with builtin call %s." % inspect_node.kind elif inspect_node.isExpressionRaiseException(): tags = "new_raise" message = "Replaced call to builtin %s with exception raising call." % inspect_node.kind elif inspect_node.isExpressionOperationUnary(): tags = "new_expression" message = "Replaced call to builtin %s with unary operation %s." % ( inspect_node.kind, inspect_node.getOperator()) else: assert False, (builtin_name, "->", inspect_node) # TODO: One day, this should be enabled by default and call either the original # built-in or the optimized above one. That should be done, once we can eliminate # the condition for most cases. if False and isDebug() and not shallMakeModule() and builtin_name: from nuitka.nodes.ConditionalNodes import ExpressionConditional from nuitka.nodes.ComparisonNodes import ExpressionComparisonIs from nuitka.nodes.BuiltinRefNodes import ( ExpressionBuiltinExceptionRef, ExpressionBuiltinOriginalRef, ExpressionBuiltinRef, ) from nuitka.nodes.ExceptionNodes import ExpressionRaiseException source_ref = called.getSourceReference() new_node = ExpressionConditional( condition=ExpressionComparisonIs( left=ExpressionBuiltinRef(builtin_name=builtin_name, source_ref=source_ref), right=ExpressionBuiltinOriginalRef( builtin_name=builtin_name, source_ref=source_ref), source_ref=source_ref), yes_expression=new_node, no_expression=makeRaiseExceptionReplacementExpression( exception_type="RuntimeError", exception_value="Builtin '%s' was overloaded'" % builtin_name, expression=call_node), source_ref=source_ref) return new_node, tags, message else: # TODO: Consider giving warnings, whitelisted potentially return call_node, None, None
def buildFunctionNode(provider, node, source_ref): # Functions have way too many details, pylint: disable=R0912,R0914 assert getKind(node) == "FunctionDef" function_statement_nodes, function_doc = extractDocFromBody(node) function_kind, flags, _written_variables, _non_local_declarations, _global_declarations = \ detectFunctionBodyKind( nodes = function_statement_nodes ) outer_body, function_body, code_object = buildFunctionWithParsing( provider=provider, function_kind=function_kind, name=node.name, function_doc=function_doc, flags=flags, node=node, source_ref=source_ref) if function_kind == "Function": code_body = function_body elif function_kind == "Generator": code_body = ExpressionGeneratorObjectBody(provider=function_body, name=node.name, flags=flags, source_ref=source_ref) for variable in function_body.getVariables(): code_body.getVariableForReference(variable.getName()) else: assert False, function_kind if function_kind == "Generator": function_body.setBody( makeStatementsSequenceFromStatement(statement=StatementReturn( expression=ExpressionMakeGeneratorObject( generator_ref=ExpressionFunctionRef( function_body=code_body, source_ref=source_ref), code_object=code_object, source_ref=source_ref), source_ref=source_ref))) decorators = buildNodeList(provider=provider, nodes=reversed(node.decorator_list), source_ref=source_ref) defaults = buildNodeList(provider=provider, nodes=node.args.defaults, source_ref=source_ref) kw_defaults = buildParameterKwDefaults(provider=provider, node=node, function_body=function_body, source_ref=source_ref) function_statements_body = buildFrameNode(provider=code_body, nodes=function_statement_nodes, code_object=code_object, source_ref=source_ref) if function_kind == "Function": # TODO: Generators might have to raise GeneratorExit instead. function_statements_body = _insertFinalReturnStatement( function_statements_body=function_statements_body, return_class=StatementReturn, source_ref=source_ref) if function_statements_body.isStatementsFrame(): function_statements_body = makeStatementsSequenceFromStatement( statement=function_statements_body) code_body.setBody(function_statements_body) annotations = buildParameterAnnotations(provider, node, source_ref) function_creation = ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=outer_body, source_ref=source_ref), code_object=code_object, defaults=defaults, kw_defaults=kw_defaults, annotations=annotations, source_ref=source_ref) # Add the "staticmethod" decorator to __new__ methods if not provided. # CPython made these optional, but secretly applies them when it does # "class __new__". We add them earlier, so our optimization will see it. if node.name == "__new__" and \ provider.isExpressionClassBody(): for decorator in decorators: if decorator.isExpressionVariableRef() and \ decorator.getVariableName() == "staticmethod": break else: decorators.append( ExpressionBuiltinRef(builtin_name="staticmethod", source_ref=source_ref)) if python_version >= 360 and \ node.name == "__init_subclass__" and \ provider.isExpressionClassBody(): for decorator in decorators: if decorator.isExpressionVariableRef() and \ decorator.getVariableName() == "classmethod": break else: decorators.append( ExpressionBuiltinRef(builtin_name="classmethod", source_ref=source_ref)) decorated_function = function_creation for decorator in decorators: decorated_function = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_function, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) result = StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name=mangleName( node.name, provider), source_ref=source_ref), source=decorated_function, source_ref=source_ref) if python_version >= 340: function_body.qualname_setup = result.getTargetVariableRef() 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,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 wrapEvalBuiltin(source, globals_arg, locals_arg, source_ref): provider = node.getParentVariableProvider() outline_body = ExpressionOutlineBody( provider = node.getParentVariableProvider(), name = "eval_call", source_ref = source_ref ) globals_ref, locals_ref, tried, final = wrapEvalGlobalsAndLocals( provider = provider, globals_node = globals_arg, locals_node = locals_arg, temp_scope = outline_body.getOutlineTempScope(), source_ref = source_ref ) # The wrapping should not relocate to the "source_ref". assert globals_arg is None or \ globals_ref.getSourceReference() == \ globals_arg.getSourceReference() assert locals_arg is None or \ locals_ref.getSourceReference() == \ locals_arg.getSourceReference() source_variable = outline_body.allocateTempVariable( temp_scope = None, name = "source" ) final.setStatements( final.getStatements() + ( StatementDelVariable( variable_ref = ExpressionTargetTempVariableRef( variable = source_variable, source_ref = source_ref ), tolerant = True, source_ref = source_ref ), ) ) strip_choice = ExpressionConstantRef( constant = (" \t",), source_ref = source_ref ) if python_version >= 300: strip_choice = ExpressionConditional( condition = ExpressionComparisonIs( left = ExpressionBuiltinType1( value = ExpressionTempVariableRef( variable = source_variable, source_ref = source_ref ), source_ref = source_ref ), right = ExpressionBuiltinRef( builtin_name = "bytes", source_ref = source_ref ), source_ref = source_ref ), expression_yes = ExpressionConstantRef( constant = (b" \t",), source_ref = source_ref ), expression_no = strip_choice, source_ref = source_ref ) # Source needs some special treatment for eval, if it's a string, it # must be stripped. string_fixup = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = source_variable, source_ref = source_ref ), source = ExpressionCallNoKeywords( called = ExpressionAttributeLookup( source = ExpressionTempVariableRef( variable = source_variable, source_ref = source_ref ), attribute_name = "strip", source_ref = source_ref ), args = strip_choice, source_ref = source_ref ), source_ref = source_ref ) ] statements = ( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = source_variable, source_ref = source_ref ), source = source, source_ref = source_ref, ), StatementConditional( condition = ExpressionOperationNOT( operand = ExpressionBuiltinIsinstance( instance = ExpressionTempVariableRef( variable = source_variable, source_ref = source_ref ), classes = ExpressionBuiltinAnonymousRef( builtin_name = "code", source_ref = source_ref, ), source_ref = source_ref ), source_ref = source_ref ), yes_branch = StatementsSequence( statements = string_fixup, source_ref = source_ref ), no_branch = None, source_ref = source_ref ), StatementReturn( expression = ExpressionBuiltinEval( source_code = ExpressionTempVariableRef( variable = source_variable, source_ref = source_ref ), globals_arg = globals_ref, locals_arg = locals_ref, source_ref = source_ref ), source_ref = source_ref ) ) tried = makeStatementsSequence( statements = ( tried, ) + statements, allow_none = False, source_ref = source_ref ) outline_body.setBody( makeStatementsSequenceFromStatement( statement = makeTryFinallyStatement( provider = outline_body, tried = tried, final = final, source_ref = source_ref ) ) ) return outline_body
def buildFunctionNode(provider, node, source_ref): assert getKind(node) == "FunctionDef" function_statements, function_doc = extractDocFromBody(node) function_body = ExpressionFunctionBody( provider = provider, name = node.name, doc = function_doc, parameters = buildParameterSpec(node.name, node, source_ref), source_ref = source_ref ) # Hack: function_body.parent = provider decorators = buildNodeList( provider = provider, nodes = reversed(node.decorator_list), source_ref = source_ref ) defaults = buildNodeList( provider = provider, nodes = node.args.defaults, source_ref = source_ref ) kw_defaults = buildParameterKwDefaults( provider, node, function_body, source_ref ) pushIndicatorVariable(Ellipsis) function_statements_body = buildStatementsNode( provider = function_body, nodes = function_statements, frame = True, source_ref = source_ref ) popIndicatorVariable() if function_body.isGenerator(): # TODO: raise generator exit? pass elif function_statements_body is None: function_statements_body = makeStatementsSequenceFromStatement( statement = StatementReturn( expression = ExpressionConstantRef( constant = None, source_ref = source_ref.atInternal() ), source_ref = source_ref.atInternal() ) ) elif not function_statements_body.isStatementAborting(): function_statements_body.setStatements( function_statements_body.getStatements() + ( StatementReturn( expression = ExpressionConstantRef( constant = None, source_ref = source_ref ), source_ref = source_ref.atInternal() ), ) ) function_body.setBody( function_statements_body ) annotations = buildParameterAnnotations(provider, node, source_ref) function_creation = ExpressionFunctionCreation( function_ref = ExpressionFunctionRef( function_body, source_ref = source_ref ), defaults = defaults, kw_defaults = kw_defaults, annotations = annotations, source_ref = source_ref ) # Add the staticmethod decorator to __new__ methods if not provided. # CPython made these optional, but applies them to every class __new__. We # add them early, so our optimization will see it. if node.name == "__new__" and not decorators and \ provider.isExpressionFunctionBody() and provider.isClassDictCreation(): decorators = ( ExpressionBuiltinRef( builtin_name = "staticmethod", source_ref = source_ref ), ) decorated_function = function_creation for decorator in decorators: decorated_function = ExpressionCallNoKeywords( called = decorator, args = ExpressionMakeTuple( elements = (decorated_function,), source_ref = source_ref ), source_ref = decorator.getSourceReference() ) result = StatementAssignmentVariable( variable_ref = ExpressionTargetVariableRef( variable_name = node.name, source_ref = source_ref ), source = decorated_function, source_ref = source_ref ) if Utils.python_version >= 340: function_body.qualname_setup = result.getTargetVariableRef() return result
def computeBuiltinCall(call_node, called): # There is some dispatching for how to output various types of changes, # with lots of cases, pylint: disable=R0912 builtin_name = called.getBuiltinName() if builtin_name in _dispatch_dict: new_node = _dispatch_dict[builtin_name](call_node) # Lets just have this contract to return "None" when no change is meant # to be done. assert new_node is not call_node if new_node is None: return call_node, None, None # For traces, we are going to ignore side effects, and output traces # only based on the basis of it. inspect_node = new_node if inspect_node.isExpressionSideEffects(): inspect_node = inspect_node.getExpression() if inspect_node.isExpressionBuiltinImport(): tags = "new_import" message = """\ Replaced dynamic __import__ %s with static module import.""" % ( inspect_node.kind, ) elif inspect_node.isExpressionBuiltin() or \ inspect_node.isStatementExec(): tags = "new_builtin" message = "Replaced call to built-in '%s' with built-in call '%s'." % ( builtin_name, inspect_node.kind, ) elif inspect_node.isExpressionRaiseException(): tags = "new_raise" message = """\ Replaced call to built-in '%s' with exception raising call.""" % ( inspect_node.kind, ) elif inspect_node.isExpressionOperationUnary(): tags = "new_expression" message = """\ Replaced call to built-in '%s' with unary operation '%s'.""" % ( inspect_node.kind, inspect_node.getOperator() ) elif inspect_node.isExpressionCall(): tags = "new_expression" message = """\ Replaced call to built-in '%s' with call.""" % ( inspect_node.kind, ) elif inspect_node.isExpressionOutlineBody(): tags = "new_expression" message = """\ Replaced call to built-in '%s' with outlined call.""" % builtin_name else: assert False, (builtin_name, "->", inspect_node) # TODO: One day, this should be enabled by default and call either the # original built-in or the optimized above one. That should be done, # once we can eliminate the condition for most cases. if False and isDebug() and not shallMakeModule() and builtin_name: source_ref = called.getSourceReference() new_node = ExpressionConditional( condition = ExpressionComparisonIs( left = ExpressionBuiltinRef( builtin_name = builtin_name, source_ref = source_ref ), right = ExpressionBuiltinOriginalRef( builtin_name = builtin_name, source_ref = source_ref ), source_ref = source_ref ), expression_yes = new_node, expression_no = makeRaiseExceptionReplacementExpression( exception_type = "RuntimeError", exception_value = "Built-in '%s' cannot be replaced." % ( builtin_name ), expression = call_node ), source_ref = source_ref ) assert tags != "" return new_node, tags, message else: if False and isDebug() and builtin_name not in _builtin_white_list: warning( "Not handling built-in '%s', consider support." % builtin_name ) return call_node, None, None
def computeBuiltinCall(call_node, called): builtin_name = called.getBuiltinName() if builtin_name in _dispatch_dict: new_node = _dispatch_dict[builtin_name](call_node) # Lets just have this contract to return "None" when no change is meant # to be done. assert new_node is not call_node if new_node is None: return call_node, None, None # For traces, we are going to ignore side effects, and output traces # only based on the basis of it. inspect_node = new_node if inspect_node.isExpressionSideEffects(): inspect_node = inspect_node.getExpression() if inspect_node.isExpressionBuiltinImport(): tags = "new_import" message = """\ Replaced dynamic __import__ %s with static module import.""" % ( inspect_node.kind, ) elif inspect_node.isExpressionBuiltin() or \ inspect_node.isStatementExec(): tags = "new_builtin" message = "Replaced call to builtin %s with builtin call %s." % ( builtin_name, inspect_node.kind, ) elif inspect_node.isExpressionRaiseException(): tags = "new_raise" message = """\ Replaced call to builtin %s with exception raising call.""" % ( inspect_node.kind, ) elif inspect_node.isExpressionOperationUnary(): tags = "new_expression" message = """\ Replaced call to builtin %s with unary operation %s.""" % ( inspect_node.kind, inspect_node.getOperator() ) elif inspect_node.isExpressionCall(): tags = "new_expression" message = """\ Replaced call to builtin %s with call.""" % ( inspect_node.kind, ) elif inspect_node.isExpressionTryFinally(): tags = "new_expression" message = """\ Replaced call to builtin %s with try/finally guarded call.""" % ( inspect_node.getExpression().kind, ) else: assert False, ( builtin_name, "->", inspect_node ) # TODO: One day, this should be enabled by default and call either the # original built-in or the optimized above one. That should be done, # once we can eliminate the condition for most cases. if False and isDebug() and not shallMakeModule() and builtin_name: from nuitka.nodes.NodeMakingHelpers import \ makeRaiseExceptionReplacementExpression source_ref = called.getSourceReference() new_node = ExpressionConditional( condition = ExpressionComparisonIs( left = ExpressionBuiltinRef( builtin_name = builtin_name, source_ref = source_ref ), right = ExpressionBuiltinOriginalRef( builtin_name = builtin_name, source_ref = source_ref ), source_ref = source_ref ), yes_expression = new_node, no_expression = makeRaiseExceptionReplacementExpression( exception_type = "RuntimeError", exception_value = "Builtin '%s' was overloaded'" % ( builtin_name ), expression = call_node ), source_ref = source_ref ) assert tags != "" return new_node, tags, message else: # TODO: Consider giving warnings, whitelisted potentially return call_node, None, None
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 buildFunctionNode(provider, node, source_ref): assert getKind(node) == "FunctionDef" function_statements, function_doc = extractDocFromBody(node) function_body = ExpressionFunctionBody(provider=provider, name=node.name, doc=function_doc, parameters=buildParameterSpec( provider, node.name, node, source_ref), is_class=False, source_ref=source_ref) decorators = buildNodeList(provider=provider, nodes=reversed(node.decorator_list), source_ref=source_ref) defaults = buildNodeList(provider=provider, nodes=node.args.defaults, source_ref=source_ref) kw_defaults = buildParameterKwDefaults(provider=provider, node=node, function_body=function_body, source_ref=source_ref) function_statements_body = buildStatementsNode(provider=function_body, nodes=function_statements, frame=True, source_ref=source_ref) if function_body.isGenerator(): # TODO: raise generator exit? pass else: function_statements_body = _insertFinalReturnStatement( function_statements_body=function_statements_body, source_ref=source_ref) if function_statements_body.isStatementsFrame(): function_statements_body = makeStatementsSequenceFromStatement( statement=function_statements_body) function_body.setBody(function_statements_body) annotations = buildParameterAnnotations(provider, node, source_ref) function_creation = ExpressionFunctionCreation( function_ref=ExpressionFunctionRef(function_body=function_body, source_ref=source_ref), defaults=defaults, kw_defaults=kw_defaults, annotations=annotations, source_ref=source_ref) # Add the "staticmethod" decorator to __new__ methods if not provided. # CPython made these optional, but secretly applies them when it does # "class __new__". We add them earlier, so our optimization will see it. if node.name == "__new__" and \ not decorators and \ provider.isExpressionClassBody(): decorators = (ExpressionBuiltinRef(builtin_name="staticmethod", source_ref=source_ref), ) decorated_function = function_creation for decorator in decorators: decorated_function = ExpressionCallNoKeywords( called=decorator, args=ExpressionMakeTuple(elements=(decorated_function, ), source_ref=source_ref), source_ref=decorator.getSourceReference()) result = StatementAssignmentVariable( variable_ref=ExpressionTargetVariableRef(variable_name=mangleName( node.name, provider), source_ref=source_ref), source=decorated_function, source_ref=source_ref) if Utils.python_version >= 340: function_body.qualname_setup = result.getTargetVariableRef() return result