Skip to content

Commit bcf58d9

Browse files
committed
Misc fixes
1 parent cd9f680 commit bcf58d9

File tree

9 files changed

+152
-119
lines changed

9 files changed

+152
-119
lines changed

ast/asdl_rs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def gen_classdef(self, name, fields, attrs, depth):
272272
structname = "Node" + name
273273
self.emit(f'#[pyclass(module = "_ast", name = {json.dumps(name)}, base = "AstNode")]', depth)
274274
self.emit(f"struct {structname};", depth)
275-
self.emit("#[pyimpl(flags(HAS_DICT))]", depth)
275+
self.emit("#[pyimpl(flags(HAS_DICT, BASETYPE))]", depth)
276276
self.emit(f"impl {structname} {{", depth)
277277
self.emit(f"#[extend_class]", depth + 1)
278278
self.emit("fn extend_class_with_fields(ctx: &PyContext, class: &PyTypeRef) {", depth + 1)

compiler/src/compile.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,12 @@ impl Compiler {
10821082
}
10831083
for var in &*code.freevars {
10841084
let table = self.symbol_table_stack.last().unwrap();
1085-
let symbol = table.lookup(var).unwrap();
1085+
let symbol = table.lookup(var).unwrap_or_else(|| {
1086+
panic!(
1087+
"couldn't look up var {} in {} in {}",
1088+
var, code.obj_name, self.source_path
1089+
)
1090+
});
10861091
let parent_code = self.code_stack.last().unwrap();
10871092
let vars = match symbol.scope {
10881093
SymbolScope::Free => &parent_code.freevar_cache,
@@ -1984,7 +1989,7 @@ impl Compiler {
19841989
unpack: false,
19851990
}),
19861991
generators,
1987-
&mut |compiler| {
1992+
&|compiler| {
19881993
compiler.compile_comprehension_element(elt)?;
19891994
compiler.emit(Instruction::ListAppend {
19901995
i: (1 + generators.len()) as u32,
@@ -2001,7 +2006,7 @@ impl Compiler {
20012006
unpack: false,
20022007
}),
20032008
generators,
2004-
&mut |compiler| {
2009+
&|compiler| {
20052010
compiler.compile_comprehension_element(elt)?;
20062011
compiler.emit(Instruction::SetAdd {
20072012
i: (1 + generators.len()) as u32,
@@ -2023,7 +2028,7 @@ impl Compiler {
20232028
unpack: false,
20242029
}),
20252030
generators,
2026-
&mut |compiler| {
2031+
&|compiler| {
20272032
// changed evaluation order for Py38 named expression PEP 572
20282033
compiler.compile_expression(key)?;
20292034
compiler.compile_expression(value)?;
@@ -2037,7 +2042,7 @@ impl Compiler {
20372042
)?;
20382043
}
20392044
GeneratorExp { elt, generators } => {
2040-
self.compile_comprehension("<genexpr>", None, generators, &mut |compiler| {
2045+
self.compile_comprehension("<genexpr>", None, generators, &|compiler| {
20412046
compiler.compile_comprehension_element(elt)?;
20422047
compiler.mark_generator();
20432048
compiler.emit(Instruction::YieldValue);
@@ -2046,9 +2051,6 @@ impl Compiler {
20462051
Ok(())
20472052
})?;
20482053
}
2049-
// Comprehension { kind, generators } => {
2050-
// self.compile_comprehension(kind, generators)?;
2051-
// }
20522054
Starred { .. } => {
20532055
return Err(self.error(CompileErrorType::InvalidStarExpr));
20542056
}

compiler/src/symboltable.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,15 +358,11 @@ impl SymbolTableAnalyzer {
358358
}
359359

360360
fn found_in_outer_scope(&mut self, name: &str) -> Option<SymbolScope> {
361-
// Interesting stuff about the __class__ variable:
362-
// https://docs.python.org/3/reference/datamodel.html?highlight=__class__#creating-the-class-object
363-
if name == "__class__" {
364-
return Some(SymbolScope::Free);
365-
}
366-
367361
let mut decl_depth = None;
368362
for (i, (symbols, typ)) in self.tables.iter().rev().enumerate() {
369-
if let SymbolTableType::Class | SymbolTableType::Module = typ {
363+
if matches!(typ, SymbolTableType::Module)
364+
|| matches!(typ, SymbolTableType::Class if name != "__class__")
365+
{
370366
continue;
371367
}
372368
if let Some(sym) = symbols.get(name) {
@@ -958,6 +954,8 @@ impl SymbolTableBuilder {
958954
self.register_name(id, SymbolUsage::Iter, location)?;
959955
}
960956
}
957+
// Interesting stuff about the __class__ variable:
958+
// https://docs.python.org/3/reference/datamodel.html?highlight=__class__#creating-the-class-object
961959
if context == ExpressionContext::Load
962960
&& self.tables.last().unwrap().typ == SymbolTableType::Function
963961
&& id == "super"

examples/parse_folder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,4 @@ struct ParsedFile {
146146
result: ParseResult,
147147
}
148148

149-
type ParseResult = Result<ast::Program, String>;
149+
type ParseResult = Result<Vec<ast::Stmt>, String>;

extra_tests/snippets/ast_snippet.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ def foo():
2323
assert foo.body[1].lineno == 4
2424

2525
n = ast.parse("3 < 4 > 5\n")
26-
assert n.body[0].value.left.n == 3
26+
assert n.body[0].value.left.value == 3
2727
assert 'Lt' in str(n.body[0].value.ops[0])
2828
assert 'Gt' in str(n.body[0].value.ops[1])
29-
assert n.body[0].value.comparators[0].n == 4
30-
assert n.body[0].value.comparators[1].n == 5
29+
assert n.body[0].value.comparators[0].value == 4
30+
assert n.body[0].value.comparators[1].value == 5
3131

3232

3333
n = ast.parse('from ... import a\n')

parser/src/python.lalrpop

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ grammar;
2121
pub Top: ast::Mod = {
2222
StartModule <body:Program> => ast::Mod::Module { body, type_ignores: vec![] },
2323
StartInteractive <body:Program> => ast::Mod::Interactive { body },
24-
StartExpression <body:Test> ("\n")* => ast::Mod::Expression { body: Box::new(body) },
24+
StartExpression <body:TestList> ("\n")* => ast::Mod::Expression { body: Box::new(body) },
2525
};
2626

2727
Program: ast::Suite = {

vm/src/stdlib/ast.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ use rustpython_parser::parser;
1515
use rustpython_compiler as compile;
1616

1717
use crate::builtins::{self, PyStrRef, PyTypeRef};
18+
use crate::function::FuncArgs;
1819
use crate::pyobject::{
1920
BorrowValue, IdProtocol, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult,
2021
PyValue, StaticType, TryFromObject, TypeProtocol,
2122
};
2223
use crate::vm::VirtualMachine;
2324

2425
#[rustfmt::skip]
26+
#[allow(clippy::all)]
2527
mod gen;
2628

2729
fn node_add_location(node: &AstNodeRef, location: ast::Location, vm: &VirtualMachine) {
@@ -43,7 +45,38 @@ pub(crate) struct AstNode;
4345
type AstNodeRef = PyRef<AstNode>;
4446

4547
#[pyimpl(flags(HAS_DICT))]
46-
impl AstNode {}
48+
impl AstNode {
49+
#[pymethod(magic)]
50+
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
51+
let fields = vm.get_attribute(zelf.clone_class().into_object(), "_fields")?;
52+
let fields = vm.extract_elements::<PyStrRef>(&fields)?;
53+
let numargs = args.args.len();
54+
if numargs > fields.len() {
55+
return Err(vm.new_type_error(format!(
56+
"{} constructor takes at most {} positional argument{}",
57+
zelf.class().name,
58+
fields.len(),
59+
if fields.len() == 1 { "" } else { "s" },
60+
)));
61+
}
62+
for (name, arg) in fields.iter().zip(args.args) {
63+
vm.set_attr(&zelf, name.clone(), arg)?;
64+
}
65+
for (key, value) in args.kwargs {
66+
if let Some(pos) = fields.iter().position(|f| f.borrow_value() == key) {
67+
if pos < numargs {
68+
return Err(vm.new_type_error(format!(
69+
"{} got multiple values for argument '{}'",
70+
zelf.class().name,
71+
key
72+
)));
73+
}
74+
}
75+
vm.set_attr(&zelf, key, value)?;
76+
}
77+
Ok(())
78+
}
79+
}
4780

4881
const MODULE_NAME: &str = "_ast";
4982
pub const PY_COMPILE_FLAG_AST_ONLY: i32 = 0x0400;

0 commit comments

Comments
 (0)