mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Add ArgFloatLike.
This commit is contained in:
@@ -12,11 +12,13 @@ mod array {
|
||||
};
|
||||
use crate::vm::{
|
||||
builtins::{
|
||||
IntoPyFloat, PyByteArray, PyBytes, PyBytesRef, PyIntRef, PyList, PyListRef, PySliceRef,
|
||||
PyStr, PyStrRef, PyTypeRef,
|
||||
PyByteArray, PyBytes, PyBytesRef, PyIntRef, PyList, PyListRef, PySliceRef, PyStr,
|
||||
PyStrRef, PyTypeRef,
|
||||
},
|
||||
class_or_notimplemented,
|
||||
function::{ArgBytesLike, ArgIterable, IntoPyObject, IntoPyResult, OptionalArg},
|
||||
function::{
|
||||
ArgBytesLike, ArgFloatLike, ArgIterable, IntoPyObject, IntoPyResult, OptionalArg,
|
||||
},
|
||||
protocol::{
|
||||
BufferInternal, BufferOptions, BufferResizeGuard, PyBuffer, PyIterReturn,
|
||||
PyMappingMethods,
|
||||
@@ -521,11 +523,11 @@ mod array {
|
||||
}
|
||||
|
||||
fn f32_try_into_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<f32> {
|
||||
IntoPyFloat::try_from_object(vm, obj).map(|x| x.to_f64() as f32)
|
||||
ArgFloatLike::try_from_object(vm, obj).map(|x| x.to_f64() as f32)
|
||||
}
|
||||
|
||||
fn f64_try_into_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<f64> {
|
||||
IntoPyFloat::try_from_object(vm, obj).map(|x| x.to_f64())
|
||||
ArgFloatLike::try_from_object(vm, obj).map(|x| x.to_f64())
|
||||
}
|
||||
|
||||
impl ArrayElement for WideChar {
|
||||
|
||||
@@ -6,8 +6,7 @@ pub(crate) use cmath::make_module;
|
||||
#[pymodule]
|
||||
mod cmath {
|
||||
use crate::vm::{
|
||||
builtins::IntoPyFloat,
|
||||
function::{ArgComplexLike, OptionalArg},
|
||||
function::{ArgComplexLike, ArgFloatLike, OptionalArg},
|
||||
PyResult, VirtualMachine,
|
||||
};
|
||||
use num_complex::Complex64;
|
||||
@@ -38,7 +37,7 @@ mod cmath {
|
||||
|
||||
/// Convert from polar coordinates to rectangular coordinates.
|
||||
#[pyfunction]
|
||||
fn rect(r: IntoPyFloat, phi: IntoPyFloat) -> Complex64 {
|
||||
fn rect(r: ArgFloatLike, phi: ArgFloatLike) -> Complex64 {
|
||||
Complex64::from_polar(r.to_f64(), phi.to_f64())
|
||||
}
|
||||
|
||||
@@ -172,9 +171,9 @@ mod cmath {
|
||||
#[pyarg(positional)]
|
||||
b: ArgComplexLike,
|
||||
#[pyarg(named, optional)]
|
||||
rel_tol: OptionalArg<IntoPyFloat>,
|
||||
rel_tol: OptionalArg<ArgFloatLike>,
|
||||
#[pyarg(named, optional)]
|
||||
abs_tol: OptionalArg<IntoPyFloat>,
|
||||
abs_tol: OptionalArg<ArgFloatLike>,
|
||||
}
|
||||
|
||||
/// Determine whether two complex numbers are close in value.
|
||||
|
||||
@@ -4,9 +4,9 @@ pub(crate) use math::make_module;
|
||||
mod math {
|
||||
use crate::vm::{
|
||||
builtins::{
|
||||
try_bigint_to_f64, try_f64_to_bigint, IntoPyFloat, PyFloatRef, PyInt, PyIntRef,
|
||||
try_bigint_to_f64, try_f64_to_bigint, PyFloatRef, PyInt, PyIntRef,
|
||||
},
|
||||
function::{ArgIterable, OptionalArg, PosArgs},
|
||||
function::{ArgFloatLike, ArgIterable, OptionalArg, PosArgs},
|
||||
utils::Either,
|
||||
PyObjectRef, PyResult, PySequence, TypeProtocol, VirtualMachine,
|
||||
};
|
||||
@@ -43,35 +43,35 @@ mod math {
|
||||
|
||||
// Number theory functions:
|
||||
#[pyfunction]
|
||||
fn fabs(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn fabs(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(abs, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn isfinite(x: IntoPyFloat) -> bool {
|
||||
fn isfinite(x: ArgFloatLike) -> bool {
|
||||
x.to_f64().is_finite()
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn isinf(x: IntoPyFloat) -> bool {
|
||||
fn isinf(x: ArgFloatLike) -> bool {
|
||||
x.to_f64().is_infinite()
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn isnan(x: IntoPyFloat) -> bool {
|
||||
fn isnan(x: ArgFloatLike) -> bool {
|
||||
x.to_f64().is_nan()
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
struct IsCloseArgs {
|
||||
#[pyarg(positional)]
|
||||
a: IntoPyFloat,
|
||||
a: ArgFloatLike,
|
||||
#[pyarg(positional)]
|
||||
b: IntoPyFloat,
|
||||
b: ArgFloatLike,
|
||||
#[pyarg(named, optional)]
|
||||
rel_tol: OptionalArg<IntoPyFloat>,
|
||||
rel_tol: OptionalArg<ArgFloatLike>,
|
||||
#[pyarg(named, optional)]
|
||||
abs_tol: OptionalArg<IntoPyFloat>,
|
||||
abs_tol: OptionalArg<ArgFloatLike>,
|
||||
}
|
||||
|
||||
#[allow(clippy::float_cmp)]
|
||||
@@ -110,7 +110,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn copysign(x: IntoPyFloat, y: IntoPyFloat) -> f64 {
|
||||
fn copysign(x: ArgFloatLike, y: ArgFloatLike) -> f64 {
|
||||
let a = x.to_f64();
|
||||
let b = y.to_f64();
|
||||
if a.is_nan() || b.is_nan() {
|
||||
@@ -122,37 +122,37 @@ mod math {
|
||||
|
||||
// Power and logarithmic functions:
|
||||
#[pyfunction]
|
||||
fn exp(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn exp(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(exp, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn expm1(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn expm1(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(exp_m1, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn log(x: IntoPyFloat, base: OptionalArg<IntoPyFloat>) -> f64 {
|
||||
fn log(x: ArgFloatLike, base: OptionalArg<ArgFloatLike>) -> f64 {
|
||||
base.map_or_else(|| x.to_f64().ln(), |base| x.to_f64().log(base.to_f64()))
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn log1p(x: IntoPyFloat) -> f64 {
|
||||
fn log1p(x: ArgFloatLike) -> f64 {
|
||||
(x.to_f64() + 1.0).ln()
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn log2(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn log2(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(log2, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn log10(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn log10(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(log10, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn pow(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn pow(x: ArgFloatLike, y: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
let x = x.to_f64();
|
||||
let y = y.to_f64();
|
||||
|
||||
@@ -170,7 +170,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn sqrt(value: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn sqrt(value: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
let value = value.to_f64();
|
||||
if value.is_sign_negative() {
|
||||
return Err(vm.new_value_error("math domain error".to_owned()));
|
||||
@@ -191,7 +191,7 @@ mod math {
|
||||
|
||||
// Trigonometric functions:
|
||||
#[pyfunction]
|
||||
fn acos(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn acos(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
let x = x.to_f64();
|
||||
if x.is_nan() || (-1.0_f64..=1.0_f64).contains(&x) {
|
||||
Ok(x.acos())
|
||||
@@ -201,7 +201,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn asin(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn asin(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
let x = x.to_f64();
|
||||
if x.is_nan() || (-1.0_f64..=1.0_f64).contains(&x) {
|
||||
Ok(x.asin())
|
||||
@@ -211,23 +211,23 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn atan(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn atan(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(atan, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn atan2(y: IntoPyFloat, x: IntoPyFloat) -> f64 {
|
||||
fn atan2(y: ArgFloatLike, x: ArgFloatLike) -> f64 {
|
||||
y.to_f64().atan2(x.to_f64())
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn cos(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn cos(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(cos, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn hypot(coordinates: PosArgs<IntoPyFloat>) -> f64 {
|
||||
let mut coordinates = IntoPyFloat::vec_into_f64(coordinates.into_vec());
|
||||
fn hypot(coordinates: PosArgs<ArgFloatLike>) -> f64 {
|
||||
let mut coordinates = ArgFloatLike::vec_into_f64(coordinates.into_vec());
|
||||
let mut max = 0.0;
|
||||
let mut has_nan = false;
|
||||
for f in &mut coordinates {
|
||||
@@ -267,15 +267,15 @@ mod math {
|
||||
|
||||
#[pyfunction]
|
||||
fn dist(
|
||||
p: PySequence<IntoPyFloat>,
|
||||
q: PySequence<IntoPyFloat>,
|
||||
p: PySequence<ArgFloatLike>,
|
||||
q: PySequence<ArgFloatLike>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<f64> {
|
||||
let mut max = 0.0;
|
||||
let mut has_nan = false;
|
||||
|
||||
let p = IntoPyFloat::vec_into_f64(p.into_vec());
|
||||
let q = IntoPyFloat::vec_into_f64(q.into_vec());
|
||||
let p = ArgFloatLike::vec_into_f64(p.into_vec());
|
||||
let q = ArgFloatLike::vec_into_f64(q.into_vec());
|
||||
let mut diffs = vec![];
|
||||
|
||||
if p.len() != q.len() {
|
||||
@@ -309,29 +309,29 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn sin(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn sin(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(sin, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn tan(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn tan(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(tan, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn degrees(x: IntoPyFloat) -> f64 {
|
||||
fn degrees(x: ArgFloatLike) -> f64 {
|
||||
x.to_f64() * (180.0 / std::f64::consts::PI)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn radians(x: IntoPyFloat) -> f64 {
|
||||
fn radians(x: ArgFloatLike) -> f64 {
|
||||
x.to_f64() * (std::f64::consts::PI / 180.0)
|
||||
}
|
||||
|
||||
// Hyperbolic functions:
|
||||
|
||||
#[pyfunction]
|
||||
fn acosh(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn acosh(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
let x = x.to_f64();
|
||||
if x.is_sign_negative() || x.is_zero() {
|
||||
Err(vm.new_value_error("math domain error".to_owned()))
|
||||
@@ -341,33 +341,33 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn asinh(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn asinh(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(asinh, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn atanh(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn atanh(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(atanh, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn cosh(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn cosh(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(cosh, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn sinh(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn sinh(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(sinh, x, vm)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn tanh(x: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn tanh(x: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
call_math_func!(tanh, x, vm)
|
||||
}
|
||||
|
||||
// Special functions:
|
||||
#[pyfunction]
|
||||
fn erf(x: IntoPyFloat) -> f64 {
|
||||
fn erf(x: ArgFloatLike) -> f64 {
|
||||
let x = x.to_f64();
|
||||
if x.is_nan() {
|
||||
x
|
||||
@@ -377,7 +377,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn erfc(x: IntoPyFloat) -> f64 {
|
||||
fn erfc(x: ArgFloatLike) -> f64 {
|
||||
let x = x.to_f64();
|
||||
if x.is_nan() {
|
||||
x
|
||||
@@ -387,7 +387,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn gamma(x: IntoPyFloat) -> f64 {
|
||||
fn gamma(x: ArgFloatLike) -> f64 {
|
||||
let x = x.to_f64();
|
||||
if x.is_finite() {
|
||||
puruspe::gamma(x)
|
||||
@@ -399,7 +399,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn lgamma(x: IntoPyFloat) -> f64 {
|
||||
fn lgamma(x: ArgFloatLike) -> f64 {
|
||||
let x = x.to_f64();
|
||||
if x.is_finite() {
|
||||
puruspe::ln_gamma(x)
|
||||
@@ -451,7 +451,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn frexp(x: IntoPyFloat) -> (f64, i32) {
|
||||
fn frexp(x: ArgFloatLike) -> (f64, i32) {
|
||||
let value = x.to_f64();
|
||||
if value.is_finite() {
|
||||
let (m, exp) = float_ops::ufrexp(value);
|
||||
@@ -509,7 +509,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn fsum(seq: ArgIterable<IntoPyFloat>, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn fsum(seq: ArgIterable<ArgFloatLike>, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
let mut partials = vec![];
|
||||
let mut special_sum = 0.0;
|
||||
let mut inf_sum = 0.0;
|
||||
@@ -700,7 +700,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn modf(x: IntoPyFloat) -> (f64, f64) {
|
||||
fn modf(x: ArgFloatLike) -> (f64, f64) {
|
||||
let x = x.to_f64();
|
||||
if !x.is_finite() {
|
||||
if x.is_infinite() {
|
||||
@@ -714,12 +714,12 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn nextafter(x: IntoPyFloat, y: IntoPyFloat) -> f64 {
|
||||
fn nextafter(x: ArgFloatLike, y: ArgFloatLike) -> f64 {
|
||||
float_ops::nextafter(x.to_f64(), y.to_f64())
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn ulp(x: IntoPyFloat) -> f64 {
|
||||
fn ulp(x: ArgFloatLike) -> f64 {
|
||||
float_ops::ulp(x.to_f64())
|
||||
}
|
||||
|
||||
@@ -732,7 +732,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction(name = "fmod")]
|
||||
fn py_fmod(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn py_fmod(x: ArgFloatLike, y: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
let x = x.to_f64();
|
||||
let y = y.to_f64();
|
||||
|
||||
@@ -746,7 +746,7 @@ mod math {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn remainder(x: IntoPyFloat, y: IntoPyFloat, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
fn remainder(x: ArgFloatLike, y: ArgFloatLike, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
let x = x.to_f64();
|
||||
let y = y.to_f64();
|
||||
|
||||
|
||||
@@ -545,33 +545,6 @@ pub(crate) fn get_value(obj: &PyObjectRef) -> f64 {
|
||||
obj.payload::<PyFloat>().unwrap().value
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[repr(transparent)]
|
||||
pub struct IntoPyFloat {
|
||||
value: f64,
|
||||
}
|
||||
|
||||
impl IntoPyFloat {
|
||||
pub fn to_f64(self) -> f64 {
|
||||
self.value
|
||||
}
|
||||
|
||||
pub fn vec_into_f64(v: Vec<Self>) -> Vec<f64> {
|
||||
// TODO: Vec::into_raw_parts once stabilized
|
||||
let mut v = std::mem::ManuallyDrop::new(v);
|
||||
let (p, l, c) = (v.as_mut_ptr(), v.len(), v.capacity());
|
||||
// SAFETY: IntoPyFloat is repr(transparent) over f64
|
||||
unsafe { Vec::from_raw_parts(p.cast(), l, c) }
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFromObject for IntoPyFloat {
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
let value = try_float(&obj, vm)?;
|
||||
Ok(IntoPyFloat { value })
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip] // to avoid line splitting
|
||||
pub fn init(context: &PyContext) {
|
||||
PyFloat::extend_class(context, &context.types.float_type);
|
||||
|
||||
@@ -22,7 +22,7 @@ pub use enumerate::PyEnumerate;
|
||||
pub(crate) mod filter;
|
||||
pub use filter::PyFilter;
|
||||
pub(crate) mod float;
|
||||
pub use float::{IntoPyFloat, PyFloat, PyFloatRef};
|
||||
pub use float::{PyFloat, PyFloatRef};
|
||||
pub(crate) mod frame;
|
||||
pub(crate) mod function;
|
||||
pub use function::{PyBoundMethod, PyFunction};
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
use crate::common::float_ops;
|
||||
use crate::{
|
||||
builtins::{try_f64_to_bigint, tuple, IntoPyFloat, PyBytes, PyFloat, PyInt, PyStr},
|
||||
builtins::{try_f64_to_bigint, tuple, PyBytes, PyFloat, PyInt, PyStr},
|
||||
function::ArgFloatLike,
|
||||
protocol::PyBuffer,
|
||||
ItemProtocol, PyObjectRef, PyResult, TryFromBorrowedObject, TryFromObject, TypeProtocol,
|
||||
VirtualMachine,
|
||||
@@ -431,7 +432,7 @@ impl CFormatSpec {
|
||||
}
|
||||
},
|
||||
CFormatType::Float(_) => {
|
||||
let value = IntoPyFloat::try_from_object(vm, obj)?.to_f64();
|
||||
let value = ArgFloatLike::try_from_object(vm, obj)?.to_f64();
|
||||
Ok(self.format_float(value).into_bytes())
|
||||
}
|
||||
CFormatType::Character => {
|
||||
@@ -504,7 +505,7 @@ impl CFormatSpec {
|
||||
}
|
||||
},
|
||||
CFormatType::Float(_) => {
|
||||
let value = IntoPyFloat::try_from_object(vm, obj)?.to_f64();
|
||||
let value = ArgFloatLike::try_from_object(vm, obj)?.to_f64();
|
||||
Ok(self.format_float(value))
|
||||
}
|
||||
CFormatType::Character => {
|
||||
|
||||
@@ -15,7 +15,7 @@ use std::ops::RangeInclusive;
|
||||
|
||||
pub use argument::{ArgCallable, ArgIterable};
|
||||
pub use byteslike::{ArgBytesLike, ArgMemoryBuffer, ArgStrOrBytesLike};
|
||||
pub use numlike::ArgComplexLike;
|
||||
pub use numlike::{ArgComplexLike, ArgFloatLike};
|
||||
|
||||
/// Implemented by any type that can be returned from a built-in Python function.
|
||||
///
|
||||
|
||||
@@ -22,3 +22,32 @@ impl TryFromObject for ArgComplexLike {
|
||||
Ok(ArgComplexLike { value })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[repr(transparent)]
|
||||
pub struct ArgFloatLike {
|
||||
value: f64,
|
||||
}
|
||||
|
||||
impl ArgFloatLike {
|
||||
pub fn to_f64(self) -> f64 {
|
||||
self.value
|
||||
}
|
||||
|
||||
pub fn vec_into_f64(v: Vec<Self>) -> Vec<f64> {
|
||||
// TODO: Vec::into_raw_parts once stabilized
|
||||
let mut v = std::mem::ManuallyDrop::new(v);
|
||||
let (p, l, c) = (v.as_mut_ptr(), v.len(), v.capacity());
|
||||
// SAFETY: IntoPyFloat is repr(transparent) over f64
|
||||
unsafe { Vec::from_raw_parts(p.cast(), l, c) }
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFromObject for ArgFloatLike {
|
||||
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
|
||||
let value = obj.try_to_f64(vm)?.ok_or_else(|| {
|
||||
vm.new_type_error(format!("must be real number, not {}", obj.class().name()))
|
||||
})?;
|
||||
Ok(ArgFloatLike { value })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user