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

Method analyze_symbol_comprehension

crates/codegen/src/symboltable.rs:834–933  ·  view source on GitHub ↗

Implements the symbol analysis and scope extension for names assigned by a named expression in a comprehension. See: https://github.com/python/cpython/blob/7b78e7f9fd77bb3280ee39fb74b86772a7d46a70/Python/symtable.c#L1435

(
        &mut self,
        symbol: &mut Symbol,
        parent_offset: usize,
    )

Source from the content-addressed store, hash-verified

832 // assigned by a named expression in a comprehension. See:
833 // https://github.com/python/cpython/blob/7b78e7f9fd77bb3280ee39fb74b86772a7d46a70/Python/symtable.c#L1435
834 fn analyze_symbol_comprehension(
835 &mut self,
836 symbol: &mut Symbol,
837 parent_offset: usize,
838 ) -> SymbolTableResult {
839 // when this is called, we expect to be in the direct parent scope of the scope that contains 'symbol'
840 let last = self.tables.iter_mut().rev().nth(parent_offset).unwrap();
841 let symbols = &mut last.0;
842 let table_type = last.1;
843
844 // it is not allowed to use an iterator variable as assignee in a named expression
845 if symbol.flags.contains(SymbolFlags::ITER) {
846 return Err(SymbolTableError {
847 error: format!(
848 "assignment expression cannot rebind comprehension iteration variable {}",
849 symbol.name
850 ),
851 // TODO: accurate location info, somehow
852 location: None,
853 });
854 }
855
856 match table_type {
857 CompilerScope::Module => {
858 symbol.scope = SymbolScope::GlobalImplicit;
859 }
860 CompilerScope::Class => {
861 // named expressions are forbidden in comprehensions on class scope
862 return Err(SymbolTableError {
863 error: "assignment expression within a comprehension cannot be used in a class body".to_string(),
864 // TODO: accurate location info, somehow
865 location: None,
866 });
867 }
868 CompilerScope::Function | CompilerScope::AsyncFunction | CompilerScope::Lambda => {
869 if let Some(parent_symbol) = symbols.get_mut(&symbol.name) {
870 if let SymbolScope::Unknown = parent_symbol.scope {
871 // this information is new, as the assignment is done in inner scope
872 parent_symbol.flags.insert(SymbolFlags::ASSIGNED);
873 }
874
875 symbol.scope = if parent_symbol.is_global() {
876 parent_symbol.scope
877 } else {
878 SymbolScope::Free
879 };
880 } else {
881 let mut cloned_sym = symbol.clone();
882 cloned_sym.scope = SymbolScope::Cell;
883 last.0.insert(cloned_sym.name.to_owned(), cloned_sym);
884 }
885 }
886 CompilerScope::Comprehension => {
887 // TODO check for conflicts - requires more context information about variables
888 match symbols.get_mut(&symbol.name) {
889 Some(parent_symbol) => {
890 // check if assignee is an iterator in top scope
891 if parent_symbol.flags.contains(SymbolFlags::ITER) {

Callers 1

analyze_symbolMethod · 0.80

Calls 11

to_stringMethod · 0.80
get_mutMethod · 0.80
ErrClass · 0.50
unwrapMethod · 0.45
revMethod · 0.45
iter_mutMethod · 0.45
containsMethod · 0.45
insertMethod · 0.45
is_globalMethod · 0.45
cloneMethod · 0.45
to_ownedMethod · 0.45

Tested by

no test coverage detected