Use PyInt::try_to_primitive.

This commit is contained in:
jfh
2021-10-02 04:16:59 +03:00
parent fad0b6b944
commit 2f6deb8fd0
5 changed files with 23 additions and 34 deletions

View File

@@ -80,24 +80,12 @@ macro_rules! impl_into_pyobject_int {
impl_into_pyobject_int!(isize i8 i16 i32 i64 usize u8 u16 u32 u64 BigInt);
pub(crate) fn try_to_primitive<'a, I>(i: &'a BigInt, vm: &VirtualMachine) -> PyResult<I>
where
I: PrimInt + TryFrom<&'a BigInt>,
{
I::try_from(i).map_err(|_| {
vm.new_overflow_error(format!(
"Python int too large to convert to Rust {}",
std::any::type_name::<I>()
))
})
}
macro_rules! impl_try_from_object_int {
($(($t:ty, $to_prim:ident),)*) => {$(
impl TryFromBorrowedObject for $t {
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Self> {
try_value_from_borrowed_object(vm, obj, |int: &PyInt| {
try_to_primitive(int.as_bigint(), vm)
int.try_to_primitive(vm)
})
}
}
@@ -306,7 +294,12 @@ impl PyInt {
where
I: PrimInt + TryFrom<&'a BigInt>,
{
try_to_primitive(self.as_bigint(), vm)
I::try_from(self.as_bigint()).map_err(|_| {
vm.new_overflow_error(format!(
"Python int too large to convert to Rust {}",
std::any::type_name::<I>()
))
})
}
#[inline]

View File

@@ -2,7 +2,7 @@
* iterator types
*/
use super::{int, PyInt, PyTypeRef};
use super::{PyInt, PyTypeRef};
use crate::{
function::ArgCallable,
protocol::PyIterReturn,
@@ -43,7 +43,7 @@ impl<T> PositionIterInternal<T> {
{
if let IterStatus::Active(obj) = &self.status {
if let Some(i) = state.payload::<PyInt>() {
let i = int::try_to_primitive(i.as_bigint(), vm).unwrap_or(0);
let i = i.try_to_primitive(vm).unwrap_or(0);
self.position = f(obj, i);
Ok(())
} else {

View File

@@ -3,7 +3,7 @@
use crate::common::float_ops;
use crate::{
builtins::{int, try_f64_to_bigint, tuple, IntoPyFloat, PyBytes, PyFloat, PyInt, PyStr},
builtins::{try_f64_to_bigint, tuple, IntoPyFloat, PyBytes, PyFloat, PyInt, PyStr},
protocol::PyBuffer,
ItemProtocol, PyObjectRef, PyResult, TryFromBorrowedObject, TryFromObject, TypeProtocol,
VirtualMachine,
@@ -561,13 +561,12 @@ fn try_update_quantity_from_tuple<'a, I: Iterator<Item = &'a PyObjectRef>>(
match q {
Some(CFormatQuantity::FromValuesTuple) => match elements.next() {
Some(width_obj) => {
if !width_obj.isinstance(&vm.ctx.types.int_type) {
Err(vm.new_type_error("* wants int".to_owned()))
} else {
let i = int::get_value(width_obj);
let i = int::try_to_primitive::<isize>(i, vm)? as usize;
if let Some(i) = width_obj.payload::<PyInt>() {
let i = i.try_to_primitive::<isize>(vm)? as usize;
*q = Some(CFormatQuantity::Amount(i));
Ok(())
} else {
Err(vm.new_type_error("* wants int".to_owned()))
}
}
None => Err(vm.new_type_error("not enough arguments for format string".to_owned())),

View File

@@ -3,11 +3,10 @@
*/
use crate::{
builtins::{int, PyBaseExceptionRef, PyInt},
builtins::{PyBaseExceptionRef, PyInt},
protocol::{PyIter, PyIterReturn},
IdProtocol, PyObjectRef, PyResult, TypeProtocol, VirtualMachine,
};
use num_traits::Signed;
pub fn try_map<F, R>(vm: &VirtualMachine, iter: &PyIter, cap: usize, mut f: F) -> PyResult<Vec<R>>
where
@@ -66,7 +65,7 @@ pub fn length_hint(vm: &VirtualMachine, iter: PyObjectRef) -> PyResult<Option<us
}
}
};
let result = result
let hint = result
.payload_if_subclass::<PyInt>(vm)
.ok_or_else(|| {
vm.new_type_error(format!(
@@ -74,12 +73,12 @@ pub fn length_hint(vm: &VirtualMachine, iter: PyObjectRef) -> PyResult<Option<us
result.class().name()
))
})?
.as_bigint();
if result.is_negative() {
return Err(vm.new_value_error("__length_hint__() should return >= 0".to_owned()));
.try_to_primitive::<isize>(vm)?;
if hint.is_negative() {
Err(vm.new_value_error("__length_hint__() should return >= 0".to_owned()))
} else {
Ok(Some(hint as usize))
}
let hint = int::try_to_primitive(result, vm)?;
Ok(Some(hint))
}
// pub fn seq_iter_method(obj: PyObjectRef) -> PySequenceIterator {

View File

@@ -11,7 +11,7 @@ mod builtins {
use crate::builtins::{
enumerate::PyReverseSequenceIterator,
function::{PyCellRef, PyFunctionRef},
int::{self, PyIntRef},
int::PyIntRef,
iter::PyCallableIterator,
list::{PyList, SortOptions},
IntoPyBool, PyByteArray, PyBytes, PyBytesRef, PyCode, PyDictRef, PyStr, PyStrRef,
@@ -153,9 +153,7 @@ mod builtins {
.map_err(|e| vm.new_unicode_decode_error(e.to_string()))?,
};
let flags = args
.flags
.map_or(Ok(0), |v| int::try_to_primitive(v.as_bigint(), vm))?;
let flags = args.flags.map_or(Ok(0), |v| v.try_to_primitive(vm))?;
if (flags & ast::PY_COMPILE_FLAG_AST_ONLY).is_zero() {
#[cfg(not(feature = "rustpython-compiler"))]