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

Method locals

crates/vm/src/frame.rs:885–985  ·  view source on GitHub ↗
(&self, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

883 }
884
885 pub fn locals(&self, vm: &VirtualMachine) -> PyResult<ArgMapping> {
886 use rustpython_compiler_core::bytecode::{
887 CO_FAST_CELL, CO_FAST_FREE, CO_FAST_HIDDEN, CO_FAST_LOCAL,
888 };
889 // SAFETY: Either the frame is not executing (caller checked owner),
890 // or we're in a trace callback on the same thread that's executing.
891 let locals = &self.locals;
892 let code = &**self.code;
893 let locals_map = locals.mapping(vm);
894 let fastlocals = unsafe { (*self.iframe.get()).localsplus.fastlocals() };
895
896 // Iterate through all localsplus slots using localspluskinds
897 let nlocalsplus = code.localspluskinds.len();
898 let nfrees = code.freevars.len();
899 let free_start = nlocalsplus - nfrees;
900 let is_optimized = code.flags.contains(bytecode::CodeFlags::OPTIMIZED);
901
902 // Track which non-merged cellvar index we're at
903 let mut nonmerged_cell_idx = 0;
904
905 for (i, &kind) in code.localspluskinds.iter().enumerate() {
906 if kind & CO_FAST_HIDDEN != 0 {
907 // Hidden variables are only skipped when their slot is empty.
908 // After a comprehension restores values, they should appear in locals().
909 let slot_empty = match fastlocals[i].as_ref() {
910 None => true,
911 Some(obj) => {
912 if kind & (CO_FAST_CELL | CO_FAST_FREE) != 0 {
913 // If it's a PyCell, check if the cell is empty.
914 // If it's a raw value (merged cell during inlined comp), not empty.
915 obj.downcast_ref::<PyCell>()
916 .is_some_and(|cell| cell.get().is_none())
917 } else {
918 false
919 }
920 }
921 };
922 if slot_empty {
923 continue;
924 }
925 }
926
927 // Free variables only included for optimized (function-like) scopes.
928 // Class/module scopes should not expose free vars in locals().
929 if kind == CO_FAST_FREE && !is_optimized {
930 continue;
931 }
932
933 // Get the name for this slot
934 let name = if kind & CO_FAST_LOCAL != 0 {
935 code.varnames[i]
936 } else if kind & CO_FAST_FREE != 0 {
937 code.freevars[i - free_start]
938 } else if kind & CO_FAST_CELL != 0 {
939 // Non-merged cell: find the name by skipping merged cellvars
940 let mut found_name = None;
941 let mut skip = nonmerged_cell_idx;
942 for cv in code.cellvars.iter() {

Callers 2

f_localsMethod · 0.80
current_localsMethod · 0.80

Calls 14

fastlocalsMethod · 0.80
fast_isinstanceMethod · 0.80
clone_mappingMethod · 0.80
SomeClass · 0.50
ErrClass · 0.50
mappingMethod · 0.45
getMethod · 0.45
lenMethod · 0.45
containsMethod · 0.45
iterMethod · 0.45
as_refMethod · 0.45
is_noneMethod · 0.45

Tested by

no test coverage detected