def runDataComposer(source_dir): data_composer_path = os.path.normpath( os.path.join(os.path.dirname(__file__), "..", "tools", "data_composer")) mapping = { "NUITKA_PACKAGE_HOME": os.path.dirname(os.path.abspath(sys.modules["nuitka"].__path__[0])) } if isExperimental("debug-constants"): mapping["NUITKA_DATACOMPOSER_VERBOSE"] = "1" blob_filename = getConstantBlobFilename(source_dir) with withEnvironmentVarsOverridden(mapping): subprocess.check_call( [ sys.executable, data_composer_path, source_dir, blob_filename, ], shell=False, ) return blob_filename
def pickCodeHelper( prefix, suffix, target_type, left_shape, right_shape, helpers, nonhelpers, source_ref, ): # Lots of details to deal with, # pylint: disable=too-many-locals left_part = left_shape.helper_code right_part = right_shape.helper_code assert left_part != "INVALID", left_shape assert right_part != "INVALID", right_shape if target_type is None: target_part = None else: target_part = target_type.helper_code assert target_part != "INVALID", target_type # Special hack for "NVOID", lets go to "NBOOL more automatically" ideal_helper = "_".join( p for p in (prefix, target_part, left_part, right_part, suffix) if p ) if target_part == "NVOID" and ideal_helper not in helpers: target_part = "NBOOL" ideal_helper = "_".join( p for p in (prefix, target_part, left_part, right_part, suffix) if p ) from .c_types.CTypeNuitkaBools import CTypeNuitkaBoolEnum helper_target = CTypeNuitkaBoolEnum else: helper_target = target_type if ideal_helper in helpers: return HelperCallHandle( helper_name=ideal_helper, target_type=target_type, helper_target=helper_target, left_shape=left_shape, helper_left=left_shape, right_shape=right_shape, helper_right=right_shape, ) if isExperimental("nuitka_ilong"): my_print(ideal_helper) if source_ref is not None and (not nonhelpers or ideal_helper not in nonhelpers): onMissingHelper(ideal_helper, source_ref) fallback_helper = "%s_%s_%s_%s%s" % (prefix, "OBJECT", "OBJECT", "OBJECT", suffix) fallback_helper = "_".join( p for p in (prefix, "OBJECT" if target_part else "", "OBJECT", "OBJECT", suffix) if p ) from .c_types.CTypePyObjectPtrs import CTypePyObjectPtr return HelperCallHandle( helper_name=fallback_helper, target_type=target_type, helper_target=CTypePyObjectPtr, left_shape=left_shape, helper_left=CTypePyObjectPtr, right_shape=right_shape, helper_right=CTypePyObjectPtr, )
def computeStatement(self, trace_collection): variable = self.variable # Special case, boolean temp variables need no "del". # TODO: Later, these might not exist, if we forward propagate them not as "del" # at all if variable.isTempVariableBool(): return ( None, "new_statements", "Removed 'del' statement of boolean '%s' without effect." % (self.getVariableName(), ), ) self.previous_trace = trace_collection.getVariableCurrentTrace( variable) # First eliminate us entirely if we can. if self.previous_trace.mustNotHaveValue(): if self.tolerant: return ( None, "new_statements", "Removed tolerant 'del' statement of '%s' without effect." % (self.getVariableName(), ), ) else: if self.variable.isLocalVariable(): result = makeRaiseExceptionReplacementStatement( statement=self, exception_type="UnboundLocalError", exception_value= """local variable '%s' referenced before assignment""" % variable.getName(), ) else: result = makeRaiseExceptionReplacementStatement( statement=self, exception_type="NameError", exception_value="""name '%s' is not defined""" % variable.getName(), ) return trace_collection.computedStatementResult( result, "new_raise", "Variable del of not initialized variable '%s'" % variable.getName(), ) if not self.tolerant: self.previous_trace.addNameUsage() # TODO: Why doesn't this module variable check not follow from other checks done here, e.g. name usages. # TODO: This currently cannot be done as releases do not create successor traces yet, although they # probably should. if isExperimental( "del_optimization") and not variable.isModuleVariable(): provider = trace_collection.getOwner() if variable.hasAccessesOutsideOf(provider) is False: last_trace = variable.getMatchingDelTrace(self) if last_trace is not None and not last_trace.getMergeOrNameUsageCount( ): if not last_trace.getUsageCount(): result = StatementReleaseVariable( variable=variable, source_ref=self.source_ref) return trace_collection.computedStatementResult( result, "new_statements", "Changed del to release for variable '%s' not used afterwards." % variable.getName(), ) # If not tolerant, we may exception exit now during the __del__ if not self.tolerant and not self.previous_trace.mustHaveValue(): trace_collection.onExceptionRaiseExit(BaseException) # Record the deletion, needs to start a new version then. self.variable_trace = trace_collection.onVariableDel( variable=variable, version=self.variable_version, del_node=self) # Any code could be run, note that. trace_collection.onControlFlowEscape(self) return self, None, None
context=context) def getVariableCodeName(in_context, variable): if in_context: # Closure case: return "closure_" + variable.getCodeName() elif variable.isParameterVariable(): return "par_" + variable.getCodeName() elif variable.isTempVariable(): return "tmp_" + variable.getCodeName() else: return "var_" + variable.getCodeName() enable_bool_ctype = isExperimental("enable_bool_ctype") def getPickedCType(variable, variable_trace, context): """ Return type to use for specific context. """ user = context.getEntryPoint() owner = variable.getEntryPoint() if owner is user: if variable.isSharedTechnically(): result = CTypeCellObject else: if enable_bool_ctype: shapes = variable.getTypeShapes()
def buildAssignmentStatementsFromDecoded(provider, kind, detail, source, source_ref): # This is using many variable names on purpose, so as to give names to the # unpacked detail values, and has many branches due to the many cases # dealt with and it is return driven. # pylint: disable=too-many-branches,too-many-locals,too-many-return-statements,too-many-statements if kind == "Name": if detail in ("_inject_c_code", "_inject_c_decl") and isExperimental("c-code-injection"): if not source.isExpressionConstantStrRef(): general.sysexit( "Error, value assigned to '%s' not be constant str" % detail) if detail == "_inject_c_code": return StatementInjectCCode( c_code=source.getCompileTimeConstant(), source_ref=source_ref) else: return StatementInjectCDecl( c_code=source.getCompileTimeConstant(), source_ref=source_ref) return StatementAssignmentVariableName( provider=provider, variable_name=detail, source=source, source_ref=source_ref, ) elif kind == "Attribute": lookup_source, attribute_name = detail return StatementAssignmentAttribute( expression=lookup_source, attribute_name=mangleName(attribute_name, provider), source=source, source_ref=source_ref, ) elif kind == "Subscript": subscribed, subscript = detail return StatementAssignmentSubscript( subscribed=subscribed, subscript=subscript, source=source, source_ref=source_ref, ) elif kind == "Slice": lookup_source, lower, upper = detail # For Python3 there is no slicing operation, this is always done # with subscript using a slice object. For Python2, it is only done # if no "step" is provided. use_sliceobj = python_version >= 0x300 if use_sliceobj: return StatementAssignmentSubscript( subscribed=lookup_source, source=source, subscript=makeExpressionBuiltinSlice(start=lower, stop=upper, step=None, source_ref=source_ref), source_ref=source_ref, ) else: return StatementAssignmentSlice( expression=lookup_source, lower=lower, upper=upper, source=source, source_ref=source_ref, ) elif kind == "Tuple": temp_scope = provider.allocateTempScope("tuple_unpack") source_iter_var = provider.allocateTempVariable(temp_scope=temp_scope, name="source_iter") element_vars = [ provider.allocateTempVariable(temp_scope=temp_scope, name="element_%d" % (element_index + 1)) for element_index in range(len(detail)) ] starred_list_var = None starred_index = None statements = [] for element_index, element in enumerate(detail): if element[0] == "Starred": if starred_index is not None: raiseSyntaxError( "two starred expressions in assignment" if python_version < 0x390 else "multiple starred expressions in assignment", source_ref.atColumnNumber(0), ) starred_index = element_index for element_index, element in enumerate(detail): element_var = element_vars[element_index] if starred_list_var is not None: statements.insert( starred_index + 1, StatementAssignmentVariable( variable=element_var, source=ExpressionListOperationPop( list_arg=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ), ) elif element[0] != "Starred": statements.append( StatementAssignmentVariable( variable=element_var, source=ExpressionSpecialUnpack( value=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), count=element_index + 1, expected=starred_index or len(detail), starred=starred_index is not None, source_ref=source_ref, ), source_ref=source_ref, )) else: assert starred_index == element_index starred_list_var = element_var statements.append( StatementAssignmentVariable( variable=element_var, source=ExpressionBuiltinList( value=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, )) if starred_list_var is None: statements.append( StatementSpecialUnpackCheck( iterator=ExpressionTempVariableRef( variable=source_iter_var, source_ref=source_ref), count=len(detail), source_ref=source_ref, )) else: statements.insert( starred_index + 1, makeStatementConditional( condition=makeComparisonExpression( comparator="Lt", left=ExpressionBuiltinLen( value=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref, ), right=makeConstantRefNode( constant=len(statements) - starred_index - 1, source_ref=source_ref, ), source_ref=source_ref, ), yes_branch=makeRaiseExceptionExpressionFromTemplate( exception_type="ValueError", template="""\ not enough values to unpack (expected at least %d, got %%d)""" % (len(statements) - 1), template_args=makeBinaryOperationNode( operator="Add", left=ExpressionBuiltinLen( value=ExpressionTempVariableRef( variable=starred_list_var, source_ref=source_ref), source_ref=source_ref, ), right=makeConstantRefNode(constant=starred_index, source_ref=source_ref), source_ref=source_ref, ), source_ref=source_ref, ).asStatement(), no_branch=None, source_ref=source_ref, ), ) if python_version >= 0x370: iter_creation_class = ExpressionBuiltinIterForUnpack else: iter_creation_class = ExpressionBuiltinIter1 statements = [ StatementAssignmentVariable( variable=source_iter_var, source=iter_creation_class(value=source, source_ref=source_ref), source_ref=source_ref, ), makeTryFinallyStatement( provider=provider, tried=statements, final=(StatementReleaseVariable(variable=source_iter_var, source_ref=source_ref), ), source_ref=source_ref, ), ] # When all is done, copy over to the actual assignment targets, starred # or not makes no difference here anymore. for element_index, element in enumerate(detail): if element[0] == "Starred": element = element[1] element_var = element_vars[element_index] statements.append( buildAssignmentStatementsFromDecoded( provider=provider, kind=element[0], detail=element[1], source=ExpressionTempVariableRef(variable=element_var, source_ref=source_ref), source_ref=source_ref, )) # Need to release temporary variables right after successful # usage. statements.append( StatementDelVariable(variable=element_var, tolerant=True, source_ref=source_ref)) final_statements = [] for element_var in element_vars: final_statements.append( StatementReleaseVariable(variable=element_var, source_ref=source_ref)) return makeTryFinallyStatement( provider=provider, tried=statements, final=final_statements, source_ref=source_ref, ) elif kind == "Starred": raiseSyntaxError( "starred assignment target must be in a list or tuple", source_ref.atColumnNumber(0), ) else: assert False, (kind, source_ref, detail)
class ShapeTypeIntOrLong(ShapeBase): if isExperimental("nuitka_ilong"): @staticmethod def getCType(): return CTypeNuitkaIntOrLongStruct @staticmethod def hasShapeSlotLen(): return False @staticmethod def hasShapeSlotInt(): return True @staticmethod def hasShapeSlotLong(): return True @staticmethod def hasShapeSlotFloat(): return True @staticmethod def hasShapeSlotComplex(): return True @staticmethod def hasShapeSlotIter(): return False @staticmethod def hasShapeSlotNext(): return False @staticmethod def hasShapeSlotContains(): return False @classmethod def getOperationBinaryAddShape(cls, right_shape): if right_shape is ShapeUnknown: return operation_result_unknown if right_shape in (ShapeTypeInt, ShapeTypeIntOrLong, ShapeTypeBool): return operation_result_intorlong_noescape if right_shape is ShapeTypeLong: return operation_result_long_noescape if right_shape in (ShapeTypeIntOrLongDerived, ShapeTypeLongDerived): return operation_result_unknown return _getOperationBinaryAddShapeGeneric(cls, right_shape) @classmethod def getComparisonLtShape(cls, right_shape): if right_shape is ShapeUnknown: return operation_result_unknown if right_shape in ( ShapeTypeInt, ShapeTypeLong, ShapeTypeIntOrLong, ShapeTypeBool, ShapeTypeFloat, ): return operation_result_bool_noescape if right_shape is ShapeTypeIntOrLongDerived: return operation_result_unknown return _getComparisonLtShapeGeneric(cls, right_shape)