BorrowValue for PyString

This commit is contained in:
Jeong YunWon
2020-08-09 04:56:32 +09:00
parent a77e78d3e1
commit ab37e455f3
53 changed files with 393 additions and 348 deletions

View File

@@ -6,7 +6,7 @@ use rustpython_vm::readline::{Readline, ReadlineResult};
use rustpython_vm::{
exceptions::{print_exception, PyBaseExceptionRef},
obj::objtype,
pyobject::PyResult,
pyobject::{BorrowValue, PyResult},
scope::Scope,
VirtualMachine,
};
@@ -61,7 +61,7 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
.get_attribute(vm.sys_module.clone(), prompt_name)
.and_then(|prompt| vm.to_str(&prompt));
let prompt = match prompt {
Ok(ref s) => s.as_str(),
Ok(ref s) => s.borrow_value(),
Err(_) => "",
};
let result = match repl.readline(prompt) {

View File

@@ -1,5 +1,5 @@
use rustpython_vm::obj::objstr::PyStringRef;
use rustpython_vm::pyobject::{PyIterable, PyResult, TryFromObject};
use rustpython_vm::pyobject::{BorrowValue, PyIterable, PyResult, TryFromObject};
use rustpython_vm::scope::{NameProtocol, Scope};
use rustpython_vm::VirtualMachine;
@@ -104,7 +104,7 @@ impl<'vm> ShellHelper<'vm> {
.filter(|res| {
res.as_ref()
.ok()
.map_or(true, |s| s.as_str().starts_with(word_start))
.map_or(true, |s| s.borrow_value().starts_with(word_start))
})
.collect::<Result<Vec<_>, _>>()
.ok()?;
@@ -117,7 +117,7 @@ impl<'vm> ShellHelper<'vm> {
let no_underscore = all_completions
.iter()
.cloned()
.filter(|s| !s.as_str().starts_with('_'))
.filter(|s| !s.borrow_value().starts_with('_'))
.collect::<Vec<_>>();
// if there are only completions that start with a '_', give them all of the
@@ -130,13 +130,13 @@ impl<'vm> ShellHelper<'vm> {
};
// sort the completions alphabetically
completions.sort_by(|a, b| std::cmp::Ord::cmp(a.as_str(), b.as_str()));
completions.sort_by(|a, b| std::cmp::Ord::cmp(a.borrow_value(), b.borrow_value()));
Some((
startpos,
completions
.into_iter()
.map(|s| s.as_str().to_owned())
.map(|s| s.borrow_value().to_owned())
.collect(),
))
}

View File

@@ -70,7 +70,7 @@ mod decl {
#[pyfunction]
fn ascii(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
let repr = vm.to_repr(&obj)?;
let ascii = to_ascii(repr.as_str());
let ascii = to_ascii(repr.borrow_value());
Ok(ascii)
}
@@ -121,11 +121,11 @@ mod decl {
fn compile(args: CompileArgs, vm: &VirtualMachine) -> PyResult {
// TODO: compile::compile should probably get bytes
let source = match &args.source {
Either::A(string) => string.as_str(),
Either::A(string) => string.borrow_value(),
Either::B(bytes) => std::str::from_utf8(bytes).unwrap(),
};
let mode_str = args.mode.as_str();
let mode_str = args.mode.borrow_value();
let flags = args
.flags
@@ -138,7 +138,7 @@ mod decl {
.parse::<compile::Mode>()
.map_err(|err| vm.new_value_error(err.to_string()))?;
vm.compile(&source, mode, args.filename.as_str().to_owned())
vm.compile(&source, mode, args.filename.borrow_value().to_owned())
.map(|o| o.into_object())
.map_err(|err| vm.new_syntax_error(&err))
} else {
@@ -230,7 +230,7 @@ mod decl {
// Determine code object:
let code_obj = match source {
Either::A(string) => vm
.compile(string.as_str(), mode, "<string>".to_owned())
.compile(string.borrow_value(), mode, "<string>".to_owned())
.map_err(|err| vm.new_syntax_error(&err))?,
Either::B(code_obj) => code_obj,
};
@@ -355,7 +355,7 @@ mod decl {
#[pyfunction]
fn input(prompt: OptionalArg<PyStringRef>, vm: &VirtualMachine) -> PyResult<String> {
let prompt = prompt.as_ref().map_or("", |s| s.as_str());
let prompt = prompt.as_ref().map_or("", |s| s.borrow_value());
let mut readline = Readline::new(());
match readline.readline(prompt) {
ReadlineResult::Line(s) => Ok(s),
@@ -568,7 +568,7 @@ mod decl {
Ok(u32::from(bytes[0]))
}),
Either::B(string) => {
let string = string.as_str();
let string = string.borrow_value();
let string_len = string.chars().count();
if string_len != 1 {
return Err(vm.new_type_error(format!(
@@ -779,7 +779,11 @@ mod decl {
mut kwargs: KwArgs,
vm: &VirtualMachine,
) -> PyResult {
let name = qualified_name.as_str().split('.').next_back().unwrap();
let name = qualified_name
.borrow_value()
.split('.')
.next_back()
.unwrap();
let name_obj = vm.new_str(name.to_owned());
let mut metaclass = if let Some(metaclass) = kwargs.pop_kwarg("metaclass") {

View File

@@ -2,7 +2,9 @@
/// [https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting]
use crate::format::get_num_digits;
use crate::obj::{objfloat, objint, objstr, objtuple, objtype};
use crate::pyobject::{ItemProtocol, PyObjectRef, PyResult, TryFromObject, TypeProtocol};
use crate::pyobject::{
BorrowValue, ItemProtocol, PyObjectRef, PyResult, TryFromObject, TypeProtocol,
};
use crate::vm::VirtualMachine;
use num_bigint::{BigInt, Sign};
use num_traits::cast::ToPrimitive;
@@ -295,7 +297,7 @@ impl CFormatSpec {
vm.call_method(&obj.clone(), "decode", vec![])?,
)?,
};
Ok(self.format_string(result.as_str().to_owned()))
Ok(self.format_string(result.borrow_value().to_owned()))
}
CFormatType::Number(number_type) => {
if !objtype::isinstance(&obj, &vm.ctx.types.int_type) {

View File

@@ -4,7 +4,7 @@
/// And: http://code.activestate.com/recipes/578375/
use crate::common::cell::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
use crate::obj::objstr::{PyString, PyStringRef};
use crate::pyobject::{IdProtocol, IntoPyObject, PyObjectRef, PyResult};
use crate::pyobject::{BorrowValue, IdProtocol, IntoPyObject, PyObjectRef, PyResult};
use crate::vm::VirtualMachine;
use rustpython_common::hash;
use std::collections::HashMap;
@@ -447,7 +447,7 @@ impl DictKey for PyStringRef {
if self.is(other_key) {
Ok(true)
} else if let Some(py_str_value) = other_key.payload::<PyString>() {
Ok(py_str_value.as_str() == self.as_str())
Ok(py_str_value.borrow_value() == self.borrow_value())
} else {
vm.bool_eq(self.clone().into_object(), other_key.clone())
}
@@ -472,7 +472,7 @@ impl DictKey for &str {
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObjectRef) -> PyResult<bool> {
if let Some(py_str_value) = other_key.payload::<PyString>() {
Ok(py_str_value.as_str() == *self)
Ok(py_str_value.borrow_value() == *self)
} else {
// Fall back to PyObjectRef implementation.
let s = vm.ctx.new_str(*self);

View File

@@ -24,7 +24,8 @@ use crate::obj::objtraceback::PyTraceback;
use crate::obj::objtuple::PyTuple;
use crate::obj::objtype::{self, PyClassRef};
use crate::pyobject::{
IdProtocol, ItemProtocol, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
BorrowValue, IdProtocol, ItemProtocol, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
};
use crate::scope::{NameProtocol, Scope};
use crate::vm::VirtualMachine;
@@ -795,7 +796,7 @@ impl ExecutingFrame<'_> {
if let Some(dict) = module.dict() {
for (k, v) in &dict {
let k = vm.to_str(&k)?;
let k = k.as_str();
let k = k.borrow_value();
if !k.starts_with('_') {
self.scope.store_name(&vm, k, v);
}
@@ -991,7 +992,7 @@ impl ExecutingFrame<'_> {
let key_repr = vm.to_repr(&key)?;
let msg = format!(
"got multiple values for keyword argument {}",
key_repr.as_str()
key_repr.borrow_value()
);
return Err(vm.new_type_error(msg));
}
@@ -1066,7 +1067,7 @@ impl ExecutingFrame<'_> {
let mut kwargs = IndexMap::new();
for (key, value) in kw_dict.into_iter() {
if let Some(key) = key.payload_if_subclass::<objstr::PyString>(vm) {
kwargs.insert(key.as_str().to_owned(), value);
kwargs.insert(key.borrow_value().to_owned(), value);
} else {
return Err(vm.new_type_error("keywords must be strings".to_owned()));
}
@@ -1285,7 +1286,11 @@ impl ExecutingFrame<'_> {
.ctx
.new_pyfunction(code_obj, scope, defaults, kw_only_defaults);
let name = qualified_name.as_str().split('.').next_back().unwrap();
let name = qualified_name
.borrow_value()
.split('.')
.next_back()
.unwrap();
vm.set_attr(&func_obj, "__name__", vm.new_str(name.to_owned()))?;
vm.set_attr(&func_obj, "__qualname__", qualified_name)?;
let module = self

View File

@@ -103,7 +103,7 @@ impl PyBool {
format_spec: PyStringRef,
vm: &VirtualMachine,
) -> PyResult<PyStringRef> {
if format_spec.as_str().is_empty() {
if format_spec.borrow_value().is_empty() {
vm.to_str(&obj)
} else {
Err(vm.new_type_error("unsupported format string passed to bool.__format__".to_owned()))

View File

@@ -256,7 +256,7 @@ impl PyByteArray {
#[pymethod]
fn fromhex(string: PyStringRef, vm: &VirtualMachine) -> PyResult<PyByteArray> {
Ok(PyBytesInner::fromhex(string.as_str(), vm)?.into())
Ok(PyBytesInner::fromhex(string.borrow_value(), vm)?.into())
}
#[pymethod(name = "center")]
@@ -590,7 +590,7 @@ impl PyByteArray {
vm.new_type_error(format!(
"'{}' decoder returned '{}' instead of 'str'; use codecs.encode() to \
encode arbitrary types",
encoding.as_ref().map_or("utf-8", |s| s.as_str()),
encoding.as_ref().map_or("utf-8", |s| s.borrow_value()),
obj.lease_class().name,
))
})

View File

@@ -238,7 +238,7 @@ impl PyBytes {
#[pymethod]
fn fromhex(string: PyStringRef, vm: &VirtualMachine) -> PyResult<PyBytes> {
Ok(PyBytesInner::fromhex(string.as_str(), vm)?.into())
Ok(PyBytesInner::fromhex(string.borrow_value(), vm)?.into())
}
#[pymethod(name = "center")]
@@ -481,7 +481,7 @@ impl PyBytes {
vm.new_type_error(format!(
"'{}' decoder returned '{}' instead of 'str'; use codecs.encode() to \
encode arbitrary types",
encoding.as_ref().map_or("utf-8", |s| s.as_str()),
encoding.as_ref().map_or("utf-8", |s| s.borrow_value()),
obj.lease_class().name,
))
})

View File

@@ -245,7 +245,7 @@ impl PyComplex {
"complex() can't take second arg if first is a string".to_owned(),
));
}
let value = Complex64::from_str(s.as_str())
let value = Complex64::from_str(s.borrow_value())
.map_err(|err| vm.new_value_error(err.to_string()))?;
return PyComplex { value }.into_ref_with_type(vm, cls);
}

View File

@@ -9,8 +9,8 @@ use crate::dictdatatype::{self, DictKey};
use crate::exceptions::PyBaseExceptionRef;
use crate::function::{KwArgs, OptionalArg, PyFuncArgs};
use crate::pyobject::{
IdProtocol, IntoPyObject, ItemProtocol, PyAttributes, PyClassImpl, PyContext, PyIterable,
PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
BorrowValue, IdProtocol, IntoPyObject, ItemProtocol, PyAttributes, PyClassImpl, PyContext,
PyIterable, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};
@@ -199,7 +199,11 @@ impl PyDictRef {
for (key, value) in self {
let key_repr = vm.to_repr(&key)?;
let value_repr = vm.to_repr(&value)?;
str_parts.push(format!("{}: {}", key_repr.as_str(), value_repr.as_str()));
str_parts.push(format!(
"{}: {}",
key_repr.borrow_value(),
value_repr.borrow_value()
));
}
format!("{{{}}}", str_parts.join(", "))
@@ -571,7 +575,7 @@ macro_rules! dict_iterator {
let mut str_parts = vec![];
for (key, value) in zelf.dict.clone() {
let s = vm.to_repr(&$result_fn(vm, key, value))?;
str_parts.push(s.as_str().to_owned());
str_parts.push(s.borrow_value().to_owned());
}
format!("{}([{}])", $class_name, str_parts.join(", "))
} else {

View File

@@ -187,7 +187,7 @@ impl PyFloat {
#[pymethod(name = "__format__")]
fn format(&self, spec: PyStringRef, vm: &VirtualMachine) -> PyResult<String> {
match FormatSpec::parse(spec.as_str())
match FormatSpec::parse(spec.borrow_value())
.and_then(|format_spec| format_spec.format_float(self.value))
{
Ok(string) => Ok(string),
@@ -508,7 +508,7 @@ impl PyFloat {
#[pymethod]
fn fromhex(repr: PyStringRef, vm: &VirtualMachine) -> PyResult<f64> {
float_ops::from_hex(repr.as_str().trim()).ok_or_else(|| {
float_ops::from_hex(repr.borrow_value().trim()).ok_or_else(|| {
vm.new_value_error("invalid hexadecimal floating-point string".to_owned())
})
}
@@ -525,7 +525,7 @@ fn to_float(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<f64> {
} else if let Some(int) = obj.payload_if_subclass::<PyInt>(vm) {
objint::try_float(int.borrow_value(), vm)?
} else if let Some(s) = obj.payload_if_subclass::<PyString>(vm) {
float_ops::parse_str(s.as_str().trim()).ok_or_else(|| {
float_ops::parse_str(s.borrow_value().trim()).ok_or_else(|| {
vm.new_value_error(format!("could not convert string to float: '{}'", s))
})?
} else if let Some(bytes) = obj.payload_if_subclass::<PyBytes>(vm) {

View File

@@ -10,8 +10,8 @@ use crate::obj::objasyncgenerator::PyAsyncGen;
use crate::obj::objcoroutine::PyCoroutine;
use crate::obj::objgenerator::PyGenerator;
use crate::pyobject::{
IdProtocol, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
TypeProtocol,
BorrowValue, IdProtocol, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult,
PyValue, TypeProtocol,
};
use crate::scope::Scope;
use crate::slots::{SlotCall, SlotDescriptor};
@@ -314,7 +314,7 @@ impl PyBoundMethod {
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
Ok(format!(
"<bound method of {}>",
vm.to_repr(&self.object)?.as_str()
vm.to_repr(&self.object)?.borrow_value()
))
}
@@ -325,7 +325,7 @@ impl PyBoundMethod {
#[pymethod(magic)]
fn getattribute(zelf: PyRef<Self>, name: PyStringRef, vm: &VirtualMachine) -> PyResult {
if let Some(obj) = zelf.get_class_attr(name.as_str()) {
if let Some(obj) = zelf.get_class_attr(name.borrow_value()) {
return vm.call_if_get_descriptor(obj, zelf.into_object());
}
vm.get_attribute(zelf.function.clone(), name)

View File

@@ -18,8 +18,9 @@ use crate::bytesinner::PyBytesInner;
use crate::format::FormatSpec;
use crate::function::{OptionalArg, PyFuncArgs};
use crate::pyobject::{
IdProtocol, IntoPyObject, IntoPyResult, PyArithmaticValue, PyClassImpl, PyComparisonValue,
PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, BorrowValue
BorrowValue, IdProtocol, IntoPyObject, IntoPyResult, PyArithmaticValue, PyClassImpl,
PyComparisonValue, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
};
use crate::stdlib::array::PyArray;
use crate::vm::VirtualMachine;
@@ -567,7 +568,7 @@ impl PyInt {
#[pymethod(name = "__format__")]
fn format(&self, spec: PyStringRef, vm: &VirtualMachine) -> PyResult<String> {
match FormatSpec::parse(spec.as_str())
match FormatSpec::parse(spec.borrow_value())
.and_then(|format_spec| format_spec.format_int(&self.value))
{
Ok(string) => Ok(string),
@@ -615,7 +616,7 @@ impl PyInt {
false
};
let value = match (args.byteorder.as_str(), signed) {
let value = match (args.byteorder.borrow_value(), signed) {
("big", true) => BigInt::from_signed_bytes_be(&args.bytes.elements),
("big", false) => BigInt::from_bytes_be(Sign::Plus, &args.bytes.elements),
("little", true) => BigInt::from_signed_bytes_le(&args.bytes.elements),
@@ -650,7 +651,7 @@ impl PyInt {
);
};
let mut origin_bytes = match args.byteorder.as_str() {
let mut origin_bytes = match args.byteorder.borrow_value() {
"big" => match signed {
true => value.to_signed_bytes_be(),
false => value.to_bytes_be().1,
@@ -677,7 +678,7 @@ impl PyInt {
};
let mut bytes = vec![];
match args.byteorder.as_str() {
match args.byteorder.borrow_value() {
"big" => {
bytes = append_bytes;
bytes.append(&mut origin_bytes);
@@ -757,7 +758,7 @@ pub(crate) fn to_int(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<BigInt>
let base = 10;
let opt = match_class!(match obj.clone() {
string @ PyString => {
let s = string.as_str();
let s = string.borrow_value();
bytes_to_int(s.as_bytes(), base)
}
bytes @ PyBytes => {
@@ -810,7 +811,7 @@ fn to_int_radix(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult<B
let opt = match_class!(match obj.clone() {
string @ PyString => {
let s = string.as_str();
let s = string.borrow_value();
bytes_to_int(s.as_bytes(), base)
}
bytes @ PyBytes => {

View File

@@ -425,7 +425,7 @@ impl PyList {
let mut str_parts = Vec::with_capacity(elements.len());
for elem in elements.iter() {
let s = vm.to_repr(elem)?;
str_parts.push(s.as_str().to_owned());
str_parts.push(s.borrow_value().to_owned());
}
format!("[{}]", str_parts.join(", "))
} else {
@@ -491,7 +491,7 @@ impl PyList {
}
}
let needle_str = vm.to_str(&needle)?;
Err(vm.new_value_error(format!("'{}' is not in list", needle_str.as_str())))
Err(vm.new_value_error(format!("'{}' is not in list", needle_str.borrow_value())))
}
#[pymethod]
@@ -526,7 +526,7 @@ impl PyList {
Ok(())
} else {
let needle_str = vm.to_str(&needle)?;
Err(vm.new_value_error(format!("'{}' is not in list", needle_str.as_str())))
Err(vm.new_value_error(format!("'{}' is not in list", needle_str.borrow_value())))
}
}

View File

@@ -4,7 +4,8 @@ use super::objstr::PyStringRef;
use super::objtype::PyClassRef;
use crate::function::OptionalArg;
use crate::pyobject::{
ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
BorrowValue, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject,
};
use crate::vm::VirtualMachine;
@@ -48,7 +49,7 @@ impl PyMappingProxy {
let opt = match &self.mapping {
MappingProxyInner::Class(class) => {
let key = PyStringRef::try_from_object(vm, key)?;
class.get_attr(key.as_str())
class.get_attr(key.borrow_value())
}
MappingProxyInner::Dict(obj) => obj.get_item(key, vm).ok(),
};
@@ -75,7 +76,7 @@ impl PyMappingProxy {
match &self.mapping {
MappingProxyInner::Class(class) => {
let key = PyStringRef::try_from_object(vm, key)?;
Ok(vm.new_bool(class.has_attr(key.as_str())))
Ok(vm.new_bool(class.has_attr(key.borrow_value())))
}
MappingProxyInner::Dict(obj) => vm._membership(obj.clone(), key),
}

View File

@@ -3,7 +3,7 @@ use super::objstr::{PyString, PyStringRef};
use super::objtype::PyClassRef;
use crate::function::OptionalOption;
use crate::pyobject::{
ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
BorrowValue, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
};
use crate::vm::VirtualMachine;
@@ -70,7 +70,10 @@ impl PyModuleRef {
None,
)
.unwrap_or(None)
.and_then(|obj| obj.payload::<PyString>().map(|s| s.as_str().to_owned()))
.and_then(|obj| {
obj.payload::<PyString>()
.map(|s| s.borrow_value().to_owned())
})
}
#[pymethod(magic)]

View File

@@ -6,8 +6,9 @@ use super::objtype::PyClassRef;
use crate::function::{OptionalArg, PyFuncArgs};
use crate::obj::objtype::PyClass;
use crate::pyobject::{
IdProtocol, ItemProtocol, PyArithmaticValue::*, PyAttributes, PyClassImpl, PyComparisonValue,
PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject, TypeProtocol,
BorrowValue, IdProtocol, ItemProtocol, PyArithmaticValue::*, PyAttributes, PyClassImpl,
PyComparisonValue, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
};
use crate::vm::VirtualMachine;
@@ -100,20 +101,20 @@ impl PyBaseObject {
#[pymethod(magic)]
fn delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
if let Some(attr) = obj.get_class_attr(attr_name.as_str()) {
if let Some(attr) = obj.get_class_attr(attr_name.borrow_value()) {
if let Some(descriptor) = attr.get_class_attr("__delete__") {
return vm.invoke(&descriptor, vec![attr, obj.clone()]).map(|_| ());
}
}
if let Some(dict) = obj.dict() {
dict.del_item(attr_name.as_str(), vm)?;
dict.del_item(attr_name.borrow_value(), vm)?;
Ok(())
} else {
Err(vm.new_attribute_error(format!(
"'{}' object has no attribute '{}'",
obj.lease_class().name,
attr_name.as_str()
attr_name.borrow_value()
)))
}
}
@@ -167,7 +168,7 @@ impl PyBaseObject {
format_spec: PyStringRef,
vm: &VirtualMachine,
) -> PyResult<PyStringRef> {
if format_spec.as_str().is_empty() {
if format_spec.borrow_value().is_empty() {
vm.to_str(&obj)
} else {
Err(vm.new_type_error(
@@ -262,7 +263,7 @@ pub(crate) fn setattr(
) -> PyResult<()> {
vm_trace!("object.__setattr__({:?}, {}, {:?})", obj, attr_name, value);
if let Some(attr) = obj.get_class_attr(attr_name.as_str()) {
if let Some(attr) = obj.get_class_attr(attr_name.borrow_value()) {
if let Some(descriptor) = attr.get_class_attr("__set__") {
return vm
.invoke(&descriptor, vec![attr, obj.clone(), value])
@@ -271,13 +272,13 @@ pub(crate) fn setattr(
}
if let Some(dict) = obj.dict() {
dict.set_item(attr_name.as_str(), value, vm)?;
dict.set_item(attr_name.borrow_value(), value, vm)?;
Ok(())
} else {
Err(vm.new_attribute_error(format!(
"'{}' object has no attribute '{}'",
obj.lease_class().name,
attr_name.as_str()
attr_name.borrow_value()
)))
}
}

View File

@@ -8,8 +8,8 @@ use super::objtype::{self, PyClassRef};
use crate::dictdatatype;
use crate::function::{Args, OptionalArg};
use crate::pyobject::{
self, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
self, BorrowValue, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};
use rustpython_common::hash::PyHash;
@@ -250,7 +250,7 @@ impl PySetInner {
let mut str_parts = Vec::with_capacity(self.content.len());
for key in self.content.keys() {
let part = vm.to_repr(&key)?;
str_parts.push(part.as_str().to_owned());
str_parts.push(part.borrow_value().to_owned());
}
Ok(format!("{{{}}}", str_parts.join(", ")))

View File

@@ -62,9 +62,9 @@ impl PySlice {
Ok(format!(
"slice({}, {}, {})",
start_repr.as_str(),
stop_repr.as_str(),
step_repr.as_str()
start_repr.borrow_value(),
stop_repr.borrow_value(),
step_repr.borrow_value()
))
}

View File

@@ -50,9 +50,16 @@ pub struct PyString {
len: AtomicCell<Option<usize>>,
}
impl PyString {
#[inline]
pub fn as_str(&self) -> &str {
impl<'a> BorrowValue<'a> for PyString {
type Borrowed = &'a str;
fn borrow_value(&'a self) -> Self::Borrowed {
&self.value
}
}
impl AsRef<str> for PyString {
fn as_ref(&self) -> &str {
&self.value
}
}
@@ -196,7 +203,7 @@ impl PyString {
if string.class().is(&cls) {
Ok(string)
} else {
PyString::from(string.as_str()).into_ref_with_type(vm, cls)
PyString::from(string.borrow_value()).into_ref_with_type(vm, cls)
}
}
@@ -502,7 +509,7 @@ impl PyString {
args,
"endswith",
"str",
|s, x: &PyStringRef| s.ends_with(x.as_str()),
|s, x: &PyStringRef| s.ends_with(x.borrow_value()),
vm,
)
}
@@ -513,7 +520,7 @@ impl PyString {
args,
"startswith",
"str",
|s, x: &PyStringRef| s.starts_with(x.as_str()),
|s, x: &PyStringRef| s.starts_with(x.borrow_value()),
vm,
)
}
@@ -609,7 +616,7 @@ impl PyString {
#[pymethod(name = "__format__")]
fn format_str(&self, spec: PyStringRef, vm: &VirtualMachine) -> PyResult<String> {
match FormatSpec::parse(spec.as_str())
match FormatSpec::parse(spec.borrow_value())
.and_then(|format_spec| format_spec.format_string(&self.value))
{
Ok(string) => Ok(string),
@@ -1088,7 +1095,7 @@ pub(crate) fn encode_string(
vm.new_type_error(format!(
"'{}' encoder returned '{}' instead of 'bytes'; use codecs.encode() to \
encode arbitrary types",
encoding.as_ref().map_or("utf-8", |s| s.as_str()),
encoding.as_ref().map_or("utf-8", |s| s.borrow_value()),
obj.lease_class().name,
))
})
@@ -1121,7 +1128,7 @@ impl IntoPyObject for &String {
impl TryFromObject for std::ffi::CString {
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
let s = PyStringRef::try_from_object(vm, obj)?;
Self::new(s.as_str().to_owned())
Self::new(s.borrow_value().to_owned())
.map_err(|_| vm.new_value_error("embedded null character".to_owned()))
}
}

View File

@@ -10,8 +10,8 @@ use super::objstr::PyStringRef;
use super::objtype::{self, PyClass, PyClassRef};
use crate::function::OptionalArg;
use crate::pyobject::{
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
TypeProtocol,
BorrowValue, IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol,
};
use crate::scope::NameProtocol;
use crate::slots::SlotDescriptor;
@@ -65,7 +65,7 @@ impl PySuper {
let mut it = obj_type.iter_mro().peekable();
for _ in it.peeking_take_while(|cls| !cls.is(&zelf.typ)) {}
for cls in it.skip(1) {
if let Some(descr) = cls.get_attr(name.as_str()) {
if let Some(descr) = cls.get_attr(name.borrow_value()) {
return vm
.call_get_descriptor_specific(
descr.clone(),

View File

@@ -6,7 +6,7 @@ use super::objsequence::get_item;
use super::objtype::PyClassRef;
use crate::function::OptionalArg;
use crate::pyobject::{
self, IntoPyObject,
self, BorrowValue, IntoPyObject,
PyArithmaticValue::{self, *},
PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
};
@@ -179,7 +179,7 @@ impl PyTuple {
let mut str_parts = Vec::with_capacity(zelf.elements.len());
for elem in zelf.elements.iter() {
let s = vm.to_repr(elem)?;
str_parts.push(s.as_str().to_owned());
str_parts.push(s.borrow_value().to_owned());
}
if str_parts.len() == 1 {

View File

@@ -12,8 +12,8 @@ use super::objtuple::PyTuple;
use super::objweakref::PyWeak;
use crate::function::{KwArgs, OptionalArg, PyFuncArgs};
use crate::pyobject::{
IdProtocol, PyAttributes, PyClassImpl, PyContext, PyIterable, PyLease, PyObject, PyObjectRef,
PyRef, PyResult, PyValue, TypeProtocol,
BorrowValue, IdProtocol, PyAttributes, PyClassImpl, PyContext, PyIterable, PyLease, PyObject,
PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::slots::{PyClassSlots, PyTpFlags};
use crate::vm::VirtualMachine;
@@ -129,7 +129,7 @@ impl PyClassRef {
#[pymethod(magic)]
fn getattribute(self, name_ref: PyStringRef, vm: &VirtualMachine) -> PyResult {
let name = name_ref.as_str();
let name = name_ref.borrow_value();
vm_trace!("type.__getattribute__({:?}, {:?})", self, name);
let mcl = self.lease_class();
@@ -182,7 +182,7 @@ impl PyClassRef {
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
if let Some(attr) = self.get_class_attr(attr_name.as_str()) {
if let Some(attr) = self.get_class_attr(attr_name.borrow_value()) {
if let Some(ref descriptor) = attr.get_class_attr("__set__") {
vm.invoke(descriptor, vec![attr, self.into_object(), value])?;
return Ok(());
@@ -195,7 +195,7 @@ impl PyClassRef {
#[pymethod(magic)]
fn delattr(self, attr_name: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
if let Some(attr) = self.get_class_attr(attr_name.as_str()) {
if let Some(attr) = self.get_class_attr(attr_name.borrow_value()) {
if let Some(ref descriptor) = attr.get_class_attr("__delete__") {
return vm
.invoke(descriptor, vec![attr, self.into_object()])
@@ -203,11 +203,11 @@ impl PyClassRef {
}
}
if self.get_attr(attr_name.as_str()).is_some() {
self.attributes.write().remove(attr_name.as_str());
if self.get_attr(attr_name.borrow_value()).is_some() {
self.attributes.write().remove(attr_name.borrow_value());
Ok(())
} else {
Err(vm.new_attribute_error(attr_name.as_str().to_owned()))
Err(vm.new_attribute_error(attr_name.borrow_value().to_owned()))
}
}
@@ -308,8 +308,14 @@ impl PyClassRef {
}
}
let typ = new(metatype, name.as_str(), base.clone(), bases, attributes)
.map_err(|e| vm.new_type_error(e))?;
let typ = new(
metatype,
name.borrow_value(),
base.clone(),
bases,
attributes,
)
.map_err(|e| vm.new_type_error(e))?;
typ.slots.write().flags = base.slots.read().flags;
vm.ctx.add_tp_new_wrapper(&typ);

View File

@@ -284,8 +284,8 @@ impl PyArray {
init: OptionalArg<PyIterable>,
vm: &VirtualMachine,
) -> PyResult<PyArrayRef> {
let spec = match spec.as_str().len() {
1 => spec.as_str().chars().next().unwrap(),
let spec = match spec.borrow_value().len() {
1 => spec.borrow_value().chars().next().unwrap(),
_ => {
return Err(vm.new_type_error(
"array() argument 1 must be a unicode character, not str".to_owned(),

View File

@@ -24,7 +24,7 @@ mod decl {
b @ PyBytes => Ok(SerializedData::Bytes(b)),
b @ PyByteArray => Ok(SerializedData::Buffer(b)),
a @ PyString => {
if a.as_str().is_ascii() {
if a.borrow_value().is_ascii() {
Ok(SerializedData::Ascii(a))
} else {
Err(vm.new_value_error(
@@ -46,7 +46,7 @@ mod decl {
match self {
SerializedData::Bytes(b) => f(b.borrow_value()),
SerializedData::Buffer(b) => f(&b.borrow_value().elements),
SerializedData::Ascii(a) => f(a.as_str().as_bytes()),
SerializedData::Ascii(a) => f(a.borrow_value().as_bytes()),
}
}
}

View File

@@ -8,8 +8,10 @@ use crate::function::PyFuncArgs;
use crate::obj::objiter;
use crate::obj::objstr::{self, PyString};
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{IntoPyObject, TryFromObject, TypeProtocol};
use crate::pyobject::{PyClassImpl, PyIterable, PyObjectRef, PyRef, PyResult, PyValue};
use crate::pyobject::{
BorrowValue, IntoPyObject, PyClassImpl, PyIterable, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject, TypeProtocol,
};
use crate::types::create_type;
use crate::VirtualMachine;
@@ -76,7 +78,7 @@ fn into_strings(iterable: &PyIterable<PyObjectRef>, vm: &VirtualMachine) -> PyRe
.iter(vm)?
.map(|py_obj_ref| {
match_class!(match py_obj_ref? {
py_str @ PyString => Ok(py_str.as_str().trim().to_owned()),
py_str @ PyString => Ok(py_str.borrow_value().trim().to_owned()),
obj => {
let msg = format!(
"iterator should return strings, not {} (did you open the file in text mode?)",

View File

@@ -1,7 +1,7 @@
use crate::bytecode::CodeFlags;
use crate::obj::objcode::PyCodeRef;
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{ItemProtocol, PyObjectRef, PyResult, TryFromObject};
use crate::pyobject::{BorrowValue, ItemProtocol, PyObjectRef, PyResult, TryFromObject};
use crate::vm::VirtualMachine;
use rustpython_compiler::compile;
@@ -14,7 +14,11 @@ fn dis_dis(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
// String:
if let Ok(co_str) = PyStringRef::try_from_object(vm, obj.clone()) {
let code = vm
.compile(co_str.as_str(), compile::Mode::Exec, "<string>".to_owned())
.compile(
co_str.borrow_value(),
compile::Mode::Exec,
"<string>".to_owned(),
)
.map_err(|err| vm.new_syntax_error(&err))?
.into_object();
return dis_disassemble(code, vm);

View File

@@ -93,7 +93,7 @@ fn hashlib_new(
data: OptionalArg<PyBytesRef>,
vm: &VirtualMachine,
) -> PyResult<PyHasher> {
match name.as_str() {
match name.borrow_value() {
"md5" => md5(data, vm),
"sha1" => sha1(data, vm),
"sha224" => sha224(data, vm),

View File

@@ -4,7 +4,7 @@ use crate::obj::objcode::PyCode;
use crate::obj::objmodule::PyModuleRef;
use crate::obj::objstr;
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{ItemProtocol, PyObjectRef, PyResult};
use crate::pyobject::{BorrowValue, ItemProtocol, PyObjectRef, PyResult};
#[cfg(not(target_arch = "wasm32"))]
use crate::stdlib::thread::RawRMutex;
use crate::vm::VirtualMachine;
@@ -48,11 +48,11 @@ fn imp_lock_held(_vm: &VirtualMachine) -> bool {
}
fn imp_is_builtin(name: PyStringRef, vm: &VirtualMachine) -> bool {
vm.state.stdlib_inits.contains_key(name.as_str())
vm.state.stdlib_inits.contains_key(name.borrow_value())
}
fn imp_is_frozen(name: PyStringRef, vm: &VirtualMachine) -> bool {
vm.state.frozen.contains_key(name.as_str())
vm.state.frozen.contains_key(name.borrow_value())
}
fn imp_create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult {
@@ -75,37 +75,29 @@ fn imp_exec_builtin(_mod: PyModuleRef) -> i32 {
}
fn imp_get_frozen_object(name: PyStringRef, vm: &VirtualMachine) -> PyResult<PyCode> {
let name = name.borrow_value();
vm.state
.frozen
.get(name.as_str())
.get(name)
.map(|frozen| {
let mut frozen = frozen.code.clone();
frozen.source_path = format!("frozen {}", name.as_str());
frozen.source_path = format!("frozen {}", name);
PyCode::new(frozen)
})
.ok_or_else(|| {
vm.new_import_error(
format!("No such frozen object named {}", name.as_str()),
name.as_str(),
)
})
.ok_or_else(|| vm.new_import_error(format!("No such frozen object named {}", name), name))
}
fn imp_init_frozen(name: PyStringRef, vm: &VirtualMachine) -> PyResult {
import::import_frozen(vm, name.as_str())
import::import_frozen(vm, name.borrow_value())
}
fn imp_is_frozen_package(name: PyStringRef, vm: &VirtualMachine) -> PyResult<bool> {
let name = name.borrow_value();
vm.state
.frozen
.get(name.as_str())
.get(name)
.map(|frozen| frozen.package)
.ok_or_else(|| {
vm.new_import_error(
format!("No such frozen object named {}", name.as_str()),
name.as_str(),
)
})
.ok_or_else(|| vm.new_import_error(format!("No such frozen object named {}", name), name))
}
fn imp_fix_co_filename(_code: PyObjectRef, _path: PyStringRef) {

View File

@@ -203,7 +203,7 @@ impl PyStringIORef {
//write string to underlying vector
fn write(self, data: PyStringRef, vm: &VirtualMachine) -> PyResult {
let bytes = data.as_str().as_bytes();
let bytes = data.borrow_value().as_bytes();
match self.buffer(vm)?.write(bytes) {
Some(value) => Ok(vm.ctx.new_int(value)),
@@ -656,7 +656,7 @@ mod fileio {
fn file_io_init(file_io: PyObjectRef, args: FileIOArgs, vm: &VirtualMachine) -> PyResult {
let mode = args
.mode
.map(|mode| mode.as_str().to_owned())
.map(|mode| mode.borrow_value().to_owned())
.unwrap_or_else(|| "r".to_owned());
let (name, file_no) = match args.name {
Either::A(name) => {
@@ -679,7 +679,7 @@ mod fileio {
fd
} else {
os::open(
os::PyPathLike::new_str(name.as_str().to_owned()),
os::PyPathLike::new_str(name.borrow_value().to_owned()),
mode as _,
OptionalArg::Missing,
OptionalArg::Missing,
@@ -887,7 +887,7 @@ struct TextIOWrapperArgs {
impl TextIOWrapperArgs {
fn validate_newline(&self, vm: &VirtualMachine) -> PyResult<()> {
if let Some(pystr) = &self.newline {
match pystr.as_str() {
match pystr.borrow_value() {
"" | "\n" | "\r" | "\r\n" => Ok(()),
_ => {
Err(vm.new_value_error(format!("illegal newline value: '{}'", pystr.repr(vm)?)))
@@ -915,7 +915,7 @@ fn text_io_wrapper_init(
if let Some(self_encoding) = self_encoding {
encoding = Some(PyString::from(self_encoding).into_ref(vm));
} else if let Some(ref encoding) = encoding {
self_encoding = Some(encoding.as_str())
self_encoding = Some(encoding.borrow_value())
} else {
return Err(vm.new_os_error("could not determine default encoding".to_owned()));
}
@@ -925,7 +925,7 @@ fn text_io_wrapper_init(
.errors
.map_or_else(|| vm.ctx.new_str("strict"), |o| o.into_object());
// let readuniversal = args.newline.map_or_else(true, |s| s.as_str().is_empty());
// let readuniversal = args.newline.map_or_else(true, |s| s.borrow_value().is_empty());
vm.set_attr(
&instance,
@@ -1017,7 +1017,7 @@ fn text_io_wrapper_write(
return Err(vm.new_value_error("not writable".to_owned()));
}
let bytes = obj.as_str().to_owned().into_bytes();
let bytes = obj.borrow_value().to_owned().into_bytes();
let len = vm.call_method(&raw, "write", vec![vm.ctx.new_bytes(bytes.clone())])?;
let len = objint::get_value(&len)
@@ -1126,7 +1126,7 @@ fn io_open_wrapper(
) -> PyResult {
io_open(
file,
mode.as_ref().into_option().map(|s| s.as_str()),
mode.as_ref().into_option().map(|s| s.borrow_value()),
opts,
vm,
)

View File

@@ -1,7 +1,9 @@
use crate::obj::objiter;
use crate::obj::objstr::PyStringRef;
use crate::obj::{objbool, objtype::PyClassRef};
use crate::pyobject::{IdProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue};
use crate::pyobject::{
BorrowValue, IdProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue,
};
use crate::VirtualMachine;
use num_bigint::BigInt;
@@ -195,7 +197,7 @@ impl JsonScanner {
return Err(vm.new_value_error("idx cannot be negative".to_owned()));
}
let idx = idx as usize;
let mut chars = pystr.as_str().chars();
let mut chars = pystr.borrow_value().chars();
if idx > 0 {
chars
.nth(idx - 1)
@@ -221,11 +223,11 @@ fn encode_string(s: &str, ascii_only: bool) -> String {
}
fn _json_encode_basestring(s: PyStringRef) -> String {
encode_string(s.as_str(), false)
encode_string(s.borrow_value(), false)
}
fn _json_encode_basestring_ascii(s: PyStringRef) -> String {
encode_string(s.as_str(), true)
encode_string(s.borrow_value(), true)
}
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {

View File

@@ -5,12 +5,12 @@
use rustpython_parser::lexer;
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{PyObjectRef, PyResult};
use crate::pyobject::{BorrowValue, PyObjectRef, PyResult};
use crate::vm::VirtualMachine;
fn keyword_iskeyword(s: PyStringRef, vm: &VirtualMachine) -> PyResult {
let keywords = lexer::get_keywords();
let value = keywords.contains_key(s.as_str());
let value = keywords.contains_key(s.borrow_value());
let value = vm.ctx.new_bool(value);
Ok(value)
}

View File

@@ -1,103 +1,103 @@
use super::os::errno_err;
use crate::obj::objbytes::PyBytesRef;
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{PyObjectRef, PyResult};
use crate::VirtualMachine;
use itertools::Itertools;
use winapi::shared::minwindef::UINT;
use winapi::um::errhandlingapi::SetErrorMode;
extern "C" {
fn _getch() -> i32;
fn _getwch() -> u32;
fn _getche() -> i32;
fn _getwche() -> u32;
fn _putch(c: u32) -> i32;
fn _putwch(c: u16) -> u32;
}
fn msvcrt_getch() -> Vec<u8> {
let c = unsafe { _getch() };
vec![c as u8]
}
fn msvcrt_getwch() -> String {
let c = unsafe { _getwch() };
std::char::from_u32(c).unwrap().to_string()
}
fn msvcrt_getche() -> Vec<u8> {
let c = unsafe { _getche() };
vec![c as u8]
}
fn msvcrt_getwche() -> String {
let c = unsafe { _getwche() };
std::char::from_u32(c).unwrap().to_string()
}
fn msvcrt_putch(b: PyBytesRef, vm: &VirtualMachine) -> PyResult<()> {
let &c = b.borrow_value().iter().exactly_one().map_err(|_| {
vm.new_type_error("putch() argument must be a byte string of length 1".to_owned())
})?;
unsafe { suppress_iph!(_putch(c.into())) };
Ok(())
}
fn msvcrt_putwch(s: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
let c = s.as_str().chars().exactly_one().map_err(|_| {
vm.new_type_error("putch() argument must be a string of length 1".to_owned())
})?;
unsafe { suppress_iph!(_putwch(c as u16)) };
Ok(())
}
extern "C" {
fn _setmode(fd: i32, flags: i32) -> i32;
}
fn msvcrt_setmode(fd: i32, flags: i32, vm: &VirtualMachine) -> PyResult<i32> {
let flags = unsafe { suppress_iph!(_setmode(fd, flags)) };
if flags == -1 {
Err(errno_err(vm))
} else {
Ok(flags)
}
}
extern "C" {
fn _open_osfhandle(osfhandle: isize, flags: i32) -> i32;
}
fn msvcrt_open_osfhandle(handle: isize, flags: i32, vm: &VirtualMachine) -> PyResult<i32> {
let ret = unsafe { suppress_iph!(_open_osfhandle(handle, flags)) };
if ret == -1 {
Err(errno_err(vm))
} else {
Ok(ret)
}
}
fn msvcrt_seterrormode(mode: UINT, _: &VirtualMachine) -> UINT {
unsafe { suppress_iph!(SetErrorMode(mode)) }
}
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
use winapi::um::winbase::{
SEM_FAILCRITICALERRORS, SEM_NOALIGNMENTFAULTEXCEPT, SEM_NOGPFAULTERRORBOX,
SEM_NOOPENFILEERRORBOX,
};
let ctx = &vm.ctx;
py_module!(vm, "msvcrt", {
"getch" => ctx.new_function(msvcrt_getch),
"getwch" => ctx.new_function(msvcrt_getwch),
"getche" => ctx.new_function(msvcrt_getche),
"getwche" => ctx.new_function(msvcrt_getwche),
"putch" => ctx.new_function(msvcrt_putch),
"putwch" => ctx.new_function(msvcrt_putwch),
"setmode" => ctx.new_function(msvcrt_setmode),
"open_osfhandle" => ctx.new_function(msvcrt_open_osfhandle),
"SetErrorMode" => ctx.new_function(msvcrt_seterrormode),
"SEM_FAILCRITICALERRORS" => ctx.new_int(SEM_FAILCRITICALERRORS),
"SEM_NOALIGNMENTFAULTEXCEPT" => ctx.new_int(SEM_NOALIGNMENTFAULTEXCEPT),
"SEM_NOGPFAULTERRORBOX" => ctx.new_int(SEM_NOGPFAULTERRORBOX),
"SEM_NOOPENFILEERRORBOX" => ctx.new_int(SEM_NOOPENFILEERRORBOX),
})
}
use super::os::errno_err;
use crate::obj::objbytes::PyBytesRef;
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{BorrowValue, PyObjectRef, PyResult};
use crate::VirtualMachine;
use itertools::Itertools;
use winapi::shared::minwindef::UINT;
use winapi::um::errhandlingapi::SetErrorMode;
extern "C" {
fn _getch() -> i32;
fn _getwch() -> u32;
fn _getche() -> i32;
fn _getwche() -> u32;
fn _putch(c: u32) -> i32;
fn _putwch(c: u16) -> u32;
}
fn msvcrt_getch() -> Vec<u8> {
let c = unsafe { _getch() };
vec![c as u8]
}
fn msvcrt_getwch() -> String {
let c = unsafe { _getwch() };
std::char::from_u32(c).unwrap().to_string()
}
fn msvcrt_getche() -> Vec<u8> {
let c = unsafe { _getche() };
vec![c as u8]
}
fn msvcrt_getwche() -> String {
let c = unsafe { _getwche() };
std::char::from_u32(c).unwrap().to_string()
}
fn msvcrt_putch(b: PyBytesRef, vm: &VirtualMachine) -> PyResult<()> {
let &c = b.borrow_value().iter().exactly_one().map_err(|_| {
vm.new_type_error("putch() argument must be a byte string of length 1".to_owned())
})?;
unsafe { suppress_iph!(_putch(c.into())) };
Ok(())
}
fn msvcrt_putwch(s: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
let c = s.borrow_value().chars().exactly_one().map_err(|_| {
vm.new_type_error("putch() argument must be a string of length 1".to_owned())
})?;
unsafe { suppress_iph!(_putwch(c as u16)) };
Ok(())
}
extern "C" {
fn _setmode(fd: i32, flags: i32) -> i32;
}
fn msvcrt_setmode(fd: i32, flags: i32, vm: &VirtualMachine) -> PyResult<i32> {
let flags = unsafe { suppress_iph!(_setmode(fd, flags)) };
if flags == -1 {
Err(errno_err(vm))
} else {
Ok(flags)
}
}
extern "C" {
fn _open_osfhandle(osfhandle: isize, flags: i32) -> i32;
}
fn msvcrt_open_osfhandle(handle: isize, flags: i32, vm: &VirtualMachine) -> PyResult<i32> {
let ret = unsafe { suppress_iph!(_open_osfhandle(handle, flags)) };
if ret == -1 {
Err(errno_err(vm))
} else {
Ok(ret)
}
}
fn msvcrt_seterrormode(mode: UINT, _: &VirtualMachine) -> UINT {
unsafe { suppress_iph!(SetErrorMode(mode)) }
}
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
use winapi::um::winbase::{
SEM_FAILCRITICALERRORS, SEM_NOALIGNMENTFAULTEXCEPT, SEM_NOGPFAULTERRORBOX,
SEM_NOOPENFILEERRORBOX,
};
let ctx = &vm.ctx;
py_module!(vm, "msvcrt", {
"getch" => ctx.new_function(msvcrt_getch),
"getwch" => ctx.new_function(msvcrt_getwch),
"getche" => ctx.new_function(msvcrt_getche),
"getwche" => ctx.new_function(msvcrt_getwche),
"putch" => ctx.new_function(msvcrt_putch),
"putwch" => ctx.new_function(msvcrt_putwch),
"setmode" => ctx.new_function(msvcrt_setmode),
"open_osfhandle" => ctx.new_function(msvcrt_open_osfhandle),
"SetErrorMode" => ctx.new_function(msvcrt_seterrormode),
"SEM_FAILCRITICALERRORS" => ctx.new_int(SEM_FAILCRITICALERRORS),
"SEM_NOALIGNMENTFAULTEXCEPT" => ctx.new_int(SEM_NOALIGNMENTFAULTEXCEPT),
"SEM_NOGPFAULTERRORBOX" => ctx.new_int(SEM_NOGPFAULTERRORBOX),
"SEM_NOOPENFILEERRORBOX" => ctx.new_int(SEM_NOOPENFILEERRORBOX),
})
}

View File

@@ -2,7 +2,7 @@ use crate::byteslike::PyBytesLike;
use crate::function::OptionalArg;
use crate::obj::objstr::PyStringRef;
use crate::obj::{objiter, objtype};
use crate::pyobject::{Either, PyObjectRef, PyResult, TypeProtocol};
use crate::pyobject::{BorrowValue, Either, PyObjectRef, PyResult, TypeProtocol};
use crate::VirtualMachine;
use volatile::Volatile;
@@ -76,12 +76,12 @@ fn operator_compare_digest(
) -> PyResult<bool> {
let res = match (a, b) {
(Either::A(a), Either::A(b)) => {
if !a.as_str().is_ascii() || !b.as_str().is_ascii() {
if !a.borrow_value().is_ascii() || !b.borrow_value().is_ascii() {
return Err(vm.new_type_error(
"comparing strings with non-ASCII characters is not supported".to_owned(),
));
}
timing_safe_cmp(a.as_str().as_bytes(), b.as_str().as_bytes())
timing_safe_cmp(a.borrow_value().as_bytes(), b.borrow_value().as_bytes())
}
(Either::B(a), Either::B(b)) => a.with_ref(|a| b.with_ref(|b| timing_safe_cmp(a, b))),
_ => {

View File

@@ -95,7 +95,7 @@ impl TryFromObject for PyPathLike {
let match1 = |obj: &PyObjectRef| {
let pathlike = match_class!(match obj {
ref l @ PyString => PyPathLike {
path: l.as_str().into(),
path: l.borrow_value().into(),
mode: OutputMode::String,
},
ref i @ PyBytes => PyPathLike {
@@ -320,7 +320,7 @@ mod _os {
#[pyfunction]
fn error(message: OptionalArg<PyStringRef>, vm: &VirtualMachine) -> PyResult {
let msg = message.map_or("".to_owned(), |msg| msg.as_str().to_owned());
let msg = message.map_or("".to_owned(), |msg| msg.borrow_value().to_owned());
Err(vm.new_os_error(msg))
}
@@ -379,7 +379,7 @@ mod _os {
#[pyfunction]
fn mkdirs(path: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
fs::create_dir_all(path.as_str()).map_err(|err| err.into_pyexception(vm))
fs::create_dir_all(path.borrow_value()).map_err(|err| err.into_pyexception(vm))
}
#[pyfunction]
@@ -407,11 +407,11 @@ mod _os {
vm: &VirtualMachine,
) -> PyResult<()> {
let key: &ffi::OsStr = match key {
Either::A(ref s) => s.as_str().as_ref(),
Either::A(ref s) => s.borrow_value().as_ref(),
Either::B(ref b) => bytes_as_osstr(b.borrow_value(), vm)?,
};
let value: &ffi::OsStr = match value {
Either::A(ref s) => s.as_str().as_ref(),
Either::A(ref s) => s.borrow_value().as_ref(),
Either::B(ref b) => bytes_as_osstr(b.borrow_value(), vm)?,
};
env::set_var(key, value);
@@ -421,7 +421,7 @@ mod _os {
#[pyfunction]
fn unsetenv(key: Either<PyStringRef, PyBytesRef>, vm: &VirtualMachine) -> PyResult<()> {
let key: &ffi::OsStr = match key {
Either::A(ref s) => s.as_str().as_ref(),
Either::A(ref s) => s.borrow_value().as_ref(),
Either::B(ref b) => bytes_as_osstr(b.borrow_value(), vm)?,
};
env::remove_var(key);
@@ -1385,7 +1385,7 @@ mod posix {
fn system(command: PyStringRef) -> PyResult<i32> {
use std::ffi::CString;
let rstr = command.as_str();
let rstr = command.borrow_value();
let cstr = CString::new(rstr).unwrap();
let x = unsafe { libc::system(cstr.as_ptr()) };
Ok(x)
@@ -1416,7 +1416,7 @@ mod posix {
argv_list: Either<PyListRef, PyTupleRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
let path = ffi::CString::new(path.as_str())
let path = ffi::CString::new(path.borrow_value())
.map_err(|_| vm.new_value_error("embedded null character".to_owned()))?;
let argv: Vec<ffi::CString> = match argv_list {
@@ -1716,7 +1716,7 @@ mod posix {
))]
#[pyfunction]
fn initgroups(user_name: PyStringRef, gid: u32, vm: &VirtualMachine) -> PyResult<()> {
let user = ffi::CString::new(user_name.as_str()).unwrap();
let user = ffi::CString::new(user_name.borrow_value()).unwrap();
let gid = Gid::from_raw(gid);
unistd::initgroups(&user, gid).map_err(|err| err.into_pyexception(vm))
}

View File

@@ -44,7 +44,7 @@ impl From<User> for Passwd {
}
fn pwd_getpwnam(name: PyStringRef, vm: &VirtualMachine) -> PyResult {
match User::from_name(name.as_str()).map_err(|err| err.into_pyexception(vm))? {
match User::from_name(name.borrow_value()).map_err(|err| err.into_pyexception(vm))? {
Some(user) => Ok(Passwd::from(user)
.into_struct_sequence(vm, vm.try_class("pwd", "struct_passwd")?)?
.into_object()),

View File

@@ -92,7 +92,7 @@ mod _struct {
fmt: &Either<PyStringRef, PyBytesRef>,
) -> PyResult<FormatSpec> {
let decoded_fmt = match fmt {
Either::A(string) => string.as_str(),
Either::A(string) => string.borrow_value(),
Either::B(bytes) if bytes.is_ascii() => std::str::from_utf8(&bytes).unwrap(),
_ => {
return Err(vm.new_unicode_decode_error(

View File

@@ -97,7 +97,7 @@ fn re_match(
vm: &VirtualMachine,
) -> PyResult {
let flags = extract_flags(flags);
let regex = make_regex(vm, pattern.as_str(), flags)?;
let regex = make_regex(vm, pattern.borrow_value(), flags)?;
do_match(vm, &regex, string)
}
@@ -108,7 +108,7 @@ fn re_search(
vm: &VirtualMachine,
) -> PyResult {
let flags = extract_flags(flags);
let regex = make_regex(vm, pattern.as_str(), flags)?;
let regex = make_regex(vm, pattern.borrow_value(), flags)?;
do_search(vm, &regex, string)
}
@@ -121,7 +121,7 @@ fn re_sub(
vm: &VirtualMachine,
) -> PyResult {
let flags = extract_flags(flags);
let regex = make_regex(vm, pattern.as_str(), flags)?;
let regex = make_regex(vm, pattern.borrow_value(), flags)?;
let limit = count.unwrap_or(0);
do_sub(vm, &regex, repl, string, limit)
}
@@ -133,7 +133,7 @@ fn re_findall(
vm: &VirtualMachine,
) -> PyResult {
let flags = extract_flags(flags);
let regex = make_regex(vm, pattern.as_str(), flags)?;
let regex = make_regex(vm, pattern.borrow_value(), flags)?;
do_findall(vm, &regex, string)
}
@@ -145,7 +145,7 @@ fn re_split(
vm: &VirtualMachine,
) -> PyResult {
let flags = extract_flags(flags);
let regex = make_regex(vm, pattern.as_str(), flags)?;
let regex = make_regex(vm, pattern.borrow_value(), flags)?;
do_split(vm, &regex, string, maxsplit.into_option())
}
@@ -157,9 +157,9 @@ fn do_sub(
limit: usize,
) -> PyResult {
let out = pattern.regex.replacen(
search_text.as_str().as_bytes(),
search_text.borrow_value().as_bytes(),
limit,
repl.as_str().as_bytes(),
repl.borrow_value().as_bytes(),
);
let out = String::from_utf8_lossy(&out).into_owned();
Ok(vm.new_str(out))
@@ -171,14 +171,14 @@ fn do_match(vm: &VirtualMachine, pattern: &PyPattern, search_text: PyStringRef)
regex.push_str(pattern.regex.as_str());
let regex = Regex::new(&regex).unwrap();
match regex.captures(search_text.as_str().as_bytes()) {
match regex.captures(search_text.borrow_value().as_bytes()) {
None => Ok(vm.get_none()),
Some(captures) => Ok(create_match(vm, search_text.clone(), captures)),
}
}
fn do_search(vm: &VirtualMachine, regex: &PyPattern, search_text: PyStringRef) -> PyResult {
match regex.regex.captures(search_text.as_str().as_bytes()) {
match regex.regex.captures(search_text.borrow_value().as_bytes()) {
None => Ok(vm.get_none()),
Some(captures) => Ok(create_match(vm, search_text.clone(), captures)),
}
@@ -187,7 +187,7 @@ fn do_search(vm: &VirtualMachine, regex: &PyPattern, search_text: PyStringRef) -
fn do_findall(vm: &VirtualMachine, pattern: &PyPattern, search_text: PyStringRef) -> PyResult {
let out = pattern
.regex
.captures_iter(search_text.as_str().as_bytes())
.captures_iter(search_text.borrow_value().as_bytes())
.map(|captures| match captures.len() {
1 => {
let full = captures.get(0).unwrap().as_bytes();
@@ -233,7 +233,7 @@ fn do_split(
.map(|i| usize::try_from_object(vm, i.into_object()))
.transpose()?
.unwrap_or(0);
let text = search_text.as_str().as_bytes();
let text = search_text.borrow_value().as_bytes();
// essentially Regex::split, but it outputs captures as well
let mut output = Vec::new();
let mut last = 0;
@@ -309,11 +309,11 @@ fn re_compile(
vm: &VirtualMachine,
) -> PyResult<PyPattern> {
let flags = extract_flags(flags);
make_regex(vm, pattern.as_str(), flags)
make_regex(vm, pattern.borrow_value(), flags)
}
fn re_escape(pattern: PyStringRef) -> String {
regex::escape(pattern.as_str())
regex::escape(pattern.borrow_value())
}
fn re_purge(_vm: &VirtualMachine) {}
@@ -332,9 +332,10 @@ impl PyPattern {
#[pymethod(name = "sub")]
fn sub(&self, repl: PyStringRef, text: PyStringRef, vm: &VirtualMachine) -> PyResult {
let replaced_text = self
.regex
.replace_all(text.as_str().as_bytes(), repl.as_str().as_bytes());
let replaced_text = self.regex.replace_all(
text.borrow_value().as_bytes(),
repl.borrow_value().as_bytes(),
);
let replaced_text = String::from_utf8_lossy(&replaced_text).into_owned();
Ok(vm.ctx.new_str(replaced_text))
}
@@ -386,7 +387,7 @@ impl PyMatch {
}
fn subgroup(&self, bounds: (usize, usize), vm: &VirtualMachine) -> PyObjectRef {
vm.new_str(self.haystack.as_str()[bounds.0..bounds.1].to_owned())
vm.new_str(self.haystack.borrow_value()[bounds.0..bounds.1].to_owned())
}
fn get_bounds(&self, id: PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<(usize, usize)>> {

View File

@@ -19,7 +19,8 @@ use crate::obj::objstr::{PyString, PyStringRef};
use crate::obj::objtuple::PyTupleRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{
Either, IntoPyObject, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
BorrowValue, Either, IntoPyObject, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject,
};
use crate::vm::VirtualMachine;
@@ -434,7 +435,7 @@ struct Address {
impl ToSocketAddrs for Address {
type Iter = std::vec::IntoIter<SocketAddr>;
fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
(self.host.as_str(), self.port).to_socket_addrs()
(self.host.borrow_value(), self.port).to_socket_addrs()
}
}
@@ -445,7 +446,7 @@ impl TryFromObject for Address {
Err(vm.new_type_error("Address tuple should have only 2 values".to_owned()))
} else {
let host = PyStringRef::try_from_object(vm, tuple.as_slice()[0].clone())?;
let host = if host.as_str().is_empty() {
let host = if host.borrow_value().is_empty() {
PyString::from("0.0.0.0").into_ref(vm)
} else {
host
@@ -478,12 +479,12 @@ fn socket_gethostname(vm: &VirtualMachine) -> PyResult {
#[cfg(all(unix, not(target_os = "redox")))]
fn socket_sethostname(hostname: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
sethostname(hostname.as_str()).map_err(|err| err.into_pyexception(vm))
sethostname(hostname.borrow_value()).map_err(|err| err.into_pyexception(vm))
}
fn socket_inet_aton(ip_string: PyStringRef, vm: &VirtualMachine) -> PyResult {
ip_string
.as_str()
.borrow_value()
.parse::<Ipv4Addr>()
.map(|ip_addr| vm.ctx.new_bytes(ip_addr.octets().to_vec()))
.map_err(|_| vm.new_os_error("illegal IP address string passed to inet_aton".to_owned()))
@@ -523,10 +524,10 @@ fn socket_getaddrinfo(opts: GAIOptions, vm: &VirtualMachine) -> PyResult {
flags: opts.flags,
};
let host = opts.host.as_ref().map(|s| s.as_str());
let host = opts.host.as_ref().map(|s| s.borrow_value());
let port = opts.port.as_ref().map(|p| -> std::borrow::Cow<str> {
match p {
Either::A(ref s) => s.as_str().into(),
Either::A(ref s) => s.borrow_value().into(),
Either::B(i) => i.to_string().into(),
}
});
@@ -563,7 +564,7 @@ fn socket_gethostbyaddr(
vm: &VirtualMachine,
) -> PyResult<(String, PyObjectRef, PyObjectRef)> {
// TODO: figure out how to do this properly
let ai = dns_lookup::getaddrinfo(Some(addr.as_str()), None, None)
let ai = dns_lookup::getaddrinfo(Some(addr.borrow_value()), None, None)
.map_err(|e| convert_sock_error(vm, e.into()))?
.next()
.unwrap()

View File

@@ -7,7 +7,8 @@ use crate::obj::objbytearray::PyByteArrayRef;
use crate::obj::objstr::PyStringRef;
use crate::obj::{objtype::PyClassRef, objweakref::PyWeak};
use crate::pyobject::{
Either, IntoPyObject, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue,
BorrowValue, Either, IntoPyObject, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult,
PyValue,
};
use crate::types::create_type;
use crate::VirtualMachine;
@@ -120,7 +121,7 @@ fn ssl_enum_certificates(store_name: PyStringRef, vm: &VirtualMachine) -> PyResu
let open_fns = [CertStore::open_current_user, CertStore::open_local_machine];
let stores = open_fns
.iter()
.filter_map(|open| open(store_name.as_str()).ok())
.filter_map(|open| open(store_name.borrow_value()).ok())
.collect::<Vec<_>>();
let certs = stores.iter().map(|s| s.certs()).flatten().map(|c| {
let cert = vm.ctx.new_bytes(c.to_der().to_owned());
@@ -200,7 +201,7 @@ fn ssl_rand_add(string: Either<PyStringRef, PyBytesLike>, entropy: f64) {
}
};
match string {
Either::A(s) => f(s.as_str().as_bytes()),
Either::A(s) => f(s.borrow_value().as_bytes()),
Either::B(b) => b.with_ref(f),
}
}
@@ -315,7 +316,7 @@ impl PySslContext {
#[pymethod]
fn set_ciphers(&self, cipherlist: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
let ciphers = cipherlist.as_str();
let ciphers = cipherlist.borrow_value();
if ciphers.contains('\0') {
return Err(vm.new_value_error("embedded null character".to_owned()));
}
@@ -378,10 +379,10 @@ impl PySslContext {
if let Some(cadata) = args.cadata {
let cert = match cadata {
Either::A(s) => {
if !s.as_str().is_ascii() {
if !s.borrow_value().is_ascii() {
return Err(vm.new_type_error("Must be an ascii string".to_owned()));
}
X509::from_pem(s.as_str().as_bytes())
X509::from_pem(s.borrow_value().as_bytes())
}
Either::B(b) => b.with_ref(X509::from_der),
};

View File

@@ -13,7 +13,7 @@ mod _string {
};
use crate::obj::objlist::PyList;
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{IntoPyObject, PyObjectRef, PyResult};
use crate::pyobject::{BorrowValue, IntoPyObject, PyObjectRef, PyResult};
use crate::vm::VirtualMachine;
fn create_format_part(
@@ -35,7 +35,7 @@ mod _string {
#[pyfunction]
fn formatter_parser(text: PyStringRef, vm: &VirtualMachine) -> PyResult<PyList> {
let format_string =
FormatString::from_str(text.as_str()).map_err(|e| e.into_pyexception(vm))?;
FormatString::from_str(text.borrow_value()).map_err(|e| e.into_pyexception(vm))?;
let mut result = Vec::new();
let mut literal = String::new();
@@ -74,7 +74,8 @@ mod _string {
text: PyStringRef,
vm: &VirtualMachine,
) -> PyResult<(PyObjectRef, PyList)> {
let field_name = FieldName::parse(text.as_str()).map_err(|e| e.into_pyexception(vm))?;
let field_name =
FieldName::parse(text.borrow_value()).map_err(|e| e.into_pyexception(vm))?;
let first = match field_name.field_type {
FieldType::Auto => vm.new_str("".to_owned()),

View File

@@ -5,7 +5,7 @@ use rustpython_parser::parser;
use crate::obj::objstr::PyStringRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue};
use crate::pyobject::{BorrowValue, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue};
use crate::vm::VirtualMachine;
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
@@ -30,11 +30,11 @@ fn symtable_symtable(
vm: &VirtualMachine,
) -> PyResult<PySymbolTableRef> {
let mode = mode
.as_str()
.borrow_value()
.parse::<compile::Mode>()
.map_err(|err| vm.new_value_error(err.to_string()))?;
let symtable = source_to_symtable(source.as_str(), mode, filename.as_str())
let symtable = source_to_symtable(source.borrow_value(), mode, filename.borrow_value())
.map_err(|err| vm.new_syntax_error(&err))?;
let py_symbol_table = to_py_symbol_table(symtable);
@@ -105,7 +105,7 @@ impl PySymbolTable {
#[pymethod(name = "lookup")]
fn lookup(&self, name: PyStringRef, vm: &VirtualMachine) -> PyResult<PySymbolRef> {
let name = name.as_str();
let name = name.borrow_value();
if let Some(symbol) = self.symtable.symbols.get(name) {
Ok(PySymbol {
symbol: symbol.clone(),

View File

@@ -6,8 +6,8 @@ use crate::obj::objstr::PyStringRef;
use crate::obj::objtuple::PyTupleRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{
Either, IdProtocol, ItemProtocol, PyCallable, PyClassImpl, PyObjectRef, PyRef, PyResult,
PyValue, TypeProtocol,
BorrowValue, Either, IdProtocol, ItemProtocol, PyCallable, PyClassImpl, PyObjectRef, PyRef,
PyResult, PyValue, TypeProtocol,
};
use crate::vm::VirtualMachine;
@@ -238,7 +238,7 @@ fn thread_start_new_thread(
let repr = vm.to_repr(&func.into_object()).ok();
let repr = repr
.as_ref()
.map_or("<object repr() failed>", |s| s.as_str());
.map_or("<object repr() failed>", |s| s.borrow_value());
writeln!(stderr, "Exception ignored in thread started by: {}", repr)
.and_then(|()| exceptions::write_exception(&mut stderr, vm, &exc))
.ok();
@@ -306,7 +306,7 @@ impl PyLocal {
#[pymethod(magic)]
fn getattribute(zelf: PyRef<Self>, attr: PyStringRef, vm: &VirtualMachine) -> PyResult {
let ldict = zelf.ldict(vm);
if attr.as_str() == "__dict__" {
if attr.borrow_value() == "__dict__" {
Ok(ldict.into_object())
} else {
let zelf = zelf.into_object();
@@ -324,7 +324,7 @@ impl PyLocal {
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
if attr.as_str() == "__dict__" {
if attr.borrow_value() == "__dict__" {
Err(vm.new_attribute_error(format!(
"{} attribute '__dict__' is read-only",
zelf.as_object()
@@ -337,7 +337,7 @@ impl PyLocal {
#[pymethod(magic)]
fn delattr(zelf: PyRef<Self>, attr: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
if attr.as_str() == "__dict__" {
if attr.borrow_value() == "__dict__" {
Err(vm.new_attribute_error(format!(
"{} attribute '__dict__' is read-only",
zelf.as_object()

View File

@@ -11,7 +11,7 @@ use crate::function::OptionalArg;
use crate::obj::objstr::PyStringRef;
use crate::obj::objtuple::PyTupleRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{Either, PyClassImpl, PyObjectRef, PyResult, TryFromObject};
use crate::pyobject::{BorrowValue, Either, PyClassImpl, PyObjectRef, PyResult, TryFromObject};
use crate::vm::VirtualMachine;
#[cfg(unix)]
@@ -152,7 +152,7 @@ fn time_strftime(
OptionalArg::Present(t) => t.to_date_time(vm)?,
OptionalArg::Missing => default,
};
let formatted_time = instant.format(format.as_str()).to_string();
let formatted_time = instant.format(format.borrow_value()).to_string();
Ok(vm.ctx.new_str(formatted_time))
}
@@ -162,10 +162,10 @@ fn time_strptime(
vm: &VirtualMachine,
) -> PyResult {
let format = match format {
OptionalArg::Present(ref format) => format.as_str(),
OptionalArg::Present(ref format) => format.borrow_value(),
OptionalArg::Missing => "%a %b %H:%M:%S %Y",
};
let instant = NaiveDateTime::parse_from_str(string.as_str(), format)
let instant = NaiveDateTime::parse_from_str(string.borrow_value(), format)
.map_err(|e| vm.new_value_error(format!("Parse error: {:?}", e)))?;
Ok(PyStructTime::new(vm, instant, -1).into_obj(vm))
}

View File

@@ -4,14 +4,13 @@
use std::iter::FromIterator;
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{BorrowValue, PyObjectRef, PyResult};
use crate::vm::VirtualMachine;
use rustpython_parser::lexer;
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{PyObjectRef, PyResult};
use crate::vm::VirtualMachine;
fn tokenize_tokenize(s: PyStringRef, vm: &VirtualMachine) -> PyResult {
let source = s.as_str();
let source = s.borrow_value();
// TODO: implement generator when the time has come.
let lexer1 = lexer::make_tokenizer(source);

View File

@@ -5,7 +5,7 @@
use crate::function::OptionalArg;
use crate::obj::objstr::PyStringRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{PyClassImpl, PyObject, PyObjectRef, PyResult, PyValue};
use crate::pyobject::{BorrowValue, PyClassImpl, PyObject, PyObjectRef, PyResult, PyValue};
use crate::vm::VirtualMachine;
use itertools::Itertools;
@@ -82,9 +82,13 @@ impl PyUCD {
}
fn extract_char(&self, character: PyStringRef, vm: &VirtualMachine) -> PyResult<Option<char>> {
let c = character.as_str().chars().exactly_one().map_err(|_| {
vm.new_type_error("argument must be an unicode character, not str".to_owned())
})?;
let c = character
.borrow_value()
.chars()
.exactly_one()
.map_err(|_| {
vm.new_type_error("argument must be an unicode character, not str".to_owned())
})?;
if self.check_age(c) {
Ok(Some(c))
@@ -104,7 +108,7 @@ impl PyUCD {
#[pymethod]
fn lookup(&self, name: PyStringRef, vm: &VirtualMachine) -> PyResult<String> {
if let Some(character) = unicode_names2::character(name.as_str()) {
if let Some(character) = unicode_names2::character(name.borrow_value()) {
if self.check_age(character) {
return Ok(character.to_string());
}
@@ -150,8 +154,8 @@ impl PyUCD {
unistr: PyStringRef,
vm: &VirtualMachine,
) -> PyResult<String> {
let text = unistr.as_str();
let normalized_text = match form.as_str() {
let text = unistr.borrow_value();
let normalized_text = match form.borrow_value() {
"NFC" => text.nfc().collect::<String>(),
"NFKC" => text.nfkc().collect::<String>(),
"NFD" => text.nfd().collect::<String>(),

View File

@@ -13,7 +13,7 @@ use super::os::errno_err;
use crate::function::OptionalArg;
use crate::obj::objdict::{PyDictRef, PyMapping};
use crate::obj::objstr::PyStringRef;
use crate::pyobject::{PyObjectRef, PyResult, PySequence, TryFromObject};
use crate::pyobject::{BorrowValue, PyObjectRef, PyResult, PySequence, TryFromObject};
use crate::VirtualMachine;
fn GetLastError() -> u32 {
@@ -170,10 +170,10 @@ fn _winapi_CreateProcess(
.map_or_else(null_mut, |l| l.attrlist.as_mut_ptr() as _);
let wstr = |s: PyStringRef| {
if s.as_str().contains('\0') {
if s.borrow_value().contains('\0') {
Err(vm.new_value_error("embedded null character".to_owned()))
} else {
Ok(s.as_str()
Ok(s.borrow_value()
.encode_utf16()
.chain(std::iter::once(0))
.collect::<Vec<_>>())
@@ -227,9 +227,9 @@ fn getenvironment(env: PyDictRef, vm: &VirtualMachine) -> PyResult<Vec<u16>> {
let mut out = vec![];
for (k, v) in env {
let k = PyStringRef::try_from_object(vm, k)?;
let k = k.as_str();
let k = k.borrow_value();
let v = PyStringRef::try_from_object(vm, v)?;
let v = v.as_str();
let v = v.borrow_value();
if k.contains('\0') || v.contains('\0') {
return Err(vm.new_value_error("embedded null character".to_owned()));
}

View File

@@ -4,7 +4,9 @@ use crate::exceptions::IntoPyException;
use crate::function::OptionalArg;
use crate::obj::objstr::PyStringRef;
use crate::obj::objtype::PyClassRef;
use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject};
use crate::pyobject::{
BorrowValue, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
};
use crate::VirtualMachine;
use std::convert::TryInto;
@@ -112,7 +114,7 @@ fn winreg_OpenKey(
return Err(vm.new_value_error("reserved param must be 0".to_owned()));
}
let subkey = subkey.as_ref().map_or("", |s| s.as_str());
let subkey = subkey.as_ref().map_or("", |s| s.borrow_value());
let key = key
.with_key(|k| k.open_subkey_with_flags(subkey, access))
.map_err(|e| e.into_pyexception(vm))?;
@@ -125,7 +127,7 @@ fn winreg_QueryValue(
subkey: Option<PyStringRef>,
vm: &VirtualMachine,
) -> PyResult<String> {
let subkey = subkey.as_ref().map_or("", |s| s.as_str());
let subkey = subkey.as_ref().map_or("", |s| s.borrow_value());
key.with_key(|k| k.get_value(subkey))
.map_err(|e| e.into_pyexception(vm))
}
@@ -135,7 +137,7 @@ fn winreg_QueryValueEx(
subkey: Option<PyStringRef>,
vm: &VirtualMachine,
) -> PyResult<(PyObjectRef, usize)> {
let subkey = subkey.as_ref().map_or("", |s| s.as_str());
let subkey = subkey.as_ref().map_or("", |s| s.borrow_value());
key.with_key(|k| k.get_raw_value(subkey))
.map_err(|e| e.into_pyexception(vm))
.and_then(|regval| {

View File

@@ -40,8 +40,8 @@ use crate::obj::objstr::{PyString, PyStringRef};
use crate::obj::objtuple::PyTuple;
use crate::obj::objtype::{self, PyClassRef};
use crate::pyobject::{
IdProtocol, ItemProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
TryFromObject, TryIntoRef, TypeProtocol, BorrowValue
BorrowValue, IdProtocol, ItemProtocol, PyContext, PyObject, PyObjectRef, PyRef, PyResult,
PyValue, TryFromObject, TryIntoRef, TypeProtocol,
};
use crate::scope::Scope;
use crate::stdlib;
@@ -655,7 +655,7 @@ impl VirtualMachine {
pub fn to_pystr<'a, T: Into<&'a PyObjectRef>>(&'a self, obj: T) -> PyResult<String> {
let py_str_obj = self.to_str(obj.into())?;
Ok(py_str_obj.as_str().to_owned())
Ok(py_str_obj.borrow_value().to_owned())
}
pub fn to_repr(&self, obj: &PyObjectRef) -> PyResult<PyStringRef> {
@@ -666,7 +666,7 @@ impl VirtualMachine {
pub fn to_ascii(&self, obj: &PyObjectRef) -> PyResult {
let repr = self.call_method(obj, "__repr__", vec![])?;
let repr: PyStringRef = TryFromObject::try_from_object(self, repr)?;
let ascii = to_ascii(repr.as_str());
let ascii = to_ascii(repr.borrow_value());
Ok(self.new_str(ascii))
}
@@ -1023,7 +1023,7 @@ impl VirtualMachine {
name_str: PyStringRef,
dict: Option<PyDictRef>,
) -> PyResult<Option<PyObjectRef>> {
let name = name_str.as_str();
let name = name_str.borrow_value();
let cls = obj.class();
if let Some(attr) = cls.get_attr(&name) {
@@ -1037,7 +1037,7 @@ impl VirtualMachine {
let dict = dict.or_else(|| obj.dict());
let attr = if let Some(dict) = dict {
dict.get_item_option(name_str.as_str(), self)?
dict.get_item_option(name, self)?
} else {
None
};

View File

@@ -9,7 +9,7 @@ use rustpython_vm::function::{OptionalArg, PyFuncArgs};
use rustpython_vm::import::import_file;
use rustpython_vm::obj::{objdict::PyDictRef, objstr::PyStringRef, objtype::PyClassRef};
use rustpython_vm::pyobject::{
PyCallable, PyClassImpl, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
BorrowValue, PyCallable, PyClassImpl, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
};
use rustpython_vm::VirtualMachine;
@@ -71,14 +71,14 @@ fn browser_fetch(url: PyStringRef, args: FetchArgs, vm: &VirtualMachine) -> PyRe
} = args;
let response_format = match response_format {
Some(s) => FetchResponseFormat::from_str(vm, s.as_str())?,
Some(s) => FetchResponseFormat::from_str(vm, s.borrow_value())?,
None => FetchResponseFormat::Text,
};
let mut opts = web_sys::RequestInit::new();
match method {
Some(s) => opts.method(s.as_str()),
Some(s) => opts.method(s.borrow_value()),
None => opts.method("GET"),
};
@@ -86,7 +86,7 @@ fn browser_fetch(url: PyStringRef, args: FetchArgs, vm: &VirtualMachine) -> PyRe
opts.body(Some(&convert::py_to_js(vm, body)));
}
let request = web_sys::Request::new_with_str_and_init(url.as_str(), &opts)
let request = web_sys::Request::new_with_str_and_init(url.borrow_value(), &opts)
.map_err(|err| convert::js_py_typeerror(vm, err))?;
if let Some(headers) = headers {
@@ -94,7 +94,7 @@ fn browser_fetch(url: PyStringRef, args: FetchArgs, vm: &VirtualMachine) -> PyRe
for (key, value) in headers {
let key = vm.to_str(&key)?;
let value = vm.to_str(&value)?;
h.set(key.as_str(), value.as_str())
h.set(key.borrow_value(), value.borrow_value())
.map_err(|err| convert::js_py_typeerror(vm, err))?;
}
}
@@ -102,7 +102,7 @@ fn browser_fetch(url: PyStringRef, args: FetchArgs, vm: &VirtualMachine) -> PyRe
if let Some(content_type) = content_type {
request
.headers()
.set("Content-Type", content_type.as_str())
.set("Content-Type", content_type.borrow_value())
.map_err(|err| convert::js_py_typeerror(vm, err))?;
}
@@ -266,7 +266,7 @@ impl Document {
fn query(&self, query: PyStringRef, vm: &VirtualMachine) -> PyResult {
let elem = self
.doc
.query_selector(query.as_str())
.query_selector(query.borrow_value())
.map_err(|err| convert::js_py_typeerror(vm, err))?;
let elem = match elem {
Some(elem) => Element { elem }.into_ref(vm).into_object(),
@@ -297,7 +297,7 @@ impl Element {
default: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyObjectRef {
match self.elem.get_attribute(attr.as_str()) {
match self.elem.get_attribute(attr.borrow_value()) {
Some(s) => vm.new_str(s),
None => default.into_option().unwrap_or_else(|| vm.get_none()),
}
@@ -306,7 +306,7 @@ impl Element {
#[pymethod]
fn set_attr(&self, attr: PyStringRef, value: PyStringRef, vm: &VirtualMachine) -> PyResult<()> {
self.elem
.set_attribute(attr.as_str(), value.as_str())
.set_attribute(attr.borrow_value(), value.borrow_value())
.map_err(|err| convert::js_py_typeerror(vm, err))
}
}
@@ -317,7 +317,7 @@ fn browser_load_module(module: PyStringRef, path: PyStringRef, vm: &VirtualMachi
let mut opts = web_sys::RequestInit::new();
opts.method("GET");
let request = web_sys::Request::new_with_str_and_init(path.as_str(), &opts)
let request = web_sys::Request::new_with_str_and_init(path.borrow_value(), &opts)
.map_err(|err| convert::js_py_typeerror(vm, err))?;
let window = window();
@@ -337,7 +337,7 @@ fn browser_load_module(module: PyStringRef, path: PyStringRef, vm: &VirtualMachi
.expect("that the vm is valid when the promise resolves");
let vm = &stored_vm.vm;
let resp_text = text.as_string().unwrap();
let res = import_file(vm, module.as_str(), "WEB".to_owned(), resp_text);
let res = import_file(vm, module.borrow_value(), "WEB".to_owned(), resp_text);
match res {
Ok(_) => Ok(JsValue::null()),
Err(err) => Err(convert::py_err_to_js_err(vm, &err)),

View File

@@ -3,7 +3,9 @@ use rustpython_vm::common::rc::PyRc;
use rustpython_vm::exceptions::PyBaseExceptionRef;
use rustpython_vm::function::Args;
use rustpython_vm::obj::{objfloat::PyFloatRef, objstr::PyStringRef, objtype::PyClassRef};
use rustpython_vm::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject};
use rustpython_vm::pyobject::{
BorrowValue, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
};
use rustpython_vm::types::create_type;
use rustpython_vm::VirtualMachine;
use wasm_bindgen::{prelude::*, JsCast};
@@ -61,7 +63,7 @@ impl TryFromObject for JsProperty {
impl JsProperty {
fn into_jsvalue(self) -> JsValue {
match self {
JsProperty::Str(s) => s.as_str().into(),
JsProperty::Str(s) => s.borrow_value().into(),
JsProperty::Js(value) => value.value.clone(),
}
}
@@ -88,7 +90,7 @@ impl PyJsValue {
#[pymethod]
fn new_from_str(&self, s: PyStringRef) -> PyJsValue {
PyJsValue::new(s.as_str())
PyJsValue::new(s.borrow_value())
}
#[pymethod]

View File

@@ -7,7 +7,7 @@
use web_sys::{self, console};
use rustpython_vm::obj::objstr::PyStringRef;
use rustpython_vm::pyobject::{PyObjectRef, PyResult};
use rustpython_vm::pyobject::{BorrowValue, PyObjectRef, PyResult};
use rustpython_vm::VirtualMachine;
pub(crate) fn window() -> web_sys::Window {
@@ -26,7 +26,7 @@ pub fn make_stdout_object(
let ctx = &vm.ctx;
let write_method = ctx.new_method(
move |_self: PyObjectRef, data: PyStringRef, vm: &VirtualMachine| -> PyResult<()> {
write_f(data.as_str(), vm)
write_f(data.borrow_value(), vm)
},
);
let flush_method = ctx.new_method(|_self: PyObjectRef| {});