Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions derive/src/pyclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,10 +564,15 @@ where
let slot_name = slot_ident.to_string();
let tokens = {
const NON_ATOMIC_SLOTS: &[&str] = &["as_buffer"];
const POINTER_SLOTS: &[&str] = &["as_number"];
if NON_ATOMIC_SLOTS.contains(&slot_name.as_str()) {
quote_spanned! { span =>
slots.#slot_ident = Some(Self::#ident as _);
}
} else if POINTER_SLOTS.contains(&slot_name.as_str()) {
quote_spanned! { span =>
slots.#slot_ident.store(Some(PointerSlot::from(Self::#ident())));
}
} else {
quote_spanned! { span =>
slots.#slot_ident.store(Some(Self::#ident as _));
Expand Down
2 changes: 1 addition & 1 deletion stdlib/src/bisect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod _bisect {
vm: &VirtualMachine,
) -> PyResult<Option<isize>> {
arg.into_option()
.map(|v| vm.to_index(&v)?.try_to_primitive(vm))
.map(|v| v.try_index(vm)?.try_to_primitive(vm))
.transpose()
}

Expand Down
2 changes: 1 addition & 1 deletion stdlib/src/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ mod math {

#[pyfunction]
fn isqrt(x: PyObjectRef, vm: &VirtualMachine) -> PyResult<BigInt> {
let index = vm.to_index(&x)?;
let index = x.try_index(vm)?;
let value = index.as_bigint();

if value.is_negative() {
Expand Down
2 changes: 1 addition & 1 deletion stdlib/src/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ mod decl {
Some(ms) => {
let ms = if let Some(float) = ms.payload::<PyFloat>() {
float.to_f64().to_i32()
} else if let Some(int) = vm.to_index_opt(ms.clone()) {
} else if let Some(int) = ms.try_index_opt(vm) {
int?.as_bigint().to_i32()
} else {
return Err(vm.new_type_error(format!(
Expand Down
6 changes: 3 additions & 3 deletions stdlib/src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,8 @@ mod _socket {
if obj.fast_isinstance(vm.ctx.types.float_type) {
return Err(vm.new_type_error("integer argument expected, got float".to_owned()));
}
let int = vm
.to_index_opt(obj)
let int = obj
.try_index_opt(vm)
.unwrap_or_else(|| Err(vm.new_type_error("an integer is required".to_owned())))?;
int.try_to_primitive::<CastFrom>(vm)
.map(|sock| sock as RawSocket)
Expand Down Expand Up @@ -1382,7 +1382,7 @@ mod _socket {
let (flags, address) = match arg3 {
OptionalArg::Present(arg3) => {
// should just be i32::try_from_obj but tests check for error message
let int = vm.to_index_opt(arg2).unwrap_or_else(|| {
let int = arg2.try_index_opt(vm).unwrap_or_else(|| {
Err(vm.new_type_error("an integer is required".to_owned()))
})?;
let flags = int.try_to_primitive::<i32>(vm)?;
Expand Down
14 changes: 7 additions & 7 deletions vm/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,15 +491,15 @@ fn get_int_or_index<T>(vm: &VirtualMachine, arg: PyObjectRef) -> PyResult<T>
where
T: PrimInt + for<'a> TryFrom<&'a BigInt>,
{
match vm.to_index_opt(arg) {
Some(index) => index?
.try_to_primitive(vm)
.map_err(|_| new_struct_error(vm, "argument out of range".to_owned())),
None => Err(new_struct_error(
let index = arg.try_index_opt(vm).unwrap_or_else(|| {
Err(new_struct_error(
vm,
"required argument is not an integer".to_owned(),
)),
}
))
})?;
index
.try_to_primitive(vm)
.map_err(|_| new_struct_error(vm, "argument out of range".to_owned()))
}

make_pack_primint!(i8);
Expand Down
20 changes: 12 additions & 8 deletions vm/src/builtins/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use super::{
};
use crate::{
anystr::{self, AnyStr},
atomic_func,
bytesinner::{
bytes_decode, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions,
ByteInnerSplitOptions, ByteInnerTranslateOptions, DecodeArgs, PyBytesInner,
Expand Down Expand Up @@ -608,14 +609,17 @@ impl AsSequence for PyBytes {
}

impl AsNumber for PyBytes {
const AS_NUMBER: PyNumberMethods = PyNumberMethods {
remainder: Some(|number, other, vm| {
Self::number_downcast(number)
.mod_(other.to_owned(), vm)
.to_pyresult(vm)
}),
..PyNumberMethods::NOT_IMPLEMENTED
};
fn as_number() -> &'static PyNumberMethods {
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
remainder: atomic_func!(|number, other, vm| {
PyBytes::number_downcast(number)
.mod_(other.to_owned(), vm)
.to_pyresult(vm)
}),
..PyNumberMethods::NOT_IMPLEMENTED
};
&AS_NUMBER
}
}

impl Hashable for PyBytes {
Expand Down
63 changes: 39 additions & 24 deletions vm/src/builtins/complex.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{float, PyStr, PyType, PyTypeRef};
use crate::{
atomic_func,
class::PyClassImpl,
convert::{ToPyObject, ToPyResult},
function::{
Expand Down Expand Up @@ -421,30 +422,44 @@ impl Hashable for PyComplex {
}

impl AsNumber for PyComplex {
const AS_NUMBER: PyNumberMethods = PyNumberMethods {
add: Some(|number, other, vm| Self::number_complex_op(number, other, |a, b| a + b, vm)),
subtract: Some(|number, other, vm| {
Self::number_complex_op(number, other, |a, b| a - b, vm)
}),
multiply: Some(|number, other, vm| {
Self::number_complex_op(number, other, |a, b| a * b, vm)
}),
power: Some(|number, other, vm| Self::number_general_op(number, other, inner_pow, vm)),
negative: Some(|number, vm| {
let value = Self::number_downcast(number).value;
(-value).to_pyresult(vm)
}),
positive: Some(|number, vm| Self::number_complex(number, vm).to_pyresult(vm)),
absolute: Some(|number, vm| {
let value = Self::number_downcast(number).value;
value.norm().to_pyresult(vm)
}),
boolean: Some(|number, _vm| Ok(Self::number_downcast(number).value.is_zero())),
true_divide: Some(|number, other, vm| {
Self::number_general_op(number, other, inner_div, vm)
}),
..PyNumberMethods::NOT_IMPLEMENTED
};
fn as_number() -> &'static PyNumberMethods {
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
add: atomic_func!(|number, other, vm| PyComplex::number_complex_op(
number,
other,
|a, b| a + b,
vm
)),
subtract: atomic_func!(|number, other, vm| {
PyComplex::number_complex_op(number, other, |a, b| a - b, vm)
}),
multiply: atomic_func!(|number, other, vm| {
PyComplex::number_complex_op(number, other, |a, b| a * b, vm)
}),
power: atomic_func!(|number, other, vm| PyComplex::number_general_op(
number, other, inner_pow, vm
)),
negative: atomic_func!(|number, vm| {
let value = PyComplex::number_downcast(number).value;
(-value).to_pyresult(vm)
}),
positive: atomic_func!(
|number, vm| PyComplex::number_complex(number, vm).to_pyresult(vm)
),
absolute: atomic_func!(|number, vm| {
let value = PyComplex::number_downcast(number).value;
value.norm().to_pyresult(vm)
}),
boolean: atomic_func!(|number, _vm| Ok(PyComplex::number_downcast(number)
.value
.is_zero())),
true_divide: atomic_func!(|number, other, vm| {
PyComplex::number_general_op(number, other, inner_div, vm)
}),
..PyNumberMethods::NOT_IMPLEMENTED
};
&AS_NUMBER
}
}

impl PyComplex {
Expand Down
98 changes: 58 additions & 40 deletions vm/src/builtins/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::{
try_bigint_to_f64, PyByteArray, PyBytes, PyInt, PyIntRef, PyStr, PyStrRef, PyType, PyTypeRef,
};
use crate::{
atomic_func,
class::PyClassImpl,
common::{float_ops, hash},
convert::{ToPyObject, ToPyResult},
Expand Down Expand Up @@ -57,16 +58,6 @@ impl From<f64> for PyFloat {
}
}

impl PyObject {
pub fn try_float_opt(&self, vm: &VirtualMachine) -> PyResult<Option<PyRef<PyFloat>>> {
PyNumber::new(self, vm).float_opt(vm)
}

pub fn try_float(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyFloat>> {
PyNumber::new(self, vm).float(vm)
}
}

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) {
Some(float.value)
Expand Down Expand Up @@ -553,36 +544,63 @@ impl Hashable for PyFloat {
}

impl AsNumber for PyFloat {
const AS_NUMBER: PyNumberMethods = PyNumberMethods {
add: Some(|number, other, vm| Self::number_float_op(number, other, |a, b| a + b, vm)),
subtract: Some(|number, other, vm| Self::number_float_op(number, other, |a, b| a - b, vm)),
multiply: Some(|number, other, vm| Self::number_float_op(number, other, |a, b| a * b, vm)),
remainder: Some(|number, other, vm| Self::number_general_op(number, other, inner_mod, vm)),
divmod: Some(|number, other, vm| Self::number_general_op(number, other, inner_divmod, vm)),
power: Some(|number, other, vm| Self::number_general_op(number, other, float_pow, vm)),
negative: Some(|number, vm| {
let value = Self::number_downcast(number).value;
(-value).to_pyresult(vm)
}),
positive: Some(|number, vm| Self::number_float(number, vm).to_pyresult(vm)),
absolute: Some(|number, vm| {
let value = Self::number_downcast(number).value;
value.abs().to_pyresult(vm)
}),
boolean: Some(|number, _vm| Ok(Self::number_downcast(number).value.is_zero())),
int: Some(|number, vm| {
let value = Self::number_downcast(number).value;
try_to_bigint(value, vm).map(|x| vm.ctx.new_int(x))
}),
float: Some(|number, vm| Ok(Self::number_float(number, vm))),
floor_divide: Some(|number, other, vm| {
Self::number_general_op(number, other, inner_floordiv, vm)
}),
true_divide: Some(|number, other, vm| {
Self::number_general_op(number, other, inner_div, vm)
}),
..PyNumberMethods::NOT_IMPLEMENTED
};
fn as_number() -> &'static PyNumberMethods {
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
add: atomic_func!(|num, other, vm| PyFloat::number_float_op(
num,
other,
|a, b| a + b,
vm
)),
subtract: atomic_func!(|num, other, vm| PyFloat::number_float_op(
num,
other,
|a, b| a - b,
vm
)),
multiply: atomic_func!(|num, other, vm| PyFloat::number_float_op(
num,
other,
|a, b| a * b,
vm
)),
remainder: atomic_func!(|num, other, vm| PyFloat::number_general_op(
num, other, inner_mod, vm
)),
divmod: atomic_func!(|num, other, vm| PyFloat::number_general_op(
num,
other,
inner_divmod,
vm
)),
power: atomic_func!(|num, other, vm| PyFloat::number_general_op(
num, other, float_pow, vm
)),
negative: atomic_func!(|num, vm| {
let value = PyFloat::number_downcast(num).value;
(-value).to_pyresult(vm)
}),
positive: atomic_func!(|num, vm| PyFloat::number_float(num, vm).to_pyresult(vm)),
absolute: atomic_func!(|num, vm| {
let value = PyFloat::number_downcast(num).value;
value.abs().to_pyresult(vm)
}),
boolean: atomic_func!(|num, _vm| Ok(PyFloat::number_downcast(num).value.is_zero())),
int: atomic_func!(|num, vm| {
let value = PyFloat::number_downcast(num).value;
try_to_bigint(value, vm).map(|x| vm.ctx.new_int(x))
}),
float: atomic_func!(|num, vm| Ok(PyFloat::number_float(num, vm))),
floor_divide: atomic_func!(|num, other, vm| {
PyFloat::number_general_op(num, other, inner_floordiv, vm)
}),
true_divide: atomic_func!(|num, other, vm| {
PyFloat::number_general_op(num, other, inner_div, vm)
}),
..PyNumberMethods::NOT_IMPLEMENTED
};
&AS_NUMBER
}
}

impl PyFloat {
Expand Down
Loading