def makeDictCreationOrConstant(keys, values, lazy_order, source_ref): # Create dictionary node. Tries to avoid it for constant values that are not # mutable. assert len(keys) == len(values) for key, value in zip(keys, values): if not key.isExpressionConstantRef(): constant = False break if not value.isExpressionConstantRef(): constant = False break else: constant = True # Note: This would happen in optimization instead, but lets just do it # immediately to save some time. if constant: # Unless told otherwise, create the dictionary in its full size, so # that no growing occurs and the constant becomes as similar as possible # before being marshaled. result = ExpressionConstantRef( constant = Constants.createConstantDict( lazy_order = not lazy_order, keys = [ key.getConstant() for key in keys ], values = [ value.getConstant() for value in values ] ), source_ref = source_ref, user_provided = True ) else: result = ExpressionMakeDict( pairs = [ ExpressionKeyValuePair( key = key, value = value, source_ref = key.getSourceReference() ) for key, value in zip(keys, values) ], lazy_order = lazy_order, source_ref = source_ref ) if values: result.setCompatibleSourceReference( source_ref = values[-1].getCompatibleSourceReference() ) return result
def computeExpression(self, constraint_collection): pairs = self.getPairs() for pair in pairs: key = pair.getKey() # TODO: Mutable key should cause an exception raise to be produced. if not key.isExpressionConstantRef() or not key.isKnownToBeHashable(): return self, None, None value = pair.getValue() if not value.isExpressionConstantRef(): return self, None, None constant_value = Constants.createConstantDict( keys = [ pair.getKey().getConstant() for pair in pairs ], values = [ pair.getValue().getConstant() for pair in pairs ] ) new_node = makeConstantReplacementNode( constant = constant_value, node = self ) return new_node, "new_constant", """\
def computeExpression(self, constraint_collection): # Children can tell all we need to know, pylint: disable=W0613 pairs = self.getPairs() for count, pair in enumerate(pairs): if pair.willRaiseException(BaseException): from .NodeMakingHelpers import wrapExpressionWithSideEffects # Later elements have no side effects after the element that # raised the exception. result = wrapExpressionWithSideEffects( side_effects = pairs[:count], new_node = pair, old_node = self ) return result, "new_raise", "Dict creation raises exception" for pair in pairs: key = pair.getKey() # TODO: Mutable key should cause something problematic. if not key.isExpressionConstantRef() or key.isMutable(): return self, None, None value = pair.getValue() if not value.isExpressionConstantRef(): return self, None, None constant_value = Constants.createConstantDict( keys = [ pair.getKey().getConstant() for pair in pairs ], values = [ pair.getValue().getConstant() for pair in pairs ], lazy_order = self.lazy_order ) from .NodeMakingHelpers import makeConstantReplacementNode new_node = makeConstantReplacementNode( constant = constant_value, node = self ) return new_node, "new_constant", """\
def computeExpression(self, constraint_collection): pairs = self.getPairs() for count, pair in enumerate(pairs): if pair.willRaiseException(BaseException): # Later elements have no side effects after the element that # raised the exception. result = wrapExpressionWithSideEffects( side_effects = pairs[:count], new_node = pair, old_node = self ) return result, "new_raise", "Dict creation raises exception" for pair in pairs: key = pair.getKey() # TODO: Mutable key should cause an exception raise to be produced. if not key.isExpressionConstantRef() or not key.isKnownToBeHashable(): return self, None, None value = pair.getValue() if not value.isExpressionConstantRef(): return self, None, None constant_value = Constants.createConstantDict( keys = [ pair.getKey().getConstant() for pair in pairs ], values = [ pair.getValue().getConstant() for pair in pairs ], lazy_order = self.lazy_order ) new_node = makeConstantReplacementNode( constant = constant_value, node = self ) return new_node, "new_constant", """\
def computeExpression(self, constraint_collection): # Children can tell all we need to know, pylint: disable=W0613 pairs = self.getPairs() for count, pair in enumerate(pairs): if pair.willRaiseException(BaseException): from .NodeMakingHelpers import wrapExpressionWithSideEffects result = wrapExpressionWithSideEffects( side_effects=pairs[:count], new_node=pair, old_node=self) return result, "new_raise", "Dict creation raises exception" for pair in pairs: key = pair.getKey() # TODO: Mutable key should cause something problematic. if not key.isExpressionConstantRef() or key.isMutable(): return self, None, None value = pair.getValue() if not value.isExpressionConstantRef(): return self, None, None constant_value = Constants.createConstantDict( keys=[pair.getKey().getConstant() for pair in pairs], values=[pair.getValue().getConstant() for pair in pairs], lazy_order=self.lazy_order) from .NodeMakingHelpers import makeConstantReplacementNode new_node = makeConstantReplacementNode(constant=constant_value, node=self) return new_node, "new_constant", """\
def computeExpression(self, trace_collection): pairs = self.subnode_pairs is_constant = True for pair in pairs: key = pair.subnode_key if key.isKnownToBeHashable() is False: side_effects = [] for pair2 in pairs: side_effects.extend(pair2.extractSideEffects()) if pair2 is pair: break result = makeRaiseExceptionExpressionFromTemplate( exception_type="TypeError", template="unhashable type: '%s'", template_args=makeExpressionAttributeLookup( expression=key.extractUnhashableNodeType(), attribute_name="__name__", source_ref=key.source_ref, ), source_ref=key.source_ref, ) result = wrapExpressionWithSideEffects( side_effects=side_effects, old_node=key, new_node=result ) return ( result, "new_raise", "Dictionary key is known to not be hashable.", ) if is_constant: if not key.isExpressionConstantRef(): is_constant = False else: value = pair.subnode_value if not value.isExpressionConstantRef(): is_constant = False if not is_constant: return self, None, None constant_value = Constants.createConstantDict( keys=[pair.subnode_key.getCompileTimeConstant() for pair in pairs], values=[pair.subnode_value.getCompileTimeConstant() for pair in pairs], ) new_node = makeConstantReplacementNode( constant=constant_value, node=self, user_provided=True ) return ( new_node, "new_constant", """\ Created dictionary found to be constant.""", )
def computeExpression(self, trace_collection): pairs = self.getPairs() is_constant = True for pair in pairs: key = pair.getKey() if key.isKnownToBeHashable() is False: side_effects = [] for pair2 in pairs: side_effects.extend(pair2.extractSideEffects()) if pair2 is pair: break result = makeRaiseExceptionExpressionFromTemplate( exception_type="TypeError", template="unhashable type: '%s'", template_args=ExpressionAttributeLookup( source=ExpressionBuiltinType1( value=key.extractUnhashableNode(), source_ref=key.source_ref ), attribute_name="__name__", source_ref=key.source_ref, ), source_ref=key.source_ref, ) result = wrapExpressionWithSideEffects( side_effects=side_effects, old_node=key, new_node=result ) return ( result, "new_raise", "Dictionary key is known to not be hashable.", ) if is_constant: if not key.isExpressionConstantRef(): is_constant = False else: value = pair.getValue() if not value.isExpressionConstantRef(): is_constant = False if not is_constant: return self, None, None constant_value = Constants.createConstantDict( keys=[pair.getKey().getConstant() for pair in pairs], values=[pair.getValue().getConstant() for pair in pairs], ) new_node = makeConstantReplacementNode(constant=constant_value, node=self) return ( new_node, "new_constant", """\ Created dictionary found to be constant.""", )