Skip to content

Commit 445c3bd

Browse files
committed
Apply PyUtf8Str
1 parent 3a58ead commit 445c3bd

File tree

23 files changed

+108
-82
lines changed

23 files changed

+108
-82
lines changed

vm/src/builtins/builtin_func.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::{PyStrInterned, PyStrRef, PyType, type_};
22
use crate::{
33
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
44
class::PyClassImpl,
5+
common::wtf8::Wtf8,
56
convert::TryFromObject,
67
function::{FuncArgs, PyComparisonValue, PyMethodDef, PyMethodFlags, PyNativeFn},
78
types::{Callable, Comparable, PyComparisonOp, Representable, Unconstructible},
@@ -27,7 +28,7 @@ impl fmt::Debug for PyNativeFunction {
2728
write!(
2829
f,
2930
"builtin function {}.{} ({:?}) self as instance of {:?}",
30-
self.module.map_or("<unknown>", |m| m.as_str()),
31+
self.module.map_or(Wtf8::new("<unknown>"), |m| m.as_wtf8()),
3132
self.value.name,
3233
self.value.flags,
3334
self.zelf.as_ref().map(|z| z.class().name().to_owned())

vm/src/builtins/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub(crate) mod bool_;
5959
pub use bool_::PyBool;
6060
#[path = "str.rs"]
6161
pub(crate) mod pystr;
62-
pub use pystr::{PyStr, PyStrInterned, PyStrRef};
62+
pub use pystr::{PyStr, PyStrInterned, PyStrRef, PyUtf8Str, PyUtf8StrRef};
6363
#[path = "super.rs"]
6464
pub(crate) mod super_;
6565
pub use super_::PySuper;

vm/src/builtins/namespace.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ impl Representable for PyNamespace {
8989
let dict = zelf.as_object().dict().unwrap();
9090
let mut parts = Vec::with_capacity(dict.__len__());
9191
for (key, value) in dict {
92-
let k = &key.repr(vm)?;
93-
let key_str = k.as_str();
92+
let k = key.repr(vm)?;
93+
let key_str = k.as_wtf8();
9494
let value_repr = value.repr(vm)?;
9595
parts.push(format!("{}={}", &key_str[1..key_str.len() - 1], value_repr));
9696
}

vm/src/builtins/slice.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,14 +292,12 @@ impl Representable for PySlice {
292292
#[inline]
293293
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
294294
let start_repr = zelf.start_ref(vm).repr(vm)?;
295-
let stop_repr = &zelf.stop.repr(vm)?;
295+
let stop_repr = zelf.stop.repr(vm)?;
296296
let step_repr = zelf.step_ref(vm).repr(vm)?;
297297

298298
Ok(format!(
299299
"slice({}, {}, {})",
300-
start_repr.as_str(),
301-
stop_repr.as_str(),
302-
step_repr.as_str()
300+
start_repr, stop_repr, step_repr
303301
))
304302
}
305303
}

vm/src/builtins/super.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl Initializer for PySuper {
104104

105105
let mut typ = None;
106106
for (i, var) in frame.code.freevars.iter().enumerate() {
107-
if var.as_str() == "__class__" {
107+
if var.as_bytes() == b"__class__" {
108108
let i = frame.code.cellvars.len() + i;
109109
let class = frame.cells_frees[i]
110110
.get()
@@ -162,7 +162,7 @@ impl GetAttr for PySuper {
162162
// We want __class__ to return the class of the super object
163163
// (i.e. super, or a subclass), not the class of su->obj.
164164

165-
if name.as_str() == "__class__" {
165+
if name.as_bytes() == b"__class__" {
166166
return skip(zelf, name);
167167
}
168168

vm/src/builtins/type.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,13 +340,13 @@ impl PyType {
340340
if name == identifier!(ctx, __new__) {
341341
continue;
342342
}
343-
if name.as_str().starts_with("__") && name.as_str().ends_with("__") {
343+
if name.as_bytes().starts_with(b"__") && name.as_bytes().ends_with(b"__") {
344344
slot_name_set.insert(name);
345345
}
346346
}
347347
}
348348
for &name in self.attributes.read().keys() {
349-
if name.as_str().starts_with("__") && name.as_str().ends_with("__") {
349+
if name.as_bytes().starts_with(b"__") && name.as_bytes().ends_with(b"__") {
350350
slot_name_set.insert(name);
351351
}
352352
}

vm/src/exceptions.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,11 @@ impl VirtualMachine {
198198
let mut filename_suffix = String::new();
199199

200200
if let Some(lineno) = maybe_lineno {
201-
writeln!(
202-
output,
203-
r##" File "{}", line {}"##,
204-
maybe_filename
205-
.as_ref()
206-
.map(|s| s.as_str())
207-
.unwrap_or("<string>"),
208-
lineno
209-
)?;
201+
let filename = match maybe_filename {
202+
Some(filename) => filename,
203+
None => vm.ctx.new_str("<string>"),
204+
};
205+
writeln!(output, r##" File "{filename}", line {lineno}"##,)?;
210206
} else if let Some(filename) = maybe_filename {
211207
filename_suffix = format!(" ({filename})");
212208
}
@@ -1498,7 +1494,7 @@ pub(super) mod types {
14981494
let args = exc.args();
14991495
let obj = exc.as_object().to_owned();
15001496

1501-
if args.len() == 2 {
1497+
let str = if args.len() == 2 {
15021498
// SAFETY: len() == 2 is checked so get_arg 1 or 2 won't panic
15031499
let errno = exc.get_arg(0).unwrap().str(vm)?;
15041500
let msg = exc.get_arg(1).unwrap().str(vm)?;
@@ -1518,10 +1514,11 @@ pub(super) mod types {
15181514
format!("[Errno {errno}] {msg}")
15191515
}
15201516
};
1521-
Ok(vm.ctx.new_str(s))
1517+
vm.ctx.new_str(s)
15221518
} else {
1523-
Ok(exc.__str__(vm))
1524-
}
1519+
exc.__str__(vm)
1520+
};
1521+
Ok(str)
15251522
}
15261523

15271524
#[pymethod]

vm/src/format.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fn format_internal(
112112

113113
// FIXME: compiler can intern specs using parser tree. Then this call can be interned_str
114114
pystr = vm.format(&argument, vm.ctx.new_str(format_spec))?;
115-
pystr.as_ref()
115+
pystr.as_wtf8()
116116
}
117117
FormatPart::Literal(literal) => literal,
118118
};

vm/src/object/core.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,11 @@ impl PyObjectRef {
541541
}
542542
}
543543

544+
pub fn try_downcast<T: PyObjectPayload>(self, vm: &VirtualMachine) -> PyResult<PyRef<T>> {
545+
T::try_downcast_from(&self, vm)?;
546+
Ok(unsafe { self.downcast_unchecked() })
547+
}
548+
544549
/// Force to downcast this reference to a subclass.
545550
///
546551
/// # Safety
@@ -720,10 +725,24 @@ impl PyObject {
720725
}
721726
}
722727

728+
#[inline]
729+
pub(crate) fn typeid(&self) -> TypeId {
730+
self.0.typeid
731+
}
732+
723733
/// Check if this object can be downcast to T.
724734
#[inline(always)]
725735
pub fn downcastable<T: PyObjectPayload>(&self) -> bool {
726-
self.0.typeid == T::payload_type_id()
736+
T::downcastable_from(self)
737+
}
738+
739+
/// Attempt to downcast this reference to a subclass.
740+
pub fn try_downcast_ref<'a, T: PyObjectPayload>(
741+
&'a self,
742+
vm: &VirtualMachine,
743+
) -> PyResult<&'a Py<T>> {
744+
T::try_downcast_from(self, vm)?;
745+
Ok(unsafe { self.downcast_unchecked_ref::<T>() })
727746
}
728747

729748
/// Attempt to downcast this reference to a subclass.

vm/src/protocol/object.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
//! <https://docs.python.org/3/c-api/object.html>
33
44
use crate::{
5-
AsObject, Py, PyObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine,
5+
AsObject, Py, PyObject, PyObjectRef, PyRef, PyResult, TryFromObject, VirtualMachine,
66
builtins::{
7-
PyAsyncGen, PyBytes, PyDict, PyDictRef, PyGenericAlias, PyInt, PyList, PyStr, PyStrRef,
8-
PyTuple, PyTupleRef, PyType, PyTypeRef, pystr::AsPyStr,
7+
PyAsyncGen, PyBytes, PyDict, PyDictRef, PyGenericAlias, PyInt, PyList, PyStr, PyTuple,
8+
PyTupleRef, PyType, PyTypeRef, PyUtf8Str, pystr::AsPyStr,
99
},
1010
bytes_inner::ByteInnerNewOptions,
1111
common::{hash::PyHash, str::to_ascii},
@@ -328,7 +328,11 @@ impl PyObject {
328328
}
329329
}
330330

331-
pub fn repr(&self, vm: &VirtualMachine) -> PyResult<PyStrRef> {
331+
pub fn repr_utf8(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyUtf8Str>> {
332+
self.repr(vm)?.try_into_utf8(vm)
333+
}
334+
335+
pub fn repr(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
332336
vm.with_recursion("while getting the repr of an object", || {
333337
// TODO: RustPython does not implement type slots inheritance yet
334338
self.class()
@@ -346,13 +350,15 @@ impl PyObject {
346350
}
347351

348352
pub fn ascii(&self, vm: &VirtualMachine) -> PyResult<ascii::AsciiString> {
349-
let repr = self.repr(vm)?;
353+
let repr = self.repr_utf8(vm)?;
350354
let ascii = to_ascii(repr.as_str());
351355
Ok(ascii)
352356
}
353357

354-
// Container of the virtual machine state:
355-
pub fn str(&self, vm: &VirtualMachine) -> PyResult<PyStrRef> {
358+
pub fn str_utf8(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyUtf8Str>> {
359+
self.str(vm)?.try_into_utf8(vm)
360+
}
361+
pub fn str(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
356362
let obj = match self.to_owned().downcast_exact::<PyStr>(vm) {
357363
Ok(s) => return Ok(s.into_pyref()),
358364
Err(obj) => obj,

0 commit comments

Comments
 (0)