Skip to content

Commit 11aefa3

Browse files
authored
Merge pull request RustPython#4735 from youknowone/try_from_borrowed_object
apply TryFromBorrowed more
2 parents 1795740 + b08f415 commit 11aefa3

File tree

25 files changed

+116
-172
lines changed

25 files changed

+116
-172
lines changed

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ fn setup_main_module(vm: &VirtualMachine) -> PyResult<Scope> {
106106
.expect("Failed to initialize __main__.__annotations__");
107107

108108
vm.sys_module
109-
.clone()
110109
.get_attr("modules", vm)?
111110
.set_item("__main__", main_module, vm)?;
112111

src/shell.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> {
105105
let prompt_name = if continuing { "ps2" } else { "ps1" };
106106
let prompt = vm
107107
.sys_module
108-
.clone()
109108
.get_attr(prompt_name, vm)
110109
.and_then(|prompt| prompt.str(vm));
111110
let prompt = match prompt {

stdlib/src/array.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ mod array {
4444
atomic_func,
4545
builtins::{
4646
PositionIterInternal, PyByteArray, PyBytes, PyBytesRef, PyDictRef, PyFloat, PyInt,
47-
PyIntRef, PyList, PyListRef, PyStr, PyStrRef, PyTupleRef, PyTypeRef,
47+
PyList, PyListRef, PyStr, PyStrRef, PyTupleRef, PyTypeRef,
4848
},
4949
class_or_notimplemented,
50-
convert::{ToPyObject, ToPyResult, TryFromObject},
50+
convert::{ToPyObject, ToPyResult, TryFromBorrowedObject, TryFromObject},
5151
function::{
5252
ArgBytesLike, ArgIntoFloat, ArgIterable, KwArgs, OptionalArg, PyComparisonValue,
5353
},
@@ -828,7 +828,7 @@ mod array {
828828

829829
#[pymethod]
830830
fn fromunicode(zelf: &Py<Self>, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
831-
let utf8 = PyStrRef::try_from_object(vm, obj.clone()).map_err(|_| {
831+
let utf8: &str = obj.try_to_value(vm).map_err(|_| {
832832
vm.new_type_error(format!(
833833
"fromunicode() argument must be str, not {}",
834834
obj.class().name()
@@ -840,7 +840,7 @@ mod array {
840840
));
841841
}
842842
let mut w = zelf.try_resizable(vm)?;
843-
let bytes = Self::_unicode_to_wchar_bytes(utf8.as_str(), w.itemsize());
843+
let bytes = Self::_unicode_to_wchar_bytes(utf8, w.itemsize());
844844
w.frombytes_move(bytes);
845845
Ok(())
846846
}
@@ -1489,9 +1489,9 @@ mod array {
14891489
}
14901490
}
14911491

1492-
impl TryFromObject for MachineFormatCode {
1493-
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
1494-
PyIntRef::try_from_object(vm, obj.clone())
1492+
impl<'a> TryFromBorrowedObject<'a> for MachineFormatCode {
1493+
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
1494+
obj.try_to_ref::<PyInt>(vm)
14951495
.map_err(|_| {
14961496
vm.new_type_error(format!(
14971497
"an integer is required (got type {})",

stdlib/src/csv.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pub(crate) use _csv::make_module;
44
mod _csv {
55
use crate::common::lock::PyMutex;
66
use crate::vm::{
7-
builtins::{PyStr, PyStrRef, PyTypeRef},
7+
builtins::{PyStr, PyTypeRef},
88
function::{ArgIterable, ArgumentError, FromArgs, FuncArgs},
99
match_class,
1010
protocol::{PyIter, PyIterReturn},
@@ -97,8 +97,8 @@ mod _csv {
9797
impl FromArgs for FormatOptions {
9898
fn from_args(vm: &VirtualMachine, args: &mut FuncArgs) -> Result<Self, ArgumentError> {
9999
let delimiter = if let Some(delimiter) = args.kwargs.remove("delimiter") {
100-
PyStrRef::try_from_object(vm, delimiter)?
101-
.as_str()
100+
delimiter
101+
.try_to_value::<&str>(vm)?
102102
.bytes()
103103
.exactly_one()
104104
.map_err(|_| {
@@ -110,8 +110,8 @@ mod _csv {
110110
};
111111

112112
let quotechar = if let Some(quotechar) = args.kwargs.remove("quotechar") {
113-
PyStrRef::try_from_object(vm, quotechar)?
114-
.as_str()
113+
quotechar
114+
.try_to_value::<&str>(vm)?
115115
.bytes()
116116
.exactly_one()
117117
.map_err(|_| {

vm/src/anystr.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::{
2-
builtins::{PyIntRef, PyTupleRef},
2+
builtins::{PyIntRef, PyTuple},
33
cformat::cformat_string,
4+
convert::TryFromBorrowedObject,
45
function::OptionalOption,
5-
PyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
6+
Py, PyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
67
};
78
use num_traits::{cast::ToPrimitive, sign::Signed};
89

@@ -213,21 +214,21 @@ pub trait AnyStr {
213214
F: Fn(&Self) -> PyObjectRef;
214215

215216
#[inline]
216-
fn py_startsendswith<T, F>(
217+
fn py_startsendswith<'a, T, F>(
217218
&self,
218-
affix: PyObjectRef,
219+
affix: &'a PyObject,
219220
func_name: &str,
220221
py_type_name: &str,
221222
func: F,
222223
vm: &VirtualMachine,
223224
) -> PyResult<bool>
224225
where
225-
T: TryFromObject,
226-
F: Fn(&Self, &T) -> bool,
226+
T: TryFromBorrowedObject<'a>,
227+
F: Fn(&Self, T) -> bool,
227228
{
228229
single_or_tuple_any(
229230
affix,
230-
&|s: &T| Ok(func(self, s)),
231+
&|s: T| Ok(func(self, s)),
231232
&|o| {
232233
format!(
233234
"{} first arg must be {} or a tuple of {}, not {}",
@@ -448,24 +449,25 @@ pub trait AnyStr {
448449
/// test that any of the values contained within the tuples satisfies the predicate. Type parameter
449450
/// T specifies the type that is expected, if the input value is not of that type or a tuple of
450451
/// values of that type, then a TypeError is raised.
451-
pub fn single_or_tuple_any<T, F, M>(
452-
obj: PyObjectRef,
452+
pub fn single_or_tuple_any<'a, T, F, M>(
453+
obj: &'a PyObject,
453454
predicate: &F,
454455
message: &M,
455456
vm: &VirtualMachine,
456457
) -> PyResult<bool>
457458
where
458-
T: TryFromObject,
459-
F: Fn(&T) -> PyResult<bool>,
459+
T: TryFromBorrowedObject<'a>,
460+
F: Fn(T) -> PyResult<bool>,
460461
M: Fn(&PyObject) -> String,
461462
{
462-
match T::try_from_object(vm, obj.clone()) {
463-
Ok(single) => (predicate)(&single),
463+
match obj.try_to_value::<T>(vm) {
464+
Ok(single) => (predicate)(single),
464465
Err(_) => {
465-
let tuple = PyTupleRef::try_from_object(vm, obj.clone())
466-
.map_err(|_| vm.new_type_error((message)(&obj)))?;
467-
for obj in &tuple {
468-
if single_or_tuple_any(obj.clone(), predicate, message, vm)? {
466+
let tuple: &Py<PyTuple> = obj
467+
.try_to_value(vm)
468+
.map_err(|_| vm.new_type_error((message)(obj)))?;
469+
for obj in tuple {
470+
if single_or_tuple_any(obj, predicate, message, vm)? {
469471
return Ok(true);
470472
}
471473
}

vm/src/builtins/bytearray.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,10 @@ impl PyByteArray {
375375
None => return Ok(false),
376376
};
377377
substr.py_startsendswith(
378-
affix,
378+
&affix,
379379
"endswith",
380380
"bytes",
381-
|s, x: &PyBytesInner| s.ends_with(x.as_bytes()),
381+
|s, x: PyBytesInner| s.ends_with(x.as_bytes()),
382382
vm,
383383
)
384384
}
@@ -396,10 +396,10 @@ impl PyByteArray {
396396
None => return Ok(false),
397397
};
398398
substr.py_startsendswith(
399-
affix,
399+
&affix,
400400
"startswith",
401401
"bytes",
402-
|s, x: &PyBytesInner| s.starts_with(x.as_bytes()),
402+
|s, x: PyBytesInner| s.starts_with(x.as_bytes()),
403403
vm,
404404
)
405405
}

vm/src/builtins/bytes.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,10 @@ impl PyBytes {
300300
None => return Ok(false),
301301
};
302302
substr.py_startsendswith(
303-
affix,
303+
&affix,
304304
"endswith",
305305
"bytes",
306-
|s, x: &PyBytesInner| s.ends_with(x.as_bytes()),
306+
|s, x: PyBytesInner| s.ends_with(x.as_bytes()),
307307
vm,
308308
)
309309
}
@@ -320,10 +320,10 @@ impl PyBytes {
320320
None => return Ok(false),
321321
};
322322
substr.py_startsendswith(
323-
affix,
323+
&affix,
324324
"startswith",
325325
"bytes",
326-
|s, x: &PyBytesInner| s.starts_with(x.as_bytes()),
326+
|s, x: PyBytesInner| s.starts_with(x.as_bytes()),
327327
vm,
328328
)
329329
}

vm/src/builtins/genericalias.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ impl Constructor for PyGenericAlias {
7777
)]
7878
impl PyGenericAlias {
7979
pub fn new(origin: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> Self {
80-
let args: PyTupleRef = if let Ok(tuple) = PyTupleRef::try_from_object(vm, args.clone()) {
81-
tuple
80+
let args = if let Ok(tuple) = args.try_to_ref::<PyTuple>(vm) {
81+
tuple.to_owned()
8282
} else {
8383
PyTuple::new_ref(vec![args], &vm.ctx)
8484
};
@@ -224,21 +224,19 @@ pub(crate) fn is_typevar(obj: &PyObjectRef, vm: &VirtualMachine) -> bool {
224224
.unwrap_or(false)
225225
}
226226

227-
fn make_parameters(args: &PyTupleRef, vm: &VirtualMachine) -> PyTupleRef {
227+
pub(crate) fn make_parameters(args: &Py<PyTuple>, vm: &VirtualMachine) -> PyTupleRef {
228228
let mut parameters: Vec<PyObjectRef> = Vec::with_capacity(args.len());
229229
for arg in args {
230230
if is_typevar(arg, vm) {
231231
if !parameters.iter().any(|param| param.is(arg)) {
232232
parameters.push(arg.clone());
233233
}
234-
} else if let Ok(subparams) = arg
235-
.clone()
236-
.get_attr(identifier!(vm, __parameters__), vm)
237-
.and_then(|obj| PyTupleRef::try_from_object(vm, obj))
238-
{
239-
for sub_param in &subparams {
240-
if !parameters.iter().any(|param| param.is(sub_param)) {
241-
parameters.push(sub_param.clone());
234+
} else if let Ok(obj) = arg.get_attr(identifier!(vm, __parameters__), vm) {
235+
if let Ok(sub_params) = obj.try_to_ref::<PyTuple>(vm) {
236+
for sub_param in sub_params {
237+
if !parameters.iter().any(|param| param.is(sub_param)) {
238+
parameters.push(sub_param.clone());
239+
}
242240
}
243241
}
244242
}
@@ -259,13 +257,12 @@ fn subs_tvars(
259257
argitems: &[PyObjectRef],
260258
vm: &VirtualMachine,
261259
) -> PyResult {
262-
obj.clone()
263-
.get_attr(identifier!(vm, __parameters__), vm)
260+
obj.get_attr(identifier!(vm, __parameters__), vm)
264261
.ok()
265262
.and_then(|sub_params| {
266263
PyTupleRef::try_from_object(vm, sub_params)
267264
.ok()
268-
.map(|sub_params| {
265+
.and_then(|sub_params| {
269266
if sub_params.len() > 0 {
270267
let sub_args = sub_params
271268
.iter()
@@ -284,7 +281,6 @@ fn subs_tvars(
284281
}
285282
})
286283
})
287-
.flatten()
288284
.unwrap_or(Ok(obj))
289285
}
290286

@@ -300,9 +296,9 @@ pub fn subs_parameters<F: Fn(&VirtualMachine) -> PyResult<String>>(
300296
return Err(vm.new_type_error(format!("There are no type variables left in {}", repr(vm)?)));
301297
}
302298

303-
let items = PyTupleRef::try_from_object(vm, needle.clone());
299+
let items = needle.try_to_ref::<PyTuple>(vm);
304300
let arg_items = match items {
305-
Ok(ref tuple) => tuple.as_slice(),
301+
Ok(tuple) => tuple.as_slice(),
306302
Err(_) => std::slice::from_ref(&needle),
307303
};
308304

vm/src/builtins/str.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -647,10 +647,10 @@ impl PyStr {
647647
None => return Ok(false),
648648
};
649649
substr.py_startsendswith(
650-
affix,
650+
&affix,
651651
"endswith",
652652
"str",
653-
|s, x: &PyStrRef| s.ends_with(x.as_str()),
653+
|s, x: &Py<PyStr>| s.ends_with(x.as_str()),
654654
vm,
655655
)
656656
}
@@ -667,10 +667,10 @@ impl PyStr {
667667
None => return Ok(false),
668668
};
669669
substr.py_startsendswith(
670-
affix,
670+
&affix,
671671
"startswith",
672672
"str",
673-
|s, x: &PyStrRef| s.starts_with(x.as_str()),
673+
|s, x: &Py<PyStr>| s.starts_with(x.as_str()),
674674
vm,
675675
)
676676
}

vm/src/builtins/tuple.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl<'a> std::iter::IntoIterator for &'a PyTuple {
139139
}
140140
}
141141

142-
impl<'a> std::iter::IntoIterator for &'a PyTupleRef {
142+
impl<'a> std::iter::IntoIterator for &'a Py<PyTuple> {
143143
type Item = &'a PyObjectRef;
144144
type IntoIter = std::slice::Iter<'a, PyObjectRef>;
145145

@@ -482,7 +482,7 @@ pub struct PyTupleTyped<T: TransmuteFromObject> {
482482
impl<T: TransmuteFromObject> TryFromObject for PyTupleTyped<T> {
483483
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
484484
let tuple = PyTupleRef::try_from_object(vm, obj)?;
485-
for elem in &tuple {
485+
for elem in &*tuple {
486486
T::check(vm, elem)?
487487
}
488488
// SAFETY: the contract of TransmuteFromObject upholds the variant on `tuple`

0 commit comments

Comments
 (0)