Skip to content

Commit 21382fa

Browse files
authored
Merge branch 'master' into py_class
2 parents e220f0a + 50de085 commit 21382fa

19 files changed

+961
-939
lines changed

tests/snippets/strings.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,45 @@
6262
assert c.title() == 'Hallo'
6363
assert c.count('l') == 2
6464

65+
assert 'aaa'.count('a') == 3
66+
assert 'aaa'.count('a', 1) == 2
67+
assert 'aaa'.count('a', 1, 2) == 1
68+
assert 'aaa'.count('a', 2, 2) == 0
69+
assert 'aaa'.count('a', 2, 1) == 0
70+
71+
assert '___a__'.find('a') == 3
72+
assert '___a__'.find('a', -10) == 3
73+
assert '___a__'.find('a', -3) == 3
74+
assert '___a__'.find('a', -2) == -1
75+
assert '___a__'.find('a', -1) == -1
76+
assert '___a__'.find('a', 0) == 3
77+
assert '___a__'.find('a', 3) == 3
78+
assert '___a__'.find('a', 4) == -1
79+
assert '___a__'.find('a', 10) == -1
80+
assert '___a__'.rfind('a', 3) == 3
81+
assert '___a__'.index('a', 3) == 3
82+
83+
assert '___a__'.find('a', 0, -10) == -1
84+
assert '___a__'.find('a', 0, -3) == -1
85+
assert '___a__'.find('a', 0, -2) == 3
86+
assert '___a__'.find('a', 0, -1) == 3
87+
assert '___a__'.find('a', 0, 0) == -1
88+
assert '___a__'.find('a', 0, 3) == -1
89+
assert '___a__'.find('a', 0, 4) == 3
90+
assert '___a__'.find('a', 0, 10) == 3
91+
92+
assert '___a__'.find('a', 3, 3) == -1
93+
assert '___a__'.find('a', 3, 4) == 3
94+
assert '___a__'.find('a', 4, 3) == -1
95+
96+
assert 'abcd'.startswith('b', 1)
97+
assert not 'abcd'.startswith('b', -4)
98+
assert 'abcd'.startswith('b', -3)
99+
100+
assert not 'abcd'.startswith('b', 3, 3)
101+
assert 'abcd'.startswith('', 3, 3)
102+
assert not 'abcd'.startswith('', 4, 3)
103+
65104
assert ' '.isspace()
66105
assert 'hello\nhallo\nHallo'.splitlines() == ['hello', 'hallo', 'Hallo']
67106
assert 'abc\t12345\txyz'.expandtabs() == 'abc 12345 xyz'

tests/snippets/types_snippet.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,14 @@
1515
assert type(cls) is metaclass
1616
assert type(metaclass) is type
1717

18+
assert issubclass(metaclass, type)
19+
assert isinstance(cls, type)
20+
21+
assert inst.__class__ is cls
22+
assert cls.__class__ is metaclass
23+
assert metaclass.__class__ is type
24+
assert type.__class__ is type
25+
assert None.__class__ is type(None)
26+
1827
assert isinstance(type, type)
1928
assert issubclass(type, type)

vm/src/compile.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
88
use crate::bytecode::{self, CallType, CodeObject, Instruction};
99
use crate::error::CompileError;
10+
use crate::obj::objcode;
1011
use crate::pyobject::{PyObject, PyObjectPayload, PyObjectRef};
1112
use num_complex::Complex64;
1213
use rustpython_parser::{ast, parser};
@@ -48,7 +49,12 @@ pub fn compile(
4849

4950
let code = compiler.pop_code_object();
5051
trace!("Compilation completed: {:?}", code);
51-
Ok(PyObject::new(PyObjectPayload::Code { code }, code_type))
52+
Ok(PyObject::new(
53+
PyObjectPayload::AnyRustValue {
54+
value: Box::new(objcode::PyCode::new(code)),
55+
},
56+
code_type,
57+
))
5258
}
5359

5460
pub enum Mode {

vm/src/function.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use crate::vm::VirtualMachine;
2222
/// A `PyRef<T>` can be directly returned from a built-in function to handle
2323
/// situations (such as when implementing in-place methods such as `__iadd__`)
2424
/// where a reference to the same object must be returned.
25+
#[derive(Clone)]
2526
pub struct PyRef<T> {
2627
// invariant: this obj must always have payload of type T
2728
obj: PyObjectRef,

vm/src/macros.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,13 @@ macro_rules! py_class {
137137
}
138138
}
139139
}
140+
141+
#[macro_export]
142+
macro_rules! extend_class {
143+
( $ctx:expr, $class:expr, { $($name:expr => $value:expr),* $(,)* }) => {
144+
let class = $class;
145+
$(
146+
$ctx.set_attr(&class, $name, $value);
147+
)*
148+
}
149+
}

vm/src/obj/objbool.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use num_traits::Zero;
22

3-
use crate::pyobject::{
4-
IntoPyObject, PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
5-
};
3+
use crate::pyobject::{IntoPyObject, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
64
use crate::vm::VirtualMachine;
75

86
use super::objdict::PyDict;
97
use super::objfloat::PyFloat;
108
use super::objint::PyInt;
9+
use super::objlist::PyList;
1110
use super::objstr::PyString;
11+
use super::objtuple::PyTuple;
1212
use super::objtype;
1313

1414
impl IntoPyObject for bool {
@@ -30,21 +30,22 @@ pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> PyResult<bool> {
3030
if let Some(i) = obj.payload::<PyInt>() {
3131
return Ok(!i.value.is_zero());
3232
}
33-
let result = match obj.payload {
34-
PyObjectPayload::Sequence { ref elements } => !elements.borrow().is_empty(),
35-
_ => {
36-
if let Ok(f) = vm.get_method(obj.clone(), "__bool__") {
37-
let bool_res = vm.invoke(f, PyFuncArgs::default())?;
38-
match bool_res.payload::<PyInt>() {
39-
Some(i) => !i.value.is_zero(),
40-
None => return Err(vm.new_type_error(String::from("TypeError"))),
41-
}
42-
} else {
43-
true
44-
}
33+
if let Some(list) = obj.payload::<PyList>() {
34+
return Ok(!list.elements.borrow().is_empty());
35+
}
36+
if let Some(tuple) = obj.payload::<PyTuple>() {
37+
return Ok(!tuple.elements.borrow().is_empty());
38+
}
39+
40+
Ok(if let Ok(f) = vm.get_method(obj.clone(), "__bool__") {
41+
let bool_res = vm.invoke(f, PyFuncArgs::default())?;
42+
match bool_res.payload::<PyInt>() {
43+
Some(i) => !i.value.is_zero(),
44+
None => return Err(vm.new_type_error(String::from("TypeError"))),
4545
}
46-
};
47-
Ok(result)
46+
} else {
47+
true
48+
})
4849
}
4950

5051
pub fn init(context: &PyContext) {

vm/src/obj/objcode.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,32 @@
44

55
use crate::bytecode;
66
use crate::pyobject::{
7-
IdProtocol, PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
7+
IdProtocol, PyContext, PyFuncArgs, PyObjectPayload2, PyObjectRef, PyResult, TypeProtocol,
88
};
99
use crate::vm::VirtualMachine;
10+
use std::fmt;
11+
12+
pub struct PyCode {
13+
code: bytecode::CodeObject,
14+
}
15+
16+
impl PyCode {
17+
pub fn new(code: bytecode::CodeObject) -> PyCode {
18+
PyCode { code }
19+
}
20+
}
21+
22+
impl fmt::Debug for PyCode {
23+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24+
write!(f, "code: {:?}", self.code)
25+
}
26+
}
27+
28+
impl PyObjectPayload2 for PyCode {
29+
fn required_type(ctx: &PyContext) -> PyObjectRef {
30+
ctx.code_type()
31+
}
32+
}
1033

1134
pub fn init(context: &PyContext) {
1235
let code_type = &context.code_type;
@@ -29,8 +52,8 @@ pub fn init(context: &PyContext) {
2952
}
3053

3154
pub fn get_value(obj: &PyObjectRef) -> bytecode::CodeObject {
32-
if let PyObjectPayload::Code { code } = &obj.payload {
33-
code.clone()
55+
if let Some(code) = obj.payload::<PyCode>() {
56+
code.code.clone()
3457
} else {
3558
panic!("Inner error getting code {:?}", obj)
3659
}

0 commit comments

Comments
 (0)