mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #3711 from youknowone/pyexact
PyExact as counterpart of PyRefExact
This commit is contained in:
@@ -16,7 +16,7 @@ use crate::{
|
||||
AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, IterNextIterable,
|
||||
Iterable, PyComparisonOp, Unconstructible,
|
||||
},
|
||||
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult,
|
||||
AsObject, Context, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult,
|
||||
TryFromBorrowedObject, VirtualMachine,
|
||||
};
|
||||
use ascii::{AsciiStr, AsciiString};
|
||||
@@ -1534,6 +1534,12 @@ impl AsRef<str> for PyRefExact<PyStr> {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for PyExact<PyStr> {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::common::{
|
||||
use crate::{
|
||||
builtins::{PyInt, PyStr, PyStrRef},
|
||||
convert::ToPyObject,
|
||||
AsObject, Py, PyObject, PyObjectRef, PyRefExact, PyResult, VirtualMachine,
|
||||
AsObject, Py, PyExact, PyObject, PyObjectRef, PyRefExact, PyResult, VirtualMachine,
|
||||
};
|
||||
use num_traits::ToPrimitive;
|
||||
use std::{fmt, mem::size_of, ops::ControlFlow};
|
||||
@@ -686,23 +686,23 @@ pub trait DictKey {
|
||||
/// to index dictionaries.
|
||||
impl DictKey for PyObject {
|
||||
type Owned = PyObjectRef;
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
|
||||
self.to_owned()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
self.hash(vm)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn key_is(&self, other: &PyObject) -> bool {
|
||||
self.is(other)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
|
||||
vm.identical_or_equal(self, other_key)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult<isize> {
|
||||
vm.to_index(self)?.try_to_primitive(vm)
|
||||
}
|
||||
@@ -710,15 +710,15 @@ impl DictKey for PyObject {
|
||||
|
||||
impl DictKey for Py<PyStr> {
|
||||
type Owned = PyStrRef;
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
|
||||
self.to_owned()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
Ok(self.hash(vm))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn key_is(&self, other: &PyObject) -> bool {
|
||||
self.is(other)
|
||||
}
|
||||
@@ -732,28 +732,31 @@ impl DictKey for Py<PyStr> {
|
||||
vm.bool_eq(self.as_object(), other_key)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult<isize> {
|
||||
self.as_object().key_as_isize(vm)
|
||||
}
|
||||
}
|
||||
|
||||
impl DictKey for PyRefExact<PyStr> {
|
||||
type Owned = Self;
|
||||
#[inline]
|
||||
impl DictKey for PyExact<PyStr> {
|
||||
type Owned = PyRefExact<PyStr>;
|
||||
#[inline(always)]
|
||||
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
|
||||
self.clone()
|
||||
self.to_owned()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
(**self).key_hash(vm)
|
||||
}
|
||||
#[inline]
|
||||
fn key_is(&self, other: &PyObject) -> bool {
|
||||
(**self).key_is(other)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
|
||||
(**self).key_eq(vm, other_key)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult<isize> {
|
||||
(**self).key_as_isize(vm)
|
||||
}
|
||||
@@ -765,16 +768,16 @@ impl DictKey for PyRefExact<PyStr> {
|
||||
/// to index dictionaries.
|
||||
impl DictKey for str {
|
||||
type Owned = String;
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned {
|
||||
self.to_owned()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn key_hash(&self, vm: &VirtualMachine) -> PyResult<HashValue> {
|
||||
// follow a similar route as the hashing of PyStrRef
|
||||
Ok(vm.state.hash_secret.hash_str(self))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn key_is(&self, _other: &PyObject) -> bool {
|
||||
// No matter who the other pyobject is, we are never the same thing, since
|
||||
// we are a str, not a pyobject.
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
builtins::{PyStr, PyTypeRef},
|
||||
common::lock::PyRwLock,
|
||||
convert::ToPyObject,
|
||||
Py, PyObject, PyObjectRef, PyRef, PyRefExact,
|
||||
Py, PyExact, PyObject, PyObjectRef, PyRef, PyRefExact,
|
||||
};
|
||||
use std::{
|
||||
borrow::{Borrow, ToOwned},
|
||||
@@ -199,7 +199,7 @@ impl std::fmt::Display for PyStrInterned {
|
||||
mod sealed {
|
||||
use crate::{
|
||||
builtins::PyStr,
|
||||
object::{Py, PyRefExact},
|
||||
object::{Py, PyExact, PyRefExact},
|
||||
};
|
||||
|
||||
pub trait SealedInternable {}
|
||||
@@ -211,7 +211,7 @@ mod sealed {
|
||||
pub trait SealedMaybeInterned {}
|
||||
|
||||
impl SealedMaybeInterned for str {}
|
||||
impl SealedMaybeInterned for PyRefExact<PyStr> {}
|
||||
impl SealedMaybeInterned for PyExact<PyStr> {}
|
||||
impl SealedMaybeInterned for Py<PyStr> {}
|
||||
}
|
||||
|
||||
@@ -259,6 +259,13 @@ impl MaybeInterned for str {
|
||||
}
|
||||
}
|
||||
|
||||
impl MaybeInterned for PyExact<PyStr> {
|
||||
#[inline(always)]
|
||||
fn as_interned(&self) -> Option<&'static PyStrInterned> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl MaybeInterned for Py<PyStr> {
|
||||
#[inline(always)]
|
||||
fn as_interned(&self) -> Option<&'static PyStrInterned> {
|
||||
|
||||
@@ -77,7 +77,7 @@ pub mod vm;
|
||||
|
||||
pub use self::convert::{TryFromBorrowedObject, TryFromObject};
|
||||
pub use self::object::{
|
||||
AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, PyWeakRef,
|
||||
AsObject, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, PyWeakRef,
|
||||
};
|
||||
pub use self::vm::{Context, Interpreter, Settings, VirtualMachine};
|
||||
|
||||
|
||||
@@ -58,7 +58,66 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct PyExact<T: PyObjectPayload> {
|
||||
inner: Py<T>,
|
||||
}
|
||||
|
||||
impl<T: PyPayload> PyExact<T> {
|
||||
/// # Safety
|
||||
/// Given reference must be exact type of payload T
|
||||
#[inline(always)]
|
||||
pub unsafe fn ref_unchecked(r: &Py<T>) -> &Self {
|
||||
&*(r as *const _ as *const Self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyPayload> Deref for PyExact<T> {
|
||||
type Target = Py<T>;
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &Py<T> {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> Borrow<PyObject> for PyExact<T> {
|
||||
#[inline(always)]
|
||||
fn borrow(&self) -> &PyObject {
|
||||
self.inner.borrow()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> AsRef<PyObject> for PyExact<T> {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &PyObject {
|
||||
self.inner.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> Borrow<Py<T>> for PyExact<T> {
|
||||
#[inline(always)]
|
||||
fn borrow(&self) -> &Py<T> {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> AsRef<Py<T>> for PyExact<T> {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &Py<T> {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyPayload> std::borrow::ToOwned for PyExact<T> {
|
||||
type Owned = PyRefExact<T>;
|
||||
fn to_owned(&self) -> Self::Owned {
|
||||
let owned = self.inner.to_owned();
|
||||
unsafe { PyRefExact::new_unchecked(owned) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct PyRefExact<T: PyObjectPayload> {
|
||||
inner: PyRef<T>,
|
||||
}
|
||||
@@ -109,10 +168,31 @@ impl<T: PyPayload> TryFromObject for PyRefExact<T> {
|
||||
}
|
||||
|
||||
impl<T: PyPayload> Deref for PyRefExact<T> {
|
||||
type Target = PyRef<T>;
|
||||
type Target = PyExact<T>;
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &PyRef<T> {
|
||||
&self.inner
|
||||
fn deref(&self) -> &PyExact<T> {
|
||||
unsafe { PyExact::ref_unchecked(self.inner.deref()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> Borrow<PyObject> for PyRefExact<T> {
|
||||
#[inline(always)]
|
||||
fn borrow(&self) -> &PyObject {
|
||||
self.inner.borrow()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> AsRef<PyObject> for PyRefExact<T> {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &PyObject {
|
||||
self.inner.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> Borrow<Py<T>> for PyRefExact<T> {
|
||||
#[inline(always)]
|
||||
fn borrow(&self) -> &Py<T> {
|
||||
self.inner.borrow()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +203,20 @@ impl<T: PyObjectPayload> AsRef<Py<T>> for PyRefExact<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyPayload> Borrow<PyExact<T>> for PyRefExact<T> {
|
||||
#[inline(always)]
|
||||
fn borrow(&self) -> &PyExact<T> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyPayload> AsRef<PyExact<T>> for PyRefExact<T> {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &PyExact<T> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyPayload> ToPyObject for PyRefExact<T> {
|
||||
#[inline(always)]
|
||||
fn to_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pub use crate::{
|
||||
object::{
|
||||
AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, PyWeakRef,
|
||||
AsObject, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult,
|
||||
PyWeakRef,
|
||||
},
|
||||
vm::{Context, Interpreter, Settings, VirtualMachine},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user