diff --git a/guide/src/conversions/tables.md b/guide/src/conversions/tables.md index 208e61671ec..8afb95fbfb3 100644 --- a/guide/src/conversions/tables.md +++ b/guide/src/conversions/tables.md @@ -16,7 +16,7 @@ The table below contains the Python type and the corresponding function argument | `str` | `String`, `Cow`, `&str`, `char`, `OsString`, `PathBuf`, `Path` | `PyString`, `PyUnicode` | | `bytes` | `Vec`, `&[u8]`, `Cow<[u8]>` | `PyBytes` | | `bool` | `bool` | `PyBool` | -| `int` | `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`, `num_bigint::BigInt`[^1], `num_bigint::BigUint`[^1] | `PyLong` | +| `int` | `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`, `num_bigint::BigInt`[^1], `num_bigint::BigUint`[^1] | `PyInt` | | `float` | `f32`, `f64` | `PyFloat` | | `complex` | `num_complex::Complex`[^2] | `PyComplex` | | `fractions.Fraction`| `num_rational::Ratio`[^8] | - | diff --git a/newsfragments/4347.changed.md b/newsfragments/4347.changed.md new file mode 100644 index 00000000000..e64ad2c6395 --- /dev/null +++ b/newsfragments/4347.changed.md @@ -0,0 +1 @@ +Deprecate `PyLong` in favor of `PyInt`. diff --git a/src/conversions/num_bigint.rs b/src/conversions/num_bigint.rs index 196ae28e788..99b5962622d 100644 --- a/src/conversions/num_bigint.rs +++ b/src/conversions/num_bigint.rs @@ -54,7 +54,7 @@ use crate::types::{bytes::PyBytesMethods, PyBytes}; use crate::{ ffi, instance::Bound, - types::{any::PyAnyMethods, PyLong}, + types::{any::PyAnyMethods, PyInt}, FromPyObject, IntoPy, Py, PyAny, PyObject, PyResult, Python, ToPyObject, }; @@ -120,7 +120,7 @@ macro_rules! bigint_conversion { } else { None }; - py.get_type_bound::() + py.get_type_bound::() .call_method("from_bytes", (bytes_obj, "little"), kwargs.as_ref()) .expect("int.from_bytes() failed during to_object()") // FIXME: #1813 or similar .into() @@ -144,8 +144,8 @@ impl<'py> FromPyObject<'py> for BigInt { fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult { let py = ob.py(); // fast path - checking for subclass of `int` just checks a bit in the type object - let num_owned: Py; - let num = if let Ok(long) = ob.downcast::() { + let num_owned: Py; + let num = if let Ok(long) = ob.downcast::() { long } else { num_owned = unsafe { Py::from_owned_ptr_or_err(py, ffi::PyNumber_Index(ob.as_ptr()))? }; @@ -192,8 +192,8 @@ impl<'py> FromPyObject<'py> for BigUint { fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult { let py = ob.py(); // fast path - checking for subclass of `int` just checks a bit in the type object - let num_owned: Py; - let num = if let Ok(long) = ob.downcast::() { + let num_owned: Py; + let num = if let Ok(long) = ob.downcast::() { long } else { num_owned = unsafe { Py::from_owned_ptr_or_err(py, ffi::PyNumber_Index(ob.as_ptr()))? }; @@ -218,7 +218,7 @@ impl<'py> FromPyObject<'py> for BigUint { #[cfg(not(any(Py_LIMITED_API, Py_3_13)))] #[inline] -fn int_to_u32_vec(long: &Bound<'_, PyLong>) -> PyResult> { +fn int_to_u32_vec(long: &Bound<'_, PyInt>) -> PyResult> { let mut buffer = Vec::new(); let n_bits = int_n_bits(long)?; if n_bits == 0 { @@ -252,7 +252,7 @@ fn int_to_u32_vec(long: &Bound<'_, PyLong>) -> PyResult(long: &Bound<'_, PyLong>) -> PyResult> { +fn int_to_u32_vec(long: &Bound<'_, PyInt>) -> PyResult> { let mut buffer = Vec::new(); let mut flags = ffi::Py_ASNATIVEBYTES_LITTLE_ENDIAN; if !SIGNED { @@ -290,7 +290,7 @@ fn int_to_u32_vec(long: &Bound<'_, PyLong>) -> PyResult( - long: &Bound<'py, PyLong>, + long: &Bound<'py, PyInt>, n_bytes: usize, is_signed: bool, ) -> PyResult> { @@ -313,7 +313,7 @@ fn int_to_py_bytes<'py>( #[inline] #[cfg(any(not(Py_3_13), Py_LIMITED_API))] -fn int_n_bits(long: &Bound<'_, PyLong>) -> PyResult { +fn int_n_bits(long: &Bound<'_, PyInt>) -> PyResult { let py = long.py(); #[cfg(not(Py_LIMITED_API))] { diff --git a/src/conversions/std/num.rs b/src/conversions/std/num.rs index 1304e73e4b6..1431b232169 100644 --- a/src/conversions/std/num.rs +++ b/src/conversions/std/num.rs @@ -59,7 +59,7 @@ macro_rules! extract_int { // See https://github.com/PyO3/pyo3/pull/3742 for detials if cfg!(Py_3_10) && !$force_index_call { err_if_invalid_value($obj.py(), $error_val, unsafe { $pylong_as($obj.as_ptr()) }) - } else if let Ok(long) = $obj.downcast::() { + } else if let Ok(long) = $obj.downcast::() { // fast path - checking for subclass of `int` just checks a bit in the type $object err_if_invalid_value($obj.py(), $error_val, unsafe { $pylong_as(long.as_ptr()) }) } else { diff --git a/src/types/any.rs b/src/types/any.rs index 745847b86ee..33ac04df763 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -1495,7 +1495,7 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// /// ```rust /// use pyo3::prelude::*; - /// use pyo3::types::{PyBool, PyLong}; + /// use pyo3::types::{PyBool, PyInt}; /// /// Python::with_gil(|py| { /// let b = PyBool::new_bound(py, true); @@ -1504,8 +1504,8 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed { /// /// // `bool` is a subtype of `int`, so `downcast` will accept a `bool` as an `int` /// // but `downcast_exact` will not. - /// assert!(any.downcast::().is_ok()); - /// assert!(any.downcast_exact::().is_err()); + /// assert!(any.downcast::().is_ok()); + /// assert!(any.downcast_exact::().is_err()); /// /// assert!(any.downcast_exact::().is_ok()); /// }); @@ -2269,7 +2269,7 @@ impl<'py> Bound<'py, PyAny> { mod tests { use crate::{ basic::CompareOp, - types::{IntoPyDict, PyAny, PyAnyMethods, PyBool, PyList, PyLong, PyModule, PyTypeMethods}, + types::{IntoPyDict, PyAny, PyAnyMethods, PyBool, PyInt, PyList, PyModule, PyTypeMethods}, Bound, PyTypeInfo, Python, ToPyObject, }; @@ -2424,7 +2424,7 @@ class SimpleClass: fn test_hasattr() { Python::with_gil(|py| { let x = 5.to_object(py).into_bound(py); - assert!(x.is_instance_of::()); + assert!(x.is_instance_of::()); assert!(x.hasattr("to_bytes").unwrap()); assert!(!x.hasattr("bbbbbbytes").unwrap()); @@ -2471,7 +2471,7 @@ class SimpleClass: fn test_any_is_instance_of() { Python::with_gil(|py| { let x = 5.to_object(py).into_bound(py); - assert!(x.is_instance_of::()); + assert!(x.is_instance_of::()); let l = vec![&x, &x].to_object(py).into_bound(py); assert!(l.is_instance_of::()); @@ -2490,11 +2490,11 @@ class SimpleClass: fn test_any_is_exact_instance_of() { Python::with_gil(|py| { let x = 5.to_object(py).into_bound(py); - assert!(x.is_exact_instance_of::()); + assert!(x.is_exact_instance_of::()); let t = PyBool::new_bound(py, true); - assert!(t.is_instance_of::()); - assert!(!t.is_exact_instance_of::()); + assert!(t.is_instance_of::()); + assert!(!t.is_exact_instance_of::()); assert!(t.is_exact_instance_of::()); let l = vec![&x, &x].to_object(py).into_bound(py); @@ -2506,8 +2506,8 @@ class SimpleClass: fn test_any_is_exact_instance() { Python::with_gil(|py| { let t = PyBool::new_bound(py, true); - assert!(t.is_instance(&py.get_type_bound::()).unwrap()); - assert!(!t.is_exact_instance(&py.get_type_bound::())); + assert!(t.is_instance(&py.get_type_bound::()).unwrap()); + assert!(!t.is_exact_instance(&py.get_type_bound::())); assert!(t.is_exact_instance(&py.get_type_bound::())); }); } diff --git a/src/types/mod.rs b/src/types/mod.rs index 2326fc5b8ef..0ca0eec66f2 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -31,8 +31,8 @@ pub use self::memoryview::PyMemoryView; pub use self::module::{PyModule, PyModuleMethods}; pub use self::none::PyNone; pub use self::notimplemented::PyNotImplemented; -pub use self::num::PyLong; -pub use self::num::PyLong as PyInt; +#[allow(deprecated)] +pub use self::num::{PyInt, PyLong}; #[cfg(not(any(PyPy, GraalPy)))] pub use self::pysuper::PySuper; pub use self::sequence::{PySequence, PySequenceMethods}; diff --git a/src/types/num.rs b/src/types/num.rs index b43dddbef88..517e769742b 100644 --- a/src/types/num.rs +++ b/src/types/num.rs @@ -3,13 +3,17 @@ use crate::{ffi, PyAny}; /// Represents a Python `int` object. /// /// Values of this type are accessed via PyO3's smart pointers, e.g. as -/// [`Py`][crate::Py] or [`Bound<'py, PyLong>`][crate::Bound]. +/// [`Py`][crate::Py] or [`Bound<'py, PyInt>`][crate::Bound]. /// /// You can usually avoid directly working with this type /// by using [`ToPyObject`](crate::conversion::ToPyObject) /// and [`extract`](super::PyAnyMethods::extract) /// with the primitive Rust integer types. #[repr(transparent)] -pub struct PyLong(PyAny); +pub struct PyInt(PyAny); -pyobject_native_type_core!(PyLong, pyobject_native_static_type_object!(ffi::PyLong_Type), #checkfunction=ffi::PyLong_Check); +pyobject_native_type_core!(PyInt, pyobject_native_static_type_object!(ffi::PyLong_Type), #checkfunction=ffi::PyLong_Check); + +/// Deprecated alias for [`PyInt`]. +#[deprecated(since = "0.23.0", note = "use `PyInt` instead")] +pub type PyLong = PyInt; diff --git a/src/types/typeobject.rs b/src/types/typeobject.rs index f4b7a6fbc43..9c2d8c17334 100644 --- a/src/types/typeobject.rs +++ b/src/types/typeobject.rs @@ -243,9 +243,7 @@ impl<'py> PyTypeMethods<'py> for Bound<'py, PyType> { #[cfg(test)] mod tests { - use crate::types::{ - PyAnyMethods, PyBool, PyInt, PyLong, PyModule, PyTuple, PyType, PyTypeMethods, - }; + use crate::types::{PyAnyMethods, PyBool, PyInt, PyModule, PyTuple, PyType, PyTypeMethods}; use crate::PyAny; use crate::Python; @@ -253,7 +251,7 @@ mod tests { fn test_type_is_subclass() { Python::with_gil(|py| { let bool_type = py.get_type_bound::(); - let long_type = py.get_type_bound::(); + let long_type = py.get_type_bound::(); assert!(bool_type.is_subclass(&long_type).unwrap()); }); } @@ -263,7 +261,7 @@ mod tests { Python::with_gil(|py| { assert!(py .get_type_bound::() - .is_subclass_of::() + .is_subclass_of::() .unwrap()); }); }