mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Merge pull request #2238 from youknowone/static-type
Trait for static type
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1670,6 +1670,7 @@ dependencies = [
|
||||
name = "rustpython-derive"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"maplit",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
@@ -1818,6 +1819,7 @@ version = "0.1.2"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"parking_lot",
|
||||
"rustpython-common",
|
||||
"rustpython-compiler",
|
||||
"rustpython-parser",
|
||||
"rustpython-vm",
|
||||
|
||||
@@ -5,4 +5,5 @@ pub mod float_ops;
|
||||
pub mod hash;
|
||||
pub mod lock;
|
||||
pub mod rc;
|
||||
pub mod static_cell;
|
||||
pub mod str;
|
||||
|
||||
76
common/src/static_cell.rs
Normal file
76
common/src/static_cell.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
#[cfg(not(feature = "threading"))]
|
||||
mod non_threading {
|
||||
use crate::lock::OnceCell;
|
||||
pub type StaticCell<T> = std::thread::LocalKey<OnceCell<&'static T>>;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! static_cells {
|
||||
// process multiple declarations
|
||||
($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty;) => (
|
||||
std::thread_local! {
|
||||
$(#[$attr])* $vis static $name: $crate::lock::OnceCell<&'static $t> = $crate::lock::OnceCell::new();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "threading"))]
|
||||
pub use non_threading::*;
|
||||
|
||||
#[cfg(feature = "threading")]
|
||||
mod threading {
|
||||
use crate::lock::OnceCell;
|
||||
|
||||
pub struct StaticKey<T> {
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T> StaticKey<T> {
|
||||
pub const fn new(inner: T) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn with<F, R>(&self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&T) -> R,
|
||||
{
|
||||
f(&self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
pub type StaticCell<T> = StaticKey<OnceCell<&'static T>>;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! static_cells {
|
||||
// process multiple declarations
|
||||
($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty;) => (
|
||||
$(#[$attr])* $vis static $name: $crate::static_cell::StaticKey<$crate::lock::OnceCell<&'static $t>> = $crate::static_cell::StaticKey::new($crate::lock::OnceCell::new());
|
||||
);
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "threading")]
|
||||
pub use threading::*;
|
||||
|
||||
pub fn get<T>(cell: &'static StaticCell<T>) -> Option<&'static T> {
|
||||
cell.with(|cell| cell.get().copied())
|
||||
}
|
||||
|
||||
pub fn init_expect<T>(cell: &'static StaticCell<T>, value: T, msg: &'static str) -> &'static T {
|
||||
cell.with(|cell| {
|
||||
let static_ref = Box::leak(Box::new(value)) as &_;
|
||||
cell.set(static_ref)
|
||||
.unwrap_or_else(|_| panic!("double initializing '{}'", msg));
|
||||
static_ref
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_or_init<T, F>(cell: &'static StaticCell<T>, f: F) -> &'static T
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
cell.with(|cell| {
|
||||
*cell.get_or_init(|| {
|
||||
let value = f();
|
||||
Box::leak(Box::new(value))
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -20,3 +20,4 @@ rustpython-bytecode = { path = "../bytecode", version = "0.1.1" }
|
||||
maplit = "1.0"
|
||||
once_cell = "1.3.1"
|
||||
textwrap = "0.12.1"
|
||||
indexmap = "^1"
|
||||
|
||||
@@ -133,6 +133,7 @@ fn generate_class_def(
|
||||
ident: &Ident,
|
||||
name: &str,
|
||||
module_name: Option<&str>,
|
||||
base: Option<String>,
|
||||
attrs: &[Attribute],
|
||||
) -> std::result::Result<TokenStream, Diagnostic> {
|
||||
let doc = if let Some(doc) = attrs.doc() {
|
||||
@@ -159,11 +160,27 @@ fn generate_class_def(
|
||||
false
|
||||
}
|
||||
});
|
||||
if base.is_some() && is_pystruct {
|
||||
return Err(syn::Error::new_spanned(
|
||||
ident,
|
||||
"PyStructSequence cannot have `base` class attr",
|
||||
)
|
||||
.into());
|
||||
}
|
||||
let base = base.map(|name| Ident::new(&name, ident.span()));
|
||||
|
||||
let base_class = if is_pystruct {
|
||||
quote! {
|
||||
fn base_class(ctx: &::rustpython_vm::pyobject::PyContext) -> ::rustpython_vm::builtins::PyTypeRef {
|
||||
ctx.types.tuple_type.clone()
|
||||
fn static_baseclass() -> &'static ::rustpython_vm::builtins::PyTypeRef {
|
||||
use rustpython_vm::pyobject::StaticType;
|
||||
rustpython_vm::builtins::PyTuple::static_type()
|
||||
}
|
||||
}
|
||||
} else if let Some(base) = base {
|
||||
quote! {
|
||||
fn static_baseclass() -> &'static ::rustpython_vm::builtins::PyTypeRef {
|
||||
use rustpython_vm::pyobject::StaticType;
|
||||
#base::static_type()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -176,6 +193,17 @@ fn generate_class_def(
|
||||
const MODULE_NAME: Option<&'static str> = #module_name;
|
||||
const TP_NAME: &'static str = #module_class_name;
|
||||
const DOC: Option<&'static str> = #doc;
|
||||
}
|
||||
|
||||
impl ::rustpython_vm::pyobject::StaticType for #ident {
|
||||
fn static_cell() -> &'static ::rustpython_common::static_cell::StaticCell<::rustpython_vm::builtins::PyTypeRef> {
|
||||
use ::rustpython_common::static_cells;
|
||||
static_cells! {
|
||||
static CELL: ::rustpython_vm::builtins::PyTypeRef;
|
||||
}
|
||||
&CELL
|
||||
}
|
||||
|
||||
#base_class
|
||||
}
|
||||
};
|
||||
@@ -191,7 +219,8 @@ pub(crate) fn impl_pyclass(
|
||||
let class_meta = ClassItemMeta::from_nested(ident.clone(), fake_ident, attr.into_iter())?;
|
||||
let class_name = class_meta.class_name()?;
|
||||
let module_name = class_meta.module()?;
|
||||
let class_def = generate_class_def(&ident, &class_name, module_name.as_deref(), &attrs)?;
|
||||
let base = class_meta.base()?;
|
||||
let class_def = generate_class_def(&ident, &class_name, module_name.as_deref(), base, &attrs)?;
|
||||
|
||||
let ret = quote! {
|
||||
#item
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use indexmap::map::IndexMap;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{quote, ToTokens};
|
||||
use std::collections::HashMap;
|
||||
@@ -18,7 +19,7 @@ pub(crate) const ALL_ALLOWED_NAMES: &[&str] = &[
|
||||
];
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct ItemNursery(HashMap<(String, Vec<Attribute>), TokenStream>);
|
||||
pub(crate) struct ItemNursery(IndexMap<(String, Vec<Attribute>), TokenStream>);
|
||||
|
||||
impl ItemNursery {
|
||||
pub fn add_item(
|
||||
@@ -27,10 +28,10 @@ impl ItemNursery {
|
||||
cfgs: Vec<Attribute>,
|
||||
tokens: TokenStream,
|
||||
) -> Result<()> {
|
||||
if let Some(existing) = self.0.insert((name, cfgs), tokens) {
|
||||
if let Some(existing) = self.0.insert((name.clone(), cfgs), tokens) {
|
||||
Err(syn::Error::new_spanned(
|
||||
existing,
|
||||
"Duplicated #[py*] attribute found",
|
||||
format!("Duplicated #[py*] attribute found for '{}'", name),
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
@@ -232,7 +233,7 @@ impl ItemMeta for SimpleItemMeta {
|
||||
pub(crate) struct ClassItemMeta(ItemMetaInner);
|
||||
|
||||
impl ItemMeta for ClassItemMeta {
|
||||
const ALLOWED_NAMES: &'static [&'static str] = &["module", "name"];
|
||||
const ALLOWED_NAMES: &'static [&'static str] = &["module", "name", "base"];
|
||||
|
||||
fn from_inner(inner: ItemMetaInner) -> Self {
|
||||
Self(inner)
|
||||
@@ -267,6 +268,10 @@ impl ClassItemMeta {
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn base(&self) -> Result<Option<String>> {
|
||||
self.inner()._optional_str("base")
|
||||
}
|
||||
|
||||
pub fn module(&self) -> Result<Option<String>> {
|
||||
const KEY: &str = "module";
|
||||
let inner = self.inner();
|
||||
|
||||
@@ -20,8 +20,8 @@ pub struct PyAsyncGen {
|
||||
type PyAsyncGenRef = PyRef<PyAsyncGen>;
|
||||
|
||||
impl PyValue for PyAsyncGen {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.async_generator.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.async_generator
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +118,8 @@ impl PyAsyncGen {
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PyAsyncGenWrappedValue(pub PyObjectRef);
|
||||
impl PyValue for PyAsyncGenWrappedValue {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.async_generator_wrapped_value.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.async_generator_wrapped_value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,8 +167,8 @@ pub(crate) struct PyAsyncGenASend {
|
||||
}
|
||||
|
||||
impl PyValue for PyAsyncGenASend {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.async_generator_asend.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.async_generator_asend
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,8 +263,8 @@ pub(crate) struct PyAsyncGenAThrow {
|
||||
}
|
||||
|
||||
impl PyValue for PyAsyncGenAThrow {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.async_generator_athrow.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.async_generator_athrow
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ pub struct PyBuiltinFunction {
|
||||
}
|
||||
|
||||
impl PyValue for PyBuiltinFunction {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.builtin_function_or_method_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.builtin_function_or_method_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,8 +139,8 @@ pub struct PyBuiltinMethod {
|
||||
}
|
||||
|
||||
impl PyValue for PyBuiltinMethod {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.method_descriptor_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.method_descriptor_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ impl From<Vec<u8>> for PyByteArray {
|
||||
}
|
||||
|
||||
impl PyValue for PyByteArray {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.bytearray_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.bytearray_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,7 +562,7 @@ impl PyByteArray {
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> (PyTypeRef, PyTupleRef) {
|
||||
let bytes = PyBytes::from(zelf.borrow_value().elements.clone()).into_pyobject(vm);
|
||||
(
|
||||
Self::class(vm),
|
||||
Self::class(vm).clone(),
|
||||
PyTupleRef::with_elements(vec![bytes], &vm.ctx),
|
||||
)
|
||||
}
|
||||
@@ -650,8 +650,8 @@ pub struct PyByteArrayIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PyByteArrayIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.bytearray_iterator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.bytearray_iterator_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,8 +89,8 @@ impl Deref for PyBytes {
|
||||
}
|
||||
|
||||
impl PyValue for PyBytes {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.bytes_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.bytes_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,8 +537,8 @@ pub struct PyBytesIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PyBytesIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.bytes_iterator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.bytes_iterator_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ impl From<PyObjectRef> for PyClassMethod {
|
||||
}
|
||||
|
||||
impl PyValue for PyClassMethod {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.classmethod_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.classmethod_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,11 +37,14 @@ impl fmt::Debug for PyCode {
|
||||
}
|
||||
|
||||
impl PyValue for PyCode {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.code_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.code_type
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(with(PyRef))]
|
||||
impl PyCode {}
|
||||
|
||||
#[pyimpl]
|
||||
impl PyCodeRef {
|
||||
#[pyslot]
|
||||
|
||||
@@ -22,8 +22,8 @@ pub struct PyComplex {
|
||||
}
|
||||
|
||||
impl PyValue for PyComplex {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.complex_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.complex_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ pub struct PyCoroutine {
|
||||
}
|
||||
|
||||
impl PyValue for PyCoroutine {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.coroutine_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.coroutine_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,8 +102,8 @@ pub struct PyCoroutineWrapper {
|
||||
}
|
||||
|
||||
impl PyValue for PyCoroutineWrapper {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.coroutine_wrapper_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.coroutine_wrapper_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ impl fmt::Debug for PyDict {
|
||||
}
|
||||
|
||||
impl PyValue for PyDict {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.dict_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.dict_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -645,8 +645,8 @@ macro_rules! dict_iterator {
|
||||
}
|
||||
|
||||
impl PyValue for $name {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.$class.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.$class
|
||||
}
|
||||
}
|
||||
|
||||
@@ -698,8 +698,8 @@ macro_rules! dict_iterator {
|
||||
}
|
||||
|
||||
impl PyValue for $iter_name {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.$iter_class.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.$iter_class
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,8 +754,8 @@ macro_rules! dict_iterator {
|
||||
}
|
||||
|
||||
impl PyValue for $reverse_iter_name {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.$reverse_iter_class.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.$reverse_iter_class
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,8 +19,8 @@ pub struct PyEnumerate {
|
||||
}
|
||||
|
||||
impl PyValue for PyEnumerate {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.enumerate_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.enumerate_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ pub struct PyFilter {
|
||||
}
|
||||
|
||||
impl PyValue for PyFilter {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.filter_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.filter_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ impl PyFloat {
|
||||
}
|
||||
|
||||
impl PyValue for PyFloat {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.float_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.float_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,17 @@
|
||||
use super::code::PyCodeRef;
|
||||
use super::dict::PyDictRef;
|
||||
use super::pystr::PyStrRef;
|
||||
use crate::frame::FrameRef;
|
||||
use crate::pyobject::{IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyResult};
|
||||
use crate::frame::{Frame, FrameRef};
|
||||
use crate::pyobject::{IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
FrameRef::extend_class(context, &context.types.frame_type);
|
||||
}
|
||||
|
||||
#[pyimpl(with(PyRef))]
|
||||
impl Frame {}
|
||||
|
||||
#[pyimpl]
|
||||
impl FrameRef {
|
||||
#[pyslot]
|
||||
|
||||
@@ -264,8 +264,8 @@ impl PyFunction {
|
||||
}
|
||||
|
||||
impl PyValue for PyFunction {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.function_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.function_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,8 +397,8 @@ impl PyBoundMethod {
|
||||
}
|
||||
|
||||
impl PyValue for PyBoundMethod {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.bound_method_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.bound_method_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ pub struct PyGenerator {
|
||||
}
|
||||
|
||||
impl PyValue for PyGenerator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.generator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.generator_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -173,8 +173,8 @@ impl std::fmt::Debug for PyGetSet {
|
||||
}
|
||||
|
||||
impl PyValue for PyGetSet {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.getset_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.getset_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,8 +71,8 @@ where
|
||||
}
|
||||
|
||||
impl PyValue for PyInt {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.int_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.int_type
|
||||
}
|
||||
|
||||
fn into_object(self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
|
||||
@@ -19,8 +19,8 @@ pub struct PySequenceIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PySequenceIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.iter_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.iter_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,8 +88,8 @@ pub struct PyCallableIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PyCallableIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.callable_iterator.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.callable_iterator
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@ impl FromIterator<PyObjectRef> for PyList {
|
||||
}
|
||||
|
||||
impl PyValue for PyList {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.list_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.list_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,8 +459,8 @@ pub struct PyListIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PyListIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.list_iterator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.list_iterator_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,8 +498,8 @@ pub struct PyListReverseIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PyListReverseIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.list_reverseiterator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.list_reverseiterator_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ pub struct PyMap {
|
||||
}
|
||||
|
||||
impl PyValue for PyMap {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.map_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.map_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ enum MappingProxyInner {
|
||||
}
|
||||
|
||||
impl PyValue for PyMappingProxy {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.mappingproxy_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.mappingproxy_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -766,8 +766,8 @@ impl Hashable for PyMemoryView {
|
||||
}
|
||||
|
||||
impl PyValue for PyMemoryView {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.memoryview_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.memoryview_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ pub struct PyModule {}
|
||||
pub type PyModuleRef = PyRef<PyModule>;
|
||||
|
||||
impl PyValue for PyModule {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.module_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.module_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ use crate::vm::VirtualMachine;
|
||||
pub struct PyNamespace;
|
||||
|
||||
impl PyValue for PyNamespace {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.namespace_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.namespace_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ use crate::vm::VirtualMachine;
|
||||
pub struct PyBaseObject;
|
||||
|
||||
impl PyValue for PyBaseObject {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.object_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.object_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@ pub struct PyProperty {
|
||||
}
|
||||
|
||||
impl PyValue for PyProperty {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.property_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.property_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ pub fn boolval(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<bool> {
|
||||
/// Returns True when the argument x is true, False otherwise.
|
||||
/// The builtins True and False are the only two instances of the class bool.
|
||||
/// The class bool is a subclass of the class int, and cannot be subclassed.
|
||||
#[pyclass(name = "bool", module = false)]
|
||||
#[pyclass(name = "bool", module = false, base = "PyInt")]
|
||||
pub struct PyBool;
|
||||
|
||||
#[pyimpl]
|
||||
|
||||
@@ -109,8 +109,8 @@ pub struct PyStrIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PyStrIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.str_iterator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.str_iterator_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,8 +156,8 @@ pub struct PyStrReverseIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PyStrReverseIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.str_reverseiterator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.str_reverseiterator_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1113,8 +1113,8 @@ pub(crate) fn encode_string(
|
||||
}
|
||||
|
||||
impl PyValue for PyStr {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.str_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.str_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ pub struct PySuper {
|
||||
}
|
||||
|
||||
impl PyValue for PySuper {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.super_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.super_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,8 @@ impl fmt::Debug for PyType {
|
||||
pub type PyTypeRef = PyRef<PyType>;
|
||||
|
||||
impl PyValue for PyType {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.type_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.type_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ pub struct PyRange {
|
||||
}
|
||||
|
||||
impl PyValue for PyRange {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.range_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.range_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,8 +376,8 @@ pub struct PyRangeIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PyRangeIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.range_iterator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.range_iterator_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,14 +52,14 @@ impl fmt::Debug for PyFrozenSet {
|
||||
}
|
||||
|
||||
impl PyValue for PySet {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.set_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.set_type
|
||||
}
|
||||
}
|
||||
|
||||
impl PyValue for PyFrozenSet {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.frozenset_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.frozenset_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -792,8 +792,8 @@ impl PySetIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PySetIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.set_iterator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.set_iterator_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ pub struct PyNone;
|
||||
pub type PyNoneRef = PyRef<PyNone>;
|
||||
|
||||
impl PyValue for PyNone {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.none.clone_class()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.none_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,8 +56,8 @@ pub struct PyNotImplemented;
|
||||
pub type PyNotImplementedRef = PyRef<PyNotImplemented>;
|
||||
|
||||
impl PyValue for PyNotImplemented {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.not_implemented.clone_class()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.not_implemented_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ pub struct PySlice {
|
||||
}
|
||||
|
||||
impl PyValue for PySlice {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.slice_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.slice_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,8 +287,8 @@ fn to_index_value(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Option<Big
|
||||
pub struct PyEllipsis;
|
||||
|
||||
impl PyValue for PyEllipsis {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.ellipsis.clone_class()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.ellipsis_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ pub struct PyStaticMethod {
|
||||
}
|
||||
|
||||
impl PyValue for PyStaticMethod {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.staticmethod_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.staticmethod_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ pub struct PyTraceback {
|
||||
pub type PyTracebackRef = PyRef<PyTraceback>;
|
||||
|
||||
impl PyValue for PyTraceback {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.traceback_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.traceback_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ impl<'a> BorrowValue<'a> for PyTuple {
|
||||
}
|
||||
|
||||
impl PyValue for PyTuple {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.tuple_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.tuple_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,8 +288,8 @@ pub struct PyTupleIterator {
|
||||
}
|
||||
|
||||
impl PyValue for PyTupleIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.tuple_iterator_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.tuple_iterator_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ pub struct PyWeakProxy {
|
||||
}
|
||||
|
||||
impl PyValue for PyWeakProxy {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.weakproxy_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.weakproxy_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ impl PyWeak {
|
||||
}
|
||||
|
||||
impl PyValue for PyWeak {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.weakref_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.weakref_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ pub struct PyZip {
|
||||
}
|
||||
|
||||
impl PyValue for PyZip {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.zip_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.zip_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,21 +6,21 @@ use crate::builtins::tuple::{PyTuple, PyTupleRef};
|
||||
use crate::common::lock::PyRwLock;
|
||||
use crate::function::FuncArgs;
|
||||
use crate::py_io::{self, Write};
|
||||
use crate::pyobject::StaticType;
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IntoPyObject, PyClassDef, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef,
|
||||
PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
BorrowValue, IntoPyObject, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult,
|
||||
PyValue, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::types::create_type_with_slots;
|
||||
use crate::VirtualMachine;
|
||||
use crate::{py_serde, sysmodule};
|
||||
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use itertools::Itertools;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead, BufReader};
|
||||
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
|
||||
#[pyclass(module = false, name = "BaseException")]
|
||||
pub struct PyBaseException {
|
||||
traceback: PyRwLock<Option<PyTracebackRef>>,
|
||||
@@ -44,8 +44,8 @@ pub trait IntoPyException {
|
||||
}
|
||||
|
||||
impl PyValue for PyBaseException {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.exceptions.base_exception_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.exceptions.base_exception_type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,7 +394,7 @@ pub fn normalize(
|
||||
Ok(exc)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ExceptionZoo {
|
||||
pub base_exception_type: PyTypeRef,
|
||||
pub system_exit: PyTypeRef,
|
||||
@@ -468,12 +468,17 @@ pub struct ExceptionZoo {
|
||||
}
|
||||
|
||||
impl ExceptionZoo {
|
||||
pub fn new(type_type: &PyTypeRef, object_type: &PyTypeRef) -> Self {
|
||||
pub(crate) fn init() -> Self {
|
||||
let base_exception_type = PyBaseException::init_bare_type().clone();
|
||||
let create_exception_type = |name: &str, base: &PyTypeRef| {
|
||||
create_type_with_slots(name, type_type, base.clone(), PyBaseException::make_slots())
|
||||
create_type_with_slots(
|
||||
name,
|
||||
PyType::static_type(),
|
||||
base,
|
||||
PyBaseException::make_slots(),
|
||||
)
|
||||
};
|
||||
// Sorted By Hierarchy then alphabetized.
|
||||
let base_exception_type = create_exception_type(PyBaseExceptionRef::NAME, &object_type);
|
||||
let system_exit = create_exception_type("SystemExit", &base_exception_type);
|
||||
let keyboard_interrupt = create_exception_type("KeyboardInterrupt", &base_exception_type);
|
||||
let generator_exit = create_exception_type("GeneratorExit", &base_exception_type);
|
||||
@@ -552,7 +557,7 @@ impl ExceptionZoo {
|
||||
let bytes_warning = create_exception_type("BytesWarning", &warning);
|
||||
let resource_warning = create_exception_type("ResourceWarning", &warning);
|
||||
|
||||
ExceptionZoo {
|
||||
Self {
|
||||
base_exception_type,
|
||||
system_exit,
|
||||
keyboard_interrupt,
|
||||
@@ -624,6 +629,62 @@ impl ExceptionZoo {
|
||||
resource_warning,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend(ctx: &PyContext) {
|
||||
let excs = &ctx.exceptions;
|
||||
|
||||
PyBaseException::extend_class(ctx, &excs.base_exception_type);
|
||||
|
||||
extend_class!(ctx, &excs.syntax_error, {
|
||||
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
|
||||
// TODO: members
|
||||
"filename" => ctx.none(),
|
||||
"lineno" => ctx.none(),
|
||||
"offset" => ctx.none(),
|
||||
"text" => ctx.none(),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.system_exit, {
|
||||
"code" => ctx.new_readonly_getset("code", system_exit_code),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.import_error, {
|
||||
"__init__" => ctx.new_method(import_error_init),
|
||||
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.stop_iteration, {
|
||||
"value" => ctx.new_readonly_getset("value", make_arg_getter(0)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.key_error, {
|
||||
"__str__" => ctx.new_method(key_error_str),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.unicode_decode_error, {
|
||||
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
|
||||
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
|
||||
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
|
||||
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
|
||||
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.unicode_encode_error, {
|
||||
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
|
||||
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
|
||||
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
|
||||
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
|
||||
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.unicode_translate_error, {
|
||||
"encoding" => ctx.new_readonly_getset("encoding", none_getter),
|
||||
"object" => ctx.new_readonly_getset("object", make_arg_getter(0)),
|
||||
"start" => ctx.new_readonly_getset("start", make_arg_getter(1)),
|
||||
"end" => ctx.new_readonly_getset("end", make_arg_getter(2)),
|
||||
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(3)),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn import_error_init(exc_self: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
@@ -672,62 +733,6 @@ fn system_exit_code(exc: PyBaseExceptionRef) -> Option<PyObjectRef> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn init(ctx: &PyContext) {
|
||||
let excs = &ctx.exceptions;
|
||||
|
||||
PyBaseException::extend_class(ctx, &excs.base_exception_type);
|
||||
|
||||
extend_class!(ctx, &excs.syntax_error, {
|
||||
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
|
||||
// TODO: members
|
||||
"filename" => ctx.none(),
|
||||
"lineno" => ctx.none(),
|
||||
"offset" => ctx.none(),
|
||||
"text" => ctx.none(),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.system_exit, {
|
||||
"code" => ctx.new_readonly_getset("code", system_exit_code),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.import_error, {
|
||||
"__init__" => ctx.new_method(import_error_init),
|
||||
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.stop_iteration, {
|
||||
"value" => ctx.new_readonly_getset("value", make_arg_getter(0)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.key_error, {
|
||||
"__str__" => ctx.new_method(key_error_str),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.unicode_decode_error, {
|
||||
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
|
||||
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
|
||||
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
|
||||
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
|
||||
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.unicode_encode_error, {
|
||||
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
|
||||
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
|
||||
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
|
||||
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
|
||||
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.unicode_translate_error, {
|
||||
"encoding" => ctx.new_readonly_getset("encoding", none_getter),
|
||||
"object" => ctx.new_readonly_getset("object", make_arg_getter(0)),
|
||||
"start" => ctx.new_readonly_getset("start", make_arg_getter(1)),
|
||||
"end" => ctx.new_readonly_getset("end", make_arg_getter(2)),
|
||||
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(3)),
|
||||
});
|
||||
}
|
||||
|
||||
pub struct SerializeException<'s> {
|
||||
vm: &'s VirtualMachine,
|
||||
exc: &'s PyBaseExceptionRef,
|
||||
|
||||
@@ -100,8 +100,8 @@ pub struct Frame {
|
||||
}
|
||||
|
||||
impl PyValue for Frame {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.ctx.types.frame_type.clone()
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef {
|
||||
&vm.ctx.types.frame_type
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ macro_rules! py_class {
|
||||
#[allow(unused_mut)]
|
||||
let mut slots = $crate::slots::PyTypeSlots::from_flags($crate::slots::PyTpFlags::DEFAULT | $flags);
|
||||
$($crate::py_class!(@extract_slots($ctx, &mut slots, $name, $value));)*
|
||||
let py_class = $ctx.new_class($class_name, $class_base.clone(), slots);
|
||||
let py_class = $ctx.new_class($class_name, $class_base, slots);
|
||||
$($crate::py_class!(@extract_attrs($ctx, &py_class, $name, $value));)*
|
||||
$ctx.add_tp_new_wrapper(&py_class);
|
||||
py_class
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
use num_bigint::BigInt;
|
||||
use num_complex::Complex64;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
use num_complex::Complex64;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
use crate::builtins::builtinfunc::PyNativeFuncDef;
|
||||
use crate::builtins::bytearray;
|
||||
use crate::builtins::bytes;
|
||||
@@ -31,18 +30,18 @@ use crate::builtins::slice::PyEllipsis;
|
||||
use crate::builtins::staticmethod::PyStaticMethod;
|
||||
use crate::builtins::tuple::{PyTuple, PyTupleRef};
|
||||
use crate::bytecode;
|
||||
pub use crate::common::borrow::BorrowValue;
|
||||
use crate::common::lock::{PyRwLock, PyRwLockReadGuard};
|
||||
use crate::common::rc::PyRc;
|
||||
use crate::common::static_cell;
|
||||
use crate::exceptions::{self, PyBaseExceptionRef};
|
||||
use crate::function::{IntoFuncArgs, IntoPyNativeFunc};
|
||||
use crate::iterator;
|
||||
pub use crate::pyobjectrc::{PyObjectRc, PyObjectWeak};
|
||||
use crate::scope::Scope;
|
||||
use crate::slots::{PyTpFlags, PyTypeSlots};
|
||||
use crate::types::{create_type_with_slots, initialize_types, TypeZoo};
|
||||
use crate::types::{create_type_with_slots, TypeZoo};
|
||||
use crate::vm::VirtualMachine;
|
||||
use rustpython_common::lock::{PyRwLock, PyRwLockReadGuard};
|
||||
use rustpython_common::rc::PyRc;
|
||||
|
||||
pub use crate::common::borrow::BorrowValue;
|
||||
|
||||
/* Python objects and references.
|
||||
|
||||
@@ -92,7 +91,7 @@ impl fmt::Display for PyObject<dyn PyObjectPayload> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PyContext {
|
||||
pub true_value: PyIntRef,
|
||||
pub false_value: PyIntRef,
|
||||
@@ -113,60 +112,62 @@ impl PyContext {
|
||||
pub const INT_CACHE_POOL_MAX: i32 = 256;
|
||||
|
||||
pub fn new() -> Self {
|
||||
flame_guard!("init PyContext");
|
||||
let types = TypeZoo::new();
|
||||
let exceptions = exceptions::ExceptionZoo::new(&types.type_type, &types.object_type);
|
||||
|
||||
fn create_object<T: PyObjectPayload + PyValue>(payload: T, cls: &PyTypeRef) -> PyRef<T> {
|
||||
PyRef::new_ref(payload, cls.clone(), None)
|
||||
use rustpython_common::static_cells;
|
||||
static_cells! {
|
||||
static CONTEXT: PyContext;
|
||||
}
|
||||
static_cell::get_or_init(&CONTEXT, || {
|
||||
flame_guard!("init PyContext");
|
||||
let types = TypeZoo::init();
|
||||
let exceptions = exceptions::ExceptionZoo::init();
|
||||
|
||||
let none_type = PyNone::create_bare_type(&types.type_type, types.object_type.clone());
|
||||
let none = create_object(PyNone, &none_type);
|
||||
fn create_object<T: PyObjectPayload + PyValue>(
|
||||
payload: T,
|
||||
cls: &PyTypeRef,
|
||||
) -> PyRef<T> {
|
||||
PyRef::new_ref(payload, cls.clone(), None)
|
||||
}
|
||||
|
||||
let ellipsis_type =
|
||||
PyEllipsis::create_bare_type(&types.type_type, types.object_type.clone());
|
||||
let ellipsis = create_object(PyEllipsis, &ellipsis_type);
|
||||
let none = create_object(PyNone, PyNone::static_type());
|
||||
let ellipsis = create_object(PyEllipsis, PyEllipsis::static_type());
|
||||
let not_implemented = create_object(PyNotImplemented, PyNotImplemented::static_type());
|
||||
|
||||
let not_implemented_type =
|
||||
PyNotImplemented::create_bare_type(&types.type_type, types.object_type.clone());
|
||||
let not_implemented = create_object(PyNotImplemented, ¬_implemented_type);
|
||||
let int_cache_pool = (Self::INT_CACHE_POOL_MIN..=Self::INT_CACHE_POOL_MAX)
|
||||
.map(|v| PyRef::new_ref(PyInt::from(BigInt::from(v)), types.int_type.clone(), None))
|
||||
.collect();
|
||||
|
||||
let int_cache_pool = (Self::INT_CACHE_POOL_MIN..=Self::INT_CACHE_POOL_MAX)
|
||||
.map(|v| PyRef::new_ref(PyInt::from(BigInt::from(v)), types.int_type.clone(), None))
|
||||
.collect();
|
||||
let true_value = create_object(PyInt::from(1), &types.bool_type);
|
||||
let false_value = create_object(PyInt::from(0), &types.bool_type);
|
||||
|
||||
let true_value = create_object(PyInt::from(1), &types.bool_type);
|
||||
let false_value = create_object(PyInt::from(0), &types.bool_type);
|
||||
let empty_tuple = create_object(
|
||||
PyTuple::_new(Vec::new().into_boxed_slice()),
|
||||
&types.tuple_type,
|
||||
);
|
||||
|
||||
let empty_tuple = create_object(
|
||||
PyTuple::_new(Vec::new().into_boxed_slice()),
|
||||
&types.tuple_type,
|
||||
);
|
||||
let tp_new_wrapper = create_object(
|
||||
PyNativeFuncDef::from(pytype::tp_new_wrapper.into_func()).into_function(),
|
||||
&types.builtin_function_or_method_type,
|
||||
)
|
||||
.into_object();
|
||||
|
||||
let tp_new_wrapper = create_object(
|
||||
PyNativeFuncDef::from(pytype::tp_new_wrapper.into_func()).into_function(),
|
||||
&types.builtin_function_or_method_type,
|
||||
)
|
||||
.into_object();
|
||||
let context = PyContext {
|
||||
true_value,
|
||||
false_value,
|
||||
not_implemented,
|
||||
none,
|
||||
empty_tuple,
|
||||
ellipsis,
|
||||
|
||||
let context = PyContext {
|
||||
true_value,
|
||||
false_value,
|
||||
not_implemented,
|
||||
none,
|
||||
empty_tuple,
|
||||
ellipsis,
|
||||
|
||||
types,
|
||||
exceptions,
|
||||
int_cache_pool,
|
||||
tp_new_wrapper,
|
||||
};
|
||||
initialize_types(&context);
|
||||
|
||||
exceptions::init(&context);
|
||||
context
|
||||
types,
|
||||
exceptions,
|
||||
int_cache_pool,
|
||||
tp_new_wrapper,
|
||||
};
|
||||
TypeZoo::extend(&context);
|
||||
exceptions::ExceptionZoo::extend(&context);
|
||||
context
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
||||
pub fn none(&self) -> PyObjectRef {
|
||||
@@ -266,7 +267,7 @@ impl PyContext {
|
||||
PyRef::new_ref(PyDict::default(), self.types.dict_type.clone(), None)
|
||||
}
|
||||
|
||||
pub fn new_class(&self, name: &str, base: PyTypeRef, slots: PyTypeSlots) -> PyTypeRef {
|
||||
pub fn new_class(&self, name: &str, base: &PyTypeRef, slots: PyTypeSlots) -> PyTypeRef {
|
||||
create_type_with_slots(name, &self.types.type_type, base, slots)
|
||||
}
|
||||
|
||||
@@ -456,7 +457,7 @@ impl PyObjectRef {
|
||||
self,
|
||||
vm: &VirtualMachine,
|
||||
) -> Result<PyRef<T>, Self> {
|
||||
if self.class().is(&T::class(vm)) {
|
||||
if self.class().is(T::class(vm)) {
|
||||
// TODO: is this always true?
|
||||
assert!(
|
||||
self.payload_is::<T>(),
|
||||
@@ -581,10 +582,10 @@ where
|
||||
T: PyValue,
|
||||
{
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
if obj.isinstance(&T::class(vm)) {
|
||||
let class = T::class(vm);
|
||||
if obj.isinstance(class) {
|
||||
PyRef::from_obj(obj, vm)
|
||||
} else {
|
||||
let class = T::class(vm);
|
||||
let expected_type = &class.name;
|
||||
let actual_type = &obj.class().name;
|
||||
Err(vm.new_type_error(format!(
|
||||
@@ -647,7 +648,7 @@ impl TryFromObject for PyCallable {
|
||||
pub type Never = std::convert::Infallible;
|
||||
|
||||
impl PyValue for Never {
|
||||
fn class(_vm: &VirtualMachine) -> PyTypeRef {
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
@@ -1081,7 +1082,7 @@ impl PyObject<dyn PyObjectPayload> {
|
||||
&self,
|
||||
vm: &VirtualMachine,
|
||||
) -> Option<&T> {
|
||||
if self.class().issubclass(&T::class(vm)) {
|
||||
if self.class().issubclass(T::class(vm)) {
|
||||
self.payload()
|
||||
} else {
|
||||
None
|
||||
@@ -1118,19 +1119,19 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
|
||||
pub trait PyValue: fmt::Debug + PyThreadingConstraint + Sized + 'static {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef;
|
||||
fn class(vm: &VirtualMachine) -> &PyTypeRef;
|
||||
|
||||
fn into_object(self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
self.into_ref(vm).into_object()
|
||||
}
|
||||
|
||||
fn into_ref(self, vm: &VirtualMachine) -> PyRef<Self> {
|
||||
self.into_ref_with_type_unchecked(Self::class(vm), vm)
|
||||
self.into_ref_with_type_unchecked(Self::class(vm).clone(), vm)
|
||||
}
|
||||
|
||||
fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult<PyRef<Self>> {
|
||||
let class = Self::class(vm);
|
||||
if cls.issubclass(&class) {
|
||||
if cls.issubclass(class) {
|
||||
Ok(self.into_ref_with_type_unchecked(cls, vm))
|
||||
} else {
|
||||
let subtype = vm.to_str(&cls.obj)?;
|
||||
@@ -1229,8 +1230,46 @@ pub trait PyClassDef {
|
||||
const MODULE_NAME: Option<&'static str>;
|
||||
const TP_NAME: &'static str;
|
||||
const DOC: Option<&'static str> = None;
|
||||
fn base_class(ctx: &PyContext) -> PyTypeRef {
|
||||
ctx.types.object_type.clone()
|
||||
}
|
||||
|
||||
pub trait StaticType {
|
||||
// Ideally, saving PyType is better than PyTypeRef
|
||||
fn static_cell() -> &'static static_cell::StaticCell<PyTypeRef>;
|
||||
fn static_metaclass() -> &'static PyTypeRef {
|
||||
crate::builtins::pytype::PyType::static_type()
|
||||
}
|
||||
fn static_baseclass() -> &'static PyTypeRef {
|
||||
crate::builtins::object::PyBaseObject::static_type()
|
||||
}
|
||||
fn static_type() -> &'static PyTypeRef {
|
||||
static_cell::get(Self::static_cell()).unwrap_or_else(|| unsafe {
|
||||
// SAFETY: object must be initialized by init_* method.
|
||||
// So this is actually not safe as itself.
|
||||
// But easy to find out when it happened in debug build
|
||||
std::hint::unreachable_unchecked()
|
||||
})
|
||||
}
|
||||
|
||||
fn init_manually(typ: PyTypeRef) -> &'static PyTypeRef {
|
||||
static_cell::init_expect(Self::static_cell(), typ, "init_manually")
|
||||
}
|
||||
fn init_bare_type() -> &'static PyTypeRef
|
||||
where
|
||||
Self: PyClassImpl,
|
||||
{
|
||||
let typ = Self::create_bare_type();
|
||||
static_cell::init_expect(Self::static_cell(), typ, Self::NAME)
|
||||
}
|
||||
fn create_bare_type() -> PyTypeRef
|
||||
where
|
||||
Self: PyClassImpl,
|
||||
{
|
||||
create_type_with_slots(
|
||||
Self::NAME,
|
||||
Self::static_metaclass(),
|
||||
Self::static_baseclass(),
|
||||
Self::make_slots(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1270,18 +1309,16 @@ pub trait PyClassImpl: PyClassDef {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_class(ctx: &PyContext) -> PyTypeRef {
|
||||
Self::make_class_with_base(ctx, Self::base_class(ctx))
|
||||
}
|
||||
|
||||
fn make_class_with_base(ctx: &PyContext, base: PyTypeRef) -> PyTypeRef {
|
||||
let py_class = ctx.new_class(Self::NAME, base, Self::make_slots());
|
||||
Self::extend_class(ctx, &py_class);
|
||||
py_class
|
||||
}
|
||||
|
||||
fn create_bare_type(type_type: &PyTypeRef, base: PyTypeRef) -> PyTypeRef {
|
||||
create_type_with_slots(Self::NAME, type_type, base, Self::make_slots())
|
||||
fn make_class(ctx: &PyContext) -> PyTypeRef
|
||||
where
|
||||
Self: StaticType,
|
||||
{
|
||||
static_cell::get_or_init(Self::static_cell(), || {
|
||||
let typ = Self::create_bare_type();
|
||||
Self::extend_class(ctx, &typ);
|
||||
typ
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
||||
fn extend_slots(slots: &mut PyTypeSlots);
|
||||
@@ -1296,13 +1333,14 @@ pub trait PyClassImpl: PyClassDef {
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
pub trait PyStructSequence: PyClassImpl + Sized + 'static {
|
||||
pub trait PyStructSequence: StaticType + PyClassImpl + Sized + 'static {
|
||||
const FIELD_NAMES: &'static [&'static str];
|
||||
|
||||
fn into_tuple(self, vm: &VirtualMachine) -> PyTuple;
|
||||
|
||||
fn into_struct_sequence(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult<PyTupleRef> {
|
||||
self.into_tuple(vm).into_ref_with_type(vm, cls)
|
||||
fn into_struct_sequence(self, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
|
||||
self.into_tuple(vm)
|
||||
.into_ref_with_type(vm, Self::static_type().clone())
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::common::lock::{
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{
|
||||
BorrowValue, Either, IdProtocol, IntoPyObject, PyClassImpl, PyComparisonValue, PyIterable,
|
||||
PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
PyObjectRef, PyRef, PyResult, PyValue, StaticType, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::sliceable::{saturate_index, PySliceableSequence, PySliceableSequenceMut};
|
||||
use crate::slots::{BufferProtocol, Comparable, PyComparisonOp};
|
||||
@@ -473,8 +473,8 @@ pub struct PyArray {
|
||||
pub type PyArrayRef = PyRef<PyArray>;
|
||||
|
||||
impl PyValue for PyArray {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("array", "array")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -914,8 +914,8 @@ pub struct PyArrayIter {
|
||||
}
|
||||
|
||||
impl PyValue for PyArrayIter {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("array", "arrayiterator")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,20 +11,25 @@ use rustpython_parser::{ast, mode::Mode, parser};
|
||||
|
||||
use crate::builtins::list::PyListRef;
|
||||
use crate::builtins::pytype::PyTypeRef;
|
||||
use crate::pyobject::{IntoPyObject, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::slots::PyTpFlags;
|
||||
use crate::pyobject::{
|
||||
IntoPyObject, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, StaticType,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[pyclass(module = "_ast", name = "AST")]
|
||||
#[derive(Debug)]
|
||||
struct AstNode;
|
||||
type AstNodeRef = PyRef<AstNode>;
|
||||
|
||||
#[pyimpl(flags(HAS_DICT))]
|
||||
impl AstNode {}
|
||||
|
||||
const MODULE_NAME: &str = "_ast";
|
||||
pub const PY_COMPILE_FLAG_AST_ONLY: i32 = 0x0400;
|
||||
|
||||
impl PyValue for AstNode {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class(MODULE_NAME, "AST")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,7 +636,7 @@ pub(crate) fn parse(vm: &VirtualMachine, source: &str, mode: Mode) -> PyResult {
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
let ast_base = py_class!(ctx, "AST", &ctx.types.object_type, PyTpFlags::HAS_DICT, {});
|
||||
let ast_base = AstNode::make_class(ctx);
|
||||
py_module!(vm, MODULE_NAME, {
|
||||
// TODO: There's got to be a better way!
|
||||
"alias" => py_class!(ctx, "alias", &ast_base, {}),
|
||||
|
||||
@@ -5,7 +5,9 @@ mod _collections {
|
||||
use crate::builtins::pytype::PyTypeRef;
|
||||
use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{PyComparisonValue, PyIterable, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{
|
||||
PyComparisonValue, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, StaticType,
|
||||
};
|
||||
use crate::slots::{Comparable, PyComparisonOp};
|
||||
use crate::vm::ReprGuard;
|
||||
use crate::VirtualMachine;
|
||||
@@ -25,8 +27,8 @@ mod _collections {
|
||||
type PyDequeRef = PyRef<PyDeque>;
|
||||
|
||||
impl PyValue for PyDeque {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_collections", "deque")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,8 +359,8 @@ mod _collections {
|
||||
}
|
||||
|
||||
impl PyValue for PyDequeIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_collections", "_deque_iterator")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ use crate::common::lock::PyRwLock;
|
||||
use crate::function::FuncArgs;
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IntoPyObject, PyClassImpl, PyIterable, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TryFromObject, TypeProtocol,
|
||||
StaticType, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::types::create_type;
|
||||
use crate::types::create_simple_type;
|
||||
use crate::VirtualMachine;
|
||||
|
||||
#[repr(i32)]
|
||||
@@ -135,8 +135,8 @@ impl Debug for Reader {
|
||||
}
|
||||
|
||||
impl PyValue for Reader {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_csv", "Reader")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,11 +198,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
|
||||
let reader_type = Reader::make_class(ctx);
|
||||
|
||||
let error = create_type(
|
||||
"Error",
|
||||
&ctx.types.type_type,
|
||||
ctx.exceptions.exception_type.clone(),
|
||||
);
|
||||
let error = create_simple_type("Error", &ctx.exceptions.exception_type);
|
||||
|
||||
py_module!(vm, "_csv", {
|
||||
"reader" => named_function!(ctx, _csv, reader),
|
||||
|
||||
@@ -7,16 +7,15 @@ mod hashlib {
|
||||
use crate::builtins::pytype::PyTypeRef;
|
||||
use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
|
||||
use crate::function::{FuncArgs, OptionalArg};
|
||||
use crate::pyobject::{BorrowValue, PyResult, PyValue};
|
||||
use crate::pyobject::{BorrowValue, PyResult, PyValue, StaticType};
|
||||
use crate::vm::VirtualMachine;
|
||||
use std::fmt;
|
||||
|
||||
use blake2::{Blake2b, Blake2s};
|
||||
use digest::DynDigest;
|
||||
use md5::Md5;
|
||||
use sha1::Sha1;
|
||||
use sha2::{Sha224, Sha256, Sha384, Sha512};
|
||||
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512}; // TODO: , Shake128, Shake256};
|
||||
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512}; // TODO: , Shake128, Shake256;
|
||||
use std::fmt;
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(module = "hashlib", name = "hasher")]
|
||||
@@ -32,8 +31,8 @@ mod hashlib {
|
||||
}
|
||||
|
||||
impl PyValue for PyHasher {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("hashlib", "hasher")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
*/
|
||||
use crate::pyobject::PyObjectRef;
|
||||
use crate::VirtualMachine;
|
||||
pub(crate) use _io::io_open as open;
|
||||
|
||||
pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let module = _io::make_module(vm);
|
||||
_io::extend_more(vm, &module);
|
||||
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
|
||||
fileio::extend_module(vm, &module);
|
||||
module
|
||||
}
|
||||
|
||||
@@ -32,7 +34,7 @@ mod _io {
|
||||
use crate::exceptions::{IntoPyException, PyBaseExceptionRef};
|
||||
use crate::function::{FuncArgs, OptionalArg, OptionalOption};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
BorrowValue, IntoPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, StaticType,
|
||||
TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
@@ -210,10 +212,10 @@ mod _io {
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(name = "_IOBase")]
|
||||
struct IOBase;
|
||||
struct _IOBase;
|
||||
|
||||
#[pyimpl(flags(BASETYPE))]
|
||||
impl IOBase {
|
||||
impl _IOBase {
|
||||
#[pyattr]
|
||||
fn __closed(ctx: &PyContext) -> PyObjectRef {
|
||||
ctx.new_bool(false)
|
||||
@@ -380,11 +382,12 @@ mod _io {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(name = "_RawIOBase", noattr)]
|
||||
struct RawIOBase;
|
||||
#[pyattr]
|
||||
#[pyclass(name = "_RawIOBase", base = "_IOBase")]
|
||||
pub(super) struct _RawIOBase;
|
||||
|
||||
#[pyimpl(flags(BASETYPE))]
|
||||
impl RawIOBase {
|
||||
impl _RawIOBase {
|
||||
#[pymethod]
|
||||
fn read(instance: PyObjectRef, size: OptionalSize, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(size) = size.to_usize() {
|
||||
@@ -406,11 +409,12 @@ mod _io {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(name = "_BufferedIOBase", noattr)]
|
||||
struct BufferedIOBase;
|
||||
#[pyattr]
|
||||
#[pyclass(name = "_BufferedIOBase", base = "_IOBase")]
|
||||
struct _BufferedIOBase;
|
||||
|
||||
#[pyimpl(flags(BASETYPE))]
|
||||
impl BufferedIOBase {
|
||||
impl _BufferedIOBase {
|
||||
// #[pymethod(magic)]
|
||||
fn init(
|
||||
instance: PyObjectRef,
|
||||
@@ -460,13 +464,15 @@ mod _io {
|
||||
}
|
||||
|
||||
// TextIO Base has no public constructor
|
||||
#[pyclass(name = "_TextIOBase", noattr)]
|
||||
struct TextIOBase;
|
||||
#[pyattr]
|
||||
#[pyclass(name = "_TextIOBase", base = "_IOBase")]
|
||||
struct _TextIOBase;
|
||||
|
||||
#[pyimpl(flags(BASETYPE))]
|
||||
impl TextIOBase {}
|
||||
impl _TextIOBase {}
|
||||
|
||||
#[pyclass(name = "BufferedReader", noattr)]
|
||||
#[pyattr]
|
||||
#[pyclass(name = "BufferedReader", base = "_BufferedIOBase")]
|
||||
struct BufferedReader;
|
||||
|
||||
#[pyimpl(flags(BASETYPE))]
|
||||
@@ -482,32 +488,32 @@ mod _io {
|
||||
buffer_size: OptionalArg<usize>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
BufferedIOBase::init(instance, raw, buffer_size, vm)
|
||||
_BufferedIOBase::init(instance, raw, buffer_size, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn fileno(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
BufferedIOBase::fileno(instance, vm)
|
||||
_BufferedIOBase::fileno(instance, vm)
|
||||
}
|
||||
|
||||
#[pyproperty]
|
||||
fn mode(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
BufferedIOBase::mode(instance, vm)
|
||||
_BufferedIOBase::mode(instance, vm)
|
||||
}
|
||||
|
||||
#[pyproperty]
|
||||
fn name(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
BufferedIOBase::name(instance, vm)
|
||||
_BufferedIOBase::name(instance, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn tell(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
BufferedIOBase::tell(instance, vm)
|
||||
_BufferedIOBase::tell(instance, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn close(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
BufferedIOBase::close(instance, vm)
|
||||
_BufferedIOBase::close(instance, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -537,7 +543,8 @@ mod _io {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(name = "BufferedWriter", noattr)]
|
||||
#[pyattr]
|
||||
#[pyclass(name = "BufferedWriter", base = "_BufferedIOBase")]
|
||||
struct BufferedWriter;
|
||||
|
||||
#[pyimpl(flags(BASETYPE))]
|
||||
@@ -553,32 +560,32 @@ mod _io {
|
||||
buffer_size: OptionalArg<usize>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
BufferedIOBase::init(instance, raw, buffer_size, vm)
|
||||
_BufferedIOBase::init(instance, raw, buffer_size, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn fileno(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
BufferedIOBase::fileno(instance, vm)
|
||||
_BufferedIOBase::fileno(instance, vm)
|
||||
}
|
||||
|
||||
#[pyproperty]
|
||||
fn mode(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
BufferedIOBase::mode(instance, vm)
|
||||
_BufferedIOBase::mode(instance, vm)
|
||||
}
|
||||
|
||||
#[pyproperty]
|
||||
fn name(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
BufferedIOBase::name(instance, vm)
|
||||
_BufferedIOBase::name(instance, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn tell(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
BufferedIOBase::tell(instance, vm)
|
||||
_BufferedIOBase::tell(instance, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn close(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
BufferedIOBase::close(instance, vm)
|
||||
_BufferedIOBase::close(instance, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -634,7 +641,8 @@ mod _io {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(name = "TextIOWrapper", noattr)]
|
||||
#[pyattr]
|
||||
#[pyclass(name = "TextIOWrapper", base = "_TextIOBase")]
|
||||
struct TextIOWrapper;
|
||||
|
||||
#[pyimpl]
|
||||
@@ -722,7 +730,7 @@ mod _io {
|
||||
size: OptionalOption<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<String> {
|
||||
let buffered_reader_class = vm.try_class("_io", "BufferedReader")?;
|
||||
let buffered_reader_class = BufferedReader::static_type();
|
||||
let raw = vm.get_attribute(instance, "buffer").unwrap();
|
||||
|
||||
if !raw.isinstance(&buffered_reader_class) {
|
||||
@@ -746,7 +754,7 @@ mod _io {
|
||||
fn write(instance: PyObjectRef, obj: PyStrRef, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
use std::str::from_utf8;
|
||||
|
||||
let buffered_writer_class = vm.try_class("_io", "BufferedWriter")?;
|
||||
let buffered_writer_class = BufferedWriter::static_type();
|
||||
let raw = vm.get_attribute(instance, "buffer").unwrap();
|
||||
|
||||
if !raw.isinstance(&buffered_writer_class) {
|
||||
@@ -773,7 +781,7 @@ mod _io {
|
||||
size: OptionalOption<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<String> {
|
||||
let buffered_reader_class = vm.try_class("_io", "BufferedReader")?;
|
||||
let buffered_reader_class = BufferedReader::static_type();
|
||||
let raw = vm.get_attribute(instance, "buffer").unwrap();
|
||||
|
||||
if !raw.isinstance(&buffered_reader_class) {
|
||||
@@ -802,7 +810,8 @@ mod _io {
|
||||
newline: Option<PyStrRef>,
|
||||
}
|
||||
|
||||
#[pyclass(name = "StringIO", noattr)]
|
||||
#[pyattr]
|
||||
#[pyclass(name = "StringIO", base = "_TextIOBase")]
|
||||
#[derive(Debug)]
|
||||
struct StringIO {
|
||||
buffer: PyRwLock<BufferedIO>,
|
||||
@@ -812,8 +821,8 @@ mod _io {
|
||||
type StringIORef = PyRef<StringIO>;
|
||||
|
||||
impl PyValue for StringIO {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("io", "StringIO")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,7 +944,8 @@ mod _io {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(name = "BytesIO", noattr)]
|
||||
#[pyattr]
|
||||
#[pyclass(name = "BytesIO", base = "_BufferedIOBase")]
|
||||
#[derive(Debug)]
|
||||
struct BytesIO {
|
||||
buffer: PyRwLock<BufferedIO>,
|
||||
@@ -947,8 +957,8 @@ mod _io {
|
||||
type BytesIORef = PyRef<BytesIO>;
|
||||
|
||||
impl PyValue for BytesIO {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("io", "BytesIO")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1304,55 +1314,6 @@ mod _io {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn extend_more(vm: &VirtualMachine, module: &PyObjectRef) {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
// IOBase the abstract base class of the IO Module
|
||||
let io_base = IOBase::make_class(&vm.ctx);
|
||||
extend_class!(ctx, &io_base, {});
|
||||
|
||||
// IOBase Subclasses
|
||||
let raw_io_base = RawIOBase::make_class_with_base(&vm.ctx, io_base.clone());
|
||||
let buffered_io_base = BufferedIOBase::make_class_with_base(&vm.ctx, io_base.clone());
|
||||
let text_io_base = TextIOBase::make_class_with_base(&vm.ctx, io_base.clone());
|
||||
|
||||
// BufferedIOBase Subclasses
|
||||
let buffered_reader =
|
||||
BufferedReader::make_class_with_base(&vm.ctx, buffered_io_base.clone());
|
||||
let buffered_writer =
|
||||
BufferedWriter::make_class_with_base(&vm.ctx, buffered_io_base.clone());
|
||||
|
||||
//TextIOBase Subclass
|
||||
let text_io_wrapper = TextIOWrapper::make_class_with_base(&vm.ctx, text_io_base.clone());
|
||||
|
||||
//StringIO: in-memory text
|
||||
let string_io = StringIO::make_class_with_base(&vm.ctx, text_io_base.clone());
|
||||
extend_class!(ctx, &string_io, {
|
||||
"__module__" => ctx.new_str("_io"),
|
||||
});
|
||||
|
||||
//BytesIO: in-memory bytes
|
||||
let bytes_io = BytesIO::make_class_with_base(&vm.ctx, buffered_io_base.clone());
|
||||
extend_class!(ctx, &bytes_io, {});
|
||||
|
||||
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
|
||||
extend_module!(vm, module, {
|
||||
"FileIO" => super::fileio::make_fileio(ctx, raw_io_base.clone()),
|
||||
});
|
||||
|
||||
extend_module!(vm, module, {
|
||||
"_IOBase" => io_base,
|
||||
"_RawIOBase" => raw_io_base,
|
||||
"_BufferedIOBase" => buffered_io_base,
|
||||
"_TextIOBase" => text_io_base,
|
||||
"BufferedReader" => buffered_reader,
|
||||
"BufferedWriter" => buffered_writer,
|
||||
"TextIOWrapper" => text_io_wrapper,
|
||||
"StringIO" => string_io,
|
||||
"BytesIO" => bytes_io,
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -1476,6 +1437,7 @@ mod _io {
|
||||
|
||||
// disable FileIO on WASM
|
||||
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
|
||||
#[pymodule]
|
||||
mod fileio {
|
||||
use super::_io::*;
|
||||
use crate::builtins::pystr::PyStrRef;
|
||||
@@ -1484,7 +1446,7 @@ mod fileio {
|
||||
use crate::exceptions::IntoPyException;
|
||||
use crate::function::{FuncArgs, OptionalArg};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, Either, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
BorrowValue, Either, PyObjectRef, PyRef, PyResult, PyValue, StaticType, TryFromObject,
|
||||
};
|
||||
use crate::stdlib::os;
|
||||
use crate::vm::VirtualMachine;
|
||||
@@ -1505,9 +1467,10 @@ mod fileio {
|
||||
flag as u32
|
||||
}
|
||||
|
||||
#[pyclass(module = "io", name)]
|
||||
#[pyattr]
|
||||
#[pyclass(module = "io", name, base = "_RawIOBase")]
|
||||
#[derive(Debug)]
|
||||
struct FileIO {
|
||||
pub(super) struct FileIO {
|
||||
fd: AtomicCell<i64>,
|
||||
closefd: AtomicCell<bool>,
|
||||
}
|
||||
@@ -1515,8 +1478,8 @@ mod fileio {
|
||||
type FileIORef = PyRef<FileIO>;
|
||||
|
||||
impl PyValue for FileIO {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_io", "FileIO")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1716,8 +1679,4 @@ mod fileio {
|
||||
Ok(pos)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_fileio(ctx: &crate::pyobject::PyContext, raw_io_base: PyTypeRef) -> PyTypeRef {
|
||||
FileIO::make_class_with_base(ctx, raw_io_base)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ mod decl {
|
||||
use crate::iterator::{call_next, get_all, get_iter, get_next_object};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IdProtocol, IntoPyRef, PyCallable, PyObjectRc, PyObjectRef, PyObjectWeak,
|
||||
PyRef, PyResult, PyValue, TypeProtocol,
|
||||
PyRef, PyResult, PyValue, StaticType, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -31,8 +31,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsChain {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "chain")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,8 +116,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsCompress {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "compress")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,8 +168,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsCount {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "count")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,8 +222,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsCycle {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "cycle")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,8 +283,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsRepeat {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "repeat")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,8 +341,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsStarmap {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "starmap")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,8 +384,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsTakewhile {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "takewhile")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,8 +444,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsDropwhile {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "dropwhile")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,8 +528,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsGroupBy {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "groupby")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,8 +635,8 @@ mod decl {
|
||||
type PyItertoolsGrouperRef = PyRef<PyItertoolsGrouper>;
|
||||
|
||||
impl PyValue for PyItertoolsGrouper {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "_grouper")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -689,8 +689,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsIslice {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "islice")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,8 +813,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsFilterFalse {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "filterfalse")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,8 +871,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsAccumulate {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "accumulate")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -955,23 +955,24 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsTee {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "tee")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
impl PyItertoolsTee {
|
||||
fn from_iter(iterable: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
let class = PyItertoolsTee::class(vm);
|
||||
let it = get_iter(vm, &iterable)?;
|
||||
if it.class().is(&PyItertoolsTee::class(vm)) {
|
||||
if it.class().is(PyItertoolsTee::class(vm)) {
|
||||
return vm.call_method(&it, "__copy__", ());
|
||||
}
|
||||
Ok(PyItertoolsTee {
|
||||
tee_data: PyItertoolsTeeData::new(it, vm)?,
|
||||
index: AtomicCell::new(0),
|
||||
}
|
||||
.into_ref_with_type(vm, PyItertoolsTee::class(vm))?
|
||||
.into_ref_with_type(vm, class.clone())?
|
||||
.into_object())
|
||||
}
|
||||
|
||||
@@ -1007,7 +1008,7 @@ mod decl {
|
||||
tee_data: PyRc::clone(&self.tee_data),
|
||||
index: AtomicCell::new(self.index.load()),
|
||||
}
|
||||
.into_ref_with_type(vm, Self::class(vm))?
|
||||
.into_ref_with_type(vm, Self::class(vm).clone())?
|
||||
.into_object())
|
||||
}
|
||||
|
||||
@@ -1035,8 +1036,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsProduct {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "product")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1152,8 +1153,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsCombinations {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "combinations")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1252,8 +1253,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsCombinationsWithReplacement {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "combinations_with_replacement")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1349,8 +1350,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsPermutations {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "permutations")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1476,8 +1477,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyItertoolsZipLongest {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("itertools", "zip_longest")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ mod _json {
|
||||
use crate::function::{FuncArgs, OptionalArg};
|
||||
use crate::iterator;
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IdProtocol, IntoPyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
BorrowValue, IdProtocol, IntoPyObject, PyObjectRef, PyRef, PyResult, PyValue, StaticType,
|
||||
TryFromObject,
|
||||
};
|
||||
use crate::slots::Callable;
|
||||
use crate::VirtualMachine;
|
||||
@@ -32,8 +33,8 @@ mod _json {
|
||||
}
|
||||
|
||||
impl PyValue for JsonScanner {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_json", "make_scanner")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ use crate::exceptions::{IntoPyException, PyBaseExceptionRef};
|
||||
use crate::function::{FuncArgs, IntoPyNativeFunc, OptionalArg};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, Either, IntoPyObject, ItemProtocol, PyObjectRef, PyRef, PyResult,
|
||||
PyStructSequence, PyValue, TryFromObject, TypeProtocol,
|
||||
PyStructSequence, PyValue, StaticType, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -464,8 +464,8 @@ mod _os {
|
||||
}
|
||||
|
||||
impl PyValue for DirEntry {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class(super::MODULE_NAME, "DirEntry")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,8 +549,8 @@ mod _os {
|
||||
}
|
||||
|
||||
impl PyValue for ScandirIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class(super::MODULE_NAME, "ScandirIter")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,9 +636,7 @@ mod _os {
|
||||
#[pyimpl(with(PyStructSequence))]
|
||||
impl StatResult {
|
||||
pub(super) fn into_obj(self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
self.into_struct_sequence(vm, vm.class(super::MODULE_NAME, "stat_result"))
|
||||
.unwrap()
|
||||
.into_object()
|
||||
self.into_struct_sequence(vm).unwrap().into_object()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1745,9 +1743,7 @@ mod posix {
|
||||
#[pyimpl(with(PyStructSequence))]
|
||||
impl UnameResult {
|
||||
fn into_obj(self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
self.into_struct_sequence(vm, vm.class(super::MODULE_NAME, "uname_result"))
|
||||
.unwrap()
|
||||
.into_object()
|
||||
self.into_struct_sequence(vm).unwrap().into_object()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2143,8 +2139,7 @@ mod posix {
|
||||
(w.ws_col.into(), w.ws_row.into())
|
||||
}
|
||||
};
|
||||
super::_os::PyTerminalSize { columns, lines }
|
||||
.into_struct_sequence(vm, vm.try_class(super::MODULE_NAME, "terminal_size")?)
|
||||
super::_os::PyTerminalSize { columns, lines }.into_struct_sequence(vm)
|
||||
}
|
||||
|
||||
// from libstd:
|
||||
@@ -2466,8 +2461,7 @@ mod nt {
|
||||
)
|
||||
}
|
||||
};
|
||||
super::_os::PyTerminalSize { columns, lines }
|
||||
.into_struct_sequence(vm, vm.try_class(super::MODULE_NAME, "terminal_size")?)
|
||||
super::_os::PyTerminalSize { columns, lines }.into_struct_sequence(vm)
|
||||
}
|
||||
|
||||
#[cfg(target_env = "msvc")]
|
||||
|
||||
@@ -48,9 +48,7 @@ impl From<User> for Passwd {
|
||||
|
||||
fn pwd_getpwnam(name: PyStrRef, vm: &VirtualMachine) -> PyResult {
|
||||
match User::from_name(name.borrow_value()).map_err(|err| err.into_pyexception(vm))? {
|
||||
Some(user) => Ok(Passwd::from(user)
|
||||
.into_struct_sequence(vm, vm.try_class("pwd", "struct_passwd")?)?
|
||||
.into_object()),
|
||||
Some(user) => Ok(Passwd::from(user).into_struct_sequence(vm)?.into_object()),
|
||||
None => {
|
||||
let name_repr = vm.to_repr(name.as_object())?;
|
||||
let message = vm
|
||||
@@ -68,9 +66,7 @@ fn pwd_getpwuid(uid: PyIntRef, vm: &VirtualMachine) -> PyResult {
|
||||
Err(_) => None,
|
||||
};
|
||||
match user {
|
||||
Some(user) => Ok(Passwd::from(user)
|
||||
.into_struct_sequence(vm, vm.try_class("pwd", "struct_passwd")?)?
|
||||
.into_object()),
|
||||
Some(user) => Ok(Passwd::from(user).into_struct_sequence(vm)?.into_object()),
|
||||
None => {
|
||||
let message = vm
|
||||
.ctx
|
||||
@@ -86,14 +82,11 @@ fn pwd_getpwall(vm: &VirtualMachine) -> PyResult {
|
||||
static GETPWALL: parking_lot::Mutex<()> = parking_lot::const_mutex(());
|
||||
let _guard = GETPWALL.lock();
|
||||
let mut list = Vec::new();
|
||||
let cls = vm.try_class("pwd", "struct_passwd")?;
|
||||
|
||||
unsafe { libc::setpwent() };
|
||||
while let Some(ptr) = NonNull::new(unsafe { libc::getpwent() }) {
|
||||
let user = User::from(unsafe { ptr.as_ref() });
|
||||
let passwd = Passwd::from(user)
|
||||
.into_struct_sequence(vm, cls.clone())?
|
||||
.into_object();
|
||||
let passwd = Passwd::from(user).into_struct_sequence(vm)?.into_object();
|
||||
list.push(passwd);
|
||||
}
|
||||
unsafe { libc::endpwent() };
|
||||
|
||||
@@ -30,7 +30,7 @@ pub(crate) mod _struct {
|
||||
use crate::exceptions::PyBaseExceptionRef;
|
||||
use crate::function::Args;
|
||||
use crate::pyobject::{
|
||||
BorrowValue, Either, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
BorrowValue, Either, PyObjectRef, PyRef, PyResult, PyValue, StaticType, TryFromObject,
|
||||
};
|
||||
use crate::VirtualMachine;
|
||||
|
||||
@@ -841,8 +841,8 @@ pub(crate) mod _struct {
|
||||
}
|
||||
|
||||
impl PyValue for UnpackIterator {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_struct", "unpack_iterator")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,8 +896,8 @@ pub(crate) mod _struct {
|
||||
}
|
||||
|
||||
impl PyValue for PyStruct {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_struct", "Struct")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,7 +988,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
|
||||
let struct_error = ctx.new_class(
|
||||
"struct.error",
|
||||
ctx.exceptions.exception_type.clone(),
|
||||
&ctx.exceptions.exception_type,
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ mod _random {
|
||||
use crate::builtins::pytype::PyTypeRef;
|
||||
use crate::common::lock::PyMutex;
|
||||
use crate::function::OptionalOption;
|
||||
use crate::pyobject::{BorrowValue, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{BorrowValue, PyRef, PyResult, PyValue, StaticType};
|
||||
use crate::VirtualMachine;
|
||||
use num_bigint::{BigInt, Sign};
|
||||
use num_traits::Signed;
|
||||
@@ -61,8 +61,8 @@ mod _random {
|
||||
}
|
||||
|
||||
impl PyValue for PyRandom {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_random", "Random")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@ use crate::builtins::pystr::{PyStr, PyStrRef};
|
||||
use crate::builtins::pytype::PyTypeRef;
|
||||
use crate::function::{Args, OptionalArg};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IntoPyObject, PyClassImpl, PyObjectRef, PyResult, PyValue, TryFromObject,
|
||||
BorrowValue, IntoPyObject, PyClassImpl, PyObjectRef, PyResult, PyValue, StaticType,
|
||||
TryFromObject,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -65,8 +66,8 @@ impl PyRegexFlags {
|
||||
}
|
||||
|
||||
impl PyValue for PyPattern {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("re", "Pattern")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +85,8 @@ impl fmt::Debug for PyMatch {
|
||||
}
|
||||
|
||||
impl PyValue for PyMatch {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("re", "Match")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
|
||||
use std::io::{self, prelude::*};
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
|
||||
use std::time::Duration;
|
||||
|
||||
use byteorder::{BigEndian, ByteOrder};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use gethostname::gethostname;
|
||||
#[cfg(all(unix, not(target_os = "redox")))]
|
||||
use nix::unistd::sethostname;
|
||||
use socket2::{Domain, Protocol, Socket, Type as SocketType};
|
||||
use std::io::{self, prelude::*};
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::builtins::bytearray::PyByteArrayRef;
|
||||
use crate::builtins::bytes::PyBytesRef;
|
||||
@@ -16,11 +14,12 @@ use crate::builtins::pystr::{PyStr, PyStrRef};
|
||||
use crate::builtins::pytype::PyTypeRef;
|
||||
use crate::builtins::tuple::PyTupleRef;
|
||||
use crate::byteslike::PyBytesLike;
|
||||
use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
|
||||
use crate::exceptions::{IntoPyException, PyBaseExceptionRef};
|
||||
use crate::function::{FuncArgs, OptionalArg};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, Either, IntoPyObject, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TryFromObject,
|
||||
StaticType, TryFromObject,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
@@ -64,8 +63,8 @@ pub struct PySocket {
|
||||
}
|
||||
|
||||
impl PyValue for PySocket {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_socket", "socket")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,12 +786,12 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
let socket_timeout = ctx.new_class(
|
||||
"socket.timeout",
|
||||
vm.ctx.exceptions.os_error.clone(),
|
||||
&vm.ctx.exceptions.os_error,
|
||||
Default::default(),
|
||||
);
|
||||
let socket_gaierror = ctx.new_class(
|
||||
"socket.gaierror",
|
||||
vm.ctx.exceptions.os_error.clone(),
|
||||
&vm.ctx.exceptions.os_error,
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ use crate::exceptions::{IntoPyException, PyBaseExceptionRef};
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{
|
||||
BorrowValue, Either, IntoPyObject, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult,
|
||||
PyValue,
|
||||
PyValue, StaticType,
|
||||
};
|
||||
use crate::types::create_type;
|
||||
use crate::types::create_simple_type;
|
||||
use crate::VirtualMachine;
|
||||
|
||||
use foreign_types_shared::{ForeignType, ForeignTypeRef};
|
||||
@@ -241,8 +241,8 @@ impl fmt::Debug for PySslContext {
|
||||
}
|
||||
|
||||
impl PyValue for PySslContext {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_ssl", "_SSLContext")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,8 +520,8 @@ impl fmt::Debug for PySslSocket {
|
||||
}
|
||||
|
||||
impl PyValue for PySslSocket {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_ssl", "_SSLSocket")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -751,11 +751,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
}
|
||||
openssl::init();
|
||||
let ctx = &vm.ctx;
|
||||
let ssl_error = create_type(
|
||||
"SSLError",
|
||||
&vm.ctx.types.type_type,
|
||||
vm.ctx.exceptions.os_error.clone(),
|
||||
);
|
||||
let ssl_error = create_simple_type("SSLError", &vm.ctx.exceptions.os_error);
|
||||
let module = py_module!(vm, "_ssl", {
|
||||
"_SSLContext" => PySslContext::make_class(ctx),
|
||||
"_SSLSocket" => PySslSocket::make_class(ctx),
|
||||
|
||||
@@ -6,7 +6,7 @@ mod decl {
|
||||
|
||||
use crate::builtins::pystr::PyStrRef;
|
||||
use crate::builtins::pytype::PyTypeRef;
|
||||
use crate::pyobject::{BorrowValue, PyRef, PyResult, PyValue};
|
||||
use crate::pyobject::{BorrowValue, PyRef, PyResult, PyValue, StaticType};
|
||||
use crate::vm::VirtualMachine;
|
||||
use rustpython_compiler::{compile, error::CompileError, symboltable};
|
||||
use rustpython_parser::parser;
|
||||
@@ -73,8 +73,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PySymbolTable {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("symtable", "SymbolTable")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,8 +191,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PySymbol {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("symtable", "Symbol")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::exceptions::{self, IntoPyException};
|
||||
use crate::function::{FuncArgs, OptionalArg};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, Either, IdProtocol, ItemProtocol, PyCallable, PyClassImpl, PyObjectRef, PyRef,
|
||||
PyResult, PyValue, TypeProtocol,
|
||||
PyResult, PyValue, StaticType, TypeProtocol,
|
||||
};
|
||||
use crate::slots::SlotGetattro;
|
||||
use crate::vm::VirtualMachine;
|
||||
@@ -100,8 +100,8 @@ struct PyLock {
|
||||
type PyLockRef = PyRef<PyLock>;
|
||||
|
||||
impl PyValue for PyLock {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_thread", "LockType")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,8 +153,8 @@ struct PyRLock {
|
||||
}
|
||||
|
||||
impl PyValue for PyRLock {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_thread", "RLock")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,8 +291,8 @@ struct PyLocal {
|
||||
}
|
||||
|
||||
impl PyValue for PyLocal {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_thread", "_local")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,14 +218,13 @@ impl PyStructTime {
|
||||
}
|
||||
|
||||
fn into_obj(self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
self.into_struct_sequence(vm, vm.class("time", "struct_time"))
|
||||
.unwrap()
|
||||
.into_object()
|
||||
self.into_struct_sequence(vm).unwrap().into_object()
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
fn tp_new(cls: PyTypeRef, seq: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
|
||||
Self::try_from_object(vm, seq)?.into_struct_sequence(vm, cls)
|
||||
fn tp_new(_cls: PyTypeRef, seq: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
|
||||
// cls is ignorable because this is not a basetype
|
||||
Self::try_from_object(vm, seq)?.into_struct_sequence(vm)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
use crate::builtins::pystr::PyStrRef;
|
||||
use crate::builtins::pytype::PyTypeRef;
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{BorrowValue, PyClassImpl, PyObject, PyObjectRef, PyResult, PyValue};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, PyClassImpl, PyObject, PyObjectRef, PyResult, PyValue, StaticType,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use itertools::Itertools;
|
||||
@@ -61,8 +63,8 @@ struct PyUCD {
|
||||
}
|
||||
|
||||
impl PyValue for PyUCD {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("unicodedata", "UCD")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
|
||||
use crate::exceptions::IntoPyException;
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{
|
||||
BorrowValue, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
BorrowValue, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, StaticType, TryFromObject,
|
||||
};
|
||||
use crate::VirtualMachine;
|
||||
|
||||
@@ -25,8 +25,8 @@ type PyHKEYRef = PyRef<PyHKEY>;
|
||||
unsafe impl Sync for PyHKEY {}
|
||||
|
||||
impl PyValue for PyHKEY {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("winreg", "HKEYType")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ mod decl {
|
||||
use crate::common::lock::PyMutex;
|
||||
use crate::exceptions::PyBaseExceptionRef;
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{BorrowValue, IntoPyRef, PyResult, PyValue};
|
||||
use crate::types::create_type;
|
||||
use crate::pyobject::{BorrowValue, IntoPyRef, PyResult, PyValue, StaticType};
|
||||
use crate::types::create_simple_type;
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use adler32::RollingAdler32 as Adler32;
|
||||
@@ -36,11 +36,7 @@ mod decl {
|
||||
|
||||
#[pyattr]
|
||||
fn error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
create_type(
|
||||
"error",
|
||||
&vm.ctx.types.type_type,
|
||||
vm.ctx.exceptions.exception_type.clone(),
|
||||
)
|
||||
create_simple_type("error", &vm.ctx.exceptions.exception_type)
|
||||
}
|
||||
|
||||
/// Compute an Adler-32 checksum of data.
|
||||
@@ -218,8 +214,8 @@ mod decl {
|
||||
unconsumed_tail: PyMutex<PyBytesRef>,
|
||||
}
|
||||
impl PyValue for PyDecompress {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("zlib", "Decompress")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
#[pyimpl]
|
||||
@@ -377,8 +373,8 @@ mod decl {
|
||||
}
|
||||
|
||||
impl PyValue for PyCompress {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("zlib", "Compress")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -287,44 +287,44 @@ fn sys_getwindowsversion(vm: &VirtualMachine) -> PyResult<crate::builtins::tuple
|
||||
version.dwOSVersionInfoSize = std::mem::size_of::<OSVERSIONINFOEXW>() as u32;
|
||||
let result = unsafe {
|
||||
let osvi = &mut version as LPOSVERSIONINFOEXW as LPOSVERSIONINFOW;
|
||||
// SAFE: GetVersionExW accepts a pointer of OSVERSIONINFOW, but winapi crate's type currently doesn't allow to do so.
|
||||
// SAFETY: GetVersionExW accepts a pointer of OSVERSIONINFOW, but winapi crate's type currently doesn't allow to do so.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversionexw#parameters
|
||||
GetVersionExW(osvi)
|
||||
};
|
||||
|
||||
if result == 0 {
|
||||
Err(vm.new_os_error("failed to get windows version".to_owned()))
|
||||
} else {
|
||||
let service_pack = {
|
||||
let (last, _) = version
|
||||
.szCSDVersion
|
||||
.iter()
|
||||
.take_while(|&x| x != &0)
|
||||
.enumerate()
|
||||
.last()
|
||||
.unwrap_or((0, &0));
|
||||
let sp = OsString::from_wide(&version.szCSDVersion[..last]);
|
||||
sp.into_string()
|
||||
.map_err(|_| vm.new_os_error("service pack is not ASCII".to_owned()))?
|
||||
};
|
||||
WindowsVersion {
|
||||
major: version.dwMajorVersion,
|
||||
minor: version.dwMinorVersion,
|
||||
build: version.dwBuildNumber,
|
||||
platform: version.dwPlatformId,
|
||||
service_pack,
|
||||
service_pack_major: version.wServicePackMajor,
|
||||
service_pack_minor: version.wServicePackMinor,
|
||||
suite_mask: version.wSuiteMask,
|
||||
product_type: version.wProductType,
|
||||
platform_version: (
|
||||
version.dwMajorVersion,
|
||||
version.dwMinorVersion,
|
||||
version.dwBuildNumber,
|
||||
), // TODO Provide accurate version, like CPython impl
|
||||
}
|
||||
.into_struct_sequence(vm, vm.try_class("sys", "_getwindowsversion_type")?)
|
||||
return Err(vm.new_os_error("failed to get windows version".to_owned()));
|
||||
}
|
||||
|
||||
let service_pack = {
|
||||
let (last, _) = version
|
||||
.szCSDVersion
|
||||
.iter()
|
||||
.take_while(|&x| x != &0)
|
||||
.enumerate()
|
||||
.last()
|
||||
.unwrap_or((0, &0));
|
||||
let sp = OsString::from_wide(&version.szCSDVersion[..last]);
|
||||
sp.into_string()
|
||||
.map_err(|_| vm.new_os_error("service pack is not ASCII".to_owned()))?
|
||||
};
|
||||
WindowsVersion {
|
||||
major: version.dwMajorVersion,
|
||||
minor: version.dwMinorVersion,
|
||||
build: version.dwBuildNumber,
|
||||
platform: version.dwPlatformId,
|
||||
service_pack,
|
||||
service_pack_major: version.wServicePackMajor,
|
||||
service_pack_minor: version.wServicePackMinor,
|
||||
suite_mask: version.wSuiteMask,
|
||||
product_type: version.wProductType,
|
||||
platform_version: (
|
||||
version.dwMajorVersion,
|
||||
version.dwMinorVersion,
|
||||
version.dwBuildNumber,
|
||||
), // TODO Provide accurate version, like CPython impl
|
||||
}
|
||||
.into_struct_sequence(vm)
|
||||
}
|
||||
|
||||
pub fn get_stdin(vm: &VirtualMachine) -> PyResult {
|
||||
@@ -485,30 +485,24 @@ impl PyIntInfo {
|
||||
pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectRef) {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
let flags_type = SysFlags::make_class(ctx);
|
||||
let _flags_type = SysFlags::make_class(ctx);
|
||||
let flags = SysFlags::from_settings(&vm.state.settings)
|
||||
.into_struct_sequence(vm, flags_type)
|
||||
.into_struct_sequence(vm)
|
||||
.unwrap();
|
||||
|
||||
let version_info_type = version::VersionInfo::make_class(ctx);
|
||||
let _version_info_type = version::VersionInfo::make_class(ctx);
|
||||
let version_info = version::VersionInfo::VERSION
|
||||
.into_struct_sequence(vm, version_info_type)
|
||||
.into_struct_sequence(vm)
|
||||
.unwrap();
|
||||
|
||||
let hash_info_type = PyHashInfo::make_class(ctx);
|
||||
let hash_info = PyHashInfo::INFO
|
||||
.into_struct_sequence(vm, hash_info_type)
|
||||
.unwrap();
|
||||
let _hash_info_type = PyHashInfo::make_class(ctx);
|
||||
let hash_info = PyHashInfo::INFO.into_struct_sequence(vm).unwrap();
|
||||
|
||||
let float_info_type = PyFloatInfo::make_class(ctx);
|
||||
let float_info = PyFloatInfo::INFO
|
||||
.into_struct_sequence(vm, float_info_type)
|
||||
.unwrap();
|
||||
let _float_info_type = PyFloatInfo::make_class(ctx);
|
||||
let float_info = PyFloatInfo::INFO.into_struct_sequence(vm).unwrap();
|
||||
|
||||
let int_info_type = PyIntInfo::make_class(ctx);
|
||||
let int_info = PyIntInfo::INFO
|
||||
.into_struct_sequence(vm, int_info_type)
|
||||
.unwrap();
|
||||
let _int_info_type = PyIntInfo::make_class(ctx);
|
||||
let int_info = PyIntInfo::INFO.into_struct_sequence(vm).unwrap();
|
||||
|
||||
// TODO Add crate version to this namespace
|
||||
let implementation = py_namespace!(vm, {
|
||||
@@ -710,7 +704,6 @@ settrace() -- set the global debug tracing function
|
||||
let getwindowsversion = WindowsVersion::make_class(ctx);
|
||||
extend_module!(vm, module, {
|
||||
"getwindowsversion" => named_function!(ctx, sys, getwindowsversion),
|
||||
"_getwindowsversion_type" => getwindowsversion, // XXX: This is not a python spec but required by current RustPython implementation
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
264
vm/src/types.rs
264
vm/src/types.rs
@@ -39,7 +39,7 @@ use crate::builtins::weakproxy;
|
||||
use crate::builtins::weakref;
|
||||
use crate::builtins::zip;
|
||||
use crate::pyobject::{
|
||||
PyAttributes, PyClassDef, PyClassImpl, PyContext, PyObject, PyObjectRc, PyObjectRef,
|
||||
PyAttributes, PyClassDef, PyClassImpl, PyContext, PyObject, PyObjectRc, PyObjectRef, StaticType,
|
||||
};
|
||||
use crate::slots::PyTypeSlots;
|
||||
use rustpython_common::{lock::PyRwLock, rc::PyRc};
|
||||
@@ -47,7 +47,7 @@ use std::mem::MaybeUninit;
|
||||
use std::ptr;
|
||||
|
||||
/// Holder of references to builtin types.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TypeZoo {
|
||||
pub async_generator: PyTypeRef,
|
||||
pub async_generator_asend: PyTypeRef,
|
||||
@@ -114,106 +114,148 @@ pub struct TypeZoo {
|
||||
pub mappingproxy_type: PyTypeRef,
|
||||
pub traceback_type: PyTypeRef,
|
||||
pub object_type: PyTypeRef,
|
||||
}
|
||||
|
||||
impl Default for TypeZoo {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
pub ellipsis_type: PyTypeRef,
|
||||
pub none_type: PyTypeRef,
|
||||
pub not_implemented_type: PyTypeRef,
|
||||
}
|
||||
|
||||
impl TypeZoo {
|
||||
pub fn new() -> Self {
|
||||
pub(crate) fn init() -> Self {
|
||||
let (type_type, object_type) = init_type_hierarchy();
|
||||
|
||||
macro_rules! create_type {
|
||||
($class:ty) => {
|
||||
<$class>::create_bare_type(&type_type, object_type.clone())
|
||||
};
|
||||
($class:ty, $base:expr) => {
|
||||
<$class>::create_bare_type(&type_type, $base.clone())
|
||||
};
|
||||
}
|
||||
|
||||
let int_type = create_type!(int::PyInt);
|
||||
Self {
|
||||
async_generator: create_type!(asyncgenerator::PyAsyncGen),
|
||||
async_generator_asend: create_type!(asyncgenerator::PyAsyncGenASend),
|
||||
async_generator_athrow: create_type!(asyncgenerator::PyAsyncGenAThrow),
|
||||
async_generator_wrapped_value: create_type!(asyncgenerator::PyAsyncGenWrappedValue),
|
||||
bool_type: create_type!(pybool::PyBool, int_type),
|
||||
bound_method_type: create_type!(function::PyBoundMethod),
|
||||
builtin_function_or_method_type: create_type!(builtinfunc::PyBuiltinFunction),
|
||||
bytearray_type: create_type!(bytearray::PyByteArray),
|
||||
bytearray_iterator_type: create_type!(bytearray::PyByteArrayIterator),
|
||||
bytes_type: create_type!(bytes::PyBytes),
|
||||
bytes_iterator_type: create_type!(bytes::PyBytesIterator),
|
||||
callable_iterator: create_type!(iter::PyCallableIterator),
|
||||
classmethod_type: create_type!(classmethod::PyClassMethod),
|
||||
code_type: create_type!(code::PyCodeRef),
|
||||
complex_type: create_type!(complex::PyComplex),
|
||||
coroutine_type: create_type!(coroutine::PyCoroutine),
|
||||
coroutine_wrapper_type: create_type!(coroutine::PyCoroutineWrapper),
|
||||
dict_type: create_type!(dict::PyDict),
|
||||
dict_keys_type: create_type!(dict::PyDictKeys),
|
||||
dict_values_type: create_type!(dict::PyDictValues),
|
||||
dict_items_type: create_type!(dict::PyDictItems),
|
||||
dict_keyiterator_type: create_type!(dict::PyDictKeyIterator),
|
||||
dict_reversekeyiterator_type: create_type!(dict::PyDictReverseKeyIterator),
|
||||
dict_valueiterator_type: create_type!(dict::PyDictValueIterator),
|
||||
dict_reversevalueiterator_type: create_type!(dict::PyDictReverseValueIterator),
|
||||
dict_itemiterator_type: create_type!(dict::PyDictItemIterator),
|
||||
dict_reverseitemiterator_type: create_type!(dict::PyDictReverseItemIterator),
|
||||
enumerate_type: create_type!(enumerate::PyEnumerate),
|
||||
filter_type: create_type!(filter::PyFilter),
|
||||
float_type: create_type!(float::PyFloat),
|
||||
frame_type: create_type!(crate::frame::FrameRef),
|
||||
frozenset_type: create_type!(set::PyFrozenSet),
|
||||
function_type: create_type!(function::PyFunction),
|
||||
generator_type: create_type!(generator::PyGenerator),
|
||||
getset_type: create_type!(getset::PyGetSet),
|
||||
int_type,
|
||||
iter_type: create_type!(iter::PySequenceIterator),
|
||||
list_type: create_type!(list::PyList),
|
||||
list_iterator_type: create_type!(list::PyListIterator),
|
||||
list_reverseiterator_type: create_type!(list::PyListReverseIterator),
|
||||
map_type: create_type!(map::PyMap),
|
||||
mappingproxy_type: create_type!(mappingproxy::PyMappingProxy),
|
||||
memoryview_type: create_type!(memory::PyMemoryView),
|
||||
module_type: create_type!(module::PyModule),
|
||||
namespace_type: create_type!(namespace::PyNamespace),
|
||||
property_type: create_type!(property::PyProperty),
|
||||
range_type: create_type!(range::PyRange),
|
||||
range_iterator_type: create_type!(range::PyRangeIterator),
|
||||
set_type: create_type!(set::PySet),
|
||||
set_iterator_type: create_type!(set::PySetIterator),
|
||||
slice_type: create_type!(slice::PySlice),
|
||||
staticmethod_type: create_type!(staticmethod::PyStaticMethod),
|
||||
str_type: create_type!(pystr::PyStr),
|
||||
str_iterator_type: create_type!(pystr::PyStrIterator),
|
||||
str_reverseiterator_type: create_type!(pystr::PyStrReverseIterator),
|
||||
super_type: create_type!(pysuper::PySuper),
|
||||
traceback_type: create_type!(traceback::PyTraceback),
|
||||
tuple_type: create_type!(tuple::PyTuple),
|
||||
tuple_iterator_type: create_type!(tuple::PyTupleIterator),
|
||||
weakproxy_type: create_type!(weakproxy::PyWeakProxy),
|
||||
weakref_type: create_type!(weakref::PyWeak),
|
||||
method_descriptor_type: create_type!(builtinfunc::PyBuiltinMethod),
|
||||
zip_type: create_type!(zip::PyZip),
|
||||
type_type,
|
||||
object_type,
|
||||
// the order matters for type, object and int
|
||||
type_type: pytype::PyType::init_manually(type_type).clone(),
|
||||
object_type: object::PyBaseObject::init_manually(object_type).clone(),
|
||||
int_type: int::PyInt::init_bare_type().clone(),
|
||||
|
||||
// types exposed as builtins
|
||||
bool_type: pybool::PyBool::init_bare_type().clone(),
|
||||
bytearray_type: bytearray::PyByteArray::init_bare_type().clone(),
|
||||
bytes_type: bytes::PyBytes::init_bare_type().clone(),
|
||||
classmethod_type: classmethod::PyClassMethod::init_bare_type().clone(),
|
||||
complex_type: complex::PyComplex::init_bare_type().clone(),
|
||||
dict_type: dict::PyDict::init_bare_type().clone(),
|
||||
enumerate_type: enumerate::PyEnumerate::init_bare_type().clone(),
|
||||
float_type: float::PyFloat::init_bare_type().clone(),
|
||||
frozenset_type: set::PyFrozenSet::init_bare_type().clone(),
|
||||
filter_type: filter::PyFilter::init_bare_type().clone(),
|
||||
list_type: list::PyList::init_bare_type().clone(),
|
||||
map_type: map::PyMap::init_bare_type().clone(),
|
||||
memoryview_type: memory::PyMemoryView::init_bare_type().clone(),
|
||||
property_type: property::PyProperty::init_bare_type().clone(),
|
||||
range_type: range::PyRange::init_bare_type().clone(),
|
||||
set_type: set::PySet::init_bare_type().clone(),
|
||||
slice_type: slice::PySlice::init_bare_type().clone(),
|
||||
staticmethod_type: staticmethod::PyStaticMethod::init_bare_type().clone(),
|
||||
str_type: pystr::PyStr::init_bare_type().clone(),
|
||||
super_type: pysuper::PySuper::init_bare_type().clone(),
|
||||
tuple_type: tuple::PyTuple::init_bare_type().clone(),
|
||||
zip_type: zip::PyZip::init_bare_type().clone(),
|
||||
|
||||
// hidden internal types. is this really need to be cached here?
|
||||
async_generator: asyncgenerator::PyAsyncGen::init_bare_type().clone(),
|
||||
async_generator_asend: asyncgenerator::PyAsyncGenASend::init_bare_type().clone(),
|
||||
async_generator_athrow: asyncgenerator::PyAsyncGenAThrow::init_bare_type().clone(),
|
||||
async_generator_wrapped_value: asyncgenerator::PyAsyncGenWrappedValue::init_bare_type()
|
||||
.clone(),
|
||||
bound_method_type: function::PyBoundMethod::init_bare_type().clone(),
|
||||
builtin_function_or_method_type: builtinfunc::PyBuiltinFunction::init_bare_type()
|
||||
.clone(),
|
||||
bytearray_iterator_type: bytearray::PyByteArrayIterator::init_bare_type().clone(),
|
||||
bytes_iterator_type: bytes::PyBytesIterator::init_bare_type().clone(),
|
||||
callable_iterator: iter::PyCallableIterator::init_bare_type().clone(),
|
||||
code_type: code::PyCode::init_bare_type().clone(),
|
||||
coroutine_type: coroutine::PyCoroutine::init_bare_type().clone(),
|
||||
coroutine_wrapper_type: coroutine::PyCoroutineWrapper::init_bare_type().clone(),
|
||||
dict_keys_type: dict::PyDictKeys::init_bare_type().clone(),
|
||||
dict_values_type: dict::PyDictValues::init_bare_type().clone(),
|
||||
dict_items_type: dict::PyDictItems::init_bare_type().clone(),
|
||||
dict_keyiterator_type: dict::PyDictKeyIterator::init_bare_type().clone(),
|
||||
dict_reversekeyiterator_type: dict::PyDictReverseKeyIterator::init_bare_type().clone(),
|
||||
dict_valueiterator_type: dict::PyDictValueIterator::init_bare_type().clone(),
|
||||
dict_reversevalueiterator_type: dict::PyDictReverseValueIterator::init_bare_type()
|
||||
.clone(),
|
||||
dict_itemiterator_type: dict::PyDictItemIterator::init_bare_type().clone(),
|
||||
dict_reverseitemiterator_type: dict::PyDictReverseItemIterator::init_bare_type()
|
||||
.clone(),
|
||||
ellipsis_type: slice::PyEllipsis::init_bare_type().clone(),
|
||||
frame_type: crate::frame::Frame::init_bare_type().clone(),
|
||||
function_type: function::PyFunction::init_bare_type().clone(),
|
||||
generator_type: generator::PyGenerator::init_bare_type().clone(),
|
||||
getset_type: getset::PyGetSet::init_bare_type().clone(),
|
||||
iter_type: iter::PySequenceIterator::init_bare_type().clone(),
|
||||
list_iterator_type: list::PyListIterator::init_bare_type().clone(),
|
||||
list_reverseiterator_type: list::PyListReverseIterator::init_bare_type().clone(),
|
||||
mappingproxy_type: mappingproxy::PyMappingProxy::init_bare_type().clone(),
|
||||
module_type: module::PyModule::init_bare_type().clone(),
|
||||
namespace_type: namespace::PyNamespace::init_bare_type().clone(),
|
||||
range_iterator_type: range::PyRangeIterator::init_bare_type().clone(),
|
||||
set_iterator_type: set::PySetIterator::init_bare_type().clone(),
|
||||
str_iterator_type: pystr::PyStrIterator::init_bare_type().clone(),
|
||||
str_reverseiterator_type: pystr::PyStrReverseIterator::init_bare_type().clone(),
|
||||
traceback_type: traceback::PyTraceback::init_bare_type().clone(),
|
||||
tuple_iterator_type: tuple::PyTupleIterator::init_bare_type().clone(),
|
||||
weakproxy_type: weakproxy::PyWeakProxy::init_bare_type().clone(),
|
||||
weakref_type: weakref::PyWeak::init_bare_type().clone(),
|
||||
method_descriptor_type: builtinfunc::PyBuiltinMethod::init_bare_type().clone(),
|
||||
none_type: singletons::PyNone::init_bare_type().clone(),
|
||||
not_implemented_type: singletons::PyNotImplemented::init_bare_type().clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill attributes of builtin types.
|
||||
pub(crate) fn extend(context: &PyContext) {
|
||||
pytype::init(&context);
|
||||
object::init(&context);
|
||||
list::init(&context);
|
||||
set::init(&context);
|
||||
tuple::init(&context);
|
||||
dict::init(&context);
|
||||
builtinfunc::init(&context);
|
||||
function::init(&context);
|
||||
staticmethod::init(&context);
|
||||
classmethod::init(&context);
|
||||
generator::init(&context);
|
||||
coroutine::init(&context);
|
||||
asyncgenerator::init(&context);
|
||||
int::init(&context);
|
||||
float::init(&context);
|
||||
complex::init(&context);
|
||||
bytes::init(&context);
|
||||
bytearray::init(&context);
|
||||
property::init(&context);
|
||||
getset::init(&context);
|
||||
memory::init(&context);
|
||||
pystr::init(&context);
|
||||
range::init(&context);
|
||||
slice::init(&context);
|
||||
pysuper::init(&context);
|
||||
iter::init(&context);
|
||||
enumerate::init(&context);
|
||||
filter::init(&context);
|
||||
map::init(&context);
|
||||
zip::init(&context);
|
||||
pybool::init(&context);
|
||||
code::init(&context);
|
||||
frame::init(&context);
|
||||
weakref::init(&context);
|
||||
weakproxy::init(&context);
|
||||
singletons::init(&context);
|
||||
module::init(&context);
|
||||
namespace::init(&context);
|
||||
mappingproxy::init(&context);
|
||||
traceback::init(&context);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_type(name: &str, type_type: &PyTypeRef, base: PyTypeRef) -> PyTypeRef {
|
||||
create_type_with_slots(name, type_type, base, Default::default())
|
||||
pub fn create_simple_type(name: &str, base: &PyTypeRef) -> PyTypeRef {
|
||||
create_type_with_slots(name, PyType::static_type(), base, Default::default())
|
||||
}
|
||||
|
||||
pub fn create_type_with_slots(
|
||||
name: &str,
|
||||
type_type: &PyTypeRef,
|
||||
base: PyTypeRef,
|
||||
base: &PyTypeRef,
|
||||
slots: PyTypeSlots,
|
||||
) -> PyTypeRef {
|
||||
let dict = PyAttributes::new();
|
||||
@@ -221,7 +263,7 @@ pub fn create_type_with_slots(
|
||||
type_type.clone(),
|
||||
name,
|
||||
base.clone(),
|
||||
vec![base],
|
||||
vec![base.clone()],
|
||||
dict,
|
||||
slots,
|
||||
)
|
||||
@@ -328,47 +370,3 @@ fn init_type_hierarchy() -> (PyTypeRef, PyTypeRef) {
|
||||
|
||||
(type_type, object_type)
|
||||
}
|
||||
|
||||
/// Fill attributes of builtin types.
|
||||
pub fn initialize_types(context: &PyContext) {
|
||||
pytype::init(&context);
|
||||
object::init(&context);
|
||||
list::init(&context);
|
||||
set::init(&context);
|
||||
tuple::init(&context);
|
||||
dict::init(&context);
|
||||
builtinfunc::init(&context);
|
||||
function::init(&context);
|
||||
staticmethod::init(&context);
|
||||
classmethod::init(&context);
|
||||
generator::init(&context);
|
||||
coroutine::init(&context);
|
||||
asyncgenerator::init(&context);
|
||||
int::init(&context);
|
||||
float::init(&context);
|
||||
complex::init(&context);
|
||||
bytes::init(&context);
|
||||
bytearray::init(&context);
|
||||
property::init(&context);
|
||||
getset::init(&context);
|
||||
memory::init(&context);
|
||||
pystr::init(&context);
|
||||
range::init(&context);
|
||||
slice::init(&context);
|
||||
pysuper::init(&context);
|
||||
iter::init(&context);
|
||||
enumerate::init(&context);
|
||||
filter::init(&context);
|
||||
map::init(&context);
|
||||
zip::init(&context);
|
||||
pybool::init(&context);
|
||||
code::init(&context);
|
||||
frame::init(&context);
|
||||
weakref::init(&context);
|
||||
weakproxy::init(&context);
|
||||
singletons::init(&context);
|
||||
module::init(&context);
|
||||
namespace::init(&context);
|
||||
mappingproxy::init(&context);
|
||||
traceback::init(&context);
|
||||
}
|
||||
|
||||
@@ -320,9 +320,13 @@ impl VirtualMachine {
|
||||
// builtins.open to io.OpenWrapper, but this is easier, since it doesn't
|
||||
// require the Python stdlib to be present
|
||||
let io = import::import_builtin(self, "_io")?;
|
||||
let io_open = self.get_attribute(io, "open")?;
|
||||
let set_stdio = |name, fd, mode: &str| {
|
||||
let stdio = self.invoke(&io_open, (fd, mode))?;
|
||||
let stdio = crate::stdlib::io::open(
|
||||
self.ctx.new_int(fd),
|
||||
Some(mode),
|
||||
Default::default(),
|
||||
self,
|
||||
)?;
|
||||
self.set_attr(
|
||||
&self.sys_module,
|
||||
format!("__{}__", name), // e.g. __stdin__
|
||||
@@ -335,6 +339,7 @@ impl VirtualMachine {
|
||||
set_stdio("stdout", 1, "w")?;
|
||||
set_stdio("stderr", 2, "w")?;
|
||||
|
||||
let io_open = self.get_attribute(io, "open")?;
|
||||
self.set_attr(&self.builtins, "open", io_open)?;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ freeze-stdlib = ["rustpython-vm/freeze-stdlib"]
|
||||
[dependencies]
|
||||
rustpython-compiler = { path = "../../compiler" }
|
||||
rustpython-parser = { path = "../../parser" }
|
||||
rustpython-common = { path = "../../common" }
|
||||
# no threading feature for rustpython-vm -- doesn't much matter anyway, but it might be more optimized
|
||||
rustpython-vm = { path = "../../vm", default-features = false, features = ["compile-parse"] }
|
||||
wasm-bindgen = "0.2"
|
||||
|
||||
@@ -9,6 +9,7 @@ use rustpython_vm::function::OptionalArg;
|
||||
use rustpython_vm::import::import_file;
|
||||
use rustpython_vm::pyobject::{
|
||||
BorrowValue, IntoPyObject, PyCallable, PyClassImpl, PyObject, PyObjectRef, PyResult, PyValue,
|
||||
StaticType,
|
||||
};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
|
||||
@@ -160,8 +161,8 @@ struct Document {
|
||||
}
|
||||
|
||||
impl PyValue for Document {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("browser", "Document")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,8 +187,8 @@ struct Element {
|
||||
}
|
||||
|
||||
impl PyValue for Element {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("browser", "Element")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ use rustpython_vm::exceptions::PyBaseExceptionRef;
|
||||
use rustpython_vm::function::{Args, OptionalArg};
|
||||
use rustpython_vm::pyobject::{
|
||||
BorrowValue, IntoPyObject, PyCallable, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TryFromObject,
|
||||
StaticType, TryFromObject,
|
||||
};
|
||||
use rustpython_vm::types::create_type;
|
||||
use rustpython_vm::types::create_simple_type;
|
||||
use rustpython_vm::VirtualMachine;
|
||||
|
||||
#[wasm_bindgen(inline_js = "
|
||||
@@ -58,8 +58,8 @@ pub struct PyJsValue {
|
||||
type PyJsValueRef = PyRef<PyJsValue>;
|
||||
|
||||
impl PyValue for PyJsValue {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_js", "JSValue")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,8 +289,8 @@ impl fmt::Debug for JsClosure {
|
||||
}
|
||||
|
||||
impl PyValue for JsClosure {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("_js", "JSClosure")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,8 +378,8 @@ pub struct PyPromise {
|
||||
pub type PyPromiseRef = PyRef<PyPromise>;
|
||||
|
||||
impl PyValue for PyPromise {
|
||||
fn class(vm: &VirtualMachine) -> PyTypeRef {
|
||||
vm.class("browser", "Promise")
|
||||
fn class(_vm: &VirtualMachine) -> &PyTypeRef {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,11 +474,7 @@ fn new_js_error(vm: &VirtualMachine, err: JsValue) -> PyBaseExceptionRef {
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
let js_error = create_type(
|
||||
"JSError",
|
||||
&ctx.types.type_type,
|
||||
ctx.exceptions.exception_type.clone(),
|
||||
);
|
||||
let js_error = create_simple_type("JSError", &ctx.exceptions.exception_type);
|
||||
extend_class!(ctx, &js_error, {
|
||||
"value" => ctx.new_readonly_getset("value", |exc: PyBaseExceptionRef| exc.get_arg(0)),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user