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

Method compile_comprehension

crates/codegen/src/compile.rs:8817–9054  ·  view source on GitHub ↗
(
        &mut self,
        name: &str,
        init_collection: Option<AnyInstruction>,
        generators: &[ast::Comprehension],
        compile_element: &dyn Fn(&mut Self) -> CompileResult<()>,
 

Source from the content-addressed store, hash-verified

8815 }
8816
8817 fn compile_comprehension(
8818 &mut self,
8819 name: &str,
8820 init_collection: Option<AnyInstruction>,
8821 generators: &[ast::Comprehension],
8822 compile_element: &dyn Fn(&mut Self) -> CompileResult<()>,
8823 comprehension_type: ComprehensionType,
8824 element_contains_await: bool,
8825 ) -> CompileResult<()> {
8826 let prev_ctx = self.ctx;
8827 let has_an_async_gen = generators.iter().any(|g| g.is_async);
8828
8829 // Check for async comprehension outside async function (list/set/dict only, not generator expressions)
8830 // Use in_async_scope to allow nested async comprehensions inside an async function
8831 if comprehension_type != ComprehensionType::Generator
8832 && (has_an_async_gen || element_contains_await)
8833 && !prev_ctx.in_async_scope
8834 {
8835 return Err(self.error(CodegenErrorType::InvalidAsyncComprehension));
8836 }
8837
8838 // Check if this comprehension should be inlined (PEP 709)
8839 let is_inlined = self.is_inlined_comprehension_context(comprehension_type);
8840
8841 // async comprehensions are allowed in various contexts:
8842 // - list/set/dict comprehensions in async functions (or nested within)
8843 // - always for generator expressions
8844 let is_async_list_set_dict_comprehension = comprehension_type
8845 != ComprehensionType::Generator
8846 && (has_an_async_gen || element_contains_await)
8847 && prev_ctx.in_async_scope;
8848
8849 let is_async_generator_comprehension = comprehension_type == ComprehensionType::Generator
8850 && (has_an_async_gen || element_contains_await);
8851
8852 debug_assert!(!(is_async_list_set_dict_comprehension && is_async_generator_comprehension));
8853
8854 let is_async = is_async_list_set_dict_comprehension || is_async_generator_comprehension;
8855
8856 // We must have at least one generator:
8857 assert!(!generators.is_empty());
8858
8859 if is_inlined && !has_an_async_gen && !element_contains_await {
8860 // PEP 709: Inlined comprehension - compile inline without new scope
8861 let was_in_inlined_comp = self.current_code_info().in_inlined_comp;
8862 self.current_code_info().in_inlined_comp = true;
8863 let result = self.compile_inlined_comprehension(
8864 init_collection,
8865 generators,
8866 compile_element,
8867 has_an_async_gen,
8868 );
8869 self.current_code_info().in_inlined_comp = was_in_inlined_comp;
8870 return result;
8871 }
8872
8873 // Non-inlined path: create a new code object (generator expressions, etc.)
8874 self.ctx = CompileContext {

Callers 1

compile_expressionMethod · 0.80

Calls 15

newFunction · 0.85
current_code_infoMethod · 0.80
push_outputMethod · 0.80
varnameMethod · 0.80
current_symbol_tableMethod · 0.80
new_blockMethod · 0.80
set_no_locationMethod · 0.80
push_fblockMethod · 0.80
compile_expressionMethod · 0.80
switch_to_blockMethod · 0.80

Tested by

no test coverage detected