Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Lib/_threading_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ def thread_deleted(_, idt=idt):

@contextmanager
def _patch(self):
old = object.__getattribute__(self, '__dict__')
impl = object.__getattribute__(self, '_local__impl')
try:
dct = impl.get_dict()
Expand All @@ -203,6 +204,7 @@ def _patch(self):
with impl.locallock:
object.__setattr__(self, '__dict__', dct)
yield
object.__setattr__(self, '__dict__', old)


class local:
Expand Down
9 changes: 9 additions & 0 deletions Lib/atexit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Dummy implementation of atexit


def register(func, *args, **kwargs):
return func


def unregister(func):
pass
7 changes: 7 additions & 0 deletions bytecode/src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ impl Default for CodeFlags {
}
}

impl CodeFlags {
pub const NAME_MAPPING: &'static [(&'static str, CodeFlags)] = &[
("GENERATOR", CodeFlags::IS_GENERATOR),
("COROUTINE", CodeFlags::IS_COROUTINE),
];
}

#[derive(Serialize, Debug, Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Label(usize);

Expand Down
5 changes: 5 additions & 0 deletions tests/snippets/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ class MyObject:
assert MyObject().__le__(MyObject()) == NotImplemented
assert MyObject().__gt__(MyObject()) == NotImplemented
assert MyObject().__ge__(MyObject()) == NotImplemented

obj = MyObject()
assert not hasattr(obj, 'a')
obj.__dict__ = {'a': 1}
assert obj.a == 1
3 changes: 2 additions & 1 deletion vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ num-rational = "0.2.2"
num-iter = "0.1.39"
rand = "0.7"
rand_distr = "0.2"
getrandom = "0.1"
log = "0.4"
rustpython-derive = {path = "../derive", version = "0.1.1"}
rustpython-parser = {path = "../parser", optional = true, version = "0.1.1"}
Expand Down Expand Up @@ -88,7 +89,7 @@ socket2 = { version = "0.3", features = ["unix"] }

[target."cfg(windows)".dependencies.winapi]
version = "0.3"
features = ["winsock2", "handleapi", "ws2def", "std"]
features = ["winsock2", "handleapi", "ws2def", "std", "winbase"]

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "0.2"
28 changes: 21 additions & 7 deletions vm/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,15 @@ fn make_scope(vm: &VirtualMachine, scope: ScopeArgs) -> PyResult<Scope> {
let globals = match globals {
Some(dict) => {
if !dict.contains_key("__builtins__", vm) {
let builtins_dict = vm.builtins.dict.as_ref().unwrap().as_object();
dict.set_item("__builtins__", builtins_dict.clone(), vm)
.unwrap();
let builtins_dict = vm
.builtins
.dict
.as_ref()
.unwrap()
.borrow()
.as_object()
.clone();
dict.set_item("__builtins__", builtins_dict, vm).unwrap();
}
dict
}
Expand Down Expand Up @@ -870,23 +876,31 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef) {
"IndexError" => ctx.exceptions.index_error.clone(),
"ImportError" => ctx.exceptions.import_error.clone(),
"LookupError" => ctx.exceptions.lookup_error.clone(),
"FileNotFoundError" => ctx.exceptions.file_not_found_error.clone(),
"FileExistsError" => ctx.exceptions.file_exists_error.clone(),
"StopIteration" => ctx.exceptions.stop_iteration.clone(),
"StopAsyncIteration" => ctx.exceptions.stop_async_iteration.clone(),
"SystemError" => ctx.exceptions.system_error.clone(),
"PermissionError" => ctx.exceptions.permission_error.clone(),
"UnicodeError" => ctx.exceptions.unicode_error.clone(),
"UnicodeDecodeError" => ctx.exceptions.unicode_decode_error.clone(),
"UnicodeEncodeError" => ctx.exceptions.unicode_encode_error.clone(),
"UnicodeTranslateError" => ctx.exceptions.unicode_translate_error.clone(),
"ZeroDivisionError" => ctx.exceptions.zero_division_error.clone(),
"KeyError" => ctx.exceptions.key_error.clone(),
"OSError" => ctx.exceptions.os_error.clone(),
"ModuleNotFoundError" => ctx.exceptions.module_not_found_error.clone(),
"EOFError" => ctx.exceptions.eof_error.clone(),
"MemoryError" => ctx.exceptions.memory_error.clone(),

"OSError" => ctx.exceptions.os_error.clone(),
"FileNotFoundError" => ctx.exceptions.file_not_found_error.clone(),
"PermissionError" => ctx.exceptions.permission_error.clone(),
"FileExistsError" => ctx.exceptions.file_exists_error.clone(),
"BlockingIOError" => ctx.exceptions.blocking_io_error.clone(),
"InterruptedError" => ctx.exceptions.interrupted_error.clone(),
"ConnectionError" => ctx.exceptions.connection_error.clone(),
"ConnectionResetError" => ctx.exceptions.connection_reset_error.clone(),
"ConnectionRefusedError" => ctx.exceptions.connection_refused_error.clone(),
"ConnectionAbortedError" => ctx.exceptions.connection_aborted_error.clone(),
"BrokenPipeError" => ctx.exceptions.broken_pipe_error.clone(),

// Warnings
"Warning" => ctx.exceptions.warning.clone(),
"BytesWarning" => ctx.exceptions.bytes_warning.clone(),
Expand Down
52 changes: 40 additions & 12 deletions vm/src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,6 @@ pub struct ExceptionZoo {
pub attribute_error: PyClassRef,
pub base_exception_type: PyClassRef,
pub exception_type: PyClassRef,
pub file_not_found_error: PyClassRef,
pub file_exists_error: PyClassRef,
pub import_error: PyClassRef,
pub index_error: PyClassRef,
pub key_error: PyClassRef,
Expand All @@ -238,9 +236,7 @@ pub struct ExceptionZoo {
pub name_error: PyClassRef,
pub not_implemented_error: PyClassRef,
pub recursion_error: PyClassRef,
pub os_error: PyClassRef,
pub overflow_error: PyClassRef,
pub permission_error: PyClassRef,
pub reference_error: PyClassRef,
pub runtime_error: PyClassRef,
pub stop_iteration: PyClassRef,
Expand All @@ -259,6 +255,18 @@ pub struct ExceptionZoo {
pub eof_error: PyClassRef,
pub memory_error: PyClassRef,

pub os_error: PyClassRef,
pub file_not_found_error: PyClassRef,
pub permission_error: PyClassRef,
pub file_exists_error: PyClassRef,
pub blocking_io_error: PyClassRef,
pub interrupted_error: PyClassRef,
pub connection_error: PyClassRef,
pub connection_reset_error: PyClassRef,
pub connection_refused_error: PyClassRef,
pub connection_aborted_error: PyClassRef,
pub broken_pipe_error: PyClassRef,

pub warning: PyClassRef,
pub bytes_warning: PyClassRef,
pub unicode_warning: PyClassRef,
Expand Down Expand Up @@ -289,7 +297,6 @@ impl ExceptionZoo {
let key_error = create_type("KeyError", &type_type, &exception_type);
let lookup_error = create_type("LookupError", &type_type, &exception_type);
let name_error = create_type("NameError", &type_type, &exception_type);
let os_error = create_type("OSError", &type_type, &exception_type);
let runtime_error = create_type("RuntimeError", &type_type, &exception_type);
let reference_error = create_type("ReferenceError", &type_type, &exception_type);
let stop_iteration = create_type("StopIteration", &type_type, &exception_type);
Expand All @@ -303,9 +310,6 @@ impl ExceptionZoo {
let module_not_found_error = create_type("ModuleNotFoundError", &type_type, &import_error);
let not_implemented_error = create_type("NotImplementedError", &type_type, &runtime_error);
let recursion_error = create_type("RecursionError", &type_type, &runtime_error);
let file_not_found_error = create_type("FileNotFoundError", &type_type, &os_error);
let permission_error = create_type("PermissionError", &type_type, &os_error);
let file_exists_error = create_type("FileExistsError", &type_type, &os_error);
let eof_error = create_type("EOFError", &type_type, &exception_type);
let indentation_error = create_type("IndentationError", &type_type, &syntax_error);
let tab_error = create_type("TabError", &type_type, &indentation_error);
Expand All @@ -316,6 +320,23 @@ impl ExceptionZoo {
create_type("UnicodeTranslateError", &type_type, &unicode_error);
let memory_error = create_type("MemoryError", &type_type, &exception_type);

// os errors
let os_error = create_type("OSError", &type_type, &exception_type);

let file_not_found_error = create_type("FileNotFoundError", &type_type, &os_error);
let permission_error = create_type("PermissionError", &type_type, &os_error);
let file_exists_error = create_type("FileExistsError", &type_type, &os_error);
let blocking_io_error = create_type("BlockingIOError", &type_type, &os_error);
let interrupted_error = create_type("InterruptedError", &type_type, &os_error);
let connection_error = create_type("ConnectionError", &type_type, &os_error);
let connection_reset_error =
create_type("ConnectionResetError", &type_type, &connection_error);
let connection_refused_error =
create_type("ConnectionRefusedError", &type_type, &connection_error);
let connection_aborted_error =
create_type("ConnectionAbortedError", &type_type, &connection_error);
let broken_pipe_error = create_type("BrokenPipeError", &type_type, &connection_error);

let warning = create_type("Warning", &type_type, &exception_type);
let bytes_warning = create_type("BytesWarning", &type_type, &warning);
let unicode_warning = create_type("UnicodeWarning", &type_type, &warning);
Expand All @@ -339,8 +360,6 @@ impl ExceptionZoo {
attribute_error,
base_exception_type,
exception_type,
file_not_found_error,
file_exists_error,
import_error,
index_error,
key_error,
Expand All @@ -349,9 +368,7 @@ impl ExceptionZoo {
name_error,
not_implemented_error,
recursion_error,
os_error,
overflow_error,
permission_error,
runtime_error,
stop_iteration,
stop_async_iteration,
Expand All @@ -368,6 +385,17 @@ impl ExceptionZoo {
zero_division_error,
eof_error,
memory_error,
os_error,
file_not_found_error,
permission_error,
file_exists_error,
blocking_io_error,
interrupted_error,
connection_error,
connection_reset_error,
connection_refused_error,
connection_aborted_error,
broken_pipe_error,
warning,
bytes_warning,
unicode_warning,
Expand Down
2 changes: 1 addition & 1 deletion vm/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ impl Frame {

// Grab all the names from the module and put them in the context
if let Some(dict) = &module.dict {
for (k, v) in dict {
for (k, v) in &*dict.borrow() {
let k = vm.to_str(&k)?;
let k = k.as_str();
if !k.starts_with('_') {
Expand Down
14 changes: 7 additions & 7 deletions vm/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,22 +116,22 @@ macro_rules! no_kwargs {

#[macro_export]
macro_rules! py_module {
( $vm:expr, $module_name:expr, { $($name:expr => $value:expr),* $(,)* }) => {{
( $vm:expr, $module_name:expr, { $($name:expr => $value:expr),* $(,)? }) => {{
let module = $vm.new_module($module_name, $vm.ctx.new_dict());
$(
$vm.set_attr(&module, $name, $value).unwrap();
)*
$crate::extend_module!($vm, module, { $($name => $value),* });
module
}};
}

#[macro_export]
macro_rules! extend_module {
( $vm:expr, $module:expr, { $($name:expr => $value:expr),* $(,)* }) => {
( $vm:expr, $module:expr, { $($name:expr => $value:expr),* $(,)? }) => {{
#[allow(unused_variables)]
let module: &$crate::pyobject::PyObjectRef = &$module;
$(
$vm.set_attr(&$module, $name, $value).unwrap();
$vm.__module_set_attr(&module, $name, $value).unwrap();
)*
}
}};
}

#[macro_export]
Expand Down
5 changes: 5 additions & 0 deletions vm/src/obj/objcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ impl PyCodeRef {
fn co_name(self, _vm: &VirtualMachine) -> String {
self.code.obj_name.clone()
}

fn co_flags(self, _vm: &VirtualMachine) -> u8 {
self.code.flags.bits()
}
}

pub fn init(context: &PyContext) {
Expand All @@ -99,5 +103,6 @@ pub fn init(context: &PyContext) {
"co_firstlineno" => context.new_property(PyCodeRef::co_firstlineno),
"co_kwonlyargcount" => context.new_property(PyCodeRef::co_kwonlyargcount),
"co_name" => context.new_property(PyCodeRef::co_name),
"co_flags" => context.new_property(PyCodeRef::co_flags),
});
}
15 changes: 14 additions & 1 deletion vm/src/obj/objfunction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,24 @@ pub struct PyMethod {
// TODO: these shouldn't be public
pub object: PyObjectRef,
pub function: PyObjectRef,
pub actually_bind: bool,
}

impl PyMethod {
pub fn new(object: PyObjectRef, function: PyObjectRef) -> Self {
PyMethod { object, function }
PyMethod {
object,
function,
actually_bind: true,
}
}

pub fn new_nobind(object: PyObjectRef, function: PyObjectRef) -> Self {
PyMethod {
object,
function,
actually_bind: false,
}
}

fn getattribute(&self, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
Expand Down
2 changes: 1 addition & 1 deletion vm/src/obj/objmodule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl PyModuleRef {
let zelf = PyModule {}.into_ref_with_type(vm, cls)?;
init_module_dict(
vm,
zelf.as_object().dict.as_ref().unwrap(),
&zelf.as_object().dict.as_ref().unwrap().borrow(),
name.into_object(),
doc.flat_option()
.map_or_else(|| vm.get_none(), PyRef::into_object),
Expand Down
26 changes: 14 additions & 12 deletions vm/src/obj/objobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn object_setattr(
}

if let Some(ref dict) = obj.clone().dict {
dict.set_item(attr_name.as_str(), value, vm)?;
dict.borrow().set_item(attr_name.as_str(), value, vm)?;
Ok(())
} else {
Err(vm.new_attribute_error(format!(
Expand All @@ -98,7 +98,7 @@ fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine)
}

if let Some(ref dict) = obj.dict {
dict.del_item(attr_name.as_str(), vm)?;
dict.borrow().del_item(attr_name.as_str(), vm)?;
Ok(())
} else {
Err(vm.new_attribute_error(format!(
Expand Down Expand Up @@ -130,7 +130,7 @@ pub fn object_dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyList> {
if let Some(object_dict) = &obj.dict {
vm.invoke(
&vm.get_attribute(dict.clone().into_object(), "update")?,
object_dict.clone().into_object(),
object_dict.borrow().clone().into_object(),
)?;
}

Expand Down Expand Up @@ -210,20 +210,22 @@ fn object_class_setter(

fn object_dict(object: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyDictRef> {
if let Some(ref dict) = object.dict {
Ok(dict.clone())
Ok(dict.borrow().clone())
} else {
Err(vm.new_attribute_error("no dictionary.".to_string()))
}
}

fn object_dict_setter(
_instance: PyObjectRef,
_value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
Err(vm.new_not_implemented_error(
"Setting __dict__ attribute on an object isn't yet implemented".to_string(),
))
fn object_dict_setter(instance: PyObjectRef, value: PyDictRef, vm: &VirtualMachine) -> PyResult {
if let Some(dict) = &instance.dict {
*dict.borrow_mut() = value;
Ok(vm.get_none())
} else {
Err(vm.new_attribute_error(format!(
"'{}' object has no attribute '__dict__'",
instance.class().name
)))
}
}

fn object_getattribute(obj: PyObjectRef, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
Expand Down
Loading