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

Function ast_replace

crates/vm/src/stdlib/_ast/python.rs:119–234  ·  view source on GitHub ↗
(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

117 }
118
119 pub(crate) fn ast_replace(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
120 if !args.args.is_empty() {
121 return Err(vm.new_type_error("__replace__() takes no positional arguments"));
122 }
123
124 let cls = zelf.class();
125 let fields = cls.get_attr(vm.ctx.intern_str("_fields"));
126 let attributes = cls.get_attr(vm.ctx.intern_str("_attributes"));
127 let dict = zelf.as_object().dict();
128
129 let mut expecting: std::collections::HashSet<String> = std::collections::HashSet::new();
130 if let Some(fields) = fields.clone() {
131 let fields: Vec<PyUtf8StrRef> = fields.try_to_value(vm)?;
132 for field in fields {
133 expecting.insert(field.as_str().to_owned());
134 }
135 }
136 if let Some(attributes) = attributes.clone() {
137 let attributes: Vec<PyUtf8StrRef> = attributes.try_to_value(vm)?;
138 for attr in attributes {
139 expecting.insert(attr.as_str().to_owned());
140 }
141 }
142
143 for (key, _value) in &args.kwargs {
144 if !expecting.remove(key) {
145 return Err(vm.new_type_error(format!(
146 "{}.__replace__ got an unexpected keyword argument '{}'.",
147 cls.name(),
148 key
149 )));
150 }
151 }
152
153 if let Some(dict) = dict.as_ref() {
154 for (key, _value) in dict.items_vec() {
155 if let Ok(key) = key.downcast::<PyUtf8Str>() {
156 expecting.remove(key.as_str());
157 }
158 }
159 if let Some(attributes) = attributes.clone() {
160 let attributes: Vec<PyUtf8StrRef> = attributes.try_to_value(vm)?;
161 for attr in attributes {
162 expecting.remove(attr.as_str());
163 }
164 }
165 }
166
167 // Discard optional fields (T | None).
168 if let Some(field_types) = cls.get_attr(vm.ctx.intern_str("_field_types"))
169 && let Ok(field_types) = field_types.downcast::<crate::builtins::PyDict>()
170 {
171 for (key, value) in field_types.items_vec() {
172 let Ok(key) = key.downcast::<PyUtf8Str>() else {
173 continue;
174 };
175 if value.fast_isinstance(vm.ctx.types.union_type) {
176 expecting.remove(key.as_str());

Callers 3

extend_classMethod · 0.85
__replace__Method · 0.85
module_execFunction · 0.85

Calls 15

newFunction · 0.85
intern_strMethod · 0.80
try_to_valueMethod · 0.80
items_vecMethod · 0.80
fast_isinstanceMethod · 0.80
collectMethod · 0.80
new_dictMethod · 0.80
ErrClass · 0.50
is_emptyMethod · 0.45
classMethod · 0.45
get_attrMethod · 0.45
dictMethod · 0.45

Tested by

no test coverage detected