diff --git a/derive-impl/src/pyclass.rs b/derive-impl/src/pyclass.rs index 777d52dd1f3..a17ac01e796 100644 --- a/derive-impl/src/pyclass.rs +++ b/derive-impl/src/pyclass.rs @@ -42,6 +42,7 @@ impl std::fmt::Display for AttrName { impl FromStr for AttrName { type Err = String; + fn from_str(s: &str) -> std::result::Result { Ok(match s { "pymethod" => Self::Method, @@ -1216,6 +1217,7 @@ impl ItemMeta for MethodItemMeta { fn from_inner(inner: ItemMetaInner) -> Self { Self(inner) } + fn inner(&self) -> &ItemMetaInner { &self.0 } @@ -1225,6 +1227,7 @@ impl MethodItemMeta { fn raw(&self) -> Result { self.inner()._bool("raw") } + fn method_name(&self) -> Result { let inner = self.inner(); let name = inner._optional_str("name")?; @@ -1244,6 +1247,7 @@ impl ItemMeta for GetSetItemMeta { fn from_inner(inner: ItemMetaInner) -> Self { Self(inner) } + fn inner(&self) -> &ItemMetaInner { &self.0 } @@ -1274,8 +1278,8 @@ impl GetSetItemMeta { if name.is_empty() { Err(err_span!( inner.meta_ident, - "A #[{}({typ})] fn with a {prefix}* name must \ - have something after \"{prefix}\"", + r#"A #[{}({typ})] fn with a {prefix}* name must \ + have something after "{prefix}""#, inner.meta_name(), typ = item_typ, prefix = prefix @@ -1286,8 +1290,8 @@ impl GetSetItemMeta { } else { Err(err_span!( inner.meta_ident, - "A #[{}(setter)] fn must either have a `name` \ - parameter or a fn name along the lines of \"set_*\"", + r#"A #[{}(setter)] fn must either have a `name` \ + parameter or a fn name along the lines of "set_*""#, inner.meta_name() )) } @@ -1337,6 +1341,7 @@ impl ItemMeta for SlotItemMeta { fn from_inner(inner: ItemMetaInner) -> Self { Self(inner) } + fn inner(&self) -> &ItemMetaInner { &self.0 } @@ -1389,6 +1394,7 @@ impl ItemMeta for MemberItemMeta { fn from_inner(inner: ItemMetaInner) -> Self { Self(inner) } + fn inner(&self) -> &ItemMetaInner { &self.0 } @@ -1403,8 +1409,8 @@ impl MemberItemMeta { if name.is_empty() { Err(err_span!( inner.meta_ident, - "A #[{}({typ})] fn with a {prefix}* name must \ - have something after \"{prefix}\"", + r#"A #[{}({typ})] fn with a {prefix}* name must \ + have something after "{prefix}""#, inner.meta_name(), typ = item_typ, prefix = prefix @@ -1415,8 +1421,8 @@ impl MemberItemMeta { } else { Err(err_span!( inner.meta_ident, - "A #[{}(setter)] fn must either have a `name` \ - parameter or a fn name along the lines of \"set_*\"", + r#"A #[{}(setter)] fn must either have a `name` \ + parameter or a fn name along the lines of "set_*""#, inner.meta_name() )) } diff --git a/vm/src/readline.rs b/vm/src/readline.rs index 9a59e42dc81..d37bbb74582 100644 --- a/vm/src/readline.rs +++ b/vm/src/readline.rs @@ -29,7 +29,7 @@ mod basic_readline { impl Readline { pub fn new(helper: H) -> Self { - Readline { helper } + Self { helper } } pub fn load_history(&mut self, _path: &Path) -> OtherResult<()> { @@ -86,7 +86,7 @@ mod rustyline_readline { ) .expect("failed to initialize line editor"); repl.set_helper(Some(helper)); - Readline { repl } + Self { repl } } pub fn load_history(&mut self, path: &Path) -> OtherResult<()> { @@ -136,7 +136,7 @@ pub struct Readline(readline_inner::Readline); impl Readline { pub fn new(helper: H) -> Self { - Readline(readline_inner::Readline::new(helper)) + Self(readline_inner::Readline::new(helper)) } pub fn load_history(&mut self, path: &Path) -> OtherResult<()> { diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index 95a1162f5b6..e815bc41596 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -55,7 +55,7 @@ mod type_parameters; fn get_node_field(vm: &VirtualMachine, obj: &PyObject, field: &'static str, typ: &str) -> PyResult { vm.get_attribute_opt(obj.to_owned(), field)? - .ok_or_else(|| vm.new_type_error(format!("required field \"{field}\" missing from {typ}"))) + .ok_or_else(|| vm.new_type_error(format!(r#"required field "{field}" missing from {typ}"#))) } fn get_node_field_opt( @@ -76,7 +76,7 @@ fn get_int_field( ) -> PyResult> { get_node_field(vm, obj, field, typ)? .downcast_exact(vm) - .map_err(|_| vm.new_type_error(format!("field \"{field}\" must have integer type"))) + .map_err(|_| vm.new_type_error(format!(r#"field "{field}" must have integer type"#))) } struct PySourceRange { @@ -107,7 +107,7 @@ impl Row { self.0.get() } - fn get_one_indexed(self) -> OneIndexed { + const fn get_one_indexed(self) -> OneIndexed { self.0 } } diff --git a/vm/src/stdlib/ast/constant.rs b/vm/src/stdlib/ast/constant.rs index 857a5a7c91f..422a352972e 100644 --- a/vm/src/stdlib/ast/constant.rs +++ b/vm/src/stdlib/ast/constant.rs @@ -21,48 +21,49 @@ impl Constant { } } - pub(super) fn new_int(value: ruff::Int, range: TextRange) -> Self { + pub(super) const fn new_int(value: ruff::Int, range: TextRange) -> Self { Self { range, value: ConstantLiteral::Int(value), } } - pub(super) fn new_float(value: f64, range: TextRange) -> Self { + pub(super) const fn new_float(value: f64, range: TextRange) -> Self { Self { range, value: ConstantLiteral::Float(value), } } - pub(super) fn new_complex(real: f64, imag: f64, range: TextRange) -> Self { + + pub(super) const fn new_complex(real: f64, imag: f64, range: TextRange) -> Self { Self { range, value: ConstantLiteral::Complex { real, imag }, } } - pub(super) fn new_bytes(value: Box<[u8]>, range: TextRange) -> Self { + pub(super) const fn new_bytes(value: Box<[u8]>, range: TextRange) -> Self { Self { range, value: ConstantLiteral::Bytes(value), } } - pub(super) fn new_bool(value: bool, range: TextRange) -> Self { + pub(super) const fn new_bool(value: bool, range: TextRange) -> Self { Self { range, value: ConstantLiteral::Bool(value), } } - pub(super) fn new_none(range: TextRange) -> Self { + pub(super) const fn new_none(range: TextRange) -> Self { Self { range, value: ConstantLiteral::None, } } - pub(super) fn new_ellipsis(range: TextRange) -> Self { + pub(super) const fn new_ellipsis(range: TextRange) -> Self { Self { range, value: ConstantLiteral::Ellipsis, @@ -137,30 +138,30 @@ impl Node for Constant { impl Node for ConstantLiteral { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { match self { - ConstantLiteral::None => vm.ctx.none(), - ConstantLiteral::Bool(value) => vm.ctx.new_bool(value).to_pyobject(vm), - ConstantLiteral::Str { value, .. } => vm.ctx.new_str(value).to_pyobject(vm), - ConstantLiteral::Bytes(value) => vm.ctx.new_bytes(value.into()).to_pyobject(vm), - ConstantLiteral::Int(value) => value.ast_to_object(vm, source_code), - ConstantLiteral::Tuple(value) => { + Self::None => vm.ctx.none(), + Self::Bool(value) => vm.ctx.new_bool(value).to_pyobject(vm), + Self::Str { value, .. } => vm.ctx.new_str(value).to_pyobject(vm), + Self::Bytes(value) => vm.ctx.new_bytes(value.into()).to_pyobject(vm), + Self::Int(value) => value.ast_to_object(vm, source_code), + Self::Tuple(value) => { let value = value .into_iter() .map(|c| c.ast_to_object(vm, source_code)) .collect(); vm.ctx.new_tuple(value).to_pyobject(vm) } - ConstantLiteral::FrozenSet(value) => PyFrozenSet::from_iter( + Self::FrozenSet(value) => PyFrozenSet::from_iter( vm, value.into_iter().map(|c| c.ast_to_object(vm, source_code)), ) .unwrap() .into_pyobject(vm), - ConstantLiteral::Float(value) => vm.ctx.new_float(value).into_pyobject(vm), - ConstantLiteral::Complex { real, imag } => vm + Self::Float(value) => vm.ctx.new_float(value).into_pyobject(vm), + Self::Complex { real, imag } => vm .ctx .new_complex(num_complex::Complex::new(real, imag)) .into_pyobject(vm), - ConstantLiteral::Ellipsis => vm.ctx.ellipsis(), + Self::Ellipsis => vm.ctx.ellipsis(), } } @@ -171,9 +172,9 @@ impl Node for ConstantLiteral { ) -> PyResult { let cls = value_object.class(); let value = if cls.is(vm.ctx.types.none_type) { - ConstantLiteral::None + Self::None } else if cls.is(vm.ctx.types.bool_type) { - ConstantLiteral::Bool(if value_object.is(&vm.ctx.true_value) { + Self::Bool(if value_object.is(&vm.ctx.true_value) { true } else if value_object.is(&vm.ctx.false_value) { false @@ -181,14 +182,14 @@ impl Node for ConstantLiteral { value_object.try_to_value(vm)? }) } else if cls.is(vm.ctx.types.str_type) { - ConstantLiteral::Str { + Self::Str { value: value_object.try_to_value::(vm)?.into(), prefix: StringLiteralPrefix::Empty, } } else if cls.is(vm.ctx.types.bytes_type) { - ConstantLiteral::Bytes(value_object.try_to_value::>(vm)?.into()) + Self::Bytes(value_object.try_to_value::>(vm)?.into()) } else if cls.is(vm.ctx.types.int_type) { - ConstantLiteral::Int(Node::ast_from_object(vm, source_code, value_object)?) + Self::Int(Node::ast_from_object(vm, source_code, value_object)?) } else if cls.is(vm.ctx.types.tuple_type) { let tuple = value_object.downcast::().map_err(|obj| { vm.new_type_error(format!( @@ -202,7 +203,7 @@ impl Node for ConstantLiteral { .cloned() .map(|object| Node::ast_from_object(vm, source_code, object)) .collect::>()?; - ConstantLiteral::Tuple(tuple) + Self::Tuple(tuple) } else if cls.is(vm.ctx.types.frozenset_type) { let set = value_object.downcast::().unwrap(); let elements = set @@ -210,10 +211,10 @@ impl Node for ConstantLiteral { .into_iter() .map(|object| Node::ast_from_object(vm, source_code, object)) .collect::>()?; - ConstantLiteral::FrozenSet(elements) + Self::FrozenSet(elements) } else if cls.is(vm.ctx.types.float_type) { let float = value_object.try_into_value(vm)?; - ConstantLiteral::Float(float) + Self::Float(float) } else if cls.is(vm.ctx.types.complex_type) { let complex = value_object.try_complex(vm)?; let complex = match complex { @@ -226,12 +227,12 @@ impl Node for ConstantLiteral { } Some((value, _was_coerced)) => value, }; - ConstantLiteral::Complex { + Self::Complex { real: complex.re, imag: complex.im, } } else if cls.is(vm.ctx.types.ellipsis_type) { - ConstantLiteral::Ellipsis + Self::Ellipsis } else { return Err(vm.new_type_error(format!( "invalid type in Constant: {}", diff --git a/vm/src/stdlib/ast/exception.rs b/vm/src/stdlib/ast/exception.rs index a76e7b569b4..4f3b4de60da 100644 --- a/vm/src/stdlib/ast/exception.rs +++ b/vm/src/stdlib/ast/exception.rs @@ -52,12 +52,13 @@ impl Node for ruff::ExceptHandlerExceptHandler { node_add_location(&dict, _range, _vm, source_code); node.into() } + fn ast_from_object( _vm: &VirtualMachine, source_code: &SourceCodeOwned, _object: PyObjectRef, ) -> PyResult { - Ok(ruff::ExceptHandlerExceptHandler { + Ok(Self { type_: get_node_field_opt(_vm, &_object, "type")? .map(|obj| Node::ast_from_object(_vm, source_code, obj)) .transpose()?, diff --git a/vm/src/stdlib/ast/expression.rs b/vm/src/stdlib/ast/expression.rs index ed42dd5d0ab..69cf534669a 100644 --- a/vm/src/stdlib/ast/expression.rs +++ b/vm/src/stdlib/ast/expression.rs @@ -7,54 +7,47 @@ use crate::stdlib::ast::string::JoinedStr; impl Node for ruff::Expr { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { match self { - ruff::Expr::BoolOp(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Name(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::BinOp(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::UnaryOp(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Lambda(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::If(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Dict(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Set(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::ListComp(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::SetComp(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::DictComp(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Generator(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Await(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Yield(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::YieldFrom(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Compare(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Call(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Attribute(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Subscript(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Starred(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::List(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Tuple(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::Slice(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::NumberLiteral(cons) => { - constant::number_literal_to_object(vm, source_code, cons) - } - ruff::Expr::StringLiteral(cons) => { - constant::string_literal_to_object(vm, source_code, cons) - } - ruff::Expr::FString(cons) => string::fstring_to_object(vm, source_code, cons), - ruff::Expr::BytesLiteral(cons) => { - constant::bytes_literal_to_object(vm, source_code, cons) - } - ruff::Expr::BooleanLiteral(cons) => { + Self::BoolOp(cons) => cons.ast_to_object(vm, source_code), + Self::Name(cons) => cons.ast_to_object(vm, source_code), + Self::BinOp(cons) => cons.ast_to_object(vm, source_code), + Self::UnaryOp(cons) => cons.ast_to_object(vm, source_code), + Self::Lambda(cons) => cons.ast_to_object(vm, source_code), + Self::If(cons) => cons.ast_to_object(vm, source_code), + Self::Dict(cons) => cons.ast_to_object(vm, source_code), + Self::Set(cons) => cons.ast_to_object(vm, source_code), + Self::ListComp(cons) => cons.ast_to_object(vm, source_code), + Self::SetComp(cons) => cons.ast_to_object(vm, source_code), + Self::DictComp(cons) => cons.ast_to_object(vm, source_code), + Self::Generator(cons) => cons.ast_to_object(vm, source_code), + Self::Await(cons) => cons.ast_to_object(vm, source_code), + Self::Yield(cons) => cons.ast_to_object(vm, source_code), + Self::YieldFrom(cons) => cons.ast_to_object(vm, source_code), + Self::Compare(cons) => cons.ast_to_object(vm, source_code), + Self::Call(cons) => cons.ast_to_object(vm, source_code), + Self::Attribute(cons) => cons.ast_to_object(vm, source_code), + Self::Subscript(cons) => cons.ast_to_object(vm, source_code), + Self::Starred(cons) => cons.ast_to_object(vm, source_code), + Self::List(cons) => cons.ast_to_object(vm, source_code), + Self::Tuple(cons) => cons.ast_to_object(vm, source_code), + Self::Slice(cons) => cons.ast_to_object(vm, source_code), + Self::NumberLiteral(cons) => constant::number_literal_to_object(vm, source_code, cons), + Self::StringLiteral(cons) => constant::string_literal_to_object(vm, source_code, cons), + Self::FString(cons) => string::fstring_to_object(vm, source_code, cons), + Self::BytesLiteral(cons) => constant::bytes_literal_to_object(vm, source_code, cons), + Self::BooleanLiteral(cons) => { constant::boolean_literal_to_object(vm, source_code, cons) } - ruff::Expr::NoneLiteral(cons) => { - constant::none_literal_to_object(vm, source_code, cons) - } - ruff::Expr::EllipsisLiteral(cons) => { + Self::NoneLiteral(cons) => constant::none_literal_to_object(vm, source_code, cons), + Self::EllipsisLiteral(cons) => { constant::ellipsis_literal_to_object(vm, source_code, cons) } - ruff::Expr::Named(cons) => cons.ast_to_object(vm, source_code), - ruff::Expr::IpyEscapeCommand(_) => { + Self::Named(cons) => cons.ast_to_object(vm, source_code), + Self::IpyEscapeCommand(_) => { unimplemented!("IPython escape command is not allowed in Python AST") } } } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -62,77 +55,77 @@ impl Node for ruff::Expr { ) -> PyResult { let cls = object.class(); Ok(if cls.is(pyast::NodeExprBoolOp::static_type()) { - ruff::Expr::BoolOp(ruff::ExprBoolOp::ast_from_object(vm, source_code, object)?) + Self::BoolOp(ruff::ExprBoolOp::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprNamedExpr::static_type()) { - ruff::Expr::Named(ruff::ExprNamed::ast_from_object(vm, source_code, object)?) + Self::Named(ruff::ExprNamed::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprBinOp::static_type()) { - ruff::Expr::BinOp(ruff::ExprBinOp::ast_from_object(vm, source_code, object)?) + Self::BinOp(ruff::ExprBinOp::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprUnaryOp::static_type()) { - ruff::Expr::UnaryOp(ruff::ExprUnaryOp::ast_from_object(vm, source_code, object)?) + Self::UnaryOp(ruff::ExprUnaryOp::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprLambda::static_type()) { - ruff::Expr::Lambda(ruff::ExprLambda::ast_from_object(vm, source_code, object)?) + Self::Lambda(ruff::ExprLambda::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprIfExp::static_type()) { - ruff::Expr::If(ruff::ExprIf::ast_from_object(vm, source_code, object)?) + Self::If(ruff::ExprIf::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprDict::static_type()) { - ruff::Expr::Dict(ruff::ExprDict::ast_from_object(vm, source_code, object)?) + Self::Dict(ruff::ExprDict::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprSet::static_type()) { - ruff::Expr::Set(ruff::ExprSet::ast_from_object(vm, source_code, object)?) + Self::Set(ruff::ExprSet::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprListComp::static_type()) { - ruff::Expr::ListComp(ruff::ExprListComp::ast_from_object( + Self::ListComp(ruff::ExprListComp::ast_from_object( vm, source_code, object, )?) } else if cls.is(pyast::NodeExprSetComp::static_type()) { - ruff::Expr::SetComp(ruff::ExprSetComp::ast_from_object(vm, source_code, object)?) + Self::SetComp(ruff::ExprSetComp::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprDictComp::static_type()) { - ruff::Expr::DictComp(ruff::ExprDictComp::ast_from_object( + Self::DictComp(ruff::ExprDictComp::ast_from_object( vm, source_code, object, )?) } else if cls.is(pyast::NodeExprGeneratorExp::static_type()) { - ruff::Expr::Generator(ruff::ExprGenerator::ast_from_object( + Self::Generator(ruff::ExprGenerator::ast_from_object( vm, source_code, object, )?) } else if cls.is(pyast::NodeExprAwait::static_type()) { - ruff::Expr::Await(ruff::ExprAwait::ast_from_object(vm, source_code, object)?) + Self::Await(ruff::ExprAwait::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprYield::static_type()) { - ruff::Expr::Yield(ruff::ExprYield::ast_from_object(vm, source_code, object)?) + Self::Yield(ruff::ExprYield::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprYieldFrom::static_type()) { - ruff::Expr::YieldFrom(ruff::ExprYieldFrom::ast_from_object( + Self::YieldFrom(ruff::ExprYieldFrom::ast_from_object( vm, source_code, object, )?) } else if cls.is(pyast::NodeExprCompare::static_type()) { - ruff::Expr::Compare(ruff::ExprCompare::ast_from_object(vm, source_code, object)?) + Self::Compare(ruff::ExprCompare::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprCall::static_type()) { - ruff::Expr::Call(ruff::ExprCall::ast_from_object(vm, source_code, object)?) + Self::Call(ruff::ExprCall::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprAttribute::static_type()) { - ruff::Expr::Attribute(ruff::ExprAttribute::ast_from_object( + Self::Attribute(ruff::ExprAttribute::ast_from_object( vm, source_code, object, )?) } else if cls.is(pyast::NodeExprSubscript::static_type()) { - ruff::Expr::Subscript(ruff::ExprSubscript::ast_from_object( + Self::Subscript(ruff::ExprSubscript::ast_from_object( vm, source_code, object, )?) } else if cls.is(pyast::NodeExprStarred::static_type()) { - ruff::Expr::Starred(ruff::ExprStarred::ast_from_object(vm, source_code, object)?) + Self::Starred(ruff::ExprStarred::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprName::static_type()) { - ruff::Expr::Name(ruff::ExprName::ast_from_object(vm, source_code, object)?) + Self::Name(ruff::ExprName::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprList::static_type()) { - ruff::Expr::List(ruff::ExprList::ast_from_object(vm, source_code, object)?) + Self::List(ruff::ExprList::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprTuple::static_type()) { - ruff::Expr::Tuple(ruff::ExprTuple::ast_from_object(vm, source_code, object)?) + Self::Tuple(ruff::ExprTuple::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprSlice::static_type()) { - ruff::Expr::Slice(ruff::ExprSlice::ast_from_object(vm, source_code, object)?) + Self::Slice(ruff::ExprSlice::ast_from_object(vm, source_code, object)?) } else if cls.is(pyast::NodeExprConstant::static_type()) { Constant::ast_from_object(vm, source_code, object)?.into_expr() } else if cls.is(pyast::NodeExprJoinedStr::static_type()) { @@ -145,6 +138,7 @@ impl Node for ruff::Expr { }) } } + // constructor impl Node for ruff::ExprBoolOp { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -160,6 +154,7 @@ impl Node for ruff::ExprBoolOp { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -180,6 +175,7 @@ impl Node for ruff::ExprBoolOp { }) } } + // constructor impl Node for ruff::ExprNamed { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -199,6 +195,7 @@ impl Node for ruff::ExprNamed { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -219,6 +216,7 @@ impl Node for ruff::ExprNamed { }) } } + // constructor impl Node for ruff::ExprBinOp { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -241,6 +239,7 @@ impl Node for ruff::ExprBinOp { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -266,6 +265,7 @@ impl Node for ruff::ExprBinOp { }) } } + // constructor impl Node for ruff::ExprUnaryOp { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -301,6 +301,7 @@ impl Node for ruff::ExprUnaryOp { }) } } + // constructor impl Node for ruff::ExprLambda { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -320,6 +321,7 @@ impl Node for ruff::ExprLambda { node_add_location(&dict, _range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -340,6 +342,7 @@ impl Node for ruff::ExprLambda { }) } } + // constructor impl Node for ruff::ExprIf { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -362,6 +365,7 @@ impl Node for ruff::ExprIf { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -387,6 +391,7 @@ impl Node for ruff::ExprIf { }) } } + // constructor impl Node for ruff::ExprDict { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -410,6 +415,7 @@ impl Node for ruff::ExprDict { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -436,6 +442,7 @@ impl Node for ruff::ExprDict { }) } } + // constructor impl Node for ruff::ExprSet { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -464,6 +471,7 @@ impl Node for ruff::ExprSet { }) } } + // constructor impl Node for ruff::ExprListComp { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -483,6 +491,7 @@ impl Node for ruff::ExprListComp { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -503,6 +512,7 @@ impl Node for ruff::ExprListComp { }) } } + // constructor impl Node for ruff::ExprSetComp { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -522,6 +532,7 @@ impl Node for ruff::ExprSetComp { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -542,6 +553,7 @@ impl Node for ruff::ExprSetComp { }) } } + // constructor impl Node for ruff::ExprDictComp { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -564,6 +576,7 @@ impl Node for ruff::ExprDictComp { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -589,6 +602,7 @@ impl Node for ruff::ExprDictComp { }) } } + // constructor impl Node for ruff::ExprGenerator { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -609,6 +623,7 @@ impl Node for ruff::ExprGenerator { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -631,6 +646,7 @@ impl Node for ruff::ExprGenerator { }) } } + // constructor impl Node for ruff::ExprAwait { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -659,6 +675,7 @@ impl Node for ruff::ExprAwait { }) } } + // constructor impl Node for ruff::ExprYield { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -672,6 +689,7 @@ impl Node for ruff::ExprYield { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -685,6 +703,7 @@ impl Node for ruff::ExprYield { }) } } + // constructor impl Node for ruff::ExprYieldFrom { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -698,6 +717,7 @@ impl Node for ruff::ExprYieldFrom { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -713,6 +733,7 @@ impl Node for ruff::ExprYieldFrom { }) } } + // constructor impl Node for ruff::ExprCompare { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -739,6 +760,7 @@ impl Node for ruff::ExprCompare { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -770,6 +792,7 @@ impl Node for ruff::ExprCompare { }) } } + // constructor impl Node for ruff::ExprCall { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -800,6 +823,7 @@ impl Node for ruff::ExprCall { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -850,6 +874,7 @@ impl Node for ruff::ExprAttribute { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -875,6 +900,7 @@ impl Node for ruff::ExprAttribute { }) } } + // constructor impl Node for ruff::ExprSubscript { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -922,6 +948,7 @@ impl Node for ruff::ExprSubscript { }) } } + // constructor impl Node for ruff::ExprStarred { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -957,6 +984,7 @@ impl Node for ruff::ExprStarred { }) } } + // constructor impl Node for ruff::ExprName { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -971,6 +999,7 @@ impl Node for ruff::ExprName { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -987,6 +1016,7 @@ impl Node for ruff::ExprName { }) } } + // constructor impl Node for ruff::ExprList { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -1002,6 +1032,7 @@ impl Node for ruff::ExprList { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -1022,6 +1053,7 @@ impl Node for ruff::ExprList { }) } } + // constructor impl Node for ruff::ExprTuple { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -1042,6 +1074,7 @@ impl Node for ruff::ExprTuple { node_add_location(&dict, _range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -1063,6 +1096,7 @@ impl Node for ruff::ExprTuple { }) } } + // constructor impl Node for ruff::ExprSlice { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -1085,6 +1119,7 @@ impl Node for ruff::ExprSlice { node_add_location(&dict, _range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -1104,14 +1139,15 @@ impl Node for ruff::ExprSlice { }) } } + // sum impl Node for ruff::ExprContext { fn ast_to_object(self, vm: &VirtualMachine, _source_code: &SourceCodeOwned) -> PyObjectRef { let node_type = match self { - ruff::ExprContext::Load => pyast::NodeExprContextLoad::static_type(), - ruff::ExprContext::Store => pyast::NodeExprContextStore::static_type(), - ruff::ExprContext::Del => pyast::NodeExprContextDel::static_type(), - ruff::ExprContext::Invalid => { + Self::Load => pyast::NodeExprContextLoad::static_type(), + Self::Store => pyast::NodeExprContextStore::static_type(), + Self::Del => pyast::NodeExprContextDel::static_type(), + Self::Invalid => { unimplemented!("Invalid expression context is not allowed in Python AST") } }; @@ -1120,6 +1156,7 @@ impl Node for ruff::ExprContext { .unwrap() .into() } + fn ast_from_object( vm: &VirtualMachine, _source_code: &SourceCodeOwned, @@ -1127,11 +1164,11 @@ impl Node for ruff::ExprContext { ) -> PyResult { let _cls = object.class(); Ok(if _cls.is(pyast::NodeExprContextLoad::static_type()) { - ruff::ExprContext::Load + Self::Load } else if _cls.is(pyast::NodeExprContextStore::static_type()) { - ruff::ExprContext::Store + Self::Store } else if _cls.is(pyast::NodeExprContextDel::static_type()) { - ruff::ExprContext::Del + Self::Del } else { return Err(vm.new_type_error(format!( "expected some sort of expr_context, but got {}", @@ -1165,6 +1202,7 @@ impl Node for ruff::Comprehension { .unwrap(); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, diff --git a/vm/src/stdlib/ast/module.rs b/vm/src/stdlib/ast/module.rs index 480ced0b6f7..409d8368086 100644 --- a/vm/src/stdlib/ast/module.rs +++ b/vm/src/stdlib/ast/module.rs @@ -33,6 +33,7 @@ impl Node for Mod { Self::FunctionType(cons) => cons.ast_to_object(vm, source_code), } } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -59,10 +60,11 @@ impl Node for Mod { }) } } + // constructor impl Node for ruff::ModModule { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { - let ruff::ModModule { + let Self { body, // type_ignores, range, @@ -85,12 +87,13 @@ impl Node for ruff::ModModule { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, object: PyObjectRef, ) -> PyResult { - Ok(ruff::ModModule { + Ok(Self { body: Node::ast_from_object( vm, source_code, @@ -123,6 +126,7 @@ impl Node for ModInteractive { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -138,6 +142,7 @@ impl Node for ModInteractive { }) } } + // constructor impl Node for ruff::ModExpression { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -151,6 +156,7 @@ impl Node for ruff::ModExpression { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -176,7 +182,7 @@ pub(super) struct ModFunctionType { // constructor impl Node for ModFunctionType { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { - let ModFunctionType { + let Self { argtypes, returns, range, @@ -196,12 +202,13 @@ impl Node for ModFunctionType { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, object: PyObjectRef, ) -> PyResult { - Ok(ModFunctionType { + Ok(Self { argtypes: { let argtypes: BoxedSlice<_> = Node::ast_from_object( vm, diff --git a/vm/src/stdlib/ast/node.rs b/vm/src/stdlib/ast/node.rs index 03c62d7eb92..bf56f6683d4 100644 --- a/vm/src/stdlib/ast/node.rs +++ b/vm/src/stdlib/ast/node.rs @@ -8,6 +8,7 @@ pub(crate) trait Node: Sized { source_code: &SourceCodeOwned, object: PyObjectRef, ) -> PyResult; + /// Used in `Option::ast_from_object`; if `true`, that impl will return None. fn is_none(&self) -> bool { false @@ -44,7 +45,7 @@ impl Node for Box { source_code: &SourceCodeOwned, object: PyObjectRef, ) -> PyResult { - T::ast_from_object(vm, source_code, object).map(Box::new) + T::ast_from_object(vm, source_code, object).map(Self::new) } fn is_none(&self) -> bool { diff --git a/vm/src/stdlib/ast/operator.rs b/vm/src/stdlib/ast/operator.rs index bf11c5e1c0b..fbb2af68c54 100644 --- a/vm/src/stdlib/ast/operator.rs +++ b/vm/src/stdlib/ast/operator.rs @@ -4,14 +4,15 @@ use super::*; impl Node for ruff::BoolOp { fn ast_to_object(self, vm: &VirtualMachine, _source_code: &SourceCodeOwned) -> PyObjectRef { let node_type = match self { - ruff::BoolOp::And => pyast::NodeBoolOpAnd::static_type(), - ruff::BoolOp::Or => pyast::NodeBoolOpOr::static_type(), + Self::And => pyast::NodeBoolOpAnd::static_type(), + Self::Or => pyast::NodeBoolOpOr::static_type(), }; NodeAst .into_ref_with_type(vm, node_type.to_owned()) .unwrap() .into() } + fn ast_from_object( _vm: &VirtualMachine, _source_code: &SourceCodeOwned, @@ -19,9 +20,9 @@ impl Node for ruff::BoolOp { ) -> PyResult { let _cls = _object.class(); Ok(if _cls.is(pyast::NodeBoolOpAnd::static_type()) { - ruff::BoolOp::And + Self::And } else if _cls.is(pyast::NodeBoolOpOr::static_type()) { - ruff::BoolOp::Or + Self::Or } else { return Err(_vm.new_type_error(format!( "expected some sort of boolop, but got {}", @@ -30,29 +31,31 @@ impl Node for ruff::BoolOp { }) } } + // sum impl Node for ruff::Operator { fn ast_to_object(self, vm: &VirtualMachine, _source_code: &SourceCodeOwned) -> PyObjectRef { let node_type = match self { - ruff::Operator::Add => pyast::NodeOperatorAdd::static_type(), - ruff::Operator::Sub => pyast::NodeOperatorSub::static_type(), - ruff::Operator::Mult => pyast::NodeOperatorMult::static_type(), - ruff::Operator::MatMult => pyast::NodeOperatorMatMult::static_type(), - ruff::Operator::Div => pyast::NodeOperatorDiv::static_type(), - ruff::Operator::Mod => pyast::NodeOperatorMod::static_type(), - ruff::Operator::Pow => pyast::NodeOperatorPow::static_type(), - ruff::Operator::LShift => pyast::NodeOperatorLShift::static_type(), - ruff::Operator::RShift => pyast::NodeOperatorRShift::static_type(), - ruff::Operator::BitOr => pyast::NodeOperatorBitOr::static_type(), - ruff::Operator::BitXor => pyast::NodeOperatorBitXor::static_type(), - ruff::Operator::BitAnd => pyast::NodeOperatorBitAnd::static_type(), - ruff::Operator::FloorDiv => pyast::NodeOperatorFloorDiv::static_type(), + Self::Add => pyast::NodeOperatorAdd::static_type(), + Self::Sub => pyast::NodeOperatorSub::static_type(), + Self::Mult => pyast::NodeOperatorMult::static_type(), + Self::MatMult => pyast::NodeOperatorMatMult::static_type(), + Self::Div => pyast::NodeOperatorDiv::static_type(), + Self::Mod => pyast::NodeOperatorMod::static_type(), + Self::Pow => pyast::NodeOperatorPow::static_type(), + Self::LShift => pyast::NodeOperatorLShift::static_type(), + Self::RShift => pyast::NodeOperatorRShift::static_type(), + Self::BitOr => pyast::NodeOperatorBitOr::static_type(), + Self::BitXor => pyast::NodeOperatorBitXor::static_type(), + Self::BitAnd => pyast::NodeOperatorBitAnd::static_type(), + Self::FloorDiv => pyast::NodeOperatorFloorDiv::static_type(), }; NodeAst .into_ref_with_type(vm, node_type.to_owned()) .unwrap() .into() } + fn ast_from_object( _vm: &VirtualMachine, _source_code: &SourceCodeOwned, @@ -60,31 +63,31 @@ impl Node for ruff::Operator { ) -> PyResult { let _cls = _object.class(); Ok(if _cls.is(pyast::NodeOperatorAdd::static_type()) { - ruff::Operator::Add + Self::Add } else if _cls.is(pyast::NodeOperatorSub::static_type()) { - ruff::Operator::Sub + Self::Sub } else if _cls.is(pyast::NodeOperatorMult::static_type()) { - ruff::Operator::Mult + Self::Mult } else if _cls.is(pyast::NodeOperatorMatMult::static_type()) { - ruff::Operator::MatMult + Self::MatMult } else if _cls.is(pyast::NodeOperatorDiv::static_type()) { - ruff::Operator::Div + Self::Div } else if _cls.is(pyast::NodeOperatorMod::static_type()) { - ruff::Operator::Mod + Self::Mod } else if _cls.is(pyast::NodeOperatorPow::static_type()) { - ruff::Operator::Pow + Self::Pow } else if _cls.is(pyast::NodeOperatorLShift::static_type()) { - ruff::Operator::LShift + Self::LShift } else if _cls.is(pyast::NodeOperatorRShift::static_type()) { - ruff::Operator::RShift + Self::RShift } else if _cls.is(pyast::NodeOperatorBitOr::static_type()) { - ruff::Operator::BitOr + Self::BitOr } else if _cls.is(pyast::NodeOperatorBitXor::static_type()) { - ruff::Operator::BitXor + Self::BitXor } else if _cls.is(pyast::NodeOperatorBitAnd::static_type()) { - ruff::Operator::BitAnd + Self::BitAnd } else if _cls.is(pyast::NodeOperatorFloorDiv::static_type()) { - ruff::Operator::FloorDiv + Self::FloorDiv } else { return Err(_vm.new_type_error(format!( "expected some sort of operator, but got {}", @@ -93,20 +96,22 @@ impl Node for ruff::Operator { }) } } + // sum impl Node for ruff::UnaryOp { fn ast_to_object(self, vm: &VirtualMachine, _source_code: &SourceCodeOwned) -> PyObjectRef { let node_type = match self { - ruff::UnaryOp::Invert => pyast::NodeUnaryOpInvert::static_type(), - ruff::UnaryOp::Not => pyast::NodeUnaryOpNot::static_type(), - ruff::UnaryOp::UAdd => pyast::NodeUnaryOpUAdd::static_type(), - ruff::UnaryOp::USub => pyast::NodeUnaryOpUSub::static_type(), + Self::Invert => pyast::NodeUnaryOpInvert::static_type(), + Self::Not => pyast::NodeUnaryOpNot::static_type(), + Self::UAdd => pyast::NodeUnaryOpUAdd::static_type(), + Self::USub => pyast::NodeUnaryOpUSub::static_type(), }; NodeAst .into_ref_with_type(vm, node_type.to_owned()) .unwrap() .into() } + fn ast_from_object( _vm: &VirtualMachine, _source_code: &SourceCodeOwned, @@ -114,13 +119,13 @@ impl Node for ruff::UnaryOp { ) -> PyResult { let _cls = _object.class(); Ok(if _cls.is(pyast::NodeUnaryOpInvert::static_type()) { - ruff::UnaryOp::Invert + Self::Invert } else if _cls.is(pyast::NodeUnaryOpNot::static_type()) { - ruff::UnaryOp::Not + Self::Not } else if _cls.is(pyast::NodeUnaryOpUAdd::static_type()) { - ruff::UnaryOp::UAdd + Self::UAdd } else if _cls.is(pyast::NodeUnaryOpUSub::static_type()) { - ruff::UnaryOp::USub + Self::USub } else { return Err(_vm.new_type_error(format!( "expected some sort of unaryop, but got {}", @@ -129,26 +134,28 @@ impl Node for ruff::UnaryOp { }) } } + // sum impl Node for ruff::CmpOp { fn ast_to_object(self, vm: &VirtualMachine, _source_code: &SourceCodeOwned) -> PyObjectRef { let node_type = match self { - ruff::CmpOp::Eq => pyast::NodeCmpOpEq::static_type(), - ruff::CmpOp::NotEq => pyast::NodeCmpOpNotEq::static_type(), - ruff::CmpOp::Lt => pyast::NodeCmpOpLt::static_type(), - ruff::CmpOp::LtE => pyast::NodeCmpOpLtE::static_type(), - ruff::CmpOp::Gt => pyast::NodeCmpOpGt::static_type(), - ruff::CmpOp::GtE => pyast::NodeCmpOpGtE::static_type(), - ruff::CmpOp::Is => pyast::NodeCmpOpIs::static_type(), - ruff::CmpOp::IsNot => pyast::NodeCmpOpIsNot::static_type(), - ruff::CmpOp::In => pyast::NodeCmpOpIn::static_type(), - ruff::CmpOp::NotIn => pyast::NodeCmpOpNotIn::static_type(), + Self::Eq => pyast::NodeCmpOpEq::static_type(), + Self::NotEq => pyast::NodeCmpOpNotEq::static_type(), + Self::Lt => pyast::NodeCmpOpLt::static_type(), + Self::LtE => pyast::NodeCmpOpLtE::static_type(), + Self::Gt => pyast::NodeCmpOpGt::static_type(), + Self::GtE => pyast::NodeCmpOpGtE::static_type(), + Self::Is => pyast::NodeCmpOpIs::static_type(), + Self::IsNot => pyast::NodeCmpOpIsNot::static_type(), + Self::In => pyast::NodeCmpOpIn::static_type(), + Self::NotIn => pyast::NodeCmpOpNotIn::static_type(), }; NodeAst .into_ref_with_type(vm, node_type.to_owned()) .unwrap() .into() } + fn ast_from_object( _vm: &VirtualMachine, _source_code: &SourceCodeOwned, @@ -156,25 +163,25 @@ impl Node for ruff::CmpOp { ) -> PyResult { let _cls = _object.class(); Ok(if _cls.is(pyast::NodeCmpOpEq::static_type()) { - ruff::CmpOp::Eq + Self::Eq } else if _cls.is(pyast::NodeCmpOpNotEq::static_type()) { - ruff::CmpOp::NotEq + Self::NotEq } else if _cls.is(pyast::NodeCmpOpLt::static_type()) { - ruff::CmpOp::Lt + Self::Lt } else if _cls.is(pyast::NodeCmpOpLtE::static_type()) { - ruff::CmpOp::LtE + Self::LtE } else if _cls.is(pyast::NodeCmpOpGt::static_type()) { - ruff::CmpOp::Gt + Self::Gt } else if _cls.is(pyast::NodeCmpOpGtE::static_type()) { - ruff::CmpOp::GtE + Self::GtE } else if _cls.is(pyast::NodeCmpOpIs::static_type()) { - ruff::CmpOp::Is + Self::Is } else if _cls.is(pyast::NodeCmpOpIsNot::static_type()) { - ruff::CmpOp::IsNot + Self::IsNot } else if _cls.is(pyast::NodeCmpOpIn::static_type()) { - ruff::CmpOp::In + Self::In } else if _cls.is(pyast::NodeCmpOpNotIn::static_type()) { - ruff::CmpOp::NotIn + Self::NotIn } else { return Err(_vm.new_type_error(format!( "expected some sort of cmpop, but got {}", diff --git a/vm/src/stdlib/ast/other.rs b/vm/src/stdlib/ast/other.rs index df70bc53f3c..9003584896d 100644 --- a/vm/src/stdlib/ast/other.rs +++ b/vm/src/stdlib/ast/other.rs @@ -55,7 +55,7 @@ impl Node for ruff::Decorator { ) -> PyResult { let expression = ruff::Expr::ast_from_object(vm, source_code, object)?; let range = expression.range(); - Ok(ruff::Decorator { expression, range }) + Ok(Self { expression, range }) } } @@ -78,6 +78,7 @@ impl Node for ruff::Alias { node_add_location(&dict, _range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -96,6 +97,7 @@ impl Node for ruff::Alias { }) } } + // product impl Node for ruff::WithItem { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -122,6 +124,7 @@ impl Node for ruff::WithItem { .unwrap(); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, diff --git a/vm/src/stdlib/ast/parameter.rs b/vm/src/stdlib/ast/parameter.rs index 82c22d020c5..b8bbfc97056 100644 --- a/vm/src/stdlib/ast/parameter.rs +++ b/vm/src/stdlib/ast/parameter.rs @@ -43,6 +43,7 @@ impl Node for ruff::Parameters { node_add_location(&dict, range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -95,6 +96,7 @@ impl Node for ruff::Parameters { self.is_empty() } } + // product impl Node for ruff::Parameter { fn ast_to_object(self, _vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -125,6 +127,7 @@ impl Node for ruff::Parameter { node_add_location(&dict, range, _vm, source_code); node.into() } + fn ast_from_object( _vm: &VirtualMachine, source_code: &SourceCodeOwned, diff --git a/vm/src/stdlib/ast/pattern.rs b/vm/src/stdlib/ast/pattern.rs index df5adefebf7..70573099892 100644 --- a/vm/src/stdlib/ast/pattern.rs +++ b/vm/src/stdlib/ast/pattern.rs @@ -21,6 +21,7 @@ impl Node for ruff::MatchCase { .unwrap(); node.into() } + fn ast_from_object( _vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -44,18 +45,19 @@ impl Node for ruff::MatchCase { }) } } + // sum impl Node for ruff::Pattern { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { match self { - ruff::Pattern::MatchValue(cons) => cons.ast_to_object(vm, source_code), - ruff::Pattern::MatchSingleton(cons) => cons.ast_to_object(vm, source_code), - ruff::Pattern::MatchSequence(cons) => cons.ast_to_object(vm, source_code), - ruff::Pattern::MatchMapping(cons) => cons.ast_to_object(vm, source_code), - ruff::Pattern::MatchClass(cons) => cons.ast_to_object(vm, source_code), - ruff::Pattern::MatchStar(cons) => cons.ast_to_object(vm, source_code), - ruff::Pattern::MatchAs(cons) => cons.ast_to_object(vm, source_code), - ruff::Pattern::MatchOr(cons) => cons.ast_to_object(vm, source_code), + Self::MatchValue(cons) => cons.ast_to_object(vm, source_code), + Self::MatchSingleton(cons) => cons.ast_to_object(vm, source_code), + Self::MatchSequence(cons) => cons.ast_to_object(vm, source_code), + Self::MatchMapping(cons) => cons.ast_to_object(vm, source_code), + Self::MatchClass(cons) => cons.ast_to_object(vm, source_code), + Self::MatchStar(cons) => cons.ast_to_object(vm, source_code), + Self::MatchAs(cons) => cons.ast_to_object(vm, source_code), + Self::MatchOr(cons) => cons.ast_to_object(vm, source_code), } } fn ast_from_object( @@ -65,49 +67,49 @@ impl Node for ruff::Pattern { ) -> PyResult { let _cls = _object.class(); Ok(if _cls.is(pyast::NodePatternMatchValue::static_type()) { - ruff::Pattern::MatchValue(ruff::PatternMatchValue::ast_from_object( + Self::MatchValue(ruff::PatternMatchValue::ast_from_object( _vm, source_code, _object, )?) } else if _cls.is(pyast::NodePatternMatchSingleton::static_type()) { - ruff::Pattern::MatchSingleton(ruff::PatternMatchSingleton::ast_from_object( + Self::MatchSingleton(ruff::PatternMatchSingleton::ast_from_object( _vm, source_code, _object, )?) } else if _cls.is(pyast::NodePatternMatchSequence::static_type()) { - ruff::Pattern::MatchSequence(ruff::PatternMatchSequence::ast_from_object( + Self::MatchSequence(ruff::PatternMatchSequence::ast_from_object( _vm, source_code, _object, )?) } else if _cls.is(pyast::NodePatternMatchMapping::static_type()) { - ruff::Pattern::MatchMapping(ruff::PatternMatchMapping::ast_from_object( + Self::MatchMapping(ruff::PatternMatchMapping::ast_from_object( _vm, source_code, _object, )?) } else if _cls.is(pyast::NodePatternMatchClass::static_type()) { - ruff::Pattern::MatchClass(ruff::PatternMatchClass::ast_from_object( + Self::MatchClass(ruff::PatternMatchClass::ast_from_object( _vm, source_code, _object, )?) } else if _cls.is(pyast::NodePatternMatchStar::static_type()) { - ruff::Pattern::MatchStar(ruff::PatternMatchStar::ast_from_object( + Self::MatchStar(ruff::PatternMatchStar::ast_from_object( _vm, source_code, _object, )?) } else if _cls.is(pyast::NodePatternMatchAs::static_type()) { - ruff::Pattern::MatchAs(ruff::PatternMatchAs::ast_from_object( + Self::MatchAs(ruff::PatternMatchAs::ast_from_object( _vm, source_code, _object, )?) } else if _cls.is(pyast::NodePatternMatchOr::static_type()) { - ruff::Pattern::MatchOr(ruff::PatternMatchOr::ast_from_object( + Self::MatchOr(ruff::PatternMatchOr::ast_from_object( _vm, source_code, _object, @@ -136,6 +138,7 @@ impl Node for ruff::PatternMatchValue { node_add_location(&dict, _range, _vm, source_code); node.into() } + fn ast_from_object( _vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -151,6 +154,7 @@ impl Node for ruff::PatternMatchValue { }) } } + // constructor impl Node for ruff::PatternMatchSingleton { fn ast_to_object(self, _vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -170,6 +174,7 @@ impl Node for ruff::PatternMatchSingleton { node_add_location(&dict, _range, _vm, source_code); node.into() } + fn ast_from_object( _vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -185,6 +190,7 @@ impl Node for ruff::PatternMatchSingleton { }) } } + impl Node for ruff::Singleton { fn ast_to_object(self, _vm: &VirtualMachine, _source_code: &SourceCodeOwned) -> PyObjectRef { todo!() @@ -198,6 +204,7 @@ impl Node for ruff::Singleton { todo!() } } + // constructor impl Node for ruff::PatternMatchSequence { fn ast_to_object(self, _vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -217,6 +224,7 @@ impl Node for ruff::PatternMatchSequence { node_add_location(&dict, _range, _vm, source_code); node.into() } + fn ast_from_object( _vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -232,6 +240,7 @@ impl Node for ruff::PatternMatchSequence { }) } } + // constructor impl Node for ruff::PatternMatchMapping { fn ast_to_object(self, _vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -257,6 +266,7 @@ impl Node for ruff::PatternMatchMapping { node_add_location(&dict, _range, _vm, source_code); node.into() } + fn ast_from_object( _vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -280,6 +290,7 @@ impl Node for ruff::PatternMatchMapping { }) } } + // constructor impl Node for ruff::PatternMatchClass { fn ast_to_object(self, vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -308,6 +319,7 @@ impl Node for ruff::PatternMatchClass { node_add_location(&dict, _range, vm, source_code); node.into() } + fn ast_from_object( vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -415,6 +427,7 @@ impl Node for ruff::PatternMatchStar { node_add_location(&dict, _range, _vm, source_code); node.into() } + fn ast_from_object( _vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -428,6 +441,7 @@ impl Node for ruff::PatternMatchStar { }) } } + // constructor impl Node for ruff::PatternMatchAs { fn ast_to_object(self, _vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { @@ -447,6 +461,7 @@ impl Node for ruff::PatternMatchAs { node_add_location(&dict, _range, _vm, source_code); node.into() } + fn ast_from_object( _vm: &VirtualMachine, source_code: &SourceCodeOwned, @@ -463,6 +478,7 @@ impl Node for ruff::PatternMatchAs { }) } } + // constructor impl Node for ruff::PatternMatchOr { fn ast_to_object(self, _vm: &VirtualMachine, source_code: &SourceCodeOwned) -> PyObjectRef { diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index e1ac84025dc..bdce5ddcfc9 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -252,8 +252,8 @@ mod _io { } impl BufferedIO { - fn new(cursor: Cursor>) -> BufferedIO { - BufferedIO { cursor } + const fn new(cursor: Cursor>) -> Self { + Self { cursor } } fn write(&mut self, data: &[u8]) -> Option { @@ -341,6 +341,7 @@ mod _io { fn file_closed(file: &PyObject, vm: &VirtualMachine) -> PyResult { file.get_attr("closed", vm)?.try_to_bool(vm) } + fn check_closed(file: &PyObject, vm: &VirtualMachine) -> PyResult<()> { if file_closed(file, vm)? { Err(io_closed_error(vm)) @@ -407,14 +408,17 @@ mod _io { ) -> PyResult { _unsupported(vm, &zelf, "seek") } + #[pymethod] fn tell(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult { vm.call_method(&zelf, "seek", (0, 1)) } + #[pymethod] fn truncate(zelf: PyObjectRef, _pos: OptionalArg, vm: &VirtualMachine) -> PyResult { _unsupported(vm, &zelf, "truncate") } + #[pymethod] fn fileno(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult { _unsupported(vm, &zelf, "truncate") @@ -447,10 +451,12 @@ mod _io { fn seekable(_self: PyObjectRef) -> bool { false } + #[pymethod] fn readable(_self: PyObjectRef) -> bool { false } + #[pymethod] fn writable(_self: PyObjectRef) -> bool { false @@ -668,10 +674,12 @@ mod _io { fn read(zelf: PyObjectRef, _size: OptionalArg, vm: &VirtualMachine) -> PyResult { _unsupported(vm, &zelf, "read") } + #[pymethod] fn read1(zelf: PyObjectRef, _size: OptionalArg, vm: &VirtualMachine) -> PyResult { _unsupported(vm, &zelf, "read1") } + fn _readinto( zelf: PyObjectRef, buf_obj: PyObjectRef, @@ -701,14 +709,17 @@ mod _io { fn readinto(zelf: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult { Self::_readinto(zelf, b, "read", vm) } + #[pymethod] fn readinto1(zelf: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult { Self::_readinto(zelf, b, "read1", vm) } + #[pymethod] fn write(zelf: PyObjectRef, _b: PyObjectRef, vm: &VirtualMachine) -> PyResult { _unsupported(vm, &zelf, "write") } + #[pymethod] fn detach(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult { _unsupported(vm, &zelf, "detach") @@ -775,6 +786,7 @@ mod _io { fn writable(&self) -> bool { self.flags.contains(BufferedFlags::WRITABLE) } + #[inline] fn readable(&self) -> bool { self.flags.contains(BufferedFlags::READABLE) @@ -784,6 +796,7 @@ mod _io { fn valid_read(&self) -> bool { self.readable() && self.read_end != -1 } + #[inline] fn valid_write(&self) -> bool { self.writable() && self.write_end != -1 @@ -797,6 +810,7 @@ mod _io { 0 } } + #[inline] fn readahead(&self) -> Offset { if self.valid_read() { @@ -809,6 +823,7 @@ mod _io { fn reset_read(&mut self) { self.read_end = -1; } + fn reset_write(&mut self) { self.write_pos = 0; self.write_end = -1; @@ -1393,7 +1408,9 @@ mod _io { const READABLE: bool; const WRITABLE: bool; const SEEKABLE: bool = false; + fn data(&self) -> &PyThreadMutex; + fn lock(&self, vm: &VirtualMachine) -> PyResult> { self.data() .lock() @@ -1462,6 +1479,7 @@ mod _io { Ok(()) } + #[pymethod] fn seek( &self, @@ -1480,6 +1498,7 @@ mod _io { let target = get_offset(target, vm)?; data.seek(target, whence, vm) } + #[pymethod] fn tell(&self, vm: &VirtualMachine) -> PyResult { let mut data = self.lock(vm)?; @@ -1492,6 +1511,7 @@ mod _io { } Ok(pos) } + #[pymethod] fn truncate( zelf: PyRef, @@ -1517,30 +1537,37 @@ mod _io { .take() .ok_or_else(|| vm.new_value_error("raw stream has been detached")) } + #[pymethod] fn seekable(&self, vm: &VirtualMachine) -> PyResult { vm.call_method(self.lock(vm)?.check_init(vm)?, "seekable", ()) } + #[pygetset] fn raw(&self, vm: &VirtualMachine) -> PyResult> { Ok(self.lock(vm)?.raw.clone()) } + #[pygetset] fn closed(&self, vm: &VirtualMachine) -> PyResult { self.lock(vm)?.check_init(vm)?.get_attr("closed", vm) } + #[pygetset] fn name(&self, vm: &VirtualMachine) -> PyResult { self.lock(vm)?.check_init(vm)?.get_attr("name", vm) } + #[pygetset] fn mode(&self, vm: &VirtualMachine) -> PyResult { self.lock(vm)?.check_init(vm)?.get_attr("mode", vm) } + #[pymethod] fn fileno(&self, vm: &VirtualMachine) -> PyResult { vm.call_method(self.lock(vm)?.check_init(vm)?, "fileno", ()) } + #[pymethod] fn isatty(&self, vm: &VirtualMachine) -> PyResult { vm.call_method(self.lock(vm)?.check_init(vm)?, "isatty", ()) @@ -1595,6 +1622,7 @@ mod _io { fn readable(&self) -> bool { Self::READABLE } + #[pymethod] fn writable(&self) -> bool { Self::WRITABLE @@ -1610,7 +1638,9 @@ mod _io { #[pyclass] trait BufferedReadable: PyPayload { type Reader: BufferedMixin; + fn reader(&self) -> &Self::Reader; + #[pymethod] fn read(&self, size: OptionalSize, vm: &VirtualMachine) -> PyResult> { let mut data = self.reader().lock(vm)?; @@ -1627,6 +1657,7 @@ mod _io { None => data.read_all(vm), } } + #[pymethod] fn peek(&self, _size: OptionalSize, vm: &VirtualMachine) -> PyResult> { let mut data = self.reader().lock(vm)?; @@ -1638,6 +1669,7 @@ mod _io { } data.peek(vm) } + #[pymethod] fn read1(&self, size: OptionalSize, vm: &VirtualMachine) -> PyResult> { let mut data = self.reader().lock(vm)?; @@ -1661,6 +1693,7 @@ mod _io { v.shrink_to_fit(); Ok(v) } + #[pymethod] fn readinto(&self, buf: ArgMemoryBuffer, vm: &VirtualMachine) -> PyResult> { let mut data = self.reader().lock(vm)?; @@ -1668,6 +1701,7 @@ mod _io { ensure_unclosed(raw, "readinto of closed file", vm)?; data.readinto_generic(buf.into(), false, vm) } + #[pymethod] fn readinto1(&self, buf: ArgMemoryBuffer, vm: &VirtualMachine) -> PyResult> { let mut data = self.reader().lock(vm)?; @@ -1694,16 +1728,20 @@ mod _io { struct BufferedReader { data: PyThreadMutex, } + impl BufferedMixin for BufferedReader { const CLASS_NAME: &'static str = "BufferedReader"; const READABLE: bool = true; const WRITABLE: bool = false; + fn data(&self) -> &PyThreadMutex { &self.data } } + impl BufferedReadable for BufferedReader { type Reader = Self; + fn reader(&self) -> &Self::Reader { self } @@ -1720,7 +1758,9 @@ mod _io { #[pyclass] trait BufferedWritable: PyPayload { type Writer: BufferedMixin; + fn writer(&self) -> &Self::Writer; + #[pymethod] fn write(&self, obj: ArgBytesLike, vm: &VirtualMachine) -> PyResult { let mut data = self.writer().lock(vm)?; @@ -1729,6 +1769,7 @@ mod _io { data.write(obj, vm) } + #[pymethod] fn flush(&self, vm: &VirtualMachine) -> PyResult<()> { let mut data = self.writer().lock(vm)?; @@ -1744,16 +1785,20 @@ mod _io { struct BufferedWriter { data: PyThreadMutex, } + impl BufferedMixin for BufferedWriter { const CLASS_NAME: &'static str = "BufferedWriter"; const READABLE: bool = false; const WRITABLE: bool = true; + fn data(&self) -> &PyThreadMutex { &self.data } } + impl BufferedWritable for BufferedWriter { type Writer = Self; + fn writer(&self) -> &Self::Writer { self } @@ -1773,23 +1818,29 @@ mod _io { struct BufferedRandom { data: PyThreadMutex, } + impl BufferedMixin for BufferedRandom { const CLASS_NAME: &'static str = "BufferedRandom"; const READABLE: bool = true; const WRITABLE: bool = true; const SEEKABLE: bool = true; + fn data(&self) -> &PyThreadMutex { &self.data } } + impl BufferedReadable for BufferedRandom { type Reader = Self; + fn reader(&self) -> &Self::Reader { self } } + impl BufferedWritable for BufferedRandom { type Writer = Self; + fn writer(&self) -> &Self::Writer { self } @@ -1810,14 +1861,18 @@ mod _io { read: BufferedReader, write: BufferedWriter, } + impl BufferedReadable for BufferedRWPair { type Reader = BufferedReader; + fn reader(&self) -> &Self::Reader { &self.read } } + impl BufferedWritable for BufferedRWPair { type Writer = BufferedWriter; + fn writer(&self) -> &Self::Writer { &self.write } @@ -1850,11 +1905,11 @@ mod _io { } #[pymethod] - fn readable(&self) -> bool { + const fn readable(&self) -> bool { true } #[pymethod] - fn writable(&self) -> bool { + const fn writable(&self) -> bool { true } @@ -1986,29 +2041,33 @@ mod _io { bytes: usize, chars: usize, } + impl Utf8size { fn len_pystr(s: &PyStr) -> Self { - Utf8size { + Self { bytes: s.byte_len(), chars: s.char_len(), } } fn len_str(s: &Wtf8) -> Self { - Utf8size { + Self { bytes: s.len(), chars: s.code_points().count(), } } } + impl std::ops::Add for Utf8size { type Output = Self; + #[inline] fn add(mut self, rhs: Self) -> Self { self += rhs; self } } + impl std::ops::AddAssign for Utf8size { #[inline] fn add_assign(&mut self, rhs: Self) { @@ -2016,14 +2075,17 @@ mod _io { self.chars += rhs.chars; } } + impl std::ops::Sub for Utf8size { type Output = Self; + #[inline] fn sub(mut self, rhs: Self) -> Self { self -= rhs; self } } + impl std::ops::SubAssign for Utf8size { #[inline] fn sub_assign(&mut self, rhs: Self) { @@ -2137,6 +2199,7 @@ mod _io { const NEED_EOF_OFF: usize = Self::CHARS_TO_SKIP_OFF + 4; const BYTES_TO_SKIP_OFF: usize = Self::NEED_EOF_OFF + 1; const BYTE_LEN: usize = Self::BYTES_TO_SKIP_OFF + 4; + fn parse(cookie: &BigInt) -> Option { let (_, mut buf) = cookie.to_bytes_le(); if buf.len() > Self::BYTE_LEN { @@ -2153,7 +2216,7 @@ mod _io { ) }}; } - Some(TextIOCookie { + Some(Self { start_pos: get_field!(Offset, START_POS_OFF), dec_flags: get_field!(i32, DEC_FLAGS_OFF), bytes_to_feed: get_field!(i32, BYTES_TO_FEED_OFF), @@ -2162,6 +2225,7 @@ mod _io { bytes_to_skip: get_field!(i32, BYTES_TO_SKIP_OFF), }) } + fn build(&self) -> BigInt { let mut buf = [0; Self::BYTE_LEN]; macro_rules! set_field { @@ -2179,6 +2243,7 @@ mod _io { set_field!(self.bytes_to_skip, BYTES_TO_SKIP_OFF); BigUint::from_bytes_le(&buf).into() } + fn set_decoder_state(&self, decoder: &PyObject, vm: &VirtualMachine) -> PyResult<()> { if self.start_pos == 0 && self.dec_flags == 0 { vm.call_method(decoder, "reset", ())?; @@ -2191,12 +2256,14 @@ mod _io { } Ok(()) } - fn num_to_skip(&self) -> Utf8size { + + const fn num_to_skip(&self) -> Utf8size { Utf8size { bytes: self.bytes_to_skip as usize, chars: self.chars_to_skip as usize, } } + fn set_num_to_skip(&mut self, num: Utf8size) { self.bytes_to_skip = num.bytes as i32; self.chars_to_skip = num.chars as i32; @@ -2368,16 +2435,19 @@ mod _io { } Ok(()) } + #[pymethod] fn seekable(&self, vm: &VirtualMachine) -> PyResult { let textio = self.lock(vm)?; vm.call_method(&textio.buffer, "seekable", ()) } + #[pymethod] fn readable(&self, vm: &VirtualMachine) -> PyResult { let textio = self.lock(vm)?; vm.call_method(&textio.buffer, "readable", ()) } + #[pymethod] fn writable(&self, vm: &VirtualMachine) -> PyResult { let textio = self.lock(vm)?; @@ -2664,10 +2734,12 @@ mod _io { let buffer = self.lock(vm)?.buffer.clone(); buffer.get_attr("name", vm) } + #[pygetset] fn encoding(&self, vm: &VirtualMachine) -> PyResult { Ok(self.lock(vm)?.encoding.clone()) } + #[pygetset] fn errors(&self, vm: &VirtualMachine) -> PyResult { Ok(self.lock(vm)?.errors.clone()) @@ -2822,11 +2894,13 @@ mod _io { #[derive(Clone)] struct SlicedStr(PyStrRef, Range); + impl SlicedStr { #[inline] fn byte_len(&self) -> usize { self.1.len() } + #[inline] fn char_len(&self) -> usize { if self.is_full_slice() { @@ -2835,14 +2909,17 @@ mod _io { self.slice().code_points().count() } } + #[inline] fn is_full_slice(&self) -> bool { self.1.len() >= self.0.byte_len() } + #[inline] fn slice(&self) -> &Wtf8 { &self.0.as_wtf8()[self.1.clone()] } + #[inline] fn slice_pystr(self, vm: &VirtualMachine) -> PyStrRef { if self.is_full_slice() { @@ -2852,6 +2929,7 @@ mod _io { PyStr::from(self.slice()).into_ref(&vm.ctx) } } + fn utf8_len(&self) -> Utf8size { Utf8size { bytes: self.byte_len(), @@ -2984,11 +3062,13 @@ mod _io { let close_res = vm.call_method(&buffer, "close", ()).map(drop); exception_chain(flush_res, close_res) } + #[pygetset] fn closed(&self, vm: &VirtualMachine) -> PyResult { let buffer = self.lock(vm)?.buffer.clone(); buffer.get_attr("closed", vm) } + #[pygetset] fn buffer(&self, vm: &VirtualMachine) -> PyResult { Ok(self.lock(vm)?.buffer.clone()) @@ -3029,6 +3109,7 @@ mod _io { vm.call_method(&self.buffer, "write", (data,))?; Ok(()) } + /// returns true on EOF fn read_chunk(&mut self, size_hint: usize, vm: &VirtualMachine) -> PyResult { let decoder = self @@ -3119,10 +3200,12 @@ mod _io { }; Some((chars, chars_used)) } + fn set_decoded_chars(&mut self, s: Option) { self.decoded_chars = s; self.decoded_chars_used = Utf8size::default(); } + fn take_decoded_chars( &mut self, append: Option, @@ -3407,7 +3490,7 @@ mod _io { .flatten() .map_or_else(Vec::new, |v| v.as_bytes().to_vec()); - StringIO { + Self { buffer: PyRwLock::new(BufferedIO::new(Cursor::new(raw_bytes))), closed: AtomicCell::new(false), } @@ -3429,15 +3512,17 @@ mod _io { #[pyclass(flags(BASETYPE, HAS_DICT), with(Constructor))] impl StringIO { #[pymethod] - fn readable(&self) -> bool { + const fn readable(&self) -> bool { true } + #[pymethod] - fn writable(&self) -> bool { + const fn writable(&self) -> bool { true } + #[pymethod] - fn seekable(&self) -> bool { + const fn seekable(&self) -> bool { true } @@ -3530,7 +3615,7 @@ mod _io { .flatten() .map_or_else(Vec::new, |input| input.as_bytes().to_vec()); - BytesIO { + Self { buffer: PyRwLock::new(BufferedIO::new(Cursor::new(raw_bytes))), closed: AtomicCell::new(false), exports: AtomicCell::new(0), @@ -3553,15 +3638,17 @@ mod _io { #[pyclass(flags(BASETYPE, HAS_DICT), with(PyRef, Constructor))] impl BytesIO { #[pymethod] - fn readable(&self) -> bool { + const fn readable(&self) -> bool { true } + #[pymethod] - fn writable(&self) -> bool { + const fn writable(&self) -> bool { true } + #[pymethod] - fn seekable(&self) -> bool { + const fn seekable(&self) -> bool { true } @@ -3698,20 +3785,24 @@ mod _io { Exclusive = b'x', Append = b'a', } + #[repr(u8)] #[derive(Debug)] enum EncodeMode { Text = b't', Bytes = b'b', } + #[derive(Debug)] struct Mode { file: FileMode, encode: EncodeMode, plus: bool, } + impl std::str::FromStr for Mode { type Err = ParseModeError; + fn from_str(s: &str) -> Result { let mut file = None; let mut encode = None; @@ -3747,11 +3838,12 @@ mod _io { let file = file.ok_or(ParseModeError::NoFile)?; let encode = encode.unwrap_or(EncodeMode::Text); - Ok(Mode { file, encode, plus }) + Ok(Self { file, encode, plus }) } } + impl Mode { - fn rawmode(&self) -> &'static str { + const fn rawmode(&self) -> &'static str { match (&self.file, self.plus) { (FileMode::Read, true) => "rb+", (FileMode::Read, false) => "rb", @@ -3764,23 +3856,23 @@ mod _io { } } } + enum ParseModeError { InvalidMode, MultipleFile, MultipleEncode, NoFile, } + impl ParseModeError { fn error_msg(&self, mode_string: &str) -> String { match self { - ParseModeError::InvalidMode => format!("invalid mode: '{mode_string}'"), - ParseModeError::MultipleFile => { + Self::InvalidMode => format!("invalid mode: '{mode_string}'"), + Self::MultipleFile => { "must have exactly one of create/read/write/append mode".to_owned() } - ParseModeError::MultipleEncode => { - "can't have text and binary mode at once".to_owned() - } - ParseModeError::NoFile => { + Self::MultipleEncode => "can't have text and binary mode at once".to_owned(), + Self::NoFile => { "Must have exactly one of create/read/write/append mode and at most one plus" .to_owned() } @@ -3796,6 +3888,7 @@ mod _io { #[pyarg(flatten)] opts: OpenArgs, } + #[pyfunction] fn open(args: IoOpenArgs, vm: &VirtualMachine) -> PyResult { io_open( @@ -3827,6 +3920,7 @@ mod _io { #[pyarg(any, default)] pub opener: Option, } + impl Default for OpenArgs { fn default() -> Self { OpenArgs { @@ -4053,11 +4147,12 @@ mod fileio { Invalid, BadRwa, } + impl ModeError { fn error_msg(&self, mode_str: &str) -> String { match self { - ModeError::Invalid => format!("invalid mode: {mode_str}"), - ModeError::BadRwa => { + Self::Invalid => format!("invalid mode: {mode_str}"), + Self::BadRwa => { "Must have exactly one of create/read/write/append mode and at most one plus" .to_owned() } @@ -4340,10 +4435,12 @@ mod fileio { fn readable(&self) -> bool { self.mode.load().contains(Mode::READABLE) } + #[pymethod] fn writable(&self) -> bool { self.mode.load().contains(Mode::WRITABLE) } + #[pygetset] fn mode(&self) -> &'static str { let mode = self.mode.load(); diff --git a/vm/src/stdlib/marshal.rs b/vm/src/stdlib/marshal.rs index 0faa0d11aac..6aaa5453a10 100644 --- a/vm/src/stdlib/marshal.rs +++ b/vm/src/stdlib/marshal.rs @@ -30,6 +30,7 @@ mod decl { impl marshal::Dumpable for PyObjectRef { type Error = DumpError; type Constant = Literal; + fn with_dump( &self, f: impl FnOnce(marshal::DumpableValue<'_, Self>) -> R, @@ -126,46 +127,60 @@ mod decl { impl<'a> marshal::MarshalBag for PyMarshalBag<'a> { type Value = PyObjectRef; + type ConstantBag = PyObjBag<'a>; + fn make_bool(&self, value: bool) -> Self::Value { self.0.ctx.new_bool(value).into() } + fn make_none(&self) -> Self::Value { self.0.ctx.none() } + fn make_ellipsis(&self) -> Self::Value { self.0.ctx.ellipsis() } + fn make_float(&self, value: f64) -> Self::Value { self.0.ctx.new_float(value).into() } + fn make_complex(&self, value: Complex64) -> Self::Value { self.0.ctx.new_complex(value).into() } + fn make_str(&self, value: &Wtf8) -> Self::Value { self.0.ctx.new_str(value).into() } + fn make_bytes(&self, value: &[u8]) -> Self::Value { self.0.ctx.new_bytes(value.to_vec()).into() } + fn make_int(&self, value: BigInt) -> Self::Value { self.0.ctx.new_int(value).into() } + fn make_tuple(&self, elements: impl Iterator) -> Self::Value { let elements = elements.collect(); self.0.ctx.new_tuple(elements).into() } + fn make_code(&self, code: CodeObject) -> Self::Value { self.0.ctx.new_code(code).into() } + fn make_stop_iter(&self) -> Result { Ok(self.0.ctx.exceptions.stop_iteration.to_owned().into()) } + fn make_list( &self, it: impl Iterator, ) -> Result { Ok(self.0.ctx.new_list(it.collect()).into()) } + fn make_set( &self, it: impl Iterator, @@ -177,6 +192,7 @@ mod decl { } Ok(set.into()) } + fn make_frozenset( &self, it: impl Iterator, @@ -184,6 +200,7 @@ mod decl { let vm = self.0; Ok(PyFrozenSet::from_iter(vm, it).unwrap().to_pyobject(vm)) } + fn make_dict( &self, it: impl Iterator, @@ -195,7 +212,7 @@ mod decl { } Ok(dict.into()) } - type ConstantBag = PyObjBag<'a>; + fn constant_bag(self) -> Self::ConstantBag { PyObjBag(&self.0.ctx) } diff --git a/vm/src/stdlib/posix.rs b/vm/src/stdlib/posix.rs index 8db4c42ff3f..f826942637e 100644 --- a/vm/src/stdlib/posix.rs +++ b/vm/src/stdlib/posix.rs @@ -391,7 +391,7 @@ pub mod module { } else if uid == -1 { None } else { - return Err(vm.new_os_error(String::from("Specified uid is not valid."))); + return Err(vm.new_os_error("Specified uid is not valid.")); }; let gid = if gid >= 0 { @@ -399,7 +399,7 @@ pub mod module { } else if gid == -1 { None } else { - return Err(vm.new_os_error(String::from("Specified gid is not valid."))); + return Err(vm.new_os_error("Specified gid is not valid.")); }; let flag = if follow_symlinks.0 { @@ -588,6 +588,7 @@ pub mod module { ) }) } + #[cfg(not(target_vendor = "apple"))] fn mknod(self, vm: &VirtualMachine) -> PyResult<()> { let ret = match self.dir_fd.get_opt() { @@ -603,6 +604,7 @@ pub mod module { }; if ret != 0 { Err(errno_err(vm)) } else { Ok(()) } } + #[cfg(target_vendor = "apple")] fn mknod(self, vm: &VirtualMachine) -> PyResult<()> { let [] = self.dir_fd.0; @@ -666,7 +668,7 @@ pub mod module { impl TryFromObject for SchedParam { fn try_from_object(_vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { - Ok(SchedParam { + Ok(Self { sched_priority: obj, }) } @@ -703,10 +705,12 @@ pub mod module { pub struct SchedParamArg { sched_priority: PyObjectRef, } + impl Constructor for SchedParam { type Args = SchedParamArg; + fn py_new(cls: PyTypeRef, arg: Self::Args, vm: &VirtualMachine) -> PyResult { - SchedParam { + Self { sched_priority: arg.sched_priority, } .into_ref_with_type(vm, cls) @@ -1591,6 +1595,7 @@ pub mod module { fn posix_spawn(args: PosixSpawnArgs, vm: &VirtualMachine) -> PyResult { args.spawn(false, vm) } + #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))] #[pyfunction] fn posix_spawnp(args: PosixSpawnArgs, vm: &VirtualMachine) -> PyResult { @@ -1601,22 +1606,27 @@ pub mod module { fn wifsignaled(status: i32) -> bool { libc::WIFSIGNALED(status) } + #[pyfunction(name = "WIFSTOPPED")] fn wifstopped(status: i32) -> bool { libc::WIFSTOPPED(status) } + #[pyfunction(name = "WIFEXITED")] fn wifexited(status: i32) -> bool { libc::WIFEXITED(status) } + #[pyfunction(name = "WTERMSIG")] fn wtermsig(status: i32) -> i32 { libc::WTERMSIG(status) } + #[pyfunction(name = "WSTOPSIG")] fn wstopsig(status: i32) -> i32 { libc::WSTOPSIG(status) } + #[pyfunction(name = "WEXITSTATUS")] fn wexitstatus(status: i32) -> i32 { libc::WEXITSTATUS(status) @@ -1629,6 +1639,7 @@ pub mod module { let pid = nix::Error::result(pid).map_err(|err| err.into_pyexception(vm))?; Ok((pid, status)) } + #[pyfunction] fn wait(vm: &VirtualMachine) -> PyResult<(libc::pid_t, i32)> { waitpid(-1, 0, vm) @@ -1753,7 +1764,7 @@ pub mod module { // function or to `cuserid()`. See man getlogin(3) for more information. let ptr = unsafe { libc::getlogin() }; if ptr.is_null() { - return Err(vm.new_os_error("unable to determine login name".to_owned())); + return Err(vm.new_os_error("unable to determine login name")); } let slice = unsafe { CStr::from_ptr(ptr) }; slice diff --git a/vm/src/stdlib/sre.rs b/vm/src/stdlib/sre.rs index 28d9a89a149..da72363e3a3 100644 --- a/vm/src/stdlib/sre.rs +++ b/vm/src/stdlib/sre.rs @@ -30,22 +30,26 @@ mod _sre { pub use rustpython_sre_engine::{CODESIZE, MAXGROUPS, MAXREPEAT, SRE_MAGIC as MAGIC}; #[pyfunction] - fn getcodesize() -> usize { + const fn getcodesize() -> usize { CODESIZE } + #[pyfunction] fn ascii_iscased(ch: i32) -> bool { - (ch >= b'a' as i32 && ch <= b'z' as i32) || (ch >= b'A' as i32 && ch <= b'Z' as i32) + (b'a' as i32..=b'z' as i32).contains(&ch) || (b'A' as i32..=b'Z' as i32).contains(&ch) } + #[pyfunction] fn unicode_iscased(ch: i32) -> bool { let ch = ch as u32; ch != lower_unicode(ch) || ch != upper_unicode(ch) } + #[pyfunction] fn ascii_tolower(ch: i32) -> i32 { lower_ascii(ch as u32) as i32 } + #[pyfunction] fn unicode_tolower(ch: i32) -> i32 { lower_unicode(ch as u32) as i32 @@ -348,6 +352,7 @@ mod _sre { fn sub(zelf: PyRef, sub_args: SubArgs, vm: &VirtualMachine) -> PyResult { Self::sub_impl(zelf, sub_args, false, vm) } + #[pymethod] fn subn(zelf: PyRef, sub_args: SubArgs, vm: &VirtualMachine) -> PyResult { Self::sub_impl(zelf, sub_args, true, vm) @@ -394,14 +399,17 @@ mod _sre { fn flags(&self) -> u16 { self.flags.bits() } + #[pygetset] fn groupindex(&self) -> PyDictRef { self.groupindex.clone() } + #[pygetset] - fn groups(&self) -> usize { + const fn groups(&self) -> usize { self.groups } + #[pygetset] fn pattern(&self) -> PyObjectRef { self.pattern.clone() @@ -630,34 +638,40 @@ mod _sre { } #[pygetset] - fn pos(&self) -> usize { + const fn pos(&self) -> usize { self.pos } + #[pygetset] - fn endpos(&self) -> usize { + const fn endpos(&self) -> usize { self.endpos } + #[pygetset] - fn lastindex(&self) -> Option { + const fn lastindex(&self) -> Option { if self.lastindex >= 0 { Some(self.lastindex) } else { None } } + #[pygetset] fn lastgroup(&self) -> Option { let i = self.lastindex.to_usize()?; self.pattern.indexgroup.get(i)?.clone() } + #[pygetset] fn re(&self) -> PyRef { self.pattern.clone() } + #[pygetset] fn string(&self) -> PyObjectRef { self.string.clone() } + #[pygetset] fn regs(&self, vm: &VirtualMachine) -> PyTupleRef { PyTuple::new_ref( @@ -670,10 +684,12 @@ mod _sre { fn start(&self, group: OptionalArg, vm: &VirtualMachine) -> PyResult { self.span(group, vm).map(|x| x.0) } + #[pymethod] fn end(&self, group: OptionalArg, vm: &VirtualMachine) -> PyResult { self.span(group, vm).map(|x| x.1) } + #[pymethod] fn span( &self, @@ -705,7 +721,7 @@ mod _sre { .into_iter() .map(|x| { self.get_index(x, vm) - .ok_or_else(|| vm.new_index_error("no such group".to_owned())) + .ok_or_else(|| vm.new_index_error("no such group")) .map(|index| { self.get_slice(index, str_drive, vm) .map(|x| x.to_pyobject(vm)) @@ -730,7 +746,7 @@ mod _sre { with_sre_str!(self.pattern, &self.string, vm, |str_drive| { let i = self .get_index(group, vm) - .ok_or_else(|| vm.new_index_error("no such group".to_owned()))?; + .ok_or_else(|| vm.new_index_error("no such group"))?; Ok(self.get_slice(i, str_drive, vm)) }) } diff --git a/vm/src/stdlib/symtable.rs b/vm/src/stdlib/symtable.rs index 76622fb126b..a848de5dc47 100644 --- a/vm/src/stdlib/symtable.rs +++ b/vm/src/stdlib/symtable.rs @@ -59,12 +59,12 @@ mod symtable { } #[pymethod] - fn get_lineno(&self) -> u32 { + const fn get_lineno(&self) -> u32 { self.symtable.line_number } #[pymethod] - fn is_nested(&self) -> bool { + const fn is_nested(&self) -> bool { self.symtable.is_nested } @@ -131,7 +131,7 @@ mod symtable { } #[pymethod] - fn has_children(&self) -> bool { + const fn has_children(&self) -> bool { !self.symtable.sub_tables.is_empty() } @@ -175,7 +175,7 @@ mod symtable { } #[pymethod] - fn is_declared_global(&self) -> bool { + const fn is_declared_global(&self) -> bool { matches!(self.symbol.scope, SymbolScope::GlobalExplicit) } @@ -185,7 +185,7 @@ mod symtable { } #[pymethod] - fn is_imported(&self) -> bool { + const fn is_imported(&self) -> bool { self.symbol.flags.contains(SymbolFlags::IMPORTED) } @@ -196,37 +196,37 @@ mod symtable { } #[pymethod] - fn is_nonlocal(&self) -> bool { + const fn is_nonlocal(&self) -> bool { self.symbol.flags.contains(SymbolFlags::NONLOCAL) } #[pymethod] - fn is_referenced(&self) -> bool { + const fn is_referenced(&self) -> bool { self.symbol.flags.contains(SymbolFlags::REFERENCED) } #[pymethod] - fn is_assigned(&self) -> bool { + const fn is_assigned(&self) -> bool { self.symbol.flags.contains(SymbolFlags::ASSIGNED) } #[pymethod] - fn is_parameter(&self) -> bool { + const fn is_parameter(&self) -> bool { self.symbol.flags.contains(SymbolFlags::PARAMETER) } #[pymethod] - fn is_free(&self) -> bool { + const fn is_free(&self) -> bool { matches!(self.symbol.scope, SymbolScope::Free) } #[pymethod] - fn is_namespace(&self) -> bool { + const fn is_namespace(&self) -> bool { !self.namespaces.is_empty() } #[pymethod] - fn is_annotated(&self) -> bool { + const fn is_annotated(&self) -> bool { self.symbol.flags.contains(SymbolFlags::ANNOTATED) }