mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Downcastable (#5986)
* simplify int power * downcastasble * deprecate payload*
This commit is contained in:
@@ -60,6 +60,7 @@
|
||||
"dedentations",
|
||||
"dedents",
|
||||
"deduped",
|
||||
"downcastable",
|
||||
"downcasted",
|
||||
"dumpable",
|
||||
"emscripten",
|
||||
|
||||
@@ -667,7 +667,7 @@ mod array {
|
||||
ArrayContentType::from_char(spec).map_err(|err| vm.new_value_error(err))?;
|
||||
|
||||
if let OptionalArg::Present(init) = init {
|
||||
if let Some(init) = init.payload::<Self>() {
|
||||
if let Some(init) = init.downcast_ref::<Self>() {
|
||||
match (spec, init.read().typecode()) {
|
||||
(spec, ch) if spec == ch => array.frombytes(&init.get_bytes()),
|
||||
(spec, 'u') => {
|
||||
@@ -681,7 +681,7 @@ mod array {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Some(wtf8) = init.payload::<PyStr>() {
|
||||
} else if let Some(wtf8) = init.downcast_ref::<PyStr>() {
|
||||
if spec == 'u' {
|
||||
let bytes = Self::_unicode_to_wchar_bytes(wtf8.as_wtf8(), array.itemsize());
|
||||
array.frombytes_move(bytes);
|
||||
@@ -690,7 +690,7 @@ mod array {
|
||||
"cannot use a str to initialize an array with typecode '{spec}'"
|
||||
)));
|
||||
}
|
||||
} else if init.payload_is::<PyBytes>() || init.payload_is::<PyByteArray>() {
|
||||
} else if init.downcastable::<PyBytes>() || init.downcastable::<PyByteArray>() {
|
||||
init.try_bytes_like(vm, |x| array.frombytes(x))?;
|
||||
} else if let Ok(iter) = ArgIterable::try_from_object(vm, init.clone()) {
|
||||
for obj in iter.iter(vm)? {
|
||||
@@ -765,7 +765,7 @@ mod array {
|
||||
let mut w = zelf.try_resizable(vm)?;
|
||||
if zelf.is(&obj) {
|
||||
w.imul(2, vm)
|
||||
} else if let Some(array) = obj.payload::<Self>() {
|
||||
} else if let Some(array) = obj.downcast_ref::<Self>() {
|
||||
w.iadd(&array.read(), vm)
|
||||
} else {
|
||||
let iter = ArgIterable::try_from_object(vm, obj)?;
|
||||
@@ -1013,7 +1013,7 @@ mod array {
|
||||
cloned = zelf.read().clone();
|
||||
&cloned
|
||||
} else {
|
||||
match value.payload::<Self>() {
|
||||
match value.downcast_ref::<Self>() {
|
||||
Some(array) => {
|
||||
guard = array.read();
|
||||
&*guard
|
||||
@@ -1059,7 +1059,7 @@ mod array {
|
||||
|
||||
#[pymethod]
|
||||
fn __add__(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
|
||||
if let Some(other) = other.payload::<Self>() {
|
||||
if let Some(other) = other.downcast_ref::<Self>() {
|
||||
self.read()
|
||||
.add(&other.read(), vm)
|
||||
.map(|array| Self::from(array).into_ref(&vm.ctx))
|
||||
@@ -1079,7 +1079,7 @@ mod array {
|
||||
) -> PyResult<PyRef<Self>> {
|
||||
if zelf.is(&other) {
|
||||
zelf.try_resizable(vm)?.imul(2, vm)?;
|
||||
} else if let Some(other) = other.payload::<Self>() {
|
||||
} else if let Some(other) = other.downcast_ref::<Self>() {
|
||||
zelf.try_resizable(vm)?.iadd(&other.read(), vm)?;
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
|
||||
@@ -269,7 +269,7 @@ mod _csv {
|
||||
mut _rest: FuncArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
let Some(name) = name.payload_if_subclass::<PyStr>(vm) else {
|
||||
let Some(name) = name.downcast_ref::<PyStr>() else {
|
||||
return Err(vm.new_type_error("argument 0 must be a string"));
|
||||
};
|
||||
let dialect = match dialect {
|
||||
@@ -290,7 +290,7 @@ mod _csv {
|
||||
mut _rest: FuncArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyDialect> {
|
||||
let Some(name) = name.payload_if_subclass::<PyStr>(vm) else {
|
||||
let Some(name) = name.downcast_ref::<PyStr>() else {
|
||||
return Err(vm.new_exception_msg(
|
||||
super::_csv::error(vm),
|
||||
format!("argument 0 must be a string, not '{}'", name.class()),
|
||||
@@ -309,7 +309,7 @@ mod _csv {
|
||||
mut _rest: FuncArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
let Some(name) = name.payload_if_subclass::<PyStr>(vm) else {
|
||||
let Some(name) = name.downcast_ref::<PyStr>() else {
|
||||
return Err(vm.new_exception_msg(
|
||||
super::_csv::error(vm),
|
||||
format!("argument 0 must be a string, not '{}'", name.class()),
|
||||
|
||||
@@ -350,7 +350,7 @@ mod decl {
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
let timeout = if vm.is_none(&obj) {
|
||||
None
|
||||
} else if let Some(float) = obj.payload::<PyFloat>() {
|
||||
} else if let Some(float) = obj.downcast_ref::<PyFloat>() {
|
||||
let float = float.to_f64();
|
||||
if float.is_nan() {
|
||||
return Err(vm.new_value_error("Invalid value NaN (not a number)"));
|
||||
|
||||
@@ -535,7 +535,7 @@ mod _sqlite {
|
||||
let access = ptr_to_str(access, vm)?;
|
||||
|
||||
let val = callable.call((action, arg1, arg2, db_name, access), vm)?;
|
||||
let Some(val) = val.payload::<PyInt>() else {
|
||||
let Some(val) = val.downcast_ref::<PyInt>() else {
|
||||
return Ok(SQLITE_DENY);
|
||||
};
|
||||
val.try_to_primitive::<c_int>(vm)
|
||||
@@ -1897,18 +1897,18 @@ mod _sqlite {
|
||||
Ok(self
|
||||
.description
|
||||
.iter()
|
||||
.map(|x| x.payload::<PyTuple>().unwrap().as_slice()[0].clone())
|
||||
.map(|x| x.downcast_ref::<PyTuple>().unwrap().as_slice()[0].clone())
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn subscript(&self, needle: &PyObject, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(i) = needle.payload::<PyInt>() {
|
||||
if let Some(i) = needle.downcast_ref::<PyInt>() {
|
||||
let i = i.try_to_primitive::<isize>(vm)?;
|
||||
self.data.getitem_by_index(vm, i)
|
||||
} else if let Some(name) = needle.payload::<PyStr>() {
|
||||
} else if let Some(name) = needle.downcast_ref::<PyStr>() {
|
||||
for (obj, i) in self.description.iter().zip(0..) {
|
||||
let obj = &obj.payload::<PyTuple>().unwrap().as_slice()[0];
|
||||
let Some(obj) = obj.payload::<PyStr>() else {
|
||||
let obj = &obj.downcast_ref::<PyTuple>().unwrap().as_slice()[0];
|
||||
let Some(obj) = obj.downcast_ref::<PyStr>() else {
|
||||
break;
|
||||
};
|
||||
let a_iter = name.as_str().chars().flat_map(|x| x.to_uppercase());
|
||||
@@ -1919,7 +1919,7 @@ mod _sqlite {
|
||||
}
|
||||
}
|
||||
Err(vm.new_index_error("No item with that key"))
|
||||
} else if let Some(slice) = needle.payload::<PySlice>() {
|
||||
} else if let Some(slice) = needle.downcast_ref::<PySlice>() {
|
||||
let list = self.data.getitem_by_slice(vm, slice.to_saturated(vm)?)?;
|
||||
Ok(vm.ctx.new_tuple(list).into())
|
||||
} else {
|
||||
@@ -1962,7 +1962,7 @@ mod _sqlite {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyComparisonValue> {
|
||||
op.eq_only(|| {
|
||||
if let Some(other) = other.payload::<Self>() {
|
||||
if let Some(other) = other.downcast_ref::<Self>() {
|
||||
let eq = vm
|
||||
.bool_eq(zelf.description.as_object(), other.description.as_object())?
|
||||
&& vm.bool_eq(zelf.data.as_object(), other.data.as_object())?;
|
||||
@@ -2179,7 +2179,7 @@ mod _sqlite {
|
||||
let mut byte: u8 = 0;
|
||||
let ret = inner.blob.read_single(&mut byte, index);
|
||||
self.check(ret, vm).map(|_| vm.ctx.new_int(byte).into())
|
||||
} else if let Some(slice) = needle.payload::<PySlice>() {
|
||||
} else if let Some(slice) = needle.downcast_ref::<PySlice>() {
|
||||
let blob_len = inner.blob.bytes();
|
||||
let slice = slice.to_saturated(vm)?;
|
||||
let (range, step, length) = slice.adjust_indices(blob_len as usize);
|
||||
@@ -2220,7 +2220,7 @@ mod _sqlite {
|
||||
let inner = self.inner(vm)?;
|
||||
|
||||
if let Some(index) = needle.try_index_opt(vm) {
|
||||
let Some(value) = value.payload::<PyInt>() else {
|
||||
let Some(value) = value.downcast_ref::<PyInt>() else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"'{}' object cannot be interpreted as an integer",
|
||||
value.class()
|
||||
@@ -2232,7 +2232,7 @@ mod _sqlite {
|
||||
Self::expect_write(blob_len, 1, index, vm)?;
|
||||
let ret = inner.blob.write_single(value, index);
|
||||
self.check(ret, vm)
|
||||
} else if let Some(_slice) = needle.payload::<PySlice>() {
|
||||
} else if let Some(_slice) = needle.downcast_ref::<PySlice>() {
|
||||
Err(vm.new_not_implemented_error("Blob slice assignment is not implemented"))
|
||||
// let blob_len = inner.blob.bytes();
|
||||
// let slice = slice.to_saturated(vm)?;
|
||||
@@ -2645,15 +2645,15 @@ mod _sqlite {
|
||||
|
||||
let ret = if vm.is_none(obj) {
|
||||
unsafe { sqlite3_bind_null(self.st, pos) }
|
||||
} else if let Some(val) = obj.payload::<PyInt>() {
|
||||
} else if let Some(val) = obj.downcast_ref::<PyInt>() {
|
||||
let val = val.try_to_primitive::<i64>(vm).map_err(|_| {
|
||||
vm.new_overflow_error("Python int too large to convert to SQLite INTEGER")
|
||||
})?;
|
||||
unsafe { sqlite3_bind_int64(self.st, pos, val) }
|
||||
} else if let Some(val) = obj.payload::<PyFloat>() {
|
||||
} else if let Some(val) = obj.downcast_ref::<PyFloat>() {
|
||||
let val = val.to_f64();
|
||||
unsafe { sqlite3_bind_double(self.st, pos, val) }
|
||||
} else if let Some(val) = obj.payload::<PyStr>() {
|
||||
} else if let Some(val) = obj.downcast_ref::<PyStr>() {
|
||||
let (ptr, len) = str_to_ptr_len(val, vm)?;
|
||||
unsafe { sqlite3_bind_text(self.st, pos, ptr, len, SQLITE_TRANSIENT()) }
|
||||
} else if let Ok(buffer) = PyBuffer::try_from_borrowed_object(vm, obj) {
|
||||
@@ -2900,11 +2900,11 @@ mod _sqlite {
|
||||
unsafe {
|
||||
if vm.is_none(val) {
|
||||
sqlite3_result_null(self.ctx)
|
||||
} else if let Some(val) = val.payload::<PyInt>() {
|
||||
} else if let Some(val) = val.downcast_ref::<PyInt>() {
|
||||
sqlite3_result_int64(self.ctx, val.try_to_primitive(vm)?)
|
||||
} else if let Some(val) = val.payload::<PyFloat>() {
|
||||
} else if let Some(val) = val.downcast_ref::<PyFloat>() {
|
||||
sqlite3_result_double(self.ctx, val.to_f64())
|
||||
} else if let Some(val) = val.payload::<PyStr>() {
|
||||
} else if let Some(val) = val.downcast_ref::<PyStr>() {
|
||||
let (ptr, len) = str_to_ptr_len(val, vm)?;
|
||||
sqlite3_result_text(self.ctx, ptr, len, SQLITE_TRANSIENT())
|
||||
} else if let Ok(buffer) = PyBuffer::try_from_borrowed_object(vm, val) {
|
||||
|
||||
@@ -217,9 +217,12 @@ mod termios {
|
||||
))
|
||||
})?;
|
||||
for (cc, x) in termios.c_cc.iter_mut().zip(cc.iter()) {
|
||||
*cc = if let Some(c) = x.payload::<PyBytes>().filter(|b| b.as_bytes().len() == 1) {
|
||||
*cc = if let Some(c) = x
|
||||
.downcast_ref::<PyBytes>()
|
||||
.filter(|b| b.as_bytes().len() == 1)
|
||||
{
|
||||
c.as_bytes()[0] as _
|
||||
} else if let Some(i) = x.payload::<PyInt>() {
|
||||
} else if let Some(i) = x.downcast_ref::<PyInt>() {
|
||||
i.try_to_primitive(vm)?
|
||||
} else {
|
||||
return Err(vm.new_type_error(
|
||||
|
||||
@@ -344,7 +344,9 @@ impl PyAsyncGenAThrow {
|
||||
let ret = self.ag.inner.send(self.ag.as_object(), val, vm);
|
||||
if self.aclose {
|
||||
match ret {
|
||||
Ok(PyIterReturn::Return(v)) if v.payload_is::<PyAsyncGenWrappedValue>() => {
|
||||
Ok(PyIterReturn::Return(v))
|
||||
if v.downcastable::<PyAsyncGenWrappedValue>() =>
|
||||
{
|
||||
Err(self.yield_close(vm))
|
||||
}
|
||||
other => other
|
||||
@@ -392,7 +394,7 @@ impl PyAsyncGenAThrow {
|
||||
|
||||
fn ignored_close(&self, res: &PyResult<PyIterReturn>) -> bool {
|
||||
res.as_ref().is_ok_and(|v| match v {
|
||||
PyIterReturn::Return(obj) => obj.payload_is::<PyAsyncGenWrappedValue>(),
|
||||
PyIterReturn::Return(obj) => obj.downcastable::<PyAsyncGenWrappedValue>(),
|
||||
PyIterReturn::StopIteration(_) => false,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ impl PyObjectRef {
|
||||
Some(method_or_err) => {
|
||||
let method = method_or_err?;
|
||||
let bool_obj = method.call((), vm)?;
|
||||
let int_obj = bool_obj.payload::<PyInt>().ok_or_else(|| {
|
||||
let int_obj = bool_obj.downcast_ref::<PyInt>().ok_or_else(|| {
|
||||
vm.new_type_error(format!(
|
||||
"'{}' object cannot be interpreted as an integer",
|
||||
bool_obj.class().name()
|
||||
@@ -128,8 +128,8 @@ impl PyBool {
|
||||
let lhs = get_value(&lhs);
|
||||
let rhs = get_value(&rhs);
|
||||
(lhs || rhs).to_pyobject(vm)
|
||||
} else if let Some(lhs) = lhs.payload::<PyInt>() {
|
||||
lhs.__or__(rhs, vm).to_pyobject(vm)
|
||||
} else if let Some(lhs) = lhs.downcast_ref::<PyInt>() {
|
||||
lhs.__or__(rhs).to_pyobject(vm)
|
||||
} else {
|
||||
vm.ctx.not_implemented()
|
||||
}
|
||||
@@ -144,8 +144,8 @@ impl PyBool {
|
||||
let lhs = get_value(&lhs);
|
||||
let rhs = get_value(&rhs);
|
||||
(lhs && rhs).to_pyobject(vm)
|
||||
} else if let Some(lhs) = lhs.payload::<PyInt>() {
|
||||
lhs.__and__(rhs, vm).to_pyobject(vm)
|
||||
} else if let Some(lhs) = lhs.downcast_ref::<PyInt>() {
|
||||
lhs.__and__(rhs).to_pyobject(vm)
|
||||
} else {
|
||||
vm.ctx.not_implemented()
|
||||
}
|
||||
@@ -160,8 +160,8 @@ impl PyBool {
|
||||
let lhs = get_value(&lhs);
|
||||
let rhs = get_value(&rhs);
|
||||
(lhs ^ rhs).to_pyobject(vm)
|
||||
} else if let Some(lhs) = lhs.payload::<PyInt>() {
|
||||
lhs.__xor__(rhs, vm).to_pyobject(vm)
|
||||
} else if let Some(lhs) = lhs.downcast_ref::<PyInt>() {
|
||||
lhs.__xor__(rhs).to_pyobject(vm)
|
||||
} else {
|
||||
vm.ctx.not_implemented()
|
||||
}
|
||||
@@ -212,5 +212,5 @@ pub(crate) fn init(context: &Context) {
|
||||
|
||||
// Retrieve inner int value:
|
||||
pub(crate) fn get_value(obj: &PyObject) -> bool {
|
||||
!obj.payload::<PyInt>().unwrap().as_bigint().is_zero()
|
||||
!obj.downcast_ref::<PyInt>().unwrap().as_bigint().is_zero()
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ impl Comparable for PyNativeMethod {
|
||||
_vm: &VirtualMachine,
|
||||
) -> PyResult<PyComparisonValue> {
|
||||
op.eq_only(|| {
|
||||
if let Some(other) = other.payload::<Self>() {
|
||||
if let Some(other) = other.downcast_ref::<Self>() {
|
||||
let eq = match (zelf.func.zelf.as_ref(), other.func.zelf.as_ref()) {
|
||||
(Some(z), Some(o)) => z.is(o),
|
||||
(None, None) => true,
|
||||
|
||||
@@ -58,7 +58,7 @@ impl PyObjectRef {
|
||||
/// Tries converting a python object into a complex, returns an option of whether the complex
|
||||
/// and whether the object was a complex originally or coerced into one
|
||||
pub fn try_complex(&self, vm: &VirtualMachine) -> PyResult<Option<(Complex64, bool)>> {
|
||||
if let Some(complex) = self.payload_if_exact::<PyComplex>(vm) {
|
||||
if let Some(complex) = self.downcast_ref_if_exact::<PyComplex>(vm) {
|
||||
return Ok(Some((complex.value, true)));
|
||||
}
|
||||
if let Some(method) = vm.get_method(self.clone(), identifier!(vm, __complex__)) {
|
||||
@@ -79,7 +79,7 @@ impl PyObjectRef {
|
||||
|
||||
return Ok(Some((ret.value, true)));
|
||||
} else {
|
||||
return match result.payload::<PyComplex>() {
|
||||
return match result.downcast_ref::<PyComplex>() {
|
||||
Some(complex_obj) => Ok(Some((complex_obj.value, true))),
|
||||
None => Err(vm.new_type_error(format!(
|
||||
"__complex__ returned non-complex (type '{}')",
|
||||
@@ -90,7 +90,7 @@ impl PyObjectRef {
|
||||
}
|
||||
// `complex` does not have a `__complex__` by default, so subclasses might not either,
|
||||
// use the actual stored value in this case
|
||||
if let Some(complex) = self.payload_if_subclass::<PyComplex>(vm) {
|
||||
if let Some(complex) = self.downcast_ref::<PyComplex>() {
|
||||
return Ok(Some((complex.value, true)));
|
||||
}
|
||||
if let Some(float) = self.try_float_opt(vm) {
|
||||
@@ -105,7 +105,7 @@ pub fn init(context: &Context) {
|
||||
}
|
||||
|
||||
fn to_op_complex(value: &PyObject, vm: &VirtualMachine) -> PyResult<Option<Complex64>> {
|
||||
let r = if let Some(complex) = value.payload_if_subclass::<PyComplex>(vm) {
|
||||
let r = if let Some(complex) = value.downcast_ref::<PyComplex>() {
|
||||
Some(complex.value)
|
||||
} else {
|
||||
float::to_op_float(value, vm)?.map(|float| Complex64::new(float, 0.0))
|
||||
@@ -175,7 +175,7 @@ impl Constructor for PyComplex {
|
||||
|
||||
if let Some(c) = val.try_complex(vm)? {
|
||||
c
|
||||
} else if let Some(s) = val.payload_if_subclass::<PyStr>(vm) {
|
||||
} else if let Some(s) = val.downcast_ref::<PyStr>() {
|
||||
if args.imag.is_present() {
|
||||
return Err(vm.new_type_error(
|
||||
"complex() can't take second arg if first is a string",
|
||||
@@ -419,7 +419,7 @@ impl Comparable for PyComplex {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<PyComparisonValue> {
|
||||
op.eq_only(|| {
|
||||
let result = if let Some(other) = other.payload_if_subclass::<Self>(vm) {
|
||||
let result = if let Some(other) = other.downcast_ref::<Self>() {
|
||||
if zelf.value.re.is_nan()
|
||||
&& zelf.value.im.is_nan()
|
||||
&& other.value.re.is_nan()
|
||||
|
||||
@@ -57,9 +57,9 @@ impl From<f64> for PyFloat {
|
||||
}
|
||||
|
||||
pub(crate) fn to_op_float(obj: &PyObject, vm: &VirtualMachine) -> PyResult<Option<f64>> {
|
||||
let v = if let Some(float) = obj.payload_if_subclass::<PyFloat>(vm) {
|
||||
let v = if let Some(float) = obj.downcast_ref::<PyFloat>() {
|
||||
Some(float.value)
|
||||
} else if let Some(int) = obj.payload_if_subclass::<PyInt>(vm) {
|
||||
} else if let Some(int) = obj.downcast_ref::<PyInt>() {
|
||||
Some(try_bigint_to_f64(int.as_bigint(), vm)?)
|
||||
} else {
|
||||
None
|
||||
@@ -154,7 +154,7 @@ impl Constructor for PyFloat {
|
||||
|
||||
fn float_from_string(val: PyObjectRef, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
let (bytearray, buffer, buffer_lock, mapped_string);
|
||||
let b = if let Some(s) = val.payload_if_subclass::<PyStr>(vm) {
|
||||
let b = if let Some(s) = val.downcast_ref::<PyStr>() {
|
||||
use crate::common::str::PyKindStr;
|
||||
match s.as_str_kind() {
|
||||
PyKindStr::Ascii(s) => s.trim().as_bytes(),
|
||||
@@ -178,9 +178,9 @@ fn float_from_string(val: PyObjectRef, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
// so we can just choose a known bad value
|
||||
PyKindStr::Wtf8(_) => b"",
|
||||
}
|
||||
} else if let Some(bytes) = val.payload_if_subclass::<PyBytes>(vm) {
|
||||
} else if let Some(bytes) = val.downcast_ref::<PyBytes>() {
|
||||
bytes.as_bytes()
|
||||
} else if let Some(buf) = val.payload_if_subclass::<PyByteArray>(vm) {
|
||||
} else if let Some(buf) = val.downcast_ref::<PyByteArray>() {
|
||||
bytearray = buf.borrow_buf();
|
||||
&*bytearray
|
||||
} else if let Ok(b) = ArgBytesLike::try_from_borrowed_object(vm, &val) {
|
||||
@@ -521,13 +521,13 @@ impl Comparable for PyFloat {
|
||||
zelf: &Py<Self>,
|
||||
other: &PyObject,
|
||||
op: PyComparisonOp,
|
||||
vm: &VirtualMachine,
|
||||
_vm: &VirtualMachine,
|
||||
) -> PyResult<PyComparisonValue> {
|
||||
let ret = if let Some(other) = other.payload_if_subclass::<Self>(vm) {
|
||||
let ret = if let Some(other) = other.downcast_ref::<Self>() {
|
||||
zelf.value
|
||||
.partial_cmp(&other.value)
|
||||
.map_or_else(|| op == PyComparisonOp::Ne, |ord| op.eval_ord(ord))
|
||||
} else if let Some(other) = other.payload_if_subclass::<PyInt>(vm) {
|
||||
} else if let Some(other) = other.downcast_ref::<PyInt>() {
|
||||
let a = zelf.to_f64();
|
||||
let b = other.as_bigint();
|
||||
match op {
|
||||
@@ -633,7 +633,7 @@ impl PyFloat {
|
||||
// Retrieve inner float value:
|
||||
#[cfg(feature = "serde")]
|
||||
pub(crate) fn get_value(obj: &PyObject) -> f64 {
|
||||
obj.payload::<PyFloat>().unwrap().value
|
||||
obj.downcast_ref::<PyFloat>().unwrap().value
|
||||
}
|
||||
|
||||
#[rustfmt::skip] // to avoid line splitting
|
||||
|
||||
@@ -293,12 +293,12 @@ impl PyInt {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn int_op<F>(&self, other: PyObjectRef, op: F, vm: &VirtualMachine) -> PyArithmeticValue<BigInt>
|
||||
fn int_op<F>(&self, other: PyObjectRef, op: F) -> PyArithmeticValue<BigInt>
|
||||
where
|
||||
F: Fn(&BigInt, &BigInt) -> BigInt,
|
||||
{
|
||||
let r = other
|
||||
.payload_if_subclass::<Self>(vm)
|
||||
.downcast_ref::<Self>()
|
||||
.map(|other| op(&self.value, &other.value));
|
||||
PyArithmeticValue::from_option(r)
|
||||
}
|
||||
@@ -308,7 +308,7 @@ impl PyInt {
|
||||
where
|
||||
F: Fn(&BigInt, &BigInt) -> PyResult,
|
||||
{
|
||||
if let Some(other) = other.payload_if_subclass::<Self>(vm) {
|
||||
if let Some(other) = other.downcast_ref::<Self>() {
|
||||
op(&self.value, &other.value)
|
||||
} else {
|
||||
Ok(vm.ctx.not_implemented())
|
||||
@@ -323,24 +323,24 @@ impl PyInt {
|
||||
impl PyInt {
|
||||
#[pymethod(name = "__radd__")]
|
||||
#[pymethod]
|
||||
fn __add__(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a + b, vm)
|
||||
fn __add__(&self, other: PyObjectRef) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a + b)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __sub__(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a - b, vm)
|
||||
fn __sub__(&self, other: PyObjectRef) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a - b)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __rsub__(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| b - a, vm)
|
||||
fn __rsub__(&self, other: PyObjectRef) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| b - a)
|
||||
}
|
||||
|
||||
#[pymethod(name = "__rmul__")]
|
||||
#[pymethod]
|
||||
fn __mul__(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a * b, vm)
|
||||
fn __mul__(&self, other: PyObjectRef) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a * b)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
@@ -385,24 +385,24 @@ impl PyInt {
|
||||
|
||||
#[pymethod(name = "__rxor__")]
|
||||
#[pymethod]
|
||||
pub fn __xor__(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a ^ b, vm)
|
||||
pub fn __xor__(&self, other: PyObjectRef) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a ^ b)
|
||||
}
|
||||
|
||||
#[pymethod(name = "__ror__")]
|
||||
#[pymethod]
|
||||
pub fn __or__(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a | b, vm)
|
||||
pub fn __or__(&self, other: PyObjectRef) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a | b)
|
||||
}
|
||||
|
||||
#[pymethod(name = "__rand__")]
|
||||
#[pymethod]
|
||||
pub fn __and__(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a & b, vm)
|
||||
pub fn __and__(&self, other: PyObjectRef) -> PyArithmeticValue<BigInt> {
|
||||
self.int_op(other, |a, b| a & b)
|
||||
}
|
||||
|
||||
fn modpow(&self, other: PyObjectRef, modulus: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
let modulus = match modulus.payload_if_subclass::<Self>(vm) {
|
||||
let modulus = match modulus.downcast_ref::<Self>() {
|
||||
Some(val) => val.as_bigint(),
|
||||
None => return Ok(vm.ctx.not_implemented()),
|
||||
};
|
||||
@@ -714,10 +714,10 @@ impl Comparable for PyInt {
|
||||
zelf: &Py<Self>,
|
||||
other: &PyObject,
|
||||
op: PyComparisonOp,
|
||||
vm: &VirtualMachine,
|
||||
_vm: &VirtualMachine,
|
||||
) -> PyResult<PyComparisonValue> {
|
||||
let r = other
|
||||
.payload_if_subclass::<Self>(vm)
|
||||
.downcast_ref::<Self>()
|
||||
.map(|other| op.eval_ord(zelf.value.cmp(&other.value)));
|
||||
Ok(PyComparisonValue::from_option(r))
|
||||
}
|
||||
@@ -757,14 +757,7 @@ impl PyInt {
|
||||
remainder: Some(|a, b, vm| Self::number_op(a, b, inner_mod, vm)),
|
||||
divmod: Some(|a, b, vm| Self::number_op(a, b, inner_divmod, vm)),
|
||||
power: Some(|a, b, c, vm| {
|
||||
if let (Some(a), Some(b)) = (
|
||||
a.payload::<Self>(),
|
||||
if b.payload_is::<Self>() {
|
||||
Some(b)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
) {
|
||||
if let Some(a) = a.downcast_ref::<Self>() {
|
||||
if vm.is_none(c) {
|
||||
a.general_op(b.to_owned(), |a, b| inner_pow(a, b, vm), vm)
|
||||
} else {
|
||||
@@ -800,7 +793,7 @@ impl PyInt {
|
||||
F: FnOnce(&BigInt, &BigInt, &VirtualMachine) -> R,
|
||||
R: ToPyResult,
|
||||
{
|
||||
if let (Some(a), Some(b)) = (a.payload::<Self>(), b.payload::<Self>()) {
|
||||
if let (Some(a), Some(b)) = (a.downcast_ref::<Self>(), b.downcast_ref::<Self>()) {
|
||||
op(&a.value, &b.value, vm).to_pyresult(vm)
|
||||
} else {
|
||||
Ok(vm.ctx.not_implemented())
|
||||
@@ -867,7 +860,7 @@ fn try_int_radix(obj: &PyObject, base: u32, vm: &VirtualMachine) -> PyResult<Big
|
||||
|
||||
// Retrieve inner int value:
|
||||
pub(crate) fn get_value(obj: &PyObject) -> &BigInt {
|
||||
&obj.payload::<PyInt>().unwrap().value
|
||||
&obj.downcast_ref::<PyInt>().unwrap().value
|
||||
}
|
||||
|
||||
pub fn try_to_float(int: &BigInt, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
|
||||
@@ -59,7 +59,7 @@ impl<T> PositionIterInternal<T> {
|
||||
F: FnOnce(&T, usize) -> usize,
|
||||
{
|
||||
if let IterStatus::Active(obj) = &self.status {
|
||||
if let Some(i) = state.payload::<PyInt>() {
|
||||
if let Some(i) = state.downcast_ref::<PyInt>() {
|
||||
let i = i.try_to_primitive(vm).unwrap_or(0);
|
||||
self.position = f(obj, i);
|
||||
Ok(())
|
||||
|
||||
@@ -131,7 +131,7 @@ impl PyList {
|
||||
}
|
||||
|
||||
fn concat(&self, other: &PyObject, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
|
||||
let other = other.payload_if_subclass::<Self>(vm).ok_or_else(|| {
|
||||
let other = other.downcast_ref::<Self>().ok_or_else(|| {
|
||||
vm.new_type_error(format!(
|
||||
"Cannot add {} and {}",
|
||||
Self::class(&vm.ctx).name(),
|
||||
@@ -346,9 +346,9 @@ where
|
||||
F: FnMut(PyObjectRef) -> PyResult<R>,
|
||||
{
|
||||
use crate::builtins::PyTuple;
|
||||
if let Some(tuple) = obj.payload_if_exact::<PyTuple>(vm) {
|
||||
if let Some(tuple) = obj.downcast_ref_if_exact::<PyTuple>(vm) {
|
||||
tuple.iter().map(|x| f(x.clone())).collect()
|
||||
} else if let Some(list) = obj.payload_if_exact::<PyList>(vm) {
|
||||
} else if let Some(list) = obj.downcast_ref_if_exact::<PyList>(vm) {
|
||||
list.borrow_vec().iter().map(|x| f(x.clone())).collect()
|
||||
} else {
|
||||
let iter = obj.to_owned().get_iter(vm)?;
|
||||
|
||||
@@ -63,9 +63,7 @@ impl Constructor for PyMappingProxy {
|
||||
|
||||
fn py_new(cls: PyTypeRef, mapping: Self::Args, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(methods) = PyMapping::find_methods(&mapping) {
|
||||
if mapping.payload_if_subclass::<PyList>(vm).is_none()
|
||||
&& mapping.payload_if_subclass::<PyTuple>(vm).is_none()
|
||||
{
|
||||
if !mapping.downcastable::<PyList>() && !mapping.downcastable::<PyTuple>() {
|
||||
return Self {
|
||||
mapping: MappingProxyInner::Mapping(ArgMapping::with_methods(
|
||||
mapping,
|
||||
|
||||
@@ -75,7 +75,7 @@ impl PyMemoryView {
|
||||
/// this should be the main entrance to create the memoryview
|
||||
/// to avoid the chained memoryview
|
||||
pub fn from_object(obj: &PyObject, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
if let Some(other) = obj.payload::<Self>() {
|
||||
if let Some(other) = obj.downcast_ref::<Self>() {
|
||||
Ok(other.new_view())
|
||||
} else {
|
||||
let buffer = PyBuffer::try_from_borrowed_object(vm, obj)?;
|
||||
@@ -330,7 +330,7 @@ impl PyMemoryView {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if let Some(other) = other.payload::<Self>() {
|
||||
if let Some(other) = other.downcast_ref::<Self>() {
|
||||
if other.released.load() {
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -665,7 +665,7 @@ impl PyMemoryView {
|
||||
if needle.is(&vm.ctx.ellipsis) {
|
||||
return Ok(zelf.into());
|
||||
}
|
||||
if let Some(tuple) = needle.payload::<PyTuple>() {
|
||||
if let Some(tuple) = needle.downcast_ref::<PyTuple>() {
|
||||
if tuple.is_empty() {
|
||||
return zelf.unpack_single(0, vm);
|
||||
}
|
||||
@@ -864,7 +864,7 @@ impl Py<PyMemoryView> {
|
||||
// TODO: merge branches when we got conditional if let
|
||||
if needle.is(&vm.ctx.ellipsis) {
|
||||
return self.pack_single(0, value, vm);
|
||||
} else if let Some(tuple) = needle.payload::<PyTuple>() {
|
||||
} else if let Some(tuple) = needle.downcast_ref::<PyTuple>() {
|
||||
if tuple.is_empty() {
|
||||
return self.pack_single(0, value, vm);
|
||||
}
|
||||
@@ -907,15 +907,15 @@ enum SubscriptNeedle {
|
||||
impl TryFromObject for SubscriptNeedle {
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
// TODO: number protocol
|
||||
if let Some(i) = obj.payload::<PyInt>() {
|
||||
if let Some(i) = obj.downcast_ref::<PyInt>() {
|
||||
Ok(Self::Index(i.try_to_primitive(vm)?))
|
||||
} else if obj.payload_is::<PySlice>() {
|
||||
} else if obj.downcastable::<PySlice>() {
|
||||
Ok(Self::Slice(unsafe { obj.downcast_unchecked::<PySlice>() }))
|
||||
} else if let Ok(i) = obj.try_index(vm) {
|
||||
Ok(Self::Index(i.try_to_primitive(vm)?))
|
||||
} else {
|
||||
if let Some(tuple) = obj.payload::<PyTuple>() {
|
||||
if tuple.iter().all(|x| x.payload_is::<PyInt>()) {
|
||||
if let Some(tuple) = obj.downcast_ref::<PyTuple>() {
|
||||
if tuple.iter().all(|x| x.downcastable::<PyInt>()) {
|
||||
let v = tuple
|
||||
.iter()
|
||||
.map(|x| {
|
||||
@@ -924,7 +924,7 @@ impl TryFromObject for SubscriptNeedle {
|
||||
})
|
||||
.try_collect()?;
|
||||
return Ok(Self::MultiIndex(v));
|
||||
} else if tuple.iter().all(|x| x.payload_is::<PySlice>()) {
|
||||
} else if tuple.iter().all(|x| x.downcastable::<PySlice>()) {
|
||||
return Err(vm.new_not_implemented_error(
|
||||
"multi-dimensional slicing is not implemented",
|
||||
));
|
||||
|
||||
@@ -165,7 +165,7 @@ impl PyRange {
|
||||
}
|
||||
|
||||
// pub fn get_value(obj: &PyObject) -> PyRange {
|
||||
// obj.payload::<PyRange>().unwrap().clone()
|
||||
// obj.downcast_ref::<PyRange>().unwrap().clone()
|
||||
// }
|
||||
|
||||
pub fn init(context: &Context) {
|
||||
@@ -677,7 +677,7 @@ fn range_iter_reduce(
|
||||
|
||||
// Silently clips state (i.e index) in range [0, usize::MAX].
|
||||
fn range_state(length: &BigInt, state: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
if let Some(i) = state.payload::<PyInt>() {
|
||||
if let Some(i) = state.downcast_ref::<PyInt>() {
|
||||
let mut index = i.as_bigint();
|
||||
let max_usize = BigInt::from(usize::MAX);
|
||||
if index > length {
|
||||
|
||||
@@ -474,7 +474,7 @@ impl PySetInner {
|
||||
F: Fn(&PyObject, &VirtualMachine) -> PyResult<T>,
|
||||
{
|
||||
op(item, vm).or_else(|original_err| {
|
||||
item.payload_if_subclass::<PySet>(vm)
|
||||
item.downcast_ref::<PySet>()
|
||||
// Keep original error around.
|
||||
.ok_or(original_err)
|
||||
.and_then(|set| {
|
||||
|
||||
@@ -549,7 +549,7 @@ impl PyStr {
|
||||
impl PyStr {
|
||||
#[pymethod]
|
||||
fn __add__(zelf: PyRef<Self>, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
if let Some(other) = other.payload::<Self>() {
|
||||
if let Some(other) = other.downcast_ref::<Self>() {
|
||||
let bytes = zelf.as_wtf8().py_add(other.as_wtf8());
|
||||
Ok(unsafe {
|
||||
// SAFETY: `kind` is safely decided
|
||||
@@ -569,7 +569,7 @@ impl PyStr {
|
||||
}
|
||||
|
||||
fn _contains(&self, needle: &PyObject, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
if let Some(needle) = needle.payload::<Self>() {
|
||||
if let Some(needle) = needle.downcast_ref::<Self>() {
|
||||
Ok(memchr::memmem::find(self.as_bytes(), needle.as_bytes()).is_some())
|
||||
} else {
|
||||
Err(vm.new_type_error(format!(
|
||||
@@ -1374,9 +1374,9 @@ impl PyStr {
|
||||
for c in self.as_str().chars() {
|
||||
match table.get_item(&*(c as u32).to_pyobject(vm), vm) {
|
||||
Ok(value) => {
|
||||
if let Some(text) = value.payload::<Self>() {
|
||||
if let Some(text) = value.downcast_ref::<Self>() {
|
||||
translated.push_str(text.as_str());
|
||||
} else if let Some(bigint) = value.payload::<PyInt>() {
|
||||
} else if let Some(bigint) = value.downcast_ref::<PyInt>() {
|
||||
let ch = bigint
|
||||
.as_bigint()
|
||||
.to_u32()
|
||||
@@ -1438,13 +1438,13 @@ impl PyStr {
|
||||
Ok(dict) => {
|
||||
for (key, val) in dict {
|
||||
// FIXME: ints are key-compatible
|
||||
if let Some(num) = key.payload::<PyInt>() {
|
||||
if let Some(num) = key.downcast_ref::<PyInt>() {
|
||||
new_dict.set_item(
|
||||
&*num.as_bigint().to_i32().to_pyobject(vm),
|
||||
val,
|
||||
vm,
|
||||
)?;
|
||||
} else if let Some(string) = key.payload::<Self>() {
|
||||
} else if let Some(string) = key.downcast_ref::<Self>() {
|
||||
if string.len() == 1 {
|
||||
let num_value = string.as_str().chars().next().unwrap() as u32;
|
||||
new_dict.set_item(&*num_value.to_pyobject(vm), val, vm)?;
|
||||
|
||||
@@ -592,7 +592,7 @@ impl PyType {
|
||||
PyType::resolve_mro(&cls.bases.read()).map_err(|msg| vm.new_type_error(msg))?;
|
||||
for subclass in cls.subclasses.write().iter() {
|
||||
let subclass = subclass.upgrade().unwrap();
|
||||
let subclass: &PyType = subclass.payload().unwrap();
|
||||
let subclass: &Py<PyType> = subclass.downcast_ref().unwrap();
|
||||
update_mro_recursively(subclass, vm)?;
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -153,7 +153,7 @@ impl PyUnion {
|
||||
|
||||
pub fn is_unionable(obj: PyObjectRef, vm: &VirtualMachine) -> bool {
|
||||
obj.class().is(vm.ctx.types.none_type)
|
||||
|| obj.payload_if_subclass::<PyType>(vm).is_some()
|
||||
|| obj.downcastable::<PyType>()
|
||||
|| obj.class().is(vm.ctx.types.generic_alias_type)
|
||||
|| obj.class().is(vm.ctx.types.union_type)
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ fn spec_format_bytes(
|
||||
obj => {
|
||||
if let Some(method) = vm.get_method(obj.clone(), identifier!(vm, __int__)) {
|
||||
let result = method?.call((), vm)?;
|
||||
if let Some(i) = result.payload::<PyInt>() {
|
||||
if let Some(i) = result.downcast_ref::<PyInt>() {
|
||||
return Ok(spec.format_number(i.as_bigint()).into_bytes());
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ fn spec_format_bytes(
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
if let Some(i) = obj.payload::<PyInt>() {
|
||||
if let Some(i) = obj.downcast_ref::<PyInt>() {
|
||||
Ok(spec.format_number(i.as_bigint()).into_bytes())
|
||||
} else {
|
||||
Err(vm.new_type_error(format!(
|
||||
@@ -101,17 +101,17 @@ fn spec_format_bytes(
|
||||
Ok(spec.format_float(value.into()).into_bytes())
|
||||
}
|
||||
CFormatType::Character(CCharacterType::Character) => {
|
||||
if let Some(i) = obj.payload::<PyInt>() {
|
||||
if let Some(i) = obj.downcast_ref::<PyInt>() {
|
||||
let ch = i
|
||||
.try_to_primitive::<u8>(vm)
|
||||
.map_err(|_| vm.new_overflow_error("%c arg not in range(256)"))?;
|
||||
return Ok(spec.format_char(ch));
|
||||
}
|
||||
if let Some(b) = obj.payload::<PyBytes>() {
|
||||
if let Some(b) = obj.downcast_ref::<PyBytes>() {
|
||||
if b.len() == 1 {
|
||||
return Ok(spec.format_char(b.as_bytes()[0]));
|
||||
}
|
||||
} else if let Some(ba) = obj.payload::<PyByteArray>() {
|
||||
} else if let Some(ba) = obj.downcast_ref::<PyByteArray>() {
|
||||
let buf = ba.borrow_buf();
|
||||
if buf.len() == 1 {
|
||||
return Ok(spec.format_char(buf[0]));
|
||||
@@ -158,7 +158,7 @@ fn spec_format_string(
|
||||
obj => {
|
||||
if let Some(method) = vm.get_method(obj.clone(), identifier!(vm, __int__)) {
|
||||
let result = method?.call((), vm)?;
|
||||
if let Some(i) = result.payload::<PyInt>() {
|
||||
if let Some(i) = result.downcast_ref::<PyInt>() {
|
||||
return Ok(spec.format_number(i.as_bigint()).into());
|
||||
}
|
||||
}
|
||||
@@ -171,7 +171,7 @@ fn spec_format_string(
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
if let Some(i) = obj.payload::<PyInt>() {
|
||||
if let Some(i) = obj.downcast_ref::<PyInt>() {
|
||||
Ok(spec.format_number(i.as_bigint()).into())
|
||||
} else {
|
||||
Err(vm.new_type_error(format!(
|
||||
@@ -187,7 +187,7 @@ fn spec_format_string(
|
||||
Ok(spec.format_float(value.into()).into())
|
||||
}
|
||||
CFormatType::Character(CCharacterType::Character) => {
|
||||
if let Some(i) = obj.payload::<PyInt>() {
|
||||
if let Some(i) = obj.downcast_ref::<PyInt>() {
|
||||
let ch = i
|
||||
.as_bigint()
|
||||
.to_u32()
|
||||
@@ -195,7 +195,7 @@ fn spec_format_string(
|
||||
.ok_or_else(|| vm.new_overflow_error("%c arg not in range(0x110000)"))?;
|
||||
return Ok(spec.format_char(ch));
|
||||
}
|
||||
if let Some(s) = obj.payload::<PyStr>() {
|
||||
if let Some(s) = obj.downcast_ref::<PyStr>() {
|
||||
if let Ok(ch) = s.as_wtf8().code_points().exactly_one() {
|
||||
return Ok(spec.format_char(ch));
|
||||
}
|
||||
@@ -211,7 +211,7 @@ fn try_update_quantity_from_element(
|
||||
) -> PyResult<CFormatQuantity> {
|
||||
match element {
|
||||
Some(width_obj) => {
|
||||
if let Some(i) = width_obj.payload::<PyInt>() {
|
||||
if let Some(i) = width_obj.downcast_ref::<PyInt>() {
|
||||
let i = i.try_to_primitive::<i32>(vm)?.unsigned_abs();
|
||||
Ok(CFormatQuantity::Amount(i as usize))
|
||||
} else {
|
||||
@@ -228,7 +228,7 @@ fn try_conversion_flag_from_tuple(
|
||||
) -> PyResult<CConversionFlags> {
|
||||
match element {
|
||||
Some(width_obj) => {
|
||||
if let Some(i) = width_obj.payload::<PyInt>() {
|
||||
if let Some(i) = width_obj.downcast_ref::<PyInt>() {
|
||||
let i = i.try_to_primitive::<i32>(vm)?;
|
||||
let flags = if i < 0 {
|
||||
CConversionFlags::LEFT_ADJUST
|
||||
@@ -299,7 +299,7 @@ pub(crate) fn cformat_bytes(
|
||||
// literal only
|
||||
return if is_mapping
|
||||
|| values_obj
|
||||
.payload::<tuple::PyTuple>()
|
||||
.downcast_ref::<tuple::PyTuple>()
|
||||
.is_some_and(|e| e.is_empty())
|
||||
{
|
||||
for (_, part) in format.iter_mut() {
|
||||
@@ -335,7 +335,7 @@ pub(crate) fn cformat_bytes(
|
||||
}
|
||||
|
||||
// tuple
|
||||
let values = if let Some(tup) = values_obj.payload_if_subclass::<tuple::PyTuple>(vm) {
|
||||
let values = if let Some(tup) = values_obj.downcast_ref::<tuple::PyTuple>() {
|
||||
tup.as_slice()
|
||||
} else {
|
||||
std::slice::from_ref(&values_obj)
|
||||
@@ -393,7 +393,7 @@ pub(crate) fn cformat_string(
|
||||
// literal only
|
||||
return if is_mapping
|
||||
|| values_obj
|
||||
.payload::<tuple::PyTuple>()
|
||||
.downcast_ref::<tuple::PyTuple>()
|
||||
.is_some_and(|e| e.is_empty())
|
||||
{
|
||||
for (_, part) in format.iter() {
|
||||
@@ -428,7 +428,7 @@ pub(crate) fn cformat_string(
|
||||
}
|
||||
|
||||
// tuple
|
||||
let values = if let Some(tup) = values_obj.payload_if_subclass::<tuple::PyTuple>(vm) {
|
||||
let values = if let Some(tup) = values_obj.downcast_ref::<tuple::PyTuple>() {
|
||||
tup.as_slice()
|
||||
} else {
|
||||
std::slice::from_ref(&values_obj)
|
||||
|
||||
@@ -852,7 +852,7 @@ impl<'a> EncodeErrorHandler<PyEncodeContext<'a>> for ErrorsHandler<'_> {
|
||||
let res = handler.call((encode_exc.clone(),), vm)?;
|
||||
let tuple_err =
|
||||
|| vm.new_type_error("encoding error handler must return (str/bytes, int) tuple");
|
||||
let (replace, restart) = match res.payload::<PyTuple>().map(|tup| tup.as_slice()) {
|
||||
let (replace, restart) = match res.downcast_ref::<PyTuple>().map(|tup| tup.as_slice()) {
|
||||
Some([replace, restart]) => (replace.clone(), restart),
|
||||
_ => return Err(tuple_err()),
|
||||
};
|
||||
@@ -910,7 +910,7 @@ impl<'a> DecodeErrorHandler<PyDecodeContext<'a>> for ErrorsHandler<'_> {
|
||||
}
|
||||
let data = &*ctx.data;
|
||||
let tuple_err = || vm.new_type_error("decoding error handler must return (str, int) tuple");
|
||||
match res.payload::<PyTuple>().map(|tup| tup.as_slice()) {
|
||||
match res.downcast_ref::<PyTuple>().map(|tup| tup.as_slice()) {
|
||||
Some([replace, restart]) => {
|
||||
let replace = replace
|
||||
.downcast_ref::<PyStr>()
|
||||
|
||||
@@ -17,7 +17,7 @@ unsafe impl<T: PyPayload> TransmuteFromObject for PyRef<T> {
|
||||
fn check(vm: &VirtualMachine, obj: &PyObject) -> PyResult<()> {
|
||||
let class = T::class(&vm.ctx);
|
||||
if obj.fast_isinstance(class) {
|
||||
if obj.payload_is::<T>() {
|
||||
if obj.downcastable::<T>() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(vm.new_downcast_runtime_error(class, obj))
|
||||
|
||||
@@ -124,7 +124,7 @@ impl<'a, T: PyPayload> TryFromBorrowedObject<'a> for &'a Py<T> {
|
||||
|
||||
impl TryFromObject for std::time::Duration {
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
if let Some(float) = obj.payload::<PyFloat>() {
|
||||
if let Some(float) = obj.downcast_ref::<PyFloat>() {
|
||||
let f = float.to_f64();
|
||||
if f < 0.0 {
|
||||
return Err(vm.new_value_error("negative duration"));
|
||||
|
||||
@@ -777,7 +777,7 @@ impl DictKey for Py<PyStr> {
|
||||
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
|
||||
if self.is(other_key) {
|
||||
Ok(true)
|
||||
} else if let Some(pystr) = other_key.payload_if_exact::<PyStr>(vm) {
|
||||
} else if let Some(pystr) = other_key.downcast_ref_if_exact::<PyStr>(vm) {
|
||||
Ok(self.as_wtf8() == pystr.as_wtf8())
|
||||
} else {
|
||||
vm.bool_eq(self.as_object(), other_key)
|
||||
@@ -875,7 +875,7 @@ impl DictKey for str {
|
||||
}
|
||||
|
||||
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
|
||||
if let Some(pystr) = other_key.payload_if_exact::<PyStr>(vm) {
|
||||
if let Some(pystr) = other_key.downcast_ref_if_exact::<PyStr>(vm) {
|
||||
Ok(pystr.as_wtf8() == self)
|
||||
} else {
|
||||
// Fall back to PyObjectRef implementation.
|
||||
@@ -936,7 +936,7 @@ impl DictKey for Wtf8 {
|
||||
}
|
||||
|
||||
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
|
||||
if let Some(pystr) = other_key.payload_if_exact::<PyStr>(vm) {
|
||||
if let Some(pystr) = other_key.downcast_ref_if_exact::<PyStr>(vm) {
|
||||
Ok(pystr.as_wtf8() == self)
|
||||
} else {
|
||||
// Fall back to PyObjectRef implementation.
|
||||
@@ -997,7 +997,7 @@ impl DictKey for [u8] {
|
||||
}
|
||||
|
||||
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
|
||||
if let Some(pystr) = other_key.payload_if_exact::<PyBytes>(vm) {
|
||||
if let Some(pystr) = other_key.downcast_ref_if_exact::<PyBytes>(vm) {
|
||||
Ok(pystr.as_bytes() == self)
|
||||
} else {
|
||||
// Fall back to PyObjectRef implementation.
|
||||
@@ -1053,7 +1053,7 @@ impl DictKey for usize {
|
||||
}
|
||||
|
||||
fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult<bool> {
|
||||
if let Some(int) = other_key.payload_if_exact::<PyInt>(vm) {
|
||||
if let Some(int) = other_key.downcast_ref_if_exact::<PyInt>(vm) {
|
||||
if let Some(i) = int.as_bigint().to_usize() {
|
||||
Ok(i == *self)
|
||||
} else {
|
||||
|
||||
@@ -1445,7 +1445,7 @@ pub(super) mod types {
|
||||
if (2..=5).contains(&len) {
|
||||
let errno = &args[0];
|
||||
errno
|
||||
.payload_if_subclass::<PyInt>(vm)
|
||||
.downcast_ref::<PyInt>()
|
||||
.and_then(|errno| errno.try_to_primitive::<i32>(vm).ok())
|
||||
.and_then(|errno| super::errno_to_exc_type(errno, vm))
|
||||
.and_then(|typ| vm.invoke_exception(typ.to_owned(), args.to_vec()).ok())
|
||||
|
||||
@@ -733,7 +733,7 @@ impl ExecutingFrame<'_> {
|
||||
.pop_multiple(size.get(arg) as usize)
|
||||
.as_slice()
|
||||
.iter()
|
||||
.map(|pyobj| pyobj.payload::<PyStr>().unwrap())
|
||||
.map(|pyobj| pyobj.downcast_ref::<PyStr>().unwrap())
|
||||
.collect::<Wtf8Buf>();
|
||||
let str_obj = vm.ctx.new_str(s);
|
||||
self.push_value(str_obj.into());
|
||||
@@ -1077,7 +1077,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
bytecode::Instruction::GetAwaitable => {
|
||||
let awaited_obj = self.pop_value();
|
||||
let awaitable = if awaited_obj.payload_is::<PyCoroutine>() {
|
||||
let awaitable = if awaited_obj.downcastable::<PyCoroutine>() {
|
||||
awaited_obj
|
||||
} else {
|
||||
let await_method = vm.get_method_or_type_error(
|
||||
@@ -1595,7 +1595,7 @@ impl ExecutingFrame<'_> {
|
||||
let kwarg_names = kwarg_names
|
||||
.as_slice()
|
||||
.iter()
|
||||
.map(|pyobj| pyobj.payload::<PyStr>().unwrap().as_str().to_owned());
|
||||
.map(|pyobj| pyobj.downcast_ref::<PyStr>().unwrap().as_str().to_owned());
|
||||
FuncArgs::with_kwargs_names(args, kwarg_names)
|
||||
}
|
||||
|
||||
@@ -1607,7 +1607,7 @@ impl ExecutingFrame<'_> {
|
||||
// Use keys() method for all mapping objects to preserve order
|
||||
Self::iterate_mapping_keys(vm, &kw_obj, "argument after **", |key| {
|
||||
let key_str = key
|
||||
.payload_if_subclass::<PyStr>(vm)
|
||||
.downcast_ref::<PyStr>()
|
||||
.ok_or_else(|| vm.new_type_error("keywords must be strings"))?;
|
||||
let value = kw_obj.get_item(&*key, vm)?;
|
||||
kwargs.insert(key_str.as_str().to_owned(), value);
|
||||
@@ -2337,7 +2337,7 @@ impl fmt::Debug for Frame {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let state = self.state.lock();
|
||||
let stack_str = state.stack.iter().fold(String::new(), |mut s, elem| {
|
||||
if elem.payload_is::<Self>() {
|
||||
if elem.downcastable::<Self>() {
|
||||
s.push_str("\n > {frame}");
|
||||
} else {
|
||||
std::fmt::write(&mut s, format_args!("\n > {elem:?}")).unwrap();
|
||||
|
||||
@@ -145,7 +145,7 @@ macro_rules! match_class {
|
||||
}
|
||||
};
|
||||
(match ($obj:expr) { ref $binding:ident @ $class:ty => $expr:expr, $($rest:tt)* }) => {
|
||||
match $obj.payload::<$class>() {
|
||||
match $obj.downcast_ref::<$class>() {
|
||||
::std::option::Option::Some($binding) => $expr,
|
||||
::std::option::Option::None => $crate::match_class!(match ($obj) { $($rest)* }),
|
||||
}
|
||||
@@ -160,7 +160,7 @@ macro_rules! match_class {
|
||||
// An arm taken when the object is an instance of the specified built-in
|
||||
// class.
|
||||
(match ($obj:expr) { $class:ty => $expr:expr, $($rest:tt)* }) => {
|
||||
if $obj.payload_is::<$class>() {
|
||||
if $obj.downcastable::<$class>() {
|
||||
$expr
|
||||
} else {
|
||||
$crate::match_class!(match ($obj) { $($rest)* })
|
||||
|
||||
@@ -534,24 +534,13 @@ impl PyObjectRef {
|
||||
/// another downcast can be attempted without unnecessary cloning.
|
||||
#[inline(always)]
|
||||
pub fn downcast<T: PyObjectPayload>(self) -> Result<PyRef<T>, Self> {
|
||||
if self.payload_is::<T>() {
|
||||
if self.downcastable::<T>() {
|
||||
Ok(unsafe { self.downcast_unchecked() })
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn downcast_ref<T: PyObjectPayload>(&self) -> Option<&Py<T>> {
|
||||
if self.payload_is::<T>() {
|
||||
// SAFETY: just checked that the payload is T, and PyRef is repr(transparent) over
|
||||
// PyObjectRef
|
||||
Some(unsafe { &*(self as *const Self as *const PyRef<T>) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Force to downcast this reference to a subclass.
|
||||
///
|
||||
/// # Safety
|
||||
@@ -566,15 +555,6 @@ impl PyObjectRef {
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
/// T must be the exact payload type
|
||||
#[inline(always)]
|
||||
pub unsafe fn downcast_unchecked_ref<T: PyObjectPayload>(&self) -> &Py<T> {
|
||||
debug_assert!(self.payload_is::<T>());
|
||||
// SAFETY: requirements forwarded from caller
|
||||
unsafe { &*(self as *const Self as *const PyRef<T>) }
|
||||
}
|
||||
|
||||
// ideally we'd be able to define these in pyobject.rs, but method visibility rules are weird
|
||||
|
||||
/// Attempt to downcast this reference to the specific class that is associated `T`.
|
||||
@@ -589,10 +569,10 @@ impl PyObjectRef {
|
||||
if self.class().is(T::class(&vm.ctx)) {
|
||||
// TODO: is this always true?
|
||||
assert!(
|
||||
self.payload_is::<T>(),
|
||||
self.downcastable::<T>(),
|
||||
"obj.__class__ is T::class() but payload is not T"
|
||||
);
|
||||
// SAFETY: just asserted that payload_is::<T>()
|
||||
// SAFETY: just asserted that downcastable::<T>()
|
||||
Ok(unsafe { PyRefExact::new_unchecked(PyRef::from_obj_unchecked(self)) })
|
||||
} else {
|
||||
Err(self)
|
||||
@@ -670,6 +650,7 @@ impl PyObject {
|
||||
&inner.payload
|
||||
}
|
||||
|
||||
#[deprecated(note = "use downcast_ref instead")]
|
||||
#[inline(always)]
|
||||
pub fn payload<T: PyObjectPayload>(&self) -> Option<&T> {
|
||||
if self.payload_is::<T>() {
|
||||
@@ -688,12 +669,14 @@ impl PyObject {
|
||||
self.0.typ.swap_to_temporary_refs(typ, vm);
|
||||
}
|
||||
|
||||
#[deprecated(note = "use downcast_ref_if_exact instead")]
|
||||
#[inline(always)]
|
||||
pub fn payload_if_exact<T: PyObjectPayload + crate::PyPayload>(
|
||||
&self,
|
||||
vm: &VirtualMachine,
|
||||
) -> Option<&T> {
|
||||
if self.class().is(T::class(&vm.ctx)) {
|
||||
#[allow(deprecated)]
|
||||
self.payload()
|
||||
} else {
|
||||
None
|
||||
@@ -722,18 +705,27 @@ impl PyObject {
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(note = "use downcast_ref instead")]
|
||||
#[inline(always)]
|
||||
pub fn payload_if_subclass<T: crate::PyPayload>(&self, vm: &VirtualMachine) -> Option<&T> {
|
||||
if self.class().fast_issubclass(T::class(&vm.ctx)) {
|
||||
#[allow(deprecated)]
|
||||
self.payload()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if this object can be downcast to T.
|
||||
#[inline(always)]
|
||||
pub fn downcastable<T: PyObjectPayload>(&self) -> bool {
|
||||
self.payload_is::<T>()
|
||||
}
|
||||
|
||||
/// Attempt to downcast this reference to a subclass.
|
||||
#[inline(always)]
|
||||
pub fn downcast_ref<T: PyObjectPayload>(&self) -> Option<&Py<T>> {
|
||||
if self.payload_is::<T>() {
|
||||
if self.downcastable::<T>() {
|
||||
// SAFETY: just checked that the payload is T, and PyRef is repr(transparent) over
|
||||
// PyObjectRef
|
||||
Some(unsafe { self.downcast_unchecked_ref::<T>() })
|
||||
@@ -756,7 +748,7 @@ impl PyObject {
|
||||
/// T must be the exact payload type
|
||||
#[inline(always)]
|
||||
pub unsafe fn downcast_unchecked_ref<T: PyObjectPayload>(&self) -> &Py<T> {
|
||||
debug_assert!(self.payload_is::<T>());
|
||||
debug_assert!(self.downcastable::<T>());
|
||||
// SAFETY: requirements forwarded from caller
|
||||
unsafe { &*(self as *const Self as *const Py<T>) }
|
||||
}
|
||||
@@ -1045,7 +1037,7 @@ impl<T: PyObjectPayload> PyRef<T> {
|
||||
/// Safety: payload type of `obj` must be `T`
|
||||
#[inline(always)]
|
||||
unsafe fn from_obj_unchecked(obj: PyObjectRef) -> Self {
|
||||
debug_assert!(obj.payload_is::<T>());
|
||||
debug_assert!(obj.downcast_ref::<T>().is_some());
|
||||
let obj = ManuallyDrop::new(obj);
|
||||
Self {
|
||||
ptr: obj.ptr.cast(),
|
||||
|
||||
@@ -25,7 +25,7 @@ impl PyObject {
|
||||
pub fn try_index_opt(&self, vm: &VirtualMachine) -> Option<PyResult<PyIntRef>> {
|
||||
if let Some(i) = self.downcast_ref_if_exact::<PyInt>(vm) {
|
||||
Some(Ok(i.to_owned()))
|
||||
} else if let Some(i) = self.payload::<PyInt>() {
|
||||
} else if let Some(i) = self.downcast_ref::<PyInt>() {
|
||||
Some(Ok(vm.ctx.new_bigint(i.as_bigint())))
|
||||
} else {
|
||||
self.to_number().index(vm)
|
||||
@@ -75,11 +75,11 @@ impl PyObject {
|
||||
ret.class()
|
||||
))
|
||||
})
|
||||
} else if let Some(s) = self.payload::<PyStr>() {
|
||||
} else if let Some(s) = self.downcast_ref::<PyStr>() {
|
||||
try_convert(self, s.as_wtf8().trim().as_bytes(), vm)
|
||||
} else if let Some(bytes) = self.payload::<PyBytes>() {
|
||||
} else if let Some(bytes) = self.downcast_ref::<PyBytes>() {
|
||||
try_convert(self, bytes, vm)
|
||||
} else if let Some(bytearray) = self.payload::<PyByteArray>() {
|
||||
} else if let Some(bytearray) = self.downcast_ref::<PyByteArray>() {
|
||||
try_convert(self, &bytearray.borrow_buf(), vm)
|
||||
} else if let Ok(buffer) = ArgBytesLike::try_from_borrowed_object(vm, self) {
|
||||
// TODO: replace to PyBuffer
|
||||
@@ -450,7 +450,7 @@ impl<'a> PyNumber<'a> {
|
||||
methods.int.load().is_some()
|
||||
|| methods.index.load().is_some()
|
||||
|| methods.float.load().is_some()
|
||||
|| obj.payload_is::<PyComplex>()
|
||||
|| obj.downcastable::<PyComplex>()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ impl PyObject {
|
||||
|
||||
// PyObject *PyObject_GetAIter(PyObject *o)
|
||||
pub fn get_aiter(&self, vm: &VirtualMachine) -> PyResult {
|
||||
if self.payload_is::<PyAsyncGen>() {
|
||||
if self.downcastable::<PyAsyncGen>() {
|
||||
vm.call_special_method(self, identifier!(vm, __aiter__), ())
|
||||
} else {
|
||||
Err(vm.new_type_error("wrong argument type"))
|
||||
|
||||
@@ -337,9 +337,9 @@ impl PySequence<'_> {
|
||||
where
|
||||
F: FnMut(&PyObject) -> PyResult<R>,
|
||||
{
|
||||
if let Some(tuple) = self.obj.payload_if_exact::<PyTuple>(vm) {
|
||||
if let Some(tuple) = self.obj.downcast_ref_if_exact::<PyTuple>(vm) {
|
||||
tuple.iter().map(|x| f(x.as_ref())).collect()
|
||||
} else if let Some(list) = self.obj.payload_if_exact::<PyList>(vm) {
|
||||
} else if let Some(list) = self.obj.downcast_ref_if_exact::<PyList>(vm) {
|
||||
list.borrow_vec().iter().map(|x| f(x.as_ref())).collect()
|
||||
} else {
|
||||
let iter = self.obj.to_owned().get_iter(vm)?;
|
||||
|
||||
@@ -62,7 +62,7 @@ impl serde::Serialize for PyObjectSerializer<'_> {
|
||||
}
|
||||
seq.end()
|
||||
};
|
||||
if let Some(s) = self.pyobject.payload::<PyStr>() {
|
||||
if let Some(s) = self.pyobject.downcast_ref::<PyStr>() {
|
||||
serializer.serialize_str(s.as_ref())
|
||||
} else if self.pyobject.fast_isinstance(self.vm.ctx.types.float_type) {
|
||||
serializer.serialize_f64(float::get_value(self.pyobject))
|
||||
@@ -80,9 +80,9 @@ impl serde::Serialize for PyObjectSerializer<'_> {
|
||||
} else {
|
||||
serializer.serialize_i64(v.to_i64().ok_or_else(int_too_large)?)
|
||||
}
|
||||
} else if let Some(list) = self.pyobject.payload_if_subclass::<PyList>(self.vm) {
|
||||
} else if let Some(list) = self.pyobject.downcast_ref::<PyList>() {
|
||||
serialize_seq_elements(serializer, &list.borrow_vec())
|
||||
} else if let Some(tuple) = self.pyobject.payload_if_subclass::<PyTuple>(self.vm) {
|
||||
} else if let Some(tuple) = self.pyobject.downcast_ref::<PyTuple>() {
|
||||
serialize_seq_elements(serializer, tuple)
|
||||
} else if self.pyobject.fast_isinstance(self.vm.ctx.types.dict_type) {
|
||||
let dict: PyDictRef = self.pyobject.to_owned().downcast().unwrap();
|
||||
|
||||
@@ -263,12 +263,12 @@ impl SequenceIndex {
|
||||
obj: &PyObject,
|
||||
type_name: &str,
|
||||
) -> PyResult<Self> {
|
||||
if let Some(i) = obj.payload::<PyInt>() {
|
||||
if let Some(i) = obj.downcast_ref::<PyInt>() {
|
||||
// TODO: number protocol
|
||||
i.try_to_primitive(vm)
|
||||
.map_err(|_| vm.new_index_error("cannot fit 'int' into an index-sized integer"))
|
||||
.map(Self::Int)
|
||||
} else if let Some(slice) = obj.payload::<PySlice>() {
|
||||
} else if let Some(slice) = obj.downcast_ref::<PySlice>() {
|
||||
slice.to_saturated(vm).map(Self::Slice)
|
||||
} else if let Some(i) = obj.try_index_opt(vm) {
|
||||
// TODO: __index__ for indices is no more supported?
|
||||
|
||||
@@ -365,7 +365,7 @@ mod _collections {
|
||||
}
|
||||
|
||||
fn concat(&self, other: &PyObject, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
if let Some(o) = other.payload_if_subclass::<Self>(vm) {
|
||||
if let Some(o) = other.downcast_ref::<Self>() {
|
||||
let mut deque = self.borrow_deque().clone();
|
||||
let elements = o.borrow_deque().clone();
|
||||
deque.extend(elements);
|
||||
@@ -446,7 +446,7 @@ mod _collections {
|
||||
let maxlen = if let Some(obj) = maxlen.into_option() {
|
||||
if !vm.is_none(&obj) {
|
||||
let maxlen: isize = obj
|
||||
.payload::<PyInt>()
|
||||
.downcast_ref::<PyInt>()
|
||||
.ok_or_else(|| vm.new_type_error("an integer is required."))?
|
||||
.try_to_primitive(vm)?;
|
||||
|
||||
|
||||
@@ -108,8 +108,8 @@ impl PyCArray {
|
||||
impl PyCArray {
|
||||
pub fn to_arg(&self, _vm: &VirtualMachine) -> PyResult<libffi::middle::Arg> {
|
||||
let value = self.value.read();
|
||||
let py_bytes = value.payload::<PyBytes>().unwrap();
|
||||
let bytes = py_bytes.as_ref().to_vec();
|
||||
let py_bytes = value.downcast_ref::<PyBytes>().unwrap();
|
||||
let bytes = py_bytes.payload().to_vec();
|
||||
Ok(libffi::middle::Arg::new(&bytes))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,14 +43,14 @@ impl Function {
|
||||
let args = args
|
||||
.iter()
|
||||
.map(|arg| {
|
||||
if let Some(arg) = arg.payload_if_subclass::<PyCSimple>(vm) {
|
||||
if let Some(arg) = arg.downcast_ref::<PyCSimple>() {
|
||||
let converted = ffi_type_from_str(&arg._type_);
|
||||
return match converted {
|
||||
Some(t) => Ok(t),
|
||||
None => Err(vm.new_type_error("Invalid type")), // TODO: add type name
|
||||
};
|
||||
}
|
||||
if let Some(arg) = arg.payload_if_subclass::<PyCArray>(vm) {
|
||||
if let Some(arg) = arg.downcast_ref::<PyCArray>() {
|
||||
let t = arg.typ.read();
|
||||
let ty_attributes = t.attributes.read();
|
||||
let ty_pystr = ty_attributes
|
||||
@@ -107,10 +107,10 @@ impl Function {
|
||||
.enumerate()
|
||||
.map(|(count, arg)| {
|
||||
// none type check
|
||||
if let Some(d) = arg.payload_if_subclass::<PyCSimple>(vm) {
|
||||
if let Some(d) = arg.downcast_ref::<PyCSimple>() {
|
||||
return Ok(d.to_arg(self.args[count].clone(), vm).unwrap());
|
||||
}
|
||||
if let Some(d) = arg.payload_if_subclass::<PyCArray>(vm) {
|
||||
if let Some(d) = arg.downcast_ref::<PyCArray>() {
|
||||
return Ok(d.to_arg(vm).unwrap());
|
||||
}
|
||||
Err(vm.new_type_error("Expected a ctypes simple type"))
|
||||
|
||||
@@ -2370,7 +2370,7 @@ mod _io {
|
||||
codec.get_incremental_encoder(Some(errors.to_owned()), vm)?;
|
||||
let encoding_name = vm.get_attribute_opt(incremental_encoder.clone(), "name")?;
|
||||
let encode_func = encoding_name.and_then(|name| {
|
||||
let name = name.payload::<PyStr>()?;
|
||||
let name = name.downcast_ref::<PyStr>()?;
|
||||
match name.as_str() {
|
||||
"utf-8" => Some(textio_encode_utf8 as EncodeFunc),
|
||||
_ => None,
|
||||
@@ -3090,7 +3090,7 @@ mod _io {
|
||||
obj.class().name()
|
||||
))
|
||||
})?;
|
||||
let flags = flags.payload::<int::PyInt>().ok_or_else(state_err)?;
|
||||
let flags = flags.downcast_ref::<int::PyInt>().ok_or_else(state_err)?;
|
||||
let flags = flags.try_to_primitive(vm)?;
|
||||
Ok((buf, flags))
|
||||
}
|
||||
@@ -4273,7 +4273,7 @@ mod fileio {
|
||||
fn init(zelf: PyRef<Self>, args: Self::Args, vm: &VirtualMachine) -> PyResult<()> {
|
||||
// TODO: let atomic_flag_works
|
||||
let name = args.name;
|
||||
let arg_fd = if let Some(i) = name.payload::<crate::builtins::PyInt>() {
|
||||
let arg_fd = if let Some(i) = name.downcast_ref::<crate::builtins::PyInt>() {
|
||||
let fd = i.try_to_primitive(vm)?;
|
||||
if fd < 0 {
|
||||
return Err(vm.new_value_error("negative file descriptor"));
|
||||
|
||||
@@ -1699,7 +1699,7 @@ mod decl {
|
||||
let r = match r.flatten() {
|
||||
Some(r) => {
|
||||
let val = r
|
||||
.payload::<PyInt>()
|
||||
.downcast_ref::<PyInt>()
|
||||
.ok_or_else(|| vm.new_type_error("Expected int as r"))?
|
||||
.as_bigint();
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ mod _operator {
|
||||
v.class().name()
|
||||
)));
|
||||
}
|
||||
v.payload::<PyInt>().unwrap().try_to_primitive(vm)
|
||||
v.downcast_ref::<PyInt>().unwrap().try_to_primitive(vm)
|
||||
})
|
||||
.unwrap_or(Ok(0))?;
|
||||
obj.length_hint(default, vm)
|
||||
|
||||
@@ -801,7 +801,7 @@ pub(super) mod _os {
|
||||
let mut vec_args = Vec::from(r);
|
||||
loop {
|
||||
if let Ok(obj) = vec_args.iter().exactly_one() {
|
||||
match obj.payload::<PyTuple>() {
|
||||
match obj.downcast_ref::<PyTuple>() {
|
||||
Some(t) => {
|
||||
vec_args = Vec::from(t.as_slice());
|
||||
}
|
||||
@@ -1045,7 +1045,7 @@ pub(super) mod _os {
|
||||
|
||||
#[pyfunction]
|
||||
fn utime(args: UtimeArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let parse_tup = |tup: &PyTuple| -> Option<(PyObjectRef, PyObjectRef)> {
|
||||
let parse_tup = |tup: &Py<PyTuple>| -> Option<(PyObjectRef, PyObjectRef)> {
|
||||
if tup.len() != 2 {
|
||||
None
|
||||
} else {
|
||||
@@ -1065,17 +1065,16 @@ pub(super) mod _os {
|
||||
let ns_in_sec: PyObjectRef = vm.ctx.new_int(1_000_000_000).into();
|
||||
let ns_to_dur = |obj: PyObjectRef| {
|
||||
let divmod = vm._divmod(&obj, &ns_in_sec)?;
|
||||
let (div, rem) =
|
||||
divmod
|
||||
.payload::<PyTuple>()
|
||||
.and_then(parse_tup)
|
||||
.ok_or_else(|| {
|
||||
vm.new_type_error(format!(
|
||||
"{}.__divmod__() must return a 2-tuple, not {}",
|
||||
obj.class().name(),
|
||||
divmod.class().name()
|
||||
))
|
||||
})?;
|
||||
let (div, rem) = divmod
|
||||
.downcast_ref::<PyTuple>()
|
||||
.and_then(parse_tup)
|
||||
.ok_or_else(|| {
|
||||
vm.new_type_error(format!(
|
||||
"{}.__divmod__() must return a 2-tuple, not {}",
|
||||
obj.class().name(),
|
||||
divmod.class().name()
|
||||
))
|
||||
})?;
|
||||
let secs = div.try_index(vm)?.try_to_primitive(vm)?;
|
||||
let ns = rem.try_index(vm)?.try_to_primitive(vm)?;
|
||||
Ok(Duration::new(secs, ns))
|
||||
|
||||
@@ -99,7 +99,7 @@ mod _sre {
|
||||
// re.Scanner has no official API and in CPython's implement
|
||||
// isbytes will be hanging (-1)
|
||||
// here is just a hack to let re.Scanner works only with str not bytes
|
||||
let isbytes = !vm.is_none(&pattern) && !pattern.payload_is::<PyStr>();
|
||||
let isbytes = !vm.is_none(&pattern) && !pattern.downcastable::<PyStr>();
|
||||
let code = code.try_to_value(vm)?;
|
||||
Ok(Pattern {
|
||||
pattern,
|
||||
@@ -155,7 +155,7 @@ mod _sre {
|
||||
|
||||
for trunk in trunks {
|
||||
let index: usize = trunk[0]
|
||||
.payload::<PyInt>()
|
||||
.downcast_ref::<PyInt>()
|
||||
.ok_or_else(|| vm.new_type_error("expected usize"))?
|
||||
.try_to_primitive(vm)?;
|
||||
items.push((index, trunk[1].clone()));
|
||||
@@ -218,7 +218,7 @@ mod _sre {
|
||||
where
|
||||
F: FnOnce(&Wtf8) -> PyResult<R>,
|
||||
{
|
||||
let string = string.payload::<PyStr>().ok_or_else(|| {
|
||||
let string = string.downcast_ref::<PyStr>().ok_or_else(|| {
|
||||
vm.new_type_error(format!("expected string got '{}'", string.class()))
|
||||
})?;
|
||||
f(string.as_wtf8())
|
||||
|
||||
@@ -56,7 +56,7 @@ mod _weakref {
|
||||
dict._as_dict_inner()
|
||||
.delete_if(vm, &*key, |wr| {
|
||||
let wr = wr
|
||||
.payload::<PyWeak>()
|
||||
.downcast_ref::<PyWeak>()
|
||||
.ok_or_else(|| vm.new_type_error("not a weakref"))?;
|
||||
Ok(wr.is_dead())
|
||||
})
|
||||
|
||||
@@ -192,7 +192,7 @@ pub(crate) type DelFunc = fn(&PyObject, &VirtualMachine) -> PyResult<()>;
|
||||
// slot_sq_length
|
||||
pub(crate) fn len_wrapper(obj: &PyObject, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
let ret = vm.call_special_method(obj, identifier!(vm, __len__), ())?;
|
||||
let len = ret.payload::<PyInt>().ok_or_else(|| {
|
||||
let len = ret.downcast_ref::<PyInt>().ok_or_else(|| {
|
||||
vm.new_type_error(format!(
|
||||
"'{}' object cannot be interpreted as an integer",
|
||||
ret.class()
|
||||
@@ -262,7 +262,7 @@ fn repr_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<PyStrRef> {
|
||||
fn hash_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<PyHash> {
|
||||
let hash_obj = vm.call_special_method(zelf, identifier!(vm, __hash__), ())?;
|
||||
let py_int = hash_obj
|
||||
.payload_if_subclass::<PyInt>(vm)
|
||||
.downcast_ref::<PyInt>()
|
||||
.ok_or_else(|| vm.new_type_error("__hash__ method should return an integer"))?;
|
||||
let big_int = py_int.as_bigint();
|
||||
let hash: PyHash = big_int
|
||||
|
||||
@@ -161,7 +161,7 @@ mod tests {
|
||||
let a = vm.new_pyobj(crate::common::ascii!("Hello "));
|
||||
let b = vm.new_pyobj(4_i32);
|
||||
let res = vm._mul(&a, &b).unwrap();
|
||||
let value = res.payload::<PyStr>().unwrap();
|
||||
let value = res.downcast_ref::<PyStr>().unwrap();
|
||||
assert_eq!(value.as_str(), "Hello Hello Hello Hello ")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -657,9 +657,9 @@ impl VirtualMachine {
|
||||
let cls = value.class();
|
||||
let list_borrow;
|
||||
let slice = if cls.is(self.ctx.types.tuple_type) {
|
||||
value.payload::<PyTuple>().unwrap().as_slice()
|
||||
value.downcast_ref::<PyTuple>().unwrap().as_slice()
|
||||
} else if cls.is(self.ctx.types.list_type) {
|
||||
list_borrow = value.payload::<PyList>().unwrap().borrow_vec();
|
||||
list_borrow = value.downcast_ref::<PyList>().unwrap().borrow_vec();
|
||||
&list_borrow
|
||||
} else {
|
||||
return self.map_py_iter(value, func);
|
||||
|
||||
@@ -119,7 +119,7 @@ impl VirtualMachine {
|
||||
}
|
||||
};
|
||||
let hint = result
|
||||
.payload_if_subclass::<PyInt>(self)
|
||||
.downcast_ref::<PyInt>()
|
||||
.ok_or_else(|| {
|
||||
self.new_type_error(format!(
|
||||
"'{}' object cannot be interpreted as an integer",
|
||||
|
||||
@@ -41,7 +41,7 @@ pub fn py_err_to_js_err(vm: &VirtualMachine, py_err: &PyBaseExceptionRef) -> JsV
|
||||
};
|
||||
let js_arg = js_arg
|
||||
.as_ref()
|
||||
.and_then(|x| x.payload::<js_module::PyJsValue>());
|
||||
.and_then(|x| x.downcast_ref::<js_module::PyJsValue>());
|
||||
match js_arg {
|
||||
Some(val) => val.value.clone(),
|
||||
None => {
|
||||
@@ -134,7 +134,7 @@ pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
|
||||
}
|
||||
// the browser module might not be injected
|
||||
if vm.try_class("_js", "Promise").is_ok() {
|
||||
if let Some(py_prom) = py_obj.payload::<js_module::PyPromise>() {
|
||||
if let Some(py_prom) = py_obj.downcast_ref::<js_module::PyPromise>() {
|
||||
return py_prom.as_js(vm).into();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user