def _transform_constant_sequence(self, seq): """ Transform a frozenset or tuple. """ should_transform = is_a(self.types) if not any(filter(should_transform, flatten(seq))): # Tuple doesn't contain any transformable strings. Ignore. yield LOAD_CONST(seq) return for const in seq: if should_transform(const): for item in self.transform_stringlike(const): yield item elif isinstance(const, (tuple, frozenset)): for item in self._transform_constant_sequence(const): yield item else: yield LOAD_CONST(const) if isinstance(seq, tuple): yield BUILD_TUPLE(len(seq)) else: assert isinstance(seq, frozenset) yield BUILD_TUPLE(len(seq)) yield LOAD_CONST(frozenset) yield ROT_TWO() yield CALL_FUNCTION(1)
def bytes_instrs(self): """ Yield instructions to call TOS.decode('utf-8').format(**locals()). """ yield LOAD_ATTR('decode') yield LOAD_CONST('utf-8') yield CALL_FUNCTION(1) yield from self.str_instrs
def str_instrs(self): """ Yield instructions to call TOS.format(**locals()). """ yield LOAD_ATTR('format') yield LOAD_CONST(locals) yield CALL_FUNCTION(0) yield CALL_FUNCTION_KW()
def _match(self, instr, CALL_FUNCTION_VAR=CALL_FUNCTION_VAR): yield ROT_TWO().steal(instr) yield POP_TOP() yield LOAD_CONST(self._matcher) yield ROT_TWO() yield LOAD_CONST(sys.exc_info) yield CALL_FUNCTION(0) yield CALL_FUNCTION_VAR(1)
def wrap_function_with_recursive_decorator(self): """Wrap function with recursive_decorator. Yield: instructions to wrap function with recursive_decorator. """ yield from self.apply_recursive_decorator_on_decorator() # Apply recursive_decorator(dec) on function yield ROT_TWO() yield CALL_FUNCTION(1)
def visit_COMPARE_OP(self, instr): if instr.arg == Comparisons.EXCEPTION_MATCH: yield ROT_TWO().steal(instr) yield POP_TOP() yield self.LOAD_CONST(self._matcher) yield ROT_TWO() yield self.LOAD_CONST(exc_info) yield CALL_FUNCTION(0) yield CALL_FUNCTION_VAR(1) else: yield instr
def _visit_load_name(self, instr): """ Loading a name immediatly wraps it in a `thunk`. """ yield self.LOAD_CONST(thunk.fromvalue).steal(instr) # TOS = thunk.fromvalue yield instr # TOS = value # TOS1 = thunk.fromvalue yield CALL_FUNCTION(1)
def _match(self, instr, CALL_FUNCTION_EX=CALL_FUNCTION_EX, BUILD_TUPLE_UNPACK_WITH_CALL=BUILD_TUPLE_UNPACK_WITH_CALL): yield ROT_TWO().steal(instr) yield POP_TOP() yield LOAD_CONST(self._matcher) yield ROT_TWO() yield BUILD_TUPLE(1) yield LOAD_CONST(sys.exc_info) yield CALL_FUNCTION(0) yield BUILD_TUPLE_UNPACK_WITH_CALL(2) yield CALL_FUNCTION_EX(0)
def call_function(fn): """Return the instructions needed to call fn. Parameters ---------- fn : function The function to call. Returns ------- instrs : tuple The instructions to use. """ return LOAD_CONST(fn), ROT_TWO(), CALL_FUNCTION(1)
def visit_UNARY_NOT(self, instr): """ Replace the `not` operator to act on the values that the thunks represent. This makes `not` lazy. """ yield self.LOAD_CONST(_lazy_not).steal(instr) # TOS = _lazy_not # TOS1 = arg yield ROT_TWO() # TOS = arg # TOS1 = _lazy_not yield CALL_FUNCTION(1)
def visit_MAKE_FUNCTION(self, instr): """ Functions should have strict names. """ yield self.LOAD_CONST(strict).steal(instr) # TOS = strict # TOS1 = func_name yield ROT_TWO() # TOS = func_name # TOS1 = strict yield CALL_FUNCTION(1) # TOS = strict(func_name) yield instr
def visit_COMPARE_OP(self, instr): """ Replace the `is` operator to act on the values the thunks represent. This makes `is` lazy. """ if instr.arg != 8: # is yield from self.visit_generic(instr) return yield self.LOAD_CONST(_lazy_is).steal(instr) # TOS = _lazy_is # TOS1 = a # TOS2 = b # This safe to do because `is` is commutative 100% of the time. # We are doing a pointer compare so we can move the operands around. # This saves us from doing an extra ROT_TWO to preserve the order. yield ROT_THREE() # TOS = a # TOS1 = b # TOS2 = _lazy_is yield CALL_FUNCTION(2)