mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Move function items out of pyobject module
This commit is contained in:
1 parent
fa9e48a5b3
commit
7bfd2e6e84
58 files changed
+670
-628
No files matched your search
+5
-4
@@ -7,6 +7,8 @@ use std::char;
|
||||
use std::io::{self, Write};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use num_traits::{Signed, ToPrimitive};
|
||||
|
||||
use crate::compile;
|
||||
use crate::import::import_module;
|
||||
use crate::obj::objbool;
|
||||
@@ -17,16 +19,15 @@ use crate::obj::objstr;
|
||||
use crate::obj::objtype;
|
||||
|
||||
use crate::frame::Scope;
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{
|
||||
AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol,
|
||||
AttributeProtocol, IdProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::stdlib::io::io_open;
|
||||
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::{Signed, ToPrimitive};
|
||||
|
||||
fn get_locals(vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
let d = vm.new_dict();
|
||||
// TODO: implement dict_iter_items?
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objsequence;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objtype;
|
||||
use crate::pyobject::{
|
||||
create_type, AttributeProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol,
|
||||
create_type, AttributeProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
|
||||
+3
-2
@@ -8,6 +8,7 @@ use rustpython_parser::ast;
|
||||
|
||||
use crate::builtins;
|
||||
use crate::bytecode;
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objbool;
|
||||
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
|
||||
use crate::obj::objcode;
|
||||
@@ -20,8 +21,8 @@ use crate::obj::objslice::PySlice;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objtype;
|
||||
use crate::pyobject::{
|
||||
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectRef,
|
||||
PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyObject, PyObjectRef, PyResult,
|
||||
PyValue, TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
use std::collections::HashMap;
|
||||
use std::iter;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use crate::obj::objtype;
|
||||
use crate::pyobject::{IntoPyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use self::OptionalArg::*;
|
||||
|
||||
/// The `PyFuncArgs` struct is one of the most used structs then creating
|
||||
/// a rust function that can be called from python. It holds both positional
|
||||
/// arguments, as well as keyword arguments passed to the function.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct PyFuncArgs {
|
||||
pub args: Vec<PyObjectRef>,
|
||||
pub kwargs: Vec<(String, PyObjectRef)>,
|
||||
}
|
||||
|
||||
/// Conversion from vector of python objects to function arguments.
|
||||
impl From<Vec<PyObjectRef>> for PyFuncArgs {
|
||||
fn from(args: Vec<PyObjectRef>) -> Self {
|
||||
PyFuncArgs {
|
||||
args: args,
|
||||
kwargs: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PyObjectRef> for PyFuncArgs {
|
||||
fn from(arg: PyObjectRef) -> Self {
|
||||
PyFuncArgs {
|
||||
args: vec![arg],
|
||||
kwargs: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PyFuncArgs {
|
||||
pub fn new(mut args: Vec<PyObjectRef>, kwarg_names: Vec<String>) -> PyFuncArgs {
|
||||
let mut kwargs = vec![];
|
||||
for name in kwarg_names.iter().rev() {
|
||||
kwargs.push((name.clone(), args.pop().unwrap()));
|
||||
}
|
||||
PyFuncArgs { args, kwargs }
|
||||
}
|
||||
|
||||
pub fn insert(&self, item: PyObjectRef) -> PyFuncArgs {
|
||||
let mut args = PyFuncArgs {
|
||||
args: self.args.clone(),
|
||||
kwargs: self.kwargs.clone(),
|
||||
};
|
||||
args.args.insert(0, item);
|
||||
args
|
||||
}
|
||||
|
||||
pub fn shift(&mut self) -> PyObjectRef {
|
||||
self.args.remove(0)
|
||||
}
|
||||
|
||||
pub fn get_kwarg(&self, key: &str, default: PyObjectRef) -> PyObjectRef {
|
||||
for (arg_name, arg_value) in self.kwargs.iter() {
|
||||
if arg_name == key {
|
||||
return arg_value.clone();
|
||||
}
|
||||
}
|
||||
default.clone()
|
||||
}
|
||||
|
||||
pub fn get_optional_kwarg(&self, key: &str) -> Option<PyObjectRef> {
|
||||
for (arg_name, arg_value) in self.kwargs.iter() {
|
||||
if arg_name == key {
|
||||
return Some(arg_value.clone());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_optional_kwarg_with_type(
|
||||
&self,
|
||||
key: &str,
|
||||
ty: PyObjectRef,
|
||||
vm: &mut VirtualMachine,
|
||||
) -> Result<Option<PyObjectRef>, PyObjectRef> {
|
||||
match self.get_optional_kwarg(key) {
|
||||
Some(kwarg) => {
|
||||
if objtype::isinstance(&kwarg, &ty) {
|
||||
Ok(Some(kwarg))
|
||||
} else {
|
||||
let expected_ty_name = vm.to_pystr(&ty)?;
|
||||
let actual_ty_name = vm.to_pystr(&kwarg.typ())?;
|
||||
Err(vm.new_type_error(format!(
|
||||
"argument of type {} is required for named parameter `{}` (got: {})",
|
||||
expected_ty_name, key, actual_ty_name
|
||||
)))
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializes these arguments into an iterator starting with the positional
|
||||
/// arguments followed by keyword arguments.
|
||||
fn into_iter(self) -> impl Iterator<Item = PyArg> {
|
||||
self.args.into_iter().map(PyArg::Positional).chain(
|
||||
self.kwargs
|
||||
.into_iter()
|
||||
.map(|(name, value)| PyArg::Keyword(name, value)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Binds these arguments to their respective values.
|
||||
///
|
||||
/// If there is an insufficient number of arguments, there are leftover
|
||||
/// arguments after performing the binding, or if an argument is not of
|
||||
/// the expected type, a TypeError is raised.
|
||||
///
|
||||
/// If the given `FromArgs` includes any conversions, exceptions raised
|
||||
/// during the conversion will halt the binding and return the error.
|
||||
fn bind<T: FromArgs>(self, vm: &mut VirtualMachine) -> PyResult<T> {
|
||||
let given_args = self.args.len();
|
||||
let mut args = self.into_iter().peekable();
|
||||
let bound = match T::from_args(vm, &mut args) {
|
||||
Ok(args) => args,
|
||||
Err(ArgumentError::TooFewArgs) => {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Expected at least {} arguments ({} given)",
|
||||
T::arity().start(),
|
||||
given_args,
|
||||
)));
|
||||
}
|
||||
Err(ArgumentError::Exception(ex)) => {
|
||||
return Err(ex);
|
||||
}
|
||||
};
|
||||
|
||||
match args.next() {
|
||||
None => Ok(bound),
|
||||
Some(PyArg::Positional(_)) => Err(vm.new_type_error(format!(
|
||||
"Expected at most {} arguments ({} given)",
|
||||
T::arity().end(),
|
||||
given_args,
|
||||
))),
|
||||
Some(PyArg::Keyword(name, _)) => {
|
||||
Err(vm.new_type_error(format!("Unexpected keyword argument {}", name)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum PyArg {
|
||||
Positional(PyObjectRef),
|
||||
Keyword(String, PyObjectRef),
|
||||
}
|
||||
|
||||
pub enum ArgumentError {
|
||||
TooFewArgs,
|
||||
Exception(PyObjectRef),
|
||||
}
|
||||
|
||||
impl From<PyObjectRef> for ArgumentError {
|
||||
fn from(ex: PyObjectRef) -> Self {
|
||||
ArgumentError::Exception(ex)
|
||||
}
|
||||
}
|
||||
|
||||
/// Implemented by any type that can be accepted as a parameter to a built-in
|
||||
/// function.
|
||||
///
|
||||
pub trait FromArgs: Sized {
|
||||
/// The range of positional arguments permitted by the function signature.
|
||||
///
|
||||
/// Returns an empty range if not applicable.
|
||||
fn arity() -> RangeInclusive<usize> {
|
||||
0..=0
|
||||
}
|
||||
|
||||
/// Extracts this item from the next argument(s).
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>;
|
||||
}
|
||||
/// A map of keyword arguments to their values.
|
||||
///
|
||||
/// A built-in function with a `KwArgs` parameter is analagous to a Python
|
||||
/// function with `*kwargs`. All remaining keyword arguments are extracted
|
||||
/// (and hence the function will permit an arbitrary number of them).
|
||||
///
|
||||
/// `KwArgs` optionally accepts a generic type parameter to allow type checks
|
||||
/// or conversions of each argument.
|
||||
pub struct KwArgs<T = PyObjectRef>(HashMap<String, T>);
|
||||
|
||||
impl<T> FromArgs for KwArgs<T>
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
let mut kwargs = HashMap::new();
|
||||
while let Some(PyArg::Keyword(name, value)) = args.next() {
|
||||
kwargs.insert(name, T::try_from_object(vm, value)?);
|
||||
}
|
||||
Ok(KwArgs(kwargs))
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of positional argument values.
|
||||
///
|
||||
/// A built-in function with a `Args` parameter is analagous to a Python
|
||||
/// function with `*args`. All remaining positional arguments are extracted
|
||||
/// (and hence the function will permit an arbitrary number of them).
|
||||
///
|
||||
/// `Args` optionally accepts a generic type parameter to allow type checks
|
||||
/// or conversions of each argument.
|
||||
pub struct Args<T>(Vec<T>);
|
||||
|
||||
impl<T> FromArgs for Args<T>
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
let mut varargs = Vec::new();
|
||||
while let Some(PyArg::Positional(value)) = args.next() {
|
||||
varargs.push(T::try_from_object(vm, value)?);
|
||||
}
|
||||
Ok(Args(varargs))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromArgs for T
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
fn arity() -> RangeInclusive<usize> {
|
||||
1..=1
|
||||
}
|
||||
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
if let Some(PyArg::Positional(value)) = args.next() {
|
||||
Ok(T::try_from_object(vm, value)?)
|
||||
} else {
|
||||
Err(ArgumentError::TooFewArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An argument that may or may not be provided by the caller.
|
||||
///
|
||||
/// This style of argument is not possible in pure Python.
|
||||
pub enum OptionalArg<T> {
|
||||
Present(T),
|
||||
Missing,
|
||||
}
|
||||
|
||||
impl<T> OptionalArg<T> {
|
||||
pub fn into_option(self) -> Option<T> {
|
||||
match self {
|
||||
Present(value) => Some(value),
|
||||
Missing => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromArgs for OptionalArg<T>
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
fn arity() -> RangeInclusive<usize> {
|
||||
0..=1
|
||||
}
|
||||
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
Ok(if let Some(PyArg::Positional(_)) = args.peek() {
|
||||
let value = if let Some(PyArg::Positional(value)) = args.next() {
|
||||
value
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
Present(T::try_from_object(vm, value)?)
|
||||
} else {
|
||||
Missing
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// For functions that accept no arguments. Implemented explicitly instead of via
|
||||
// macro below to avoid unused warnings.
|
||||
impl FromArgs for () {
|
||||
fn from_args<I>(
|
||||
_vm: &mut VirtualMachine,
|
||||
_args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// A tuple of types that each implement `FromArgs` represents a sequence of
|
||||
// arguments that can be bound and passed to a built-in function.
|
||||
//
|
||||
// Technically, a tuple can contain tuples, which can contain tuples, and so on,
|
||||
// so this actually represents a tree of values to be bound from arguments, but
|
||||
// in practice this is only used for the top-level parameters.
|
||||
macro_rules! tuple_from_py_func_args {
|
||||
($($T:ident),+) => {
|
||||
impl<$($T),+> FromArgs for ($($T,)+)
|
||||
where
|
||||
$($T: FromArgs),+
|
||||
{
|
||||
fn arity() -> RangeInclusive<usize> {
|
||||
let mut min = 0;
|
||||
let mut max = 0;
|
||||
$(
|
||||
let (start, end) = $T::arity().into_inner();
|
||||
min += start;
|
||||
max += end;
|
||||
)+
|
||||
min..=max
|
||||
}
|
||||
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>
|
||||
{
|
||||
Ok(($($T::from_args(vm, args)?,)+))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Implement `FromArgs` for up to 5-tuples, allowing built-in functions to bind
|
||||
// up to 5 top-level parameters (note that `Args`, `KwArgs`, nested tuples, etc.
|
||||
// count as 1, so this should actually be more than enough).
|
||||
tuple_from_py_func_args!(A);
|
||||
tuple_from_py_func_args!(A, B);
|
||||
tuple_from_py_func_args!(A, B, C);
|
||||
tuple_from_py_func_args!(A, B, C, D);
|
||||
tuple_from_py_func_args!(A, B, C, D, E);
|
||||
|
||||
/// A built-in Python function.
|
||||
pub type PyNativeFunc = Box<dyn Fn(&mut VirtualMachine, PyFuncArgs) -> PyResult + 'static>;
|
||||
|
||||
/// Implemented by types that are or can generate built-in functions.
|
||||
///
|
||||
/// For example, any function that:
|
||||
///
|
||||
/// - Accepts a sequence of types that implement `FromArgs`, followed by a
|
||||
/// `&mut VirtualMachine`
|
||||
/// - Returns some type that implements `IntoPyObject`
|
||||
///
|
||||
/// will generate a `PyNativeFunc` that performs the appropriate type and arity
|
||||
/// checking, any requested conversions, and then if successful call the function
|
||||
/// with the bound values.
|
||||
///
|
||||
/// A bare `PyNativeFunc` also implements this trait, allowing the above to be
|
||||
/// done manually, for rare situations that don't fit into this model.
|
||||
pub trait IntoPyNativeFunc<T, R> {
|
||||
fn into_func(self) -> PyNativeFunc;
|
||||
}
|
||||
|
||||
impl<F> IntoPyNativeFunc<PyFuncArgs, PyResult> for F
|
||||
where
|
||||
F: Fn(&mut VirtualMachine, PyFuncArgs) -> PyResult + 'static,
|
||||
{
|
||||
fn into_func(self) -> PyNativeFunc {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPyNativeFunc<PyFuncArgs, PyResult> for PyNativeFunc {
|
||||
fn into_func(self) -> PyNativeFunc {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// This is the "magic" that allows rust functions of varying signatures to
|
||||
// generate native python functions.
|
||||
//
|
||||
// Note that this could be done without a macro - it is simply to avoid repetition.
|
||||
macro_rules! into_py_native_func_tuple {
|
||||
($(($n:tt, $T:ident)),*) => {
|
||||
impl<F, $($T,)* R> IntoPyNativeFunc<($($T,)*), R> for F
|
||||
where
|
||||
F: Fn($($T,)* &mut VirtualMachine) -> R + 'static,
|
||||
$($T: FromArgs,)*
|
||||
($($T,)*): FromArgs,
|
||||
R: IntoPyObject,
|
||||
{
|
||||
fn into_func(self) -> PyNativeFunc {
|
||||
Box::new(move |vm, args| {
|
||||
let ($($n,)*) = args.bind::<($($T,)*)>(vm)?;
|
||||
|
||||
(self)($($n,)* vm).into_pyobject(vm)
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
into_py_native_func_tuple!();
|
||||
into_py_native_func_tuple!((a, A));
|
||||
into_py_native_func_tuple!((a, A), (b, B));
|
||||
into_py_native_func_tuple!((a, A), (b, B), (c, C));
|
||||
into_py_native_func_tuple!((a, A), (b, B), (c, C), (d, D));
|
||||
into_py_native_func_tuple!((a, A), (b, B), (c, C), (d, D), (e, E));
|
||||
@@ -41,6 +41,7 @@ pub mod eval;
|
||||
mod exceptions;
|
||||
pub mod format;
|
||||
pub mod frame;
|
||||
pub mod function;
|
||||
pub mod import;
|
||||
pub mod obj;
|
||||
pub mod pyobject;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use num_traits::Zero;
|
||||
|
||||
use crate::pyobject::{IntoPyObject, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{IntoPyObject, PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objdict::PyDict;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use crate::pyobject::{PyNativeFunc, PyObjectRef, PyValue};
|
||||
use crate::function::PyNativeFunc;
|
||||
use crate::pyobject::{PyObjectRef, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub struct PyBuiltinFunction {
|
||||
|
||||
@@ -4,15 +4,14 @@ use std::cell::RefCell;
|
||||
use std::fmt::Write;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objint;
|
||||
|
||||
use super::objtype;
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyByteArray {
|
||||
|
||||
@@ -2,13 +2,16 @@ use std::cell::Cell;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
|
||||
use super::objint;
|
||||
use super::objtype;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
PyContext, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
use super::objint;
|
||||
use super::objtype;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyBytes {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::pyobject::{AttributeProtocol, PyContext, PyFuncArgs, PyResult, TypeProtocol};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{AttributeProtocol, PyContext, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
*/
|
||||
|
||||
use crate::bytecode;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use std::fmt;
|
||||
|
||||
use crate::bytecode;
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub struct PyCode {
|
||||
code: bytecode::CodeObject,
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use num_complex::Complex64;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objfloat;
|
||||
use super::objint;
|
||||
use super::objtype;
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_complex::Complex64;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct PyComplex {
|
||||
|
||||
@@ -3,9 +3,10 @@ use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{
|
||||
PyAttributes, PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectRef, PyRef, PyResult,
|
||||
PyValue, TypeProtocol,
|
||||
PyAttributes, PyContext, PyIteratorValue, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TypeProtocol,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyResult, TypeProtocol};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
use std::cell::RefCell;
|
||||
use std::ops::AddAssign;
|
||||
|
||||
use super::objint;
|
||||
use super::objiter;
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::Zero;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objint;
|
||||
use super::objiter;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyEnumerate {
|
||||
counter: RefCell<BigInt>,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
IdProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine; // Required for arg_check! to use isinstance
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
*/
|
||||
|
||||
use crate::frame::Frame;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::frame::Scope;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
*/
|
||||
|
||||
use crate::frame::{ExecutionResult, Frame};
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -5,9 +5,10 @@ use num_integer::Integer;
|
||||
use num_traits::{Pow, Signed, ToPrimitive, Zero};
|
||||
|
||||
use crate::format::FormatSpec;
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::pyobject::{
|
||||
IntoPyObject, OptionalArg, PyContext, PyFuncArgs, PyObject, PyObjectRef, PyRef, PyResult,
|
||||
PyValue, TryFromObject, TypeProtocol,
|
||||
IntoPyObject, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
* Various types to support iteration.
|
||||
*/
|
||||
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyIteratorValue, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyIteratorValue, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objbool;
|
||||
|
||||
+10
-7
@@ -1,4 +1,14 @@
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::fmt;
|
||||
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyContext, PyIteratorValue, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TypeProtocol,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
use super::objbool;
|
||||
use super::objint;
|
||||
@@ -8,13 +18,6 @@ use super::objsequence::{
|
||||
};
|
||||
use super::objstr;
|
||||
use super::objtype;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, OptionalArg, PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectRef, PyRef,
|
||||
PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
use num_traits::ToPrimitive;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PyList {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objiter;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{
|
||||
IntoPyObject, PyContext, PyFuncArgs, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
IntoPyObject, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objproperty::PropertyBuilder;
|
||||
use crate::pyobject::{
|
||||
AttributeProtocol, DictProtocol, IdProtocol, PyAttributes, PyContext, PyObjectRef, PyRef,
|
||||
PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objlist::PyList;
|
||||
use super::objstr;
|
||||
use super::objtype;
|
||||
use crate::obj::objproperty::PropertyBuilder;
|
||||
use crate::pyobject::{
|
||||
AttributeProtocol, DictProtocol, IdProtocol, PyAttributes, PyContext, PyFuncArgs, PyObjectRef,
|
||||
PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PyInstance;
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
*/
|
||||
|
||||
use crate::function::IntoPyNativeFunc;
|
||||
use crate::function::OptionalArg;
|
||||
use crate::obj::objstr::PyStringRef;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{
|
||||
IntoPyNativeFunc, OptionalArg, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
};
|
||||
use crate::VirtualMachine;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
/// Read-only property, doesn't have __set__ or __delete__
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -5,8 +5,9 @@ use num_bigint::{BigInt, Sign};
|
||||
use num_integer::Integer;
|
||||
use num_traits::{One, Signed, ToPrimitive, Zero};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
PyContext, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
|
||||
@@ -7,15 +7,17 @@ use std::collections::{hash_map::DefaultHasher, HashMap};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{
|
||||
PyContext, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
use super::objbool;
|
||||
use super::objint;
|
||||
use super::objiter;
|
||||
use super::objstr;
|
||||
use super::objtype;
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PySet {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use super::objint;
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objint;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PySlice {
|
||||
// TODO: should be private
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::pyobject::{AttributeProtocol, PyContext, PyFuncArgs, PyResult, TypeProtocol};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{AttributeProtocol, PyContext, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
|
||||
@@ -6,9 +6,10 @@ use num_traits::ToPrimitive;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use crate::format::{FormatParseError, FormatPart, FormatString};
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::pyobject::{
|
||||
IdProtocol, IntoPyObject, OptionalArg, PyContext, PyFuncArgs, PyIterable, PyObjectRef, PyRef,
|
||||
PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
IdProtocol, IntoPyObject, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TryFromObject, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
|
||||
@@ -6,10 +6,12 @@ https://github.com/python/cpython/blob/50b48572d9a90c5bb36e2bef6179548ea927a35a/
|
||||
|
||||
*/
|
||||
|
||||
use super::objtype;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyResult, TypeProtocol};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objtype;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let super_type = &context.super_type;
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ use std::cell::{Cell, RefCell};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, OptionalArg, PyContext, PyIteratorValue, PyObject, PyObjectRef, PyRef, PyResult,
|
||||
PyValue,
|
||||
IdProtocol, PyContext, PyIteratorValue, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{
|
||||
AttributeProtocol, FromPyObjectRef, IdProtocol, PyAttributes, PyContext, PyFuncArgs, PyObject,
|
||||
PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
AttributeProtocol, FromPyObjectRef, IdProtocol, PyAttributes, PyContext, PyObject, PyObjectRef,
|
||||
PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objiter;
|
||||
|
||||
+3
-433
@@ -2,10 +2,9 @@ use std::any::Any;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::{Deref, RangeInclusive};
|
||||
use std::ops::Deref;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -16,6 +15,7 @@ use num_traits::{One, Zero};
|
||||
use crate::bytecode;
|
||||
use crate::exceptions;
|
||||
use crate::frame::{Frame, Scope};
|
||||
use crate::function::{IntoPyNativeFunc, PyFuncArgs};
|
||||
use crate::obj::objbool;
|
||||
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
|
||||
use crate::obj::objbytearray;
|
||||
@@ -40,6 +40,7 @@ use crate::obj::objmodule::{self, PyModule};
|
||||
use crate::obj::objnone;
|
||||
use crate::obj::objobject;
|
||||
use crate::obj::objproperty;
|
||||
use crate::obj::objproperty::PropertyBuilder;
|
||||
use crate::obj::objrange;
|
||||
use crate::obj::objset::{self, PySet};
|
||||
use crate::obj::objslice;
|
||||
@@ -975,166 +976,6 @@ impl fmt::Debug for PyObject {
|
||||
}
|
||||
}
|
||||
|
||||
/// The `PyFuncArgs` struct is one of the most used structs then creating
|
||||
/// a rust function that can be called from python. It holds both positional
|
||||
/// arguments, as well as keyword arguments passed to the function.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct PyFuncArgs {
|
||||
pub args: Vec<PyObjectRef>,
|
||||
pub kwargs: Vec<(String, PyObjectRef)>,
|
||||
}
|
||||
|
||||
/// Conversion from vector of python objects to function arguments.
|
||||
impl From<Vec<PyObjectRef>> for PyFuncArgs {
|
||||
fn from(args: Vec<PyObjectRef>) -> Self {
|
||||
PyFuncArgs {
|
||||
args: args,
|
||||
kwargs: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PyObjectRef> for PyFuncArgs {
|
||||
fn from(arg: PyObjectRef) -> Self {
|
||||
PyFuncArgs {
|
||||
args: vec![arg],
|
||||
kwargs: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PyFuncArgs {
|
||||
pub fn new(mut args: Vec<PyObjectRef>, kwarg_names: Vec<String>) -> PyFuncArgs {
|
||||
let mut kwargs = vec![];
|
||||
for name in kwarg_names.iter().rev() {
|
||||
kwargs.push((name.clone(), args.pop().unwrap()));
|
||||
}
|
||||
PyFuncArgs { args, kwargs }
|
||||
}
|
||||
|
||||
pub fn insert(&self, item: PyObjectRef) -> PyFuncArgs {
|
||||
let mut args = PyFuncArgs {
|
||||
args: self.args.clone(),
|
||||
kwargs: self.kwargs.clone(),
|
||||
};
|
||||
args.args.insert(0, item);
|
||||
args
|
||||
}
|
||||
|
||||
pub fn shift(&mut self) -> PyObjectRef {
|
||||
self.args.remove(0)
|
||||
}
|
||||
|
||||
pub fn get_kwarg(&self, key: &str, default: PyObjectRef) -> PyObjectRef {
|
||||
for (arg_name, arg_value) in self.kwargs.iter() {
|
||||
if arg_name == key {
|
||||
return arg_value.clone();
|
||||
}
|
||||
}
|
||||
default.clone()
|
||||
}
|
||||
|
||||
pub fn get_optional_kwarg(&self, key: &str) -> Option<PyObjectRef> {
|
||||
for (arg_name, arg_value) in self.kwargs.iter() {
|
||||
if arg_name == key {
|
||||
return Some(arg_value.clone());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_optional_kwarg_with_type(
|
||||
&self,
|
||||
key: &str,
|
||||
ty: PyObjectRef,
|
||||
vm: &mut VirtualMachine,
|
||||
) -> Result<Option<PyObjectRef>, PyObjectRef> {
|
||||
match self.get_optional_kwarg(key) {
|
||||
Some(kwarg) => {
|
||||
if objtype::isinstance(&kwarg, &ty) {
|
||||
Ok(Some(kwarg))
|
||||
} else {
|
||||
let expected_ty_name = vm.to_pystr(&ty)?;
|
||||
let actual_ty_name = vm.to_pystr(&kwarg.typ())?;
|
||||
Err(vm.new_type_error(format!(
|
||||
"argument of type {} is required for named parameter `{}` (got: {})",
|
||||
expected_ty_name, key, actual_ty_name
|
||||
)))
|
||||
}
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializes these arguments into an iterator starting with the positional
|
||||
/// arguments followed by keyword arguments.
|
||||
fn into_iter(self) -> impl Iterator<Item = PyArg> {
|
||||
self.args.into_iter().map(PyArg::Positional).chain(
|
||||
self.kwargs
|
||||
.into_iter()
|
||||
.map(|(name, value)| PyArg::Keyword(name, value)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Binds these arguments to their respective values.
|
||||
///
|
||||
/// If there is an insufficient number of arguments, there are leftover
|
||||
/// arguments after performing the binding, or if an argument is not of
|
||||
/// the expected type, a TypeError is raised.
|
||||
///
|
||||
/// If the given `FromArgs` includes any conversions, exceptions raised
|
||||
/// during the conversion will halt the binding and return the error.
|
||||
fn bind<T: FromArgs>(self, vm: &mut VirtualMachine) -> PyResult<T> {
|
||||
let given_args = self.args.len();
|
||||
let mut args = self.into_iter().peekable();
|
||||
let bound = match T::from_args(vm, &mut args) {
|
||||
Ok(args) => args,
|
||||
Err(ArgumentError::TooFewArgs) => {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Expected at least {} arguments ({} given)",
|
||||
T::arity().start(),
|
||||
given_args,
|
||||
)));
|
||||
}
|
||||
Err(ArgumentError::Exception(ex)) => {
|
||||
return Err(ex);
|
||||
}
|
||||
};
|
||||
|
||||
match args.next() {
|
||||
None => Ok(bound),
|
||||
Some(PyArg::Positional(_)) => Err(vm.new_type_error(format!(
|
||||
"Expected at most {} arguments ({} given)",
|
||||
T::arity().end(),
|
||||
given_args,
|
||||
))),
|
||||
Some(PyArg::Keyword(name, _)) => {
|
||||
Err(vm.new_type_error(format!("Unexpected keyword argument {}", name)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implemented by any type that can be accepted as a parameter to a built-in
|
||||
/// function.
|
||||
///
|
||||
pub trait FromArgs: Sized {
|
||||
/// The range of positional arguments permitted by the function signature.
|
||||
///
|
||||
/// Returns an empty range if not applicable.
|
||||
fn arity() -> RangeInclusive<usize> {
|
||||
0..=0
|
||||
}
|
||||
|
||||
/// Extracts this item from the next argument(s).
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>;
|
||||
}
|
||||
|
||||
/// An iterable Python object.
|
||||
///
|
||||
/// `PyIterable` implements `FromArgs` so that a built-in function can accept
|
||||
@@ -1224,151 +1065,6 @@ impl<T: TryFromObject> TryFromObject for Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A map of keyword arguments to their values.
|
||||
///
|
||||
/// A built-in function with a `KwArgs` parameter is analagous to a Python
|
||||
/// function with `*kwargs`. All remaining keyword arguments are extracted
|
||||
/// (and hence the function will permit an arbitrary number of them).
|
||||
///
|
||||
/// `KwArgs` optionally accepts a generic type parameter to allow type checks
|
||||
/// or conversions of each argument.
|
||||
pub struct KwArgs<T = PyObjectRef>(HashMap<String, T>);
|
||||
|
||||
impl<T> FromArgs for KwArgs<T>
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
let mut kwargs = HashMap::new();
|
||||
while let Some(PyArg::Keyword(name, value)) = args.next() {
|
||||
kwargs.insert(name, T::try_from_object(vm, value)?);
|
||||
}
|
||||
Ok(KwArgs(kwargs))
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of positional argument values.
|
||||
///
|
||||
/// A built-in function with a `Args` parameter is analagous to a Python
|
||||
/// function with `*args`. All remaining positional arguments are extracted
|
||||
/// (and hence the function will permit an arbitrary number of them).
|
||||
///
|
||||
/// `Args` optionally accepts a generic type parameter to allow type checks
|
||||
/// or conversions of each argument.
|
||||
pub struct Args<T>(Vec<T>);
|
||||
|
||||
impl<T> FromArgs for Args<T>
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
let mut varargs = Vec::new();
|
||||
while let Some(PyArg::Positional(value)) = args.next() {
|
||||
varargs.push(T::try_from_object(vm, value)?);
|
||||
}
|
||||
Ok(Args(varargs))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromArgs for T
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
fn arity() -> RangeInclusive<usize> {
|
||||
1..=1
|
||||
}
|
||||
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
if let Some(PyArg::Positional(value)) = args.next() {
|
||||
Ok(T::try_from_object(vm, value)?)
|
||||
} else {
|
||||
Err(ArgumentError::TooFewArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An argument that may or may not be provided by the caller.
|
||||
///
|
||||
/// This style of argument is not possible in pure Python.
|
||||
pub enum OptionalArg<T> {
|
||||
Present(T),
|
||||
Missing,
|
||||
}
|
||||
|
||||
use self::OptionalArg::*;
|
||||
use crate::obj::objproperty::PropertyBuilder;
|
||||
|
||||
impl<T> OptionalArg<T> {
|
||||
pub fn into_option(self) -> Option<T> {
|
||||
match self {
|
||||
Present(value) => Some(value),
|
||||
Missing => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromArgs for OptionalArg<T>
|
||||
where
|
||||
T: TryFromObject,
|
||||
{
|
||||
fn arity() -> RangeInclusive<usize> {
|
||||
0..=1
|
||||
}
|
||||
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
Ok(if let Some(PyArg::Positional(_)) = args.peek() {
|
||||
let value = if let Some(PyArg::Positional(value)) = args.next() {
|
||||
value
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
Present(T::try_from_object(vm, value)?)
|
||||
} else {
|
||||
Missing
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub enum PyArg {
|
||||
Positional(PyObjectRef),
|
||||
Keyword(String, PyObjectRef),
|
||||
}
|
||||
|
||||
pub enum ArgumentError {
|
||||
TooFewArgs,
|
||||
Exception(PyObjectRef),
|
||||
}
|
||||
|
||||
impl From<PyObjectRef> for ArgumentError {
|
||||
fn from(ex: PyObjectRef) -> Self {
|
||||
ArgumentError::Exception(ex)
|
||||
}
|
||||
}
|
||||
|
||||
/// Implemented by any type that can be created from a Python object.
|
||||
///
|
||||
/// Any type that implements `TryFromObject` is automatically `FromArgs`, and
|
||||
@@ -1413,132 +1109,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// For functions that accept no arguments. Implemented explicitly instead of via
|
||||
// macro below to avoid unused warnings.
|
||||
impl FromArgs for () {
|
||||
fn from_args<I>(
|
||||
_vm: &mut VirtualMachine,
|
||||
_args: &mut iter::Peekable<I>,
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>,
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// A tuple of types that each implement `FromArgs` represents a sequence of
|
||||
// arguments that can be bound and passed to a built-in function.
|
||||
//
|
||||
// Technically, a tuple can contain tuples, which can contain tuples, and so on,
|
||||
// so this actually represents a tree of values to be bound from arguments, but
|
||||
// in practice this is only used for the top-level parameters.
|
||||
macro_rules! tuple_from_py_func_args {
|
||||
($($T:ident),+) => {
|
||||
impl<$($T),+> FromArgs for ($($T,)+)
|
||||
where
|
||||
$($T: FromArgs),+
|
||||
{
|
||||
fn arity() -> RangeInclusive<usize> {
|
||||
let mut min = 0;
|
||||
let mut max = 0;
|
||||
$(
|
||||
let (start, end) = $T::arity().into_inner();
|
||||
min += start;
|
||||
max += end;
|
||||
)+
|
||||
min..=max
|
||||
}
|
||||
|
||||
fn from_args<I>(
|
||||
vm: &mut VirtualMachine,
|
||||
args: &mut iter::Peekable<I>
|
||||
) -> Result<Self, ArgumentError>
|
||||
where
|
||||
I: Iterator<Item = PyArg>
|
||||
{
|
||||
Ok(($($T::from_args(vm, args)?,)+))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Implement `FromArgs` for up to 5-tuples, allowing built-in functions to bind
|
||||
// up to 5 top-level parameters (note that `Args`, `KwArgs`, nested tuples, etc.
|
||||
// count as 1, so this should actually be more than enough).
|
||||
tuple_from_py_func_args!(A);
|
||||
tuple_from_py_func_args!(A, B);
|
||||
tuple_from_py_func_args!(A, B, C);
|
||||
tuple_from_py_func_args!(A, B, C, D);
|
||||
tuple_from_py_func_args!(A, B, C, D, E);
|
||||
|
||||
/// A built-in Python function.
|
||||
pub type PyNativeFunc = Box<dyn Fn(&mut VirtualMachine, PyFuncArgs) -> PyResult + 'static>;
|
||||
|
||||
/// Implemented by types that are or can generate built-in functions.
|
||||
///
|
||||
/// For example, any function that:
|
||||
///
|
||||
/// - Accepts a sequence of types that implement `FromArgs`, followed by a
|
||||
/// `&mut VirtualMachine`
|
||||
/// - Returns some type that implements `IntoPyObject`
|
||||
///
|
||||
/// will generate a `PyNativeFunc` that performs the appropriate type and arity
|
||||
/// checking, any requested conversions, and then if successful call the function
|
||||
/// with the bound values.
|
||||
///
|
||||
/// A bare `PyNativeFunc` also implements this trait, allowing the above to be
|
||||
/// done manually, for rare situations that don't fit into this model.
|
||||
pub trait IntoPyNativeFunc<T, R> {
|
||||
fn into_func(self) -> PyNativeFunc;
|
||||
}
|
||||
|
||||
impl<F> IntoPyNativeFunc<PyFuncArgs, PyResult> for F
|
||||
where
|
||||
F: Fn(&mut VirtualMachine, PyFuncArgs) -> PyResult + 'static,
|
||||
{
|
||||
fn into_func(self) -> PyNativeFunc {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPyNativeFunc<PyFuncArgs, PyResult> for PyNativeFunc {
|
||||
fn into_func(self) -> PyNativeFunc {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// This is the "magic" that allows rust functions of varying signatures to
|
||||
// generate native python functions.
|
||||
//
|
||||
// Note that this could be done without a macro - it is simply to avoid repetition.
|
||||
macro_rules! into_py_native_func_tuple {
|
||||
($(($n:tt, $T:ident)),*) => {
|
||||
impl<F, $($T,)* R> IntoPyNativeFunc<($($T,)*), R> for F
|
||||
where
|
||||
F: Fn($($T,)* &mut VirtualMachine) -> R + 'static,
|
||||
$($T: FromArgs,)*
|
||||
($($T,)*): FromArgs,
|
||||
R: IntoPyObject,
|
||||
{
|
||||
fn into_func(self) -> PyNativeFunc {
|
||||
Box::new(move |vm, args| {
|
||||
let ($($n,)*) = args.bind::<($($T,)*)>(vm)?;
|
||||
|
||||
(self)($($n,)* vm).into_pyobject(vm)
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
into_py_native_func_tuple!();
|
||||
into_py_native_func_tuple!((a, A));
|
||||
into_py_native_func_tuple!((a, A), (b, B));
|
||||
into_py_native_func_tuple!((a, A), (b, B), (c, C));
|
||||
into_py_native_func_tuple!((a, A), (b, B), (c, C), (d, D));
|
||||
into_py_native_func_tuple!((a, A), (b, B), (c, C), (d, D), (e, E));
|
||||
|
||||
// TODO: This is a workaround and shouldn't exist.
|
||||
// Each iterable type should have its own distinct iterator type.
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -3,15 +3,17 @@
|
||||
//! This module makes use of the parser logic, and translates all ast nodes
|
||||
//! into python ast.AST objects.
|
||||
|
||||
extern crate rustpython_parser;
|
||||
|
||||
use self::rustpython_parser::{ast, parser};
|
||||
use crate::obj::objstr;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::VirtualMachine;
|
||||
use num_complex::Complex64;
|
||||
use std::ops::Deref;
|
||||
|
||||
use num_complex::Complex64;
|
||||
|
||||
use rustpython_parser::{ast, parser};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objstr;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
/*
|
||||
* Idea: maybe we can create a sort of struct with some helper functions?
|
||||
struct AstToPyAst {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objcode;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
fn dis_dis(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
+3
-7
@@ -2,29 +2,25 @@
|
||||
* I/O core tools.
|
||||
*/
|
||||
|
||||
//library imports
|
||||
use std::collections::HashSet;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::io::BufReader;
|
||||
use std::path::PathBuf;
|
||||
|
||||
//3rd party imports
|
||||
use num_bigint::ToBigInt;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
//custom imports
|
||||
use super::os;
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::import;
|
||||
use crate::obj::objbytearray::PyByteArray;
|
||||
use crate::obj::objbytes;
|
||||
use crate::obj::objint;
|
||||
use crate::obj::objstr;
|
||||
|
||||
use crate::pyobject::{
|
||||
AttributeProtocol, BufferProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol,
|
||||
AttributeProtocol, BufferProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
|
||||
use crate::import;
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
fn compute_c_flag(mode: &str) -> u16 {
|
||||
|
||||
@@ -5,14 +5,14 @@ use serde::de::{DeserializeSeed, Visitor};
|
||||
use serde::ser::{SerializeMap, SerializeSeq};
|
||||
use serde_json;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::{
|
||||
objbool, objdict, objfloat, objint, objsequence,
|
||||
objstr::{self, PyString},
|
||||
objtype,
|
||||
};
|
||||
use crate::pyobject::{
|
||||
create_type, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult,
|
||||
TypeProtocol,
|
||||
create_type, DictProtocol, IdProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::VirtualMachine;
|
||||
use num_traits::cast::ToPrimitive;
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
* Testing if a string is a keyword.
|
||||
*/
|
||||
|
||||
extern crate rustpython_parser;
|
||||
use self::rustpython_parser::lexer;
|
||||
use rustpython_parser::lexer;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objstr;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::VirtualMachine;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
fn keyword_iskeyword(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(s, Some(vm.ctx.str_type()))]);
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
use crate::obj::objfloat;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::VirtualMachine;
|
||||
use statrs::function::erf::{erf, erfc};
|
||||
use statrs::function::gamma::{gamma, ln_gamma};
|
||||
use std;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objfloat;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
// Helper macro:
|
||||
macro_rules! make_math_func {
|
||||
|
||||
+2
-7
@@ -1,18 +1,13 @@
|
||||
//library imports
|
||||
use std::fs::File;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::ErrorKind;
|
||||
// use std::env;
|
||||
|
||||
//3rd party imports
|
||||
use num_traits::cast::ToPrimitive;
|
||||
|
||||
//custom imports
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objint;
|
||||
use crate::obj::objstr;
|
||||
// use crate::obj::objdict;
|
||||
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[cfg(unix)]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
extern crate rustc_version_runtime;
|
||||
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult};
|
||||
use crate::VirtualMachine;
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
py_module!(ctx, "platform", {
|
||||
|
||||
@@ -7,15 +7,16 @@
|
||||
* https://docs.rs/byteorder/1.2.6/byteorder/
|
||||
*/
|
||||
|
||||
extern crate byteorder;
|
||||
use self::byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::io::{Cursor, Read, Write};
|
||||
|
||||
use crate::obj::{objbool, objbytes, objfloat, objint, objstr, objtype};
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::VirtualMachine;
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::io::{Cursor, Read, Write};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::{objbool, objbytes, objfloat, objint, objstr, objtype};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::VirtualMachine;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FormatCode {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//! Random module.
|
||||
|
||||
extern crate rand;
|
||||
use rand::distributions::{Distribution, Normal};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objfloat;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::stdlib::random::rand::distributions::{Distribution, Normal};
|
||||
use crate::VirtualMachine;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
|
||||
py_module!(ctx, "random", {
|
||||
|
||||
+3
-3
@@ -9,13 +9,13 @@ use std::path::PathBuf;
|
||||
|
||||
use regex::{Match, Regex};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::import;
|
||||
use crate::obj::objstr;
|
||||
use crate::pyobject::{
|
||||
AttributeProtocol, PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue,
|
||||
TypeProtocol,
|
||||
AttributeProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::VirtualMachine;
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
impl PyValue for Regex {
|
||||
fn class(vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
|
||||
@@ -5,13 +5,12 @@ use std::io::Write;
|
||||
use std::net::{SocketAddr, TcpListener, TcpStream, ToSocketAddrs, UdpSocket};
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objbytes;
|
||||
use crate::obj::objint;
|
||||
use crate::obj::objsequence::get_elements;
|
||||
use crate::obj::objstr;
|
||||
use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
//! The python `time` module.
|
||||
|
||||
use crate::obj::objfloat;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::VirtualMachine;
|
||||
use std::thread;
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objfloat;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
fn time_sleep(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(seconds, Some(vm.ctx.float_type()))]);
|
||||
let seconds = objfloat::get_value(seconds);
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
* python tokenize module.
|
||||
*/
|
||||
|
||||
extern crate rustpython_parser;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use self::rustpython_parser::lexer;
|
||||
use rustpython_parser::lexer;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objstr;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::VirtualMachine;
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
fn tokenize_tokenize(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(readline, Some(vm.ctx.str_type()))]);
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
* Dynamic type creation and names for built in types.
|
||||
*/
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objtype;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::VirtualMachine;
|
||||
|
||||
fn types_new_class(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
+7
-4
@@ -1,10 +1,13 @@
|
||||
use crate::obj::objint;
|
||||
use crate::pyobject::{DictProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::rc::Rc;
|
||||
use std::{env, mem};
|
||||
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objint;
|
||||
use crate::pyobject::{DictProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
/*
|
||||
* The magic sys module.
|
||||
*/
|
||||
|
||||
+2
-2
@@ -14,6 +14,7 @@ use std::sync::{Mutex, MutexGuard};
|
||||
use crate::builtins;
|
||||
use crate::bytecode;
|
||||
use crate::frame::{ExecutionResult, Frame, Scope};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objbool;
|
||||
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
|
||||
use crate::obj::objcode;
|
||||
@@ -27,8 +28,7 @@ use crate::obj::objstr;
|
||||
use crate::obj::objtuple::PyTuple;
|
||||
use crate::obj::objtype;
|
||||
use crate::pyobject::{
|
||||
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult,
|
||||
TypeProtocol,
|
||||
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::stdlib;
|
||||
use crate::sysmodule;
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
use crate::{convert, vm_class::AccessibleVM, wasm_builtins::window};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use futures::Future;
|
||||
use js_sys::Promise;
|
||||
use num_traits::cast::ToPrimitive;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::{future_to_promise, JsFuture};
|
||||
|
||||
use rustpython_vm::function::PyFuncArgs;
|
||||
use rustpython_vm::import::import_module;
|
||||
use rustpython_vm::obj::{objint, objstr};
|
||||
use rustpython_vm::pyobject::{
|
||||
AttributeProtocol, PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue,
|
||||
TypeProtocol,
|
||||
AttributeProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use rustpython_vm::{import::import_module, VirtualMachine};
|
||||
use std::path::PathBuf;
|
||||
use wasm_bindgen::{prelude::*, JsCast};
|
||||
use wasm_bindgen_futures::{future_to_promise, JsFuture};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
|
||||
use crate::{convert, vm_class::AccessibleVM, wasm_builtins::window};
|
||||
|
||||
enum FetchResponseFormat {
|
||||
Json,
|
||||
|
||||
+11
-10
@@ -1,14 +1,15 @@
|
||||
use crate::browser_module;
|
||||
use crate::vm_class::{AccessibleVM, WASMVirtualMachine};
|
||||
use js_sys::{Array, ArrayBuffer, Object, Promise, Reflect, Uint8Array};
|
||||
use num_traits::cast::ToPrimitive;
|
||||
use rustpython_vm::obj::{objbytes, objint, objsequence, objtype};
|
||||
use rustpython_vm::pyobject::{
|
||||
self, AttributeProtocol, DictProtocol, PyFuncArgs, PyObjectRef, PyResult,
|
||||
};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
use wasm_bindgen::{closure::Closure, prelude::*, JsCast};
|
||||
|
||||
use rustpython_vm::function::PyFuncArgs;
|
||||
use rustpython_vm::obj::{objbytes, objint, objsequence, objtype};
|
||||
use rustpython_vm::pyobject::{AttributeProtocol, DictProtocol, PyObjectRef, PyResult};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
|
||||
use crate::browser_module;
|
||||
use crate::vm_class::{AccessibleVM, WASMVirtualMachine};
|
||||
|
||||
pub fn py_err_to_js_err(vm: &mut VirtualMachine, py_err: &PyObjectRef) -> JsValue {
|
||||
macro_rules! map_exceptions {
|
||||
($py_exc:ident, $msg:expr, { $($py_exc_ty:expr => $js_err_new:expr),*$(,)? }) => {
|
||||
@@ -83,7 +84,7 @@ pub fn py_to_js(vm: &mut VirtualMachine, py_obj: PyObjectRef) -> JsValue {
|
||||
let vm = &mut acc_vm
|
||||
.upgrade()
|
||||
.expect("acc. VM to be invalid when WASM vm is valid");
|
||||
let mut py_func_args = rustpython_vm::pyobject::PyFuncArgs::default();
|
||||
let mut py_func_args = PyFuncArgs::default();
|
||||
if let Some(ref args) = args {
|
||||
for arg in args.values() {
|
||||
py_func_args.args.push(js_to_py(vm, arg?));
|
||||
@@ -132,7 +133,7 @@ pub fn py_to_js(vm: &mut VirtualMachine, py_obj: PyObjectRef) -> JsValue {
|
||||
.expect("Couldn't get json module")
|
||||
.get_attr("dumps".into())
|
||||
.expect("Couldn't get json dumps");
|
||||
match vm.invoke(dumps, pyobject::PyFuncArgs::new(vec![py_obj], vec![])) {
|
||||
match vm.invoke(dumps, PyFuncArgs::new(vec![py_obj], vec![])) {
|
||||
Ok(value) => {
|
||||
let json = vm.to_pystr(&value).unwrap();
|
||||
js_sys::JSON::parse(&json).unwrap_or(JsValue::UNDEFINED)
|
||||
@@ -239,7 +240,7 @@ pub fn js_to_py(vm: &mut VirtualMachine, js_val: JsValue) -> PyObjectRef {
|
||||
};
|
||||
let py_json = vm.new_str(json);
|
||||
|
||||
vm.invoke(loads, pyobject::PyFuncArgs::new(vec![py_json], vec![]))
|
||||
vm.invoke(loads, PyFuncArgs::new(vec![py_json], vec![]))
|
||||
// can safely unwrap because we know it's valid JSON
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
+12
-10
@@ -1,18 +1,20 @@
|
||||
use crate::browser_module::setup_browser_module;
|
||||
use crate::convert;
|
||||
use crate::wasm_builtins;
|
||||
use js_sys::{Object, Reflect, SyntaxError, TypeError};
|
||||
use rustpython_vm::{
|
||||
compile,
|
||||
frame::{NameProtocol, Scope},
|
||||
pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult},
|
||||
VirtualMachine,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
use js_sys::{Object, Reflect, SyntaxError, TypeError};
|
||||
use wasm_bindgen::{prelude::*, JsCast};
|
||||
|
||||
use rustpython_vm::compile;
|
||||
use rustpython_vm::frame::{NameProtocol, Scope};
|
||||
use rustpython_vm::function::PyFuncArgs;
|
||||
use rustpython_vm::pyobject::{PyContext, PyObjectRef, PyResult};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
|
||||
use crate::browser_module::setup_browser_module;
|
||||
use crate::convert;
|
||||
use crate::wasm_builtins;
|
||||
|
||||
pub trait HeldRcInner {}
|
||||
|
||||
impl<T> HeldRcInner for T {}
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
//! Implements functions listed here: https://docs.python.org/3/library/builtins.html.
|
||||
|
||||
use js_sys::{self, Array};
|
||||
use rustpython_vm::obj::{objstr, objtype};
|
||||
use rustpython_vm::pyobject::{IdProtocol, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
use web_sys::{self, console};
|
||||
|
||||
use rustpython_vm::function::PyFuncArgs;
|
||||
use rustpython_vm::obj::{objstr, objtype};
|
||||
use rustpython_vm::pyobject::{IdProtocol, PyObjectRef, PyResult, TypeProtocol};
|
||||
use rustpython_vm::VirtualMachine;
|
||||
|
||||
pub(crate) fn window() -> web_sys::Window {
|
||||
web_sys::window().expect("Window to be available")
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user