Skip to content

Commit 273729d

Browse files
authored
Merge pull request RustPython#3264 from youknowone/new-return-type
Make PyContext::new* to return PyRef instead of PyObjectRef
2 parents d4b7a03 + 379cf2d commit 273729d

36 files changed

+269
-249
lines changed

derive/src/pymodule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ impl ModuleItem for FunctionItem {
290290
#doc
291291
.into_function()
292292
.with_module(vm.ctx.new_utf8_str(#module.to_owned()))
293-
.build(&vm.ctx)
293+
.into_ref(&vm.ctx)
294294
);
295295
quote! {
296296
vm.__module_set_attr(&module, #py_name, #new_func).unwrap();

examples/mini_repl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn run(vm: &vm::VirtualMachine) -> vm::PyResult<()> {
4343
// typing `quit()` is too long, let's make `on(False)` work instead.
4444
scope
4545
.globals
46-
.set_item("on", vm.ctx.new_function("on", on), vm)?;
46+
.set_item("on", vm.ctx.new_function("on", on).into(), vm)?;
4747

4848
// let's include a fibonacci function, but let's be lazy and write it in Python
4949
add_python_function!(

stdlib/src/fcntl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ mod fcntl {
4343
if ret < 0 {
4444
return Err(os::errno_err(vm));
4545
}
46-
return Ok(vm.ctx.new_bytes(buf[..arg_len].to_vec()));
46+
return Ok(vm.ctx.new_bytes(buf[..arg_len].to_vec()).into());
4747
}
4848
OptionalArg::Present(Either::B(i)) => i.as_u32_mask(),
4949
OptionalArg::Missing => 0,
@@ -96,7 +96,7 @@ mod fcntl {
9696
if ret < 0 {
9797
return Err(os::errno_err(vm));
9898
}
99-
Ok(vm.ctx.new_bytes(buf[..buf_len].to_vec()))
99+
Ok(vm.ctx.new_bytes(buf[..buf_len].to_vec()).into())
100100
}
101101
Either::B(i) => {
102102
let ret = unsafe { libc::ioctl(fd, request as _, i) };

stdlib/src/pyexpat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ macro_rules! create_property {
2525
move |this: &PyExpatLikeXmlParser, func: PyObjectRef| *this.$element.write() = func,
2626
);
2727

28-
$attributes.insert($name.to_owned(), attr);
28+
$attributes.insert($name.to_owned(), attr.into());
2929
};
3030
}
3131

stdlib/src/socket.rs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -839,10 +839,9 @@ impl PySocket {
839839
)
840840
};
841841
if ret < 0 {
842-
Err(crate::vm::stdlib::os::errno_err(vm))
843-
} else {
844-
Ok(vm.ctx.new_int(flag).into())
842+
return Err(crate::vm::stdlib::os::errno_err(vm));
845843
}
844+
Ok(vm.ctx.new_int(flag).into())
846845
} else {
847846
if buflen <= 0 || buflen > 1024 {
848847
return Err(vm.new_os_error("getsockopt buflen out of range".to_owned()));
@@ -853,10 +852,9 @@ impl PySocket {
853852
unsafe { c::getsockopt(fd, level, name, buf.as_mut_ptr() as *mut _, &mut buflen) };
854853
buf.truncate(buflen as usize);
855854
if ret < 0 {
856-
Err(crate::vm::stdlib::os::errno_err(vm))
857-
} else {
858-
Ok(vm.ctx.new_bytes(buf))
855+
return Err(crate::vm::stdlib::os::errno_err(vm));
859856
}
857+
Ok(vm.ctx.new_bytes(buf).into())
860858
}
861859
}
862860

@@ -1024,7 +1022,7 @@ fn get_addr_tuple(addr: &socket2::SockAddr, vm: &VirtualMachine) -> PyObjectRef
10241022
{
10251023
let abstractaddrlen = addr_len - sun_path_offset;
10261024
let abstractpath = &path_u8[..abstractaddrlen];
1027-
vm.ctx.new_bytes(abstractpath.to_vec())
1025+
vm.ctx.new_bytes(abstractpath.to_vec()).into()
10281026
} else {
10291027
let len = memchr::memchr(b'\0', path_u8).unwrap_or_else(|| path_u8.len());
10301028
let path = &path_u8[..len];
@@ -1304,24 +1302,24 @@ fn _socket_gethostbyname(name: PyStrRef, vm: &VirtualMachine) -> PyResult<String
13041302
}
13051303
}
13061304

1307-
fn _socket_inet_pton(af_inet: i32, ip_string: PyStrRef, vm: &VirtualMachine) -> PyResult {
1308-
match af_inet {
1305+
fn _socket_inet_pton(af_inet: i32, ip_string: PyStrRef, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
1306+
static ERROR_MSG: &str = "illegal IP address string passed to inet_pton";
1307+
let ip_addr = match af_inet {
13091308
c::AF_INET => ip_string
13101309
.as_str()
13111310
.parse::<Ipv4Addr>()
1312-
.map(|ip_addr| vm.ctx.new_bytes(ip_addr.octets().to_vec()))
1313-
.map_err(|_| {
1314-
vm.new_os_error("illegal IP address string passed to inet_pton".to_owned())
1315-
}),
1311+
.map_err(|_| vm.new_os_error(ERROR_MSG.to_owned()))?
1312+
.octets()
1313+
.to_vec(),
13161314
c::AF_INET6 => ip_string
13171315
.as_str()
13181316
.parse::<Ipv6Addr>()
1319-
.map(|ip_addr| vm.ctx.new_bytes(ip_addr.octets().to_vec()))
1320-
.map_err(|_| {
1321-
vm.new_os_error("illegal IP address string passed to inet_pton".to_owned())
1322-
}),
1323-
_ => Err(vm.new_os_error("Address family not supported by protocol".to_owned())),
1324-
}
1317+
.map_err(|_| vm.new_os_error(ERROR_MSG.to_owned()))?
1318+
.octets()
1319+
.to_vec(),
1320+
_ => return Err(vm.new_os_error("Address family not supported by protocol".to_owned())),
1321+
};
1322+
Ok(ip_addr)
13251323
}
13261324

13271325
fn _socket_inet_ntop(

stdlib/src/ssl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ impl PySslSocket {
960960
Either::B(mut buf) => {
961961
buf.truncate(n);
962962
buf.shrink_to_fit();
963-
vm.ctx.new_bytes(buf)
963+
vm.ctx.new_bytes(buf).into()
964964
}
965965
};
966966
Ok(ret)
@@ -1064,7 +1064,7 @@ fn cipher_to_tuple(cipher: &ssl::SslCipherRef) -> CipherTuple {
10641064
fn cert_to_py(vm: &VirtualMachine, cert: &X509Ref, binary: bool) -> PyResult {
10651065
let r = if binary {
10661066
let b = cert.to_der().map_err(|e| convert_openssl_error(vm, e))?;
1067-
vm.ctx.new_bytes(b)
1067+
vm.ctx.new_bytes(b).into()
10681068
} else {
10691069
let dict = vm.ctx.new_dict();
10701070

stdlib/src/termios.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ mod termios {
3434
.enumerate()
3535
.map(|(i, &c)| match i {
3636
termios::VMIN | termios::VTIME if noncanon => vm.ctx.new_int(c).into(),
37-
_ => vm.ctx.new_bytes(vec![c as u8]),
37+
_ => vm.ctx.new_bytes(vec![c as u8]).into(),
3838
})
3939
.collect::<Vec<_>>();
4040
let out = vec![

stdlib/src/zlib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ mod zlib {
9696

9797
/// Returns a bytes object containing compressed data.
9898
#[pyfunction]
99-
fn compress(data: ArgBytesLike, level: OptionalArg<i32>, vm: &VirtualMachine) -> PyResult {
99+
fn compress(
100+
data: ArgBytesLike,
101+
level: OptionalArg<i32>,
102+
vm: &VirtualMachine,
103+
) -> PyResult<PyBytesRef> {
100104
let compression = compression_from_int(level.into_option())
101105
.ok_or_else(|| new_zlib_error("Bad compression level", vm))?;
102106

vm/src/builtins/builtinfunc.rs

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use super::{pytype, PyClassMethod, PyStrRef, PyTypeRef};
1+
use super::{pytype, PyClassMethod, PyStr, PyStrRef, PyTypeRef};
22
use crate::{
3-
function::{FuncArgs, PyNativeFunc},
3+
builtins::PyBoundMethod,
4+
function::{FuncArgs, IntoPyNativeFunc, PyNativeFunc},
45
slots::{Callable, SlotDescriptor},
5-
PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
6-
VirtualMachine,
6+
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
77
};
88
use std::fmt;
99

@@ -21,34 +21,29 @@ impl PyNativeFuncDef {
2121
doc: None,
2222
}
2323
}
24-
}
2524

26-
impl PyNativeFuncDef {
2725
pub fn with_doc(mut self, doc: String, ctx: &PyContext) -> Self {
28-
self.doc = Some(ctx.new_stringref(doc));
26+
self.doc = Some(PyStr::new_ref(doc, ctx));
2927
self
3028
}
3129

3230
pub fn into_function(self) -> PyBuiltinFunction {
3331
self.into()
3432
}
35-
pub fn build_function(self, ctx: &PyContext) -> PyObjectRef {
36-
self.into_function().build(ctx)
33+
pub fn build_function(self, ctx: &PyContext) -> PyRef<PyBuiltinFunction> {
34+
self.into_function().into_ref(ctx)
3735
}
38-
pub fn build_method(self, ctx: &PyContext, class: PyTypeRef) -> PyObjectRef {
39-
PyObject::new(
36+
pub fn build_method(self, ctx: &PyContext, class: PyTypeRef) -> PyRef<PyBuiltinMethod> {
37+
PyRef::new_ref(
4038
PyBuiltinMethod { value: self, class },
4139
ctx.types.method_descriptor_type.clone(),
4240
None,
4341
)
4442
}
45-
pub fn build_classmethod(self, ctx: &PyContext, class: PyTypeRef) -> PyObjectRef {
43+
pub fn build_classmethod(self, ctx: &PyContext, class: PyTypeRef) -> PyRef<PyClassMethod> {
4644
// TODO: classmethod_descriptor
47-
PyObject::new(
48-
PyClassMethod::from(self.build_method(ctx, class)),
49-
ctx.types.classmethod_type.clone(),
50-
None,
51-
)
45+
let callable = self.build_method(ctx, class).into();
46+
PyClassMethod::new_ref(callable, ctx)
5247
}
5348
}
5449

@@ -85,8 +80,8 @@ impl PyBuiltinFunction {
8580
self
8681
}
8782

88-
pub fn build(self, ctx: &PyContext) -> PyObjectRef {
89-
PyObject::new(
83+
pub fn into_ref(self, ctx: &PyContext) -> PyRef<Self> {
84+
PyRef::new_ref(
9085
self,
9186
ctx.types.builtin_function_or_method_type.clone(),
9287
None,
@@ -183,11 +178,12 @@ impl SlotDescriptor for PyBuiltinMethod {
183178
Ok(obj) => obj,
184179
Err(result) => return result,
185180
};
186-
if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) {
187-
Ok(zelf.into())
181+
let r = if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) {
182+
zelf.into()
188183
} else {
189-
Ok(vm.ctx.new_bound_method(zelf.into(), obj))
190-
}
184+
PyBoundMethod::new_ref(obj, zelf.into(), &vm.ctx).into()
185+
};
186+
Ok(r)
191187
}
192188
}
193189

@@ -197,6 +193,20 @@ impl Callable for PyBuiltinMethod {
197193
}
198194
}
199195

196+
impl PyBuiltinMethod {
197+
pub fn new_ref<F, FKind>(
198+
name: impl Into<PyStr>,
199+
class: PyTypeRef,
200+
f: F,
201+
ctx: &PyContext,
202+
) -> PyRef<Self>
203+
where
204+
F: IntoPyNativeFunc<FKind>,
205+
{
206+
ctx.make_funcdef(name, f).build_method(ctx, class)
207+
}
208+
}
209+
200210
#[pyimpl(with(SlotDescriptor, Callable), flags(METHOD_DESCR))]
201211
impl PyBuiltinMethod {
202212
#[pyproperty(magic)]

vm/src/builtins/bytearray.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ pub struct PyByteArray {
5555
pub type PyByteArrayRef = PyRef<PyByteArray>;
5656

5757
impl PyByteArray {
58+
pub fn new_ref(data: Vec<u8>, ctx: &PyContext) -> PyRef<Self> {
59+
PyRef::new_ref(Self::from(data), ctx.types.bytearray_type.clone(), None)
60+
}
61+
5862
fn from_inner(inner: PyBytesInner) -> Self {
5963
PyByteArray {
6064
inner: PyRwLock::new(inner),
@@ -92,11 +96,6 @@ impl PyValue for PyByteArray {
9296
/// Fill bytearray class methods dictionary.
9397
pub(crate) fn init(context: &PyContext) {
9498
PyByteArray::extend_class(context, &context.types.bytearray_type);
95-
let bytearray_type = &context.types.bytearray_type;
96-
extend_class!(context, bytearray_type, {
97-
"maketrans" => context.new_method("maketrans", bytearray_type.clone(), PyBytesInner::maketrans),
98-
});
99-
10099
PyByteArrayIterator::extend_class(context, &context.types.bytearray_iterator_type);
101100
}
102101

@@ -151,8 +150,8 @@ impl PyByteArray {
151150
}
152151

153152
#[pymethod(magic)]
154-
fn add(&self, other: ArgBytesLike, vm: &VirtualMachine) -> PyObjectRef {
155-
vm.ctx.new_bytearray(self.inner().add(&*other.borrow_buf()))
153+
fn add(&self, other: ArgBytesLike) -> Self {
154+
self.inner().add(&*other.borrow_buf()).into()
156155
}
157156

158157
#[pymethod(magic)]
@@ -227,6 +226,11 @@ impl PyByteArray {
227226
}
228227
}
229228

229+
#[pymethod]
230+
fn maketrans(from: PyBytesInner, to: PyBytesInner) -> PyResult<Vec<u8>> {
231+
PyBytesInner::maketrans(from, to)
232+
}
233+
230234
#[pymethod]
231235
fn pop(zelf: PyRef<Self>, index: OptionalArg<isize>, vm: &VirtualMachine) -> PyResult<u8> {
232236
let elements = &mut zelf.try_resizable(vm)?.elements;
@@ -384,7 +388,7 @@ impl PyByteArray {
384388
fn fromhex(cls: PyTypeRef, string: PyStrRef, vm: &VirtualMachine) -> PyResult {
385389
let bytes = PyBytesInner::fromhex(string.as_str(), vm)?;
386390
let bytes = vm.ctx.new_bytes(bytes);
387-
Callable::call(&cls, vec![bytes].into(), vm)
391+
Callable::call(&cls, vec![bytes.into()].into(), vm)
388392
}
389393

390394
#[pymethod]
@@ -524,14 +528,20 @@ impl PyByteArray {
524528

525529
#[pymethod]
526530
fn split(&self, options: ByteInnerSplitOptions, vm: &VirtualMachine) -> PyResult {
527-
self.inner()
528-
.split(options, |s, vm| vm.ctx.new_bytearray(s.to_vec()), vm)
531+
self.inner().split(
532+
options,
533+
|s, vm| Self::new_ref(s.to_vec(), &vm.ctx).into(),
534+
vm,
535+
)
529536
}
530537

531538
#[pymethod]
532539
fn rsplit(&self, options: ByteInnerSplitOptions, vm: &VirtualMachine) -> PyResult {
533-
self.inner()
534-
.rsplit(options, |s, vm| vm.ctx.new_bytearray(s.to_vec()), vm)
540+
self.inner().rsplit(
541+
options,
542+
|s, vm| Self::new_ref(s.to_vec(), &vm.ctx).into(),
543+
vm,
544+
)
535545
}
536546

537547
#[pymethod]
@@ -541,10 +551,9 @@ impl PyByteArray {
541551
let value = self.inner();
542552
let (front, has_mid, back) = value.partition(&sep, vm)?;
543553
Ok(vm.new_tuple((
544-
vm.ctx.new_bytearray(front.to_vec()),
545-
vm.ctx
546-
.new_bytearray(if has_mid { sep.elements } else { Vec::new() }),
547-
vm.ctx.new_bytearray(back.to_vec()),
554+
Self::new_ref(front.to_vec(), &vm.ctx),
555+
Self::new_ref(if has_mid { sep.elements } else { Vec::new() }, &vm.ctx),
556+
Self::new_ref(back.to_vec(), &vm.ctx),
548557
)))
549558
}
550559

@@ -553,10 +562,9 @@ impl PyByteArray {
553562
let value = self.inner();
554563
let (back, has_mid, front) = value.rpartition(&sep, vm)?;
555564
Ok(vm.new_tuple((
556-
vm.ctx.new_bytearray(front.to_vec()),
557-
vm.ctx
558-
.new_bytearray(if has_mid { sep.elements } else { Vec::new() }),
559-
vm.ctx.new_bytearray(back.to_vec()),
565+
Self::new_ref(front.to_vec(), &vm.ctx),
566+
Self::new_ref(if has_mid { sep.elements } else { Vec::new() }, &vm.ctx),
567+
Self::new_ref(back.to_vec(), &vm.ctx),
560568
)))
561569
}
562570

@@ -569,7 +577,7 @@ impl PyByteArray {
569577
fn splitlines(&self, options: anystr::SplitLinesArgs, vm: &VirtualMachine) -> PyObjectRef {
570578
let lines = self
571579
.inner()
572-
.splitlines(options, |x| vm.ctx.new_bytearray(x.to_vec()));
580+
.splitlines(options, |x| Self::new_ref(x.to_vec(), &vm.ctx).into());
573581
vm.ctx.new_list(lines)
574582
}
575583

0 commit comments

Comments
 (0)