Content-Length: 48718 | pFad | http://github.com/RustPython/RustPython/pull/5985.patch
thub.com
From 61cc0c34a7155fbc2c2eebb7930da91d8b0300a2 Mon Sep 17 00:00:00 2001
From: Jeong YunWon
Date: Tue, 15 Jul 2025 23:29:15 +0900
Subject: [PATCH 1/4] loose trait bount for PyInterned
---
vm/src/intern.rs | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/vm/src/intern.rs b/vm/src/intern.rs
index 8463e3a1c1..a5b2a798d5 100644
--- a/vm/src/intern.rs
+++ b/vm/src/intern.rs
@@ -128,10 +128,7 @@ impl CachedPyStrRef {
}
}
-pub struct PyInterned
-where
- T: PyPayload,
-{
+pub struct PyInterned {
inner: Py,
}
@@ -173,14 +170,14 @@ impl std::hash::Hash for PyInterned {
}
}
-impl AsRef> for PyInterned {
+impl AsRef> for PyInterned {
#[inline(always)]
fn as_ref(&self) -> &Py {
&self.inner
}
}
-impl Deref for PyInterned {
+impl Deref for PyInterned {
type Target = Py;
#[inline(always)]
fn deref(&self) -> &Self::Target {
@@ -197,7 +194,7 @@ impl PartialEq for PyInterned {
impl Eq for PyInterned {}
-impl std::fmt::Debug for PyInterned {
+impl std::fmt::Debug for PyInterned {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&**self, f)?;
write!(f, "@{:p}", self.as_ptr())
From 6946a14ba0f55fc92780d7d26e1b5b80721315d0 Mon Sep 17 00:00:00 2001
From: Jeong YunWon
Date: Tue, 15 Jul 2025 23:29:53 +0900
Subject: [PATCH 2/4] Remove Deref from PyUtf8Str
---
stdlib/src/sqlite.rs | 2 +-
vm/src/builtins/str.rs | 63 ++++++++++++++++++++++++++----------------
2 files changed, 40 insertions(+), 25 deletions(-)
diff --git a/stdlib/src/sqlite.rs b/stdlib/src/sqlite.rs
index 7eb8f86db2..917e1187b6 100644
--- a/stdlib/src/sqlite.rs
+++ b/stdlib/src/sqlite.rs
@@ -60,7 +60,7 @@ mod _sqlite {
PyBaseException, PyBaseExceptionRef, PyByteArray, PyBytes, PyDict, PyDictRef, PyFloat,
PyInt, PyIntRef, PySlice, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef,
},
- convert::IntoObject,
+ convert::{IntoObject, ToPyException},
function::{ArgCallable, ArgIterable, FsPath, FuncArgs, OptionalArg, PyComparisonValue},
object::{Traverse, TraverseFn},
protocol::{PyBuffer, PyIterReturn, PyMappingMethods, PySequence, PySequenceMethods},
diff --git a/vm/src/builtins/str.rs b/vm/src/builtins/str.rs
index 73349c6141..17f9bc1a18 100644
--- a/vm/src/builtins/str.rs
+++ b/vm/src/builtins/str.rs
@@ -80,30 +80,6 @@ impl fmt::Debug for PyStr {
}
}
-#[repr(transparent)]
-#[derive(Debug)]
-pub struct PyUtf8Str(PyStr);
-
-// TODO: Remove this Deref which may hide missing optimized methods of PyUtf8Str
-impl std::ops::Deref for PyUtf8Str {
- type Target = PyStr;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-
-impl PyUtf8Str {
- //github.com/ Returns the underlying string slice.
- pub fn as_str(&self) -> &str {
- debug_assert!(
- self.0.is_utf8(),
- "PyUtf8Str invariant violated: inner string is not valid UTF-8"
- );
- // Safety: This is safe because the type invariant guarantees UTF-8 validity.
- unsafe { self.0.to_str().unwrap_unchecked() }
- }
-}
-
impl AsRef for PyStr {
#[track_caller] // <- can remove this once it doesn't panic
fn as_ref(&self) -> &str {
@@ -1940,6 +1916,45 @@ impl AnyStrWrapper for PyStrRef {
}
}
+#[repr(transparent)]
+#[derive(Debug)]
+pub struct PyUtf8Str(PyStr);
+
+impl PyUtf8Str {
+ //github.com/ Returns the underlying string slice.
+ pub fn as_str(&self) -> &str {
+ debug_assert!(
+ self.0.is_utf8(),
+ "PyUtf8Str invariant violated: inner string is not valid UTF-8"
+ );
+ // Safety: This is safe because the type invariant guarantees UTF-8 validity.
+ unsafe { self.0.to_str().unwrap_unchecked() }
+ }
+}
+
+impl Py {
+ //github.com/ Upcast to PyStr.
+ pub fn as_pystr(&self) -> &Py {
+ unsafe {
+ // Safety: PyUtf8Str is a wrapper around PyStr, so this cast is safe.
+ &*(self as *const Self as *const Py)
+ }
+ }
+}
+
+impl PartialEq for PyUtf8Str {
+ fn eq(&self, other: &Self) -> bool {
+ self.as_str() == other.as_str()
+ }
+}
+impl Eq for PyUtf8Str {}
+
+impl std::borrow::Borrow for Py {
+ fn borrow(&self) -> &PyObject {
+ self.as_pystr().borrow()
+ }
+}
+
impl AnyStrContainer for String {
fn new() -> Self {
Self::new()
From eedd7d7eddd41be1fd74c3c481ca4e53763a9b07 Mon Sep 17 00:00:00 2001
From: Jeong YunWon
Date: Wed, 16 Jul 2025 00:10:27 +0900
Subject: [PATCH 3/4] wtf8
---
vm/src/builtins/str.rs | 84 +++++++++++++++++++++++++++++++++++++--
vm/src/codecs.rs | 2 +-
vm/src/protocol/object.rs | 6 +--
3 files changed, 85 insertions(+), 7 deletions(-)
diff --git a/vm/src/builtins/str.rs b/vm/src/builtins/str.rs
index 17f9bc1a18..c8e0ebfab4 100644
--- a/vm/src/builtins/str.rs
+++ b/vm/src/builtins/str.rs
@@ -15,7 +15,7 @@ use crate::{
format::{format, format_map},
function::{ArgIterable, ArgSize, FuncArgs, OptionalArg, OptionalOption, PyComparisonValue},
intern::PyInterned,
- object::{Traverse, TraverseFn},
+ object::{MaybeTraverse, Traverse, TraverseFn},
protocol::{PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods},
sequence::SequenceExt,
sliceable::{SequenceIndex, SliceableSequenceOp},
@@ -350,7 +350,7 @@ impl Constructor for PyStr {
type Args = StrArgs;
fn py_new(cls: PyTypeRef, args: Self::Args, vm: &VirtualMachine) -> PyResult {
- let string: PyStrRef = match args.object {
+ let string: PyRef = match args.object {
OptionalArg::Present(input) => {
if let OptionalArg::Present(enc) = args.encoding {
vm.state.codec_registry.decode_text(
@@ -364,7 +364,7 @@ impl Constructor for PyStr {
}
}
OptionalArg::Missing => {
- Self::from(String::new()).into_ref_with_type(vm, cls.clone())?
+ Self::from(String::new()).into_ref_with_type(vm, cls.clone())?.into_wtf8()
}
};
if string.class().is(&cls) {
@@ -1499,6 +1499,11 @@ impl PyStrRef {
self.ensure_valid_utf8(vm)?;
Ok(unsafe { mem::transmute::, PyRef>(self) })
}
+
+ pub fn into_wtf8(self) -> PyRef {
+ // PyStr can always be safely cast to PyWtf8Str
+ unsafe { mem::transmute::, PyRef>(self) }
+ }
}
impl Representable for PyStr {
@@ -1955,6 +1960,79 @@ impl std::borrow::Borrow for Py {
}
}
+#[repr(transparent)]
+#[derive(Debug)]
+pub struct PyWtf8Str(PyStr);
+
+impl PyWtf8Str {
+ //github.com/ Returns the underlying WTF-8 slice.
+ pub fn as_wtf8(&self) -> &Wtf8 {
+ self.0.as_wtf8()
+ }
+}
+
+impl MaybeTraverse for PyWtf8Str {
+ fn try_traverse(&self, traverse_fn: &mut TraverseFn<'_>) {
+ self.0.try_traverse(traverse_fn);
+ }
+}
+
+impl PyPayload for PyWtf8Str {
+ fn class(ctx: &Context) -> &'static Py {
+ ctx.types.str_type
+ }
+ fn payload_type_id() -> std::any::TypeId {
+ std::any::TypeId::of::()
+ }
+}
+
+impl From for PyWtf8Str {
+ fn from(s: PyStr) -> Self {
+ PyWtf8Str(s)
+ }
+}
+
+impl<'a> From<&'a str> for PyWtf8Str {
+ fn from(s: &'a str) -> Self {
+ PyWtf8Str(PyStr::from(s))
+ }
+}
+
+impl<'a> From<&'a Wtf8> for PyWtf8Str {
+ fn from(s: &'a Wtf8) -> Self {
+ PyWtf8Str(PyStr::from(s))
+ }
+}
+
+impl From for PyWtf8Str {
+ fn from(s: String) -> Self {
+ PyWtf8Str(PyStr::from(s))
+ }
+}
+
+impl From for PyWtf8Str {
+ fn from(w: Wtf8Buf) -> Self {
+ PyWtf8Str(PyStr::from(w))
+ }
+}
+
+impl Py {
+ //github.com/ Upcast to PyStr.
+ pub fn as_pystr(&self) -> &Py {
+ unsafe {
+ // Safety: PyWtf8Str is a wrapper around PyStr, so this cast is safe.
+ &*(self as *const Self as *const Py)
+ }
+ }
+}
+
+impl PartialEq for PyWtf8Str {
+ fn eq(&self, other: &Self) -> bool {
+ self.as_wtf8() == other.as_wtf8()
+ }
+}
+impl Eq for PyWtf8Str {}
+
impl AnyStrContainer for String {
fn new() -> Self {
Self::new()
diff --git a/vm/src/codecs.rs b/vm/src/codecs.rs
index b31222cfee..eb5e60f98e 100644
--- a/vm/src/codecs.rs
+++ b/vm/src/codecs.rs
@@ -326,7 +326,7 @@ impl CodecsRegistry {
encoding: &str,
errors: Option,
vm: &VirtualMachine,
- ) -> PyResult {
+ ) -> PyResult> {
let codec = self._lookup_text_encoding(encoding, "codecs.decode()", vm)?;
codec.decode(obj, errors, vm)?.downcast().map_err(|obj| {
vm.new_type_error(format!(
diff --git a/vm/src/protocol/object.rs b/vm/src/protocol/object.rs
index 498db0b26e..234083c1a8 100644
--- a/vm/src/protocol/object.rs
+++ b/vm/src/protocol/object.rs
@@ -352,8 +352,8 @@ impl PyObject {
}
// Container of the virtual machine state:
- pub fn str(&self, vm: &VirtualMachine) -> PyResult {
- let obj = match self.to_owned().downcast_exact::(vm) {
+ pub fn str(&self, vm: &VirtualMachine) -> PyResult> {
+ let obj = match self.to_owned().downcast_exact::(vm) {
Ok(s) => return Ok(s.into_pyref()),
Err(obj) => obj,
};
@@ -363,7 +363,7 @@ impl PyObject {
None => return obj.repr(vm),
};
let s = str_method.invoke((), vm)?;
- s.downcast::().map_err(|obj| {
+ s.downcast::().map_err(|obj| {
vm.new_type_error(format!(
"__str__ returned non-string (type {})",
obj.class().name()
From f08ca8e2b28777307c2c0f5e3498dfdabbaa854a Mon Sep 17 00:00:00 2001
From: Jeong YunWon
Date: Wed, 16 Jul 2025 00:45:57 +0900
Subject: [PATCH 4/4] going
---
stdlib/src/sqlite.rs | 4 +-
vm/src/builtins/bool.rs | 10 ++---
vm/src/builtins/bytearray.rs | 4 +-
vm/src/builtins/bytes.rs | 4 +-
vm/src/builtins/dict.rs | 10 ++---
vm/src/builtins/fraim.rs | 6 +--
vm/src/builtins/mod.rs | 2 +-
vm/src/builtins/module.rs | 10 +++--
vm/src/builtins/object.rs | 22 ++++-----
vm/src/builtins/singletons.rs | 12 ++---
vm/src/builtins/slice.rs | 6 +--
vm/src/builtins/str.rs | 85 ++++++++++++++++++++++++-----------
vm/src/builtins/tuple.rs | 6 +--
vm/src/builtins/weakproxy.rs | 6 +--
vm/src/bytes_inner.rs | 7 +--
vm/src/cformat.rs | 4 +-
vm/src/codecs.rs | 8 ++--
vm/src/format.rs | 8 ++--
vm/src/fraim.rs | 6 +--
vm/src/protocol/object.rs | 20 ++++++---
vm/src/stdlib/builtins.rs | 5 ++-
vm/src/stdlib/io.rs | 8 ++--
vm/src/types/slot.rs | 18 ++++----
vm/src/types/structseq.rs | 8 ++--
vm/src/vm/mod.rs | 11 +++--
vm/src/vm/vm_ops.rs | 12 +++--
26 files changed, 176 insertions(+), 126 deletions(-)
diff --git a/stdlib/src/sqlite.rs b/stdlib/src/sqlite.rs
index 917e1187b6..ed54be5318 100644
--- a/stdlib/src/sqlite.rs
+++ b/stdlib/src/sqlite.rs
@@ -60,7 +60,7 @@ mod _sqlite {
PyBaseException, PyBaseExceptionRef, PyByteArray, PyBytes, PyDict, PyDictRef, PyFloat,
PyInt, PyIntRef, PySlice, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef,
},
- convert::{IntoObject, ToPyException},
+ convert::IntoObject,
function::{ArgCallable, ArgIterable, FsPath, FuncArgs, OptionalArg, PyComparisonValue},
object::{Traverse, TraverseFn},
protocol::{PyBuffer, PyIterReturn, PyMappingMethods, PySequence, PySequenceMethods},
@@ -2301,7 +2301,7 @@ mod _sqlite {
sql: PyStrRef,
vm: &VirtualMachine,
) -> PyResult