def buildExtSliceNode(provider, node, source_ref): elements = [] for dim in node.slice.dims: dim_kind = getKind(dim) if dim_kind == "Slice": lower = buildNode(provider, dim.lower, source_ref, True) upper = buildNode(provider, dim.upper, source_ref, True) step = buildNode(provider, dim.step, source_ref, True) element = ExpressionSliceObject(lower=lower, upper=upper, step=step, source_ref=source_ref) elif dim_kind == "Ellipsis": element = ExpressionConstantRef(constant=Ellipsis, source_ref=source_ref, user_provided=True) elif dim_kind == "Index": element = buildNode(provider=provider, node=dim.value, source_ref=source_ref) else: assert False, dim elements.append(element) return makeSequenceCreationOrConstant(sequence_kind="tuple", elements=elements, source_ref=source_ref)
def buildDeleteStatementFromDecoded(kind, detail, source_ref): if kind in ("Name", "Name_Exception"): # Note: Name_Exception is a "del" for exception handlers that doesn't # insist on the variable being defined, user code may do it too, and # that will be fine, so make that tolerant. variable_ref = detail return StatementDelVariable(variable_ref=variable_ref, tolerant=kind == "Name_Exception", source_ref=source_ref) elif kind == "Attribute": lookup_source, attribute_name = detail return StatementDelAttribute(expression=lookup_source, attribute_name=attribute_name, source_ref=source_ref) elif kind == "Subscript": subscribed, subscript = detail return StatementDelSubscript(expression=subscribed, subscript=subscript, source_ref=source_ref) elif kind == "Slice": lookup_source, lower, upper = detail use_sliceobj = Utils.python_version >= 300 if use_sliceobj: return StatementDelSubscript(expression=lookup_source, subscript=ExpressionSliceObject( lower=lower, upper=upper, step=None, source_ref=source_ref), source_ref=source_ref) else: return StatementDelSlice(expression=lookup_source, lower=lower, upper=upper, source_ref=source_ref) elif kind == "Tuple": result = [] for sub_node in detail: result.append( buildDeleteStatementFromDecoded(kind=sub_node[0], detail=sub_node[1], source_ref=source_ref)) return makeStatementsSequenceOrStatement(statements=result, source_ref=source_ref) else: assert False, (kind, detail, source_ref)
def buildSubscriptNode(provider, node, source_ref): # Subscript expression nodes. assert getKind(node.ctx) == "Load", source_ref # The subscribt "[]" operator is one of many different things. This is # expressed by this kind, there are "slice" lookups (two values, even if one # is using default), and then "index" lookups. The form with three argument # is really an "index" lookup, with a slice object. And the "..." lookup is # also an index loopup, with it as the argument. So this splits things into # two different operations, "subscript" with a single "subscript" object. Or # a slice lookup with a lower and higher boundary. These things should # behave similar, but they are different slots. kind = getKind(node.slice) if kind == "Index": return ExpressionSubscriptLookup( subscribed=buildNode(provider, node.value, source_ref), subscript=buildNode(provider, node.slice.value, source_ref), source_ref=source_ref) elif kind == "Slice": lower = buildNode(provider, node.slice.lower, source_ref, True) upper = buildNode(provider, node.slice.upper, source_ref, True) if node.slice.step is not None: step = buildNode(provider, node.slice.step, source_ref) return ExpressionSubscriptLookup( subscribed=buildNode(provider, node.value, source_ref), subscript=ExpressionSliceObject(lower=lower, upper=upper, step=step, source_ref=source_ref), source_ref=source_ref) else: return ExpressionSliceLookup(expression=buildNode( provider, node.value, source_ref), lower=lower, upper=upper, source_ref=source_ref) elif kind == "ExtSlice": return ExpressionSubscriptLookup( subscribed=buildNode(provider, node.value, source_ref), subscript=buildExtSliceNode(provider, node, source_ref), source_ref=source_ref) elif kind == "Ellipsis": return ExpressionSubscriptLookup( subscribed=buildNode(provider, node.value, source_ref), subscript=ExpressionConstantRef(constant=Ellipsis, source_ref=source_ref), source_ref=source_ref) else: assert False, kind
def _buildInplaceAssignSliceNode(lookup_source, lower, upper, tmp_variable1, tmp_variable2, tmp_variable3, operator, expression, source_ref): # Due to the 3 inputs, which we need to also put into temporary variables, # there are too many variables here, but they are needed. # pylint: disable=R0914 # First assign the target value, lower and upper to temporary variables. copy_to_tmp = StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), source = lookup_source, source_ref = source_ref ) final_statements = [ StatementReleaseVariable( variable = tmp_variable1, tolerant = False, source_ref = source_ref ) ] statements = [] if lower is not None: statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable2, source_ref = source_ref ), source = lower, source_ref = source_ref ) ) final_statements.append( StatementReleaseVariable( variable = tmp_variable2, tolerant = True, source_ref = source_ref ) ) lower_ref1 = ExpressionTempVariableRef( variable = tmp_variable2, source_ref = source_ref ) lower_ref2 = ExpressionTempVariableRef( variable = tmp_variable2, source_ref = source_ref ) else: assert tmp_variable2 is None lower_ref1 = lower_ref2 = None if upper is not None: statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = tmp_variable3, source_ref = source_ref ), source = upper, source_ref = source_ref ) ) final_statements.append( StatementReleaseVariable( variable = tmp_variable3, tolerant = True, source_ref = source_ref ) ) upper_ref1 = ExpressionTempVariableRef( variable = tmp_variable3, source_ref = source_ref ) upper_ref2 = ExpressionTempVariableRef( variable = tmp_variable3, source_ref = source_ref ) else: assert tmp_variable3 is None upper_ref1 = upper_ref2 = None use_sliceobj = Utils.python_version >= 300 # Second assign the in-place result over the original value. if use_sliceobj: statements.append( StatementAssignmentSubscript( expression = ExpressionTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), subscript = ExpressionSliceObject( lower = lower_ref1, upper = upper_ref1, step = None, source_ref = source_ref ), source = ExpressionOperationBinaryInplace( operator = operator, left = ExpressionSubscriptLookup( subscribed = ExpressionTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), subscript = ExpressionSliceObject( lower = lower_ref2, upper = upper_ref2, step = None, source_ref = source_ref ), source_ref = source_ref ), right = expression, source_ref = source_ref ), source_ref = source_ref ) ) else: statements.append( StatementAssignmentSlice( expression = ExpressionTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), lower = lower_ref1, upper = upper_ref1, source = ExpressionOperationBinaryInplace( operator = operator, left = ExpressionSliceLookup( expression = ExpressionTempVariableRef( variable = tmp_variable1, source_ref = source_ref ), lower = lower_ref2, upper = upper_ref2, source_ref = source_ref ), right = expression, source_ref = source_ref ), source_ref = source_ref ) ) return ( copy_to_tmp, makeTryFinallyStatement( tried = statements, final = final_statements, source_ref = source_ref ) )
def decodeAssignTarget(provider, node, source_ref, allow_none = False): # Many cases to deal with, because of the different assign targets, # pylint: disable=R0911,R0912 if node is None and allow_none: return None if hasattr(node, "ctx"): assert getKind(node.ctx) in ("Store", "Del") kind = getKind(node) if type(node) is str: return "Name", ExpressionTargetVariableRef( variable_name = mangleName(node, provider), source_ref = source_ref ) elif kind == "Name": return kind, ExpressionTargetVariableRef( variable_name = mangleName(node.id, provider), source_ref = source_ref ) elif kind == "Attribute": return kind, ( buildNode(provider, node.value, source_ref), node.attr ) elif kind == "Subscript": slice_kind = getKind(node.slice) if slice_kind == "Index": return "Subscript", ( buildNode(provider, node.value, source_ref), buildNode(provider, node.slice.value, source_ref) ) elif slice_kind == "Slice": lower = buildNode(provider, node.slice.lower, source_ref, True) upper = buildNode(provider, node.slice.upper, source_ref, True) if node.slice.step is not None: step = buildNode(provider, node.slice.step, source_ref) return "Subscript", ( buildNode(provider, node.value, source_ref), ExpressionSliceObject( lower = lower, upper = upper, step = step, source_ref = source_ref ) ) else: return "Slice", ( buildNode(provider, node.value, source_ref), lower, upper ) elif slice_kind == "ExtSlice": return "Subscript", ( buildNode(provider, node.value, source_ref), buildExtSliceNode(provider, node, source_ref) ) elif slice_kind == "Ellipsis": return "Subscript", ( buildNode(provider, node.value, source_ref), ExpressionConstantRef( constant = Ellipsis, source_ref = source_ref ) ) else: assert False, slice_kind elif kind in ("Tuple", "List"): return "Tuple", tuple( decodeAssignTarget( provider = provider, node = sub_node, source_ref = source_ref, allow_none = False ) for sub_node in node.elts ) elif kind == "Starred": return "Starred", decodeAssignTarget( provider = provider, node = node.value, source_ref = source_ref, allow_none = False ) else: assert False, (source_ref, kind)
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, pylint: disable=R0912,R0914 if kind == "Name": variable_ref = detail return StatementAssignmentVariable( variable_ref = variable_ref, source = source, source_ref = source_ref ) elif kind == "Attribute": lookup_source, attribute_name = detail return StatementAssignmentAttribute( expression = lookup_source, attribute_name = attribute_name, source = source, source_ref = source_ref ) elif kind == "Subscript": subscribed, subscript = detail return StatementAssignmentSubscript( expression = 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 = Utils.python_version >= 300 if use_sliceobj: return StatementAssignmentSubscript( expression = lookup_source, source = source, subscript = ExpressionSliceObject( lower = lower, upper = 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" ) statements = [ StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = source_iter_var, source_ref = source_ref ), source = ExpressionBuiltinIter1( value = source, source_ref = source_ref ), source_ref = source_ref ) ] element_vars = [ provider.allocateTempVariable( temp_scope = temp_scope, name = "element_%d" % ( element_index + 1 ) ) for element_index in range(len(detail)) ] starred = False for element_index, element in enumerate(detail): element_var = element_vars[element_index] if element[0] != "Starred": statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = element_var, source_ref = source_ref ), source = ExpressionSpecialUnpack( value = ExpressionTempVariableRef( variable = source_iter_var, source_ref = source_ref ), count = element_index + 1, source_ref = source_ref ), source_ref = source_ref ) ) else: starred = True statements.append( StatementAssignmentVariable( variable_ref = ExpressionTargetTempVariableRef( variable = element_var, source_ref = source_ref ), source = ExpressionBuiltinList( value = ExpressionTempVariableRef( variable = source_iter_var, source_ref = source_ref ), source_ref = source_ref ), source_ref = source_ref ) ) if not starred: statements.append( StatementSpecialUnpackCheck( iterator = ExpressionTempVariableRef( variable = source_iter_var, source_ref = source_ref ), count = len(detail), source_ref = source_ref ) ) 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 ) ) final_statements = [] final_statements.append( StatementReleaseVariable( variable = source_iter_var, tolerant = True, source_ref = source_ref ) ) # TODO: In that order, or reversed. for element_var in element_vars: final_statements.append( StatementReleaseVariable( variable = element_var, tolerant = True, source_ref = source_ref ) ) return makeTryFinallyStatement( tried = statements, final = final_statements, source_ref = source_ref ) else: assert False, (kind, source_ref, detail)