MCPcopy Index your code
hub / github.com/RustPython/RustPython / compile_with

Method compile_with

crates/codegen/src/compile.rs:5550–5780  ·  view source on GitHub ↗
(
        &mut self,
        items: &[ast::WithItem],
        body: &[ast::Stmt],
        is_async: bool,
    )

Source from the content-addressed store, hash-verified

5548 }
5549
5550 fn compile_with(
5551 &mut self,
5552 items: &[ast::WithItem],
5553 body: &[ast::Stmt],
5554 is_async: bool,
5555 ) -> CompileResult<()> {
5556 self.enter_conditional_block();
5557
5558 // Python 3.12+ style with statement:
5559 //
5560 // BEFORE_WITH # TOS: ctx_mgr -> [__exit__, __enter__ result]
5561 // L1: STORE_NAME f # exception table: L1 to L2 -> L3 [1] lasti
5562 // L2: ... body ...
5563 // LOAD_CONST None # normal exit
5564 // LOAD_CONST None
5565 // LOAD_CONST None
5566 // CALL 2 # __exit__(None, None, None)
5567 // POP_TOP
5568 // JUMP after
5569 // L3: PUSH_EXC_INFO # exception handler
5570 // WITH_EXCEPT_START # call __exit__(type, value, tb), push result
5571 // TO_BOOL
5572 // POP_JUMP_IF_TRUE suppress
5573 // RERAISE 2
5574 // suppress:
5575 // POP_TOP # pop exit result
5576 // L5: POP_EXCEPT
5577 // POP_TOP # pop __exit__
5578 // POP_TOP # pop prev_exc (or lasti depending on layout)
5579 // JUMP after
5580 // L6: COPY 3 # cleanup handler for reraise
5581 // POP_EXCEPT
5582 // RERAISE 1
5583 // after: ...
5584
5585 let with_range = self.current_source_range;
5586
5587 let Some((item, items)) = items.split_first() else {
5588 return Err(self.error(CodegenErrorType::EmptyWithItems));
5589 };
5590
5591 let exc_handler_block = self.new_block();
5592 let after_block = self.new_block();
5593
5594 // Compile context expression and load __enter__/__exit__ methods
5595 self.compile_expression(&item.context_expr)?;
5596 self.set_source_range(with_range);
5597
5598 // Stack: [cm]
5599 emit!(self, Instruction::Copy { i: 1 }); // [cm, cm]
5600
5601 if is_async {
5602 if self.ctx.func != FunctionContext::AsyncFunction {
5603 return Err(self.error(CodegenErrorType::InvalidAsyncWith));
5604 }
5605 // Load __aexit__ and __aenter__, then call __aenter__
5606 emit!(
5607 self,

Callers 1

compile_statementMethod · 0.80

Calls 15

new_blockMethod · 0.80
compile_expressionMethod · 0.80
set_source_rangeMethod · 0.80
emit_load_constMethod · 0.80
push_fblockMethod · 0.80
compile_storeMethod · 0.80
compile_statementsMethod · 0.80
pop_fblockMethod · 0.80
switch_to_blockMethod · 0.80

Tested by

no test coverage detected