def visit_Tuple(self, tup): """Try to turn tuple building into a constant.""" if tup.ctx != ast.Load: return tup # Don't do the rest for assignment or delete targets. # It would replace Tuple([]) with Constant('()')! if tup.elts: consts_w = [None] * len(tup.elts) for i in range(len(tup.elts)): node = tup.elts[i] w_const = node.as_constant(self.space, self.compile_info) if w_const is None: new_elts = self._optimize_constant_star_unpacks(tup.elts) if new_elts is not None: return ast.Tuple(new_elts, ast.Load, tup.lineno, tup.col_offset) return tup consts_w[i] = w_const # intern the string constants packed into the tuple here, # because assemble.py will see the result as just a tuple constant for i in range(len(consts_w)): consts_w[i] = misc.intern_if_common_string( self.space, consts_w[i]) else: consts_w = [] w_consts = self.space.newtuple(consts_w) return ast.Constant(w_consts, tup.lineno, tup.col_offset)
def visit_UnaryOp(self, unary): w_operand = unary.operand.as_constant(self.space, self.compile_info) op = unary.op if w_operand is not None: try: for op_kind, folder in unrolling_unary_folders: if op_kind == op: w_const = folder(self.space, w_operand) break else: raise AssertionError("unknown unary operation") w_minint = self.space.newint(-sys.maxint - 1) # This makes sure the result is an integer. if self.space.eq_w(w_minint, w_const): w_const = w_minint except OperationError: pass else: return ast.Constant(w_const, unary.lineno, unary.col_offset) elif op == ast.Not: compare = unary.operand if isinstance(compare, ast.Compare) and len(compare.ops) == 1: cmp_op = compare.ops[0] try: opposite = opposite_compare_operations(cmp_op) except KeyError: pass else: compare.ops[0] = opposite return compare return unary
def visit_BinOp(self, binop): left = binop.left.as_constant(self.space, self.compile_info) if left is not None: right = binop.right.as_constant(self.space, self.compile_info) if right is not None: op = binop.op try: for op_kind, folder in unrolling_binary_folders: if op_kind == op: w_const = folder(self.space, left, right) break else: raise AssertionError("unknown binary operation") # Let all errors be found at runtime. except OperationError: pass else: # To avoid blowing up the size of pyc files, we only fold # reasonably sized sequences. try: w_len = self.space.len(w_const) except OperationError: pass else: if self.space.int_w(w_len) > 20: return binop return ast.Constant(w_const, binop.lineno, binop.col_offset) return binop
def as_node_list(self, space): try: values_w = space.unpackiterable(self.value) except OperationError: return None line = self.lineno column = self.col_offset return [ast.Constant(w_obj, line, column) for w_obj in values_w]
def visit_Subscript(self, subs): if subs.ctx == ast.Load: w_obj = subs.value.as_constant(self.space, self.compile_info) if w_obj is not None: w_idx = subs.slice.as_constant(self.space, self.compile_info) if w_idx is not None: try: w_const = self.space.getitem(w_obj, w_idx) except OperationError: # Let exceptions propagate at runtime. return subs # CPython issue5057: if v is unicode, there might # be differences between wide and narrow builds in # cases like u'\U00012345'[0]. # Wide builds will return a non-BMP char, whereas # narrow builds will return a surrogate. In both # the cases skip the optimization in order to # produce compatible pycs. if (self.space.isinstance_w(w_obj, self.space.w_unicode) and self.space.isinstance_w( w_const, self.space.w_unicode)): #unistr = self.space.utf8_w(w_const) #if len(unistr) == 1: # ch = ord(unistr[0]) #else: # ch = 0 #if (ch > 0xFFFF or # (MAXUNICODE == 0xFFFF and 0xD800 <= ch <= 0xDFFF)): # --XXX-- for now we always disable optimization of # u'...'[constant] because the tests above are not # enough to fix issue5057 (CPython has the same # problem as of April 24, 2012). # See test_const_fold_unicode_subscr return subs return ast.Constant(w_const, subs.lineno, subs.col_offset) return subs
def unparse(self, node): return ast.Constant(w_unparse(self.space, node), node.lineno, node.col_offset)
def _make_starred_tuple_const(self, consts_w, firstelt): w_consts = self.space.newtuple(consts_w[:]) return ast.Starred( ast.Constant(w_consts, firstelt.lineno, firstelt.col_offset), ast.Load, firstelt.lineno, firstelt.col_offset)
def test_constant(self): w_one = self.space.newint(1) node = ast.Constant(w_one, 0, 0) assert unparse(self.space, node) == "1"
def test_constant(self): node = ast.Constant(self.space.newlist([1]), 0, 0) self.expr(node, "got an invalid type in Constant: list", exc=validate.ValidationTypeError)