forked from RustPython/RustPython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpython.rs
More file actions
57 lines (53 loc) · 1.91 KB
/
python.rs
File metadata and controls
57 lines (53 loc) · 1.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use super::PY_COMPILE_FLAG_AST_ONLY;
#[pymodule]
pub(crate) mod _ast {
use crate::{
AsObject, Context, PyObjectRef, PyResult, VirtualMachine,
builtins::{PyStrRef, PyTupleRef},
function::FuncArgs,
};
#[pyattr]
#[pyclass(module = "_ast", name = "AST")]
#[derive(Debug)]
pub(crate) struct NodeAst;
#[pyclass(flags(BASETYPE, HAS_DICT))]
impl NodeAst {
#[pyslot]
#[pymethod(magic)]
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
let fields = zelf.get_attr("_fields", vm)?;
let fields: Vec<PyStrRef> = fields.try_to_value(vm)?;
let n_args = args.args.len();
if n_args > fields.len() {
return Err(vm.new_type_error(format!(
"{} constructor takes at most {} positional argument{}",
zelf.class().name(),
fields.len(),
if fields.len() == 1 { "" } else { "s" },
)));
}
for (name, arg) in fields.iter().zip(args.args) {
zelf.set_attr(name, arg, vm)?;
}
for (key, value) in args.kwargs {
if let Some(pos) = fields.iter().position(|f| f.as_str() == key) {
if pos < n_args {
return Err(vm.new_type_error(format!(
"{} got multiple values for argument '{}'",
zelf.class().name(),
key
)));
}
}
zelf.set_attr(vm.ctx.intern_str(key), value, vm)?;
}
Ok(())
}
#[pyattr(name = "_fields")]
fn fields(ctx: &Context) -> PyTupleRef {
ctx.empty_tuple.clone()
}
}
#[pyattr(name = "PyCF_ONLY_AST")]
use super::PY_COMPILE_FLAG_AST_ONLY;
}