Skip to main content

pyo3/types/
any.rs

1use crate::call::PyCallArgs;
2use crate::class::basic::CompareOp;
3use crate::conversion::{FromPyObject, IntoPyObject};
4use crate::err::{error_on_minusone, PyErr, PyResult};
5use crate::exceptions::PyTypeError;
6use crate::ffi_ptr_ext::FfiPtrExt;
7#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
8use crate::impl_::pycell::{PyClassObjectBase, PyStaticClassObject};
9use crate::instance::Bound;
10use crate::internal::get_slot::TP_DESCR_GET;
11use crate::py_result_ext::PyResultExt;
12use crate::type_object::{PyTypeCheck, PyTypeInfo};
13use crate::types::PySuper;
14use crate::types::{PyDict, PyIterator, PyList, PyString, PyType};
15use crate::{err, ffi, Borrowed, BoundObject, IntoPyObjectExt, Py};
16#[cfg(RustPython)]
17use crate::{sync::PyOnceLock, types::typeobject::PyTypeMethods};
18use core::cell::UnsafeCell;
19use core::cmp::Ordering;
20use core::ffi::c_int;
21use core::ptr;
22
23/// Represents any Python object.
24///
25/// Values of this type are accessed via PyO3's smart pointers, e.g. as
26/// [`Py<PyAny>`][crate::Py] or [`Bound<'py, PyAny>`][Bound].
27///
28/// For APIs available on all Python objects, see the [`PyAnyMethods`] trait which is implemented for
29/// [`Bound<'py, PyAny>`][Bound].
30///
31/// See
32#[doc = concat!("[the guide](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/types.html#concrete-python-types)")]
33/// for an explanation of the different Python object types.
34#[repr(transparent)]
35pub struct PyAny(UnsafeCell<ffi::PyObject>);
36
37#[allow(non_snake_case)]
38// Copied here as the macro does not accept deprecated functions.
39// Originally ffi::object::PyObject_Check, but this is not in the Python C API.
40fn PyObject_Check(_: *mut ffi::PyObject) -> c_int {
41    1
42}
43
44// We follow stub writing guidelines and use "object" instead of "typing.Any": https://typing.python.org/en/latest/guides/writing_stubs.html#using-any
45#[cfg(not(RustPython))]
46pyobject_native_type_info!(
47    PyAny,
48    pyobject_native_static_type_object!(ffi::PyBaseObject_Type),
49    "typing",
50    "Any",
51    Some("builtins"),
52    #checkfunction=PyObject_Check
53);
54
55#[cfg(RustPython)]
56pyobject_native_type_info!(
57    PyAny,
58    |py| {
59        static TYPE: PyOnceLock<Py<PyType>> = PyOnceLock::new();
60        TYPE.import(py, "builtins", "object").unwrap().as_type_ptr()
61    },
62    "typing",
63    "Any",
64    Some("builtins"),
65    #checkfunction=PyObject_Check
66);
67
68pyobject_native_type_sized!(PyAny, ffi::PyObject);
69// We could use pyobject_subclassable_native_type for all builds here, but for
70// now only on opaque PyObject builds to not introduce unintended behavior
71// changes on older Python releases.
72//
73// The difference is that pyobject_subclassable_native_type will use variable
74// object size for inheritance rather than PyStaticClassObject
75#[cfg(not(all(Py_LIMITED_API, Py_GIL_DISABLED)))]
76impl crate::impl_::pyclass::PyClassBaseType for PyAny {
77    type LayoutAsBase = PyClassObjectBase<ffi::PyObject>;
78    type BaseNativeType = PyAny;
79    type Initializer = crate::impl_::pyclass_init::PyNativeTypeInitializer<Self>;
80    type PyClassMutability = crate::pycell::impl_::ImmutableClass;
81    type Layout<T: crate::impl_::pyclass::PyClassImpl> = PyStaticClassObject<T>;
82}
83
84#[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))]
85pyobject_subclassable_native_type!(PyAny, ffi::PyObject);
86
87/// This trait represents the Python APIs which are usable on all Python objects.
88///
89/// It is recommended you import this trait via `use pyo3::prelude::*` rather than
90/// by importing this trait directly.
91#[doc(alias = "PyAny")]
92pub trait PyAnyMethods<'py>: crate::sealed::Sealed {
93    /// Returns whether `self` and `other` point to the same object. To compare
94    /// the equality of two objects (the `==` operator), use [`eq`](PyAnyMethods::eq).
95    ///
96    /// This is equivalent to the Python expression `self is other`.
97    fn is<T: AsRef<Py<PyAny>>>(&self, other: T) -> bool;
98
99    /// Determines whether this object has the given attribute.
100    ///
101    /// This is equivalent to the Python expression `hasattr(self, attr_name)`.
102    ///
103    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
104    /// to intern `attr_name`.
105    ///
106    /// # Example: `intern!`ing the attribute name
107    ///
108    /// ```
109    /// # use pyo3::{prelude::*, intern};
110    /// #
111    /// #[pyfunction]
112    /// fn has_version(sys: &Bound<'_, PyModule>) -> PyResult<bool> {
113    ///     sys.hasattr(intern!(sys.py(), "version"))
114    /// }
115    /// #
116    /// # Python::attach(|py| {
117    /// #    let sys = py.import("sys").unwrap();
118    /// #    has_version(&sys).unwrap();
119    /// # });
120    /// ```
121    fn hasattr<N>(&self, attr_name: N) -> PyResult<bool>
122    where
123        N: IntoPyObject<'py, Target = PyString>;
124
125    /// Retrieves an attribute value.
126    ///
127    /// This is equivalent to the Python expression `self.attr_name`.
128    ///
129    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
130    /// to intern `attr_name`.
131    ///
132    /// # Example: `intern!`ing the attribute name
133    ///
134    /// ```
135    /// # use pyo3::{prelude::*, intern};
136    /// #
137    /// #[pyfunction]
138    /// fn version<'py>(sys: &Bound<'py, PyModule>) -> PyResult<Bound<'py, PyAny>> {
139    ///     sys.getattr(intern!(sys.py(), "version"))
140    /// }
141    /// #
142    /// # Python::attach(|py| {
143    /// #    let sys = py.import("sys").unwrap();
144    /// #    version(&sys).unwrap();
145    /// # });
146    /// ```
147    fn getattr<N>(&self, attr_name: N) -> PyResult<Bound<'py, PyAny>>
148    where
149        N: IntoPyObject<'py, Target = PyString>;
150
151    /// Retrieves an attribute value optionally.
152    ///
153    /// This is equivalent to the Python expression `getattr(self, attr_name, None)`, which may
154    /// be more efficient in some cases by simply returning `None` if the attribute is not found
155    /// instead of raising `AttributeError`.
156    ///
157    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
158    /// to intern `attr_name`.
159    ///
160    /// # Errors
161    /// Returns `Err` if an exception other than `AttributeError` is raised during attribute lookup,
162    /// such as a `ValueError` from a property or descriptor.
163    ///
164    /// # Example: Retrieving an optional attribute
165    /// ```
166    /// # use pyo3::{prelude::*, intern};
167    /// #
168    /// #[pyfunction]
169    /// fn get_version_if_exists<'py>(sys: &Bound<'py, PyModule>) -> PyResult<Option<Bound<'py, PyAny>>> {
170    ///     sys.getattr_opt(intern!(sys.py(), "version"))
171    /// }
172    /// #
173    /// # Python::attach(|py| {
174    /// #    let sys = py.import("sys").unwrap();
175    /// #    let version = get_version_if_exists(&sys).unwrap();
176    /// #    assert!(version.is_some());
177    /// # });
178    /// ```
179    fn getattr_opt<N>(&self, attr_name: N) -> PyResult<Option<Bound<'py, PyAny>>>
180    where
181        N: IntoPyObject<'py, Target = PyString>;
182
183    /// Sets an attribute value.
184    ///
185    /// This is equivalent to the Python expression `self.attr_name = value`.
186    ///
187    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
188    /// to intern `name`.
189    ///
190    /// # Example: `intern!`ing the attribute name
191    ///
192    /// ```
193    /// # use pyo3::{prelude::*, intern};
194    /// #
195    /// #[pyfunction]
196    /// fn set_answer(ob: &Bound<'_, PyAny>) -> PyResult<()> {
197    ///     ob.setattr(intern!(ob.py(), "answer"), 42)
198    /// }
199    /// #
200    /// # Python::attach(|py| {
201    /// #    let ob = PyModule::new(py, "empty").unwrap();
202    /// #    set_answer(&ob).unwrap();
203    /// # });
204    /// ```
205    fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
206    where
207        N: IntoPyObject<'py, Target = PyString>,
208        V: IntoPyObject<'py>;
209
210    /// Deletes an attribute.
211    ///
212    /// This is equivalent to the Python statement `del self.attr_name`.
213    ///
214    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
215    /// to intern `attr_name`.
216    fn delattr<N>(&self, attr_name: N) -> PyResult<()>
217    where
218        N: IntoPyObject<'py, Target = PyString>;
219
220    /// Returns an [`Ordering`] between `self` and `other`.
221    ///
222    /// This is equivalent to the following Python code:
223    /// ```python
224    /// if self == other:
225    ///     return Equal
226    /// elif a < b:
227    ///     return Less
228    /// elif a > b:
229    ///     return Greater
230    /// else:
231    ///     raise TypeError("PyAny::compare(): All comparisons returned false")
232    /// ```
233    ///
234    /// # Examples
235    ///
236    /// ```rust
237    /// use pyo3::prelude::*;
238    /// use pyo3::types::PyFloat;
239    /// use core::cmp::Ordering;
240    ///
241    /// # fn main() -> PyResult<()> {
242    /// Python::attach(|py| -> PyResult<()> {
243    ///     let a = PyFloat::new(py, 0_f64);
244    ///     let b = PyFloat::new(py, 42_f64);
245    ///     assert_eq!(a.compare(b)?, Ordering::Less);
246    ///     Ok(())
247    /// })?;
248    /// # Ok(())}
249    /// ```
250    ///
251    /// It will return `PyErr` for values that cannot be compared:
252    ///
253    /// ```rust
254    /// use pyo3::prelude::*;
255    /// use pyo3::types::{PyFloat, PyString};
256    ///
257    /// # fn main() -> PyResult<()> {
258    /// Python::attach(|py| -> PyResult<()> {
259    ///     let a = PyFloat::new(py, 0_f64);
260    ///     let b = PyString::new(py, "zero");
261    ///     assert!(a.compare(b).is_err());
262    ///     Ok(())
263    /// })?;
264    /// # Ok(())}
265    /// ```
266    fn compare<O>(&self, other: O) -> PyResult<Ordering>
267    where
268        O: IntoPyObject<'py>;
269
270    /// Tests whether two Python objects obey a given [`CompareOp`].
271    ///
272    /// [`lt`](Self::lt), [`le`](Self::le), [`eq`](Self::eq), [`ne`](Self::ne),
273    /// [`gt`](Self::gt) and [`ge`](Self::ge) are the specialized versions
274    /// of this function.
275    ///
276    /// Depending on the value of `compare_op`, this is equivalent to one of the
277    /// following Python expressions:
278    ///
279    /// | `compare_op` | Python expression |
280    /// | :---: | :----: |
281    /// | [`CompareOp::Eq`] | `self == other` |
282    /// | [`CompareOp::Ne`] | `self != other` |
283    /// | [`CompareOp::Lt`] | `self < other` |
284    /// | [`CompareOp::Le`] | `self <= other` |
285    /// | [`CompareOp::Gt`] | `self > other` |
286    /// | [`CompareOp::Ge`] | `self >= other` |
287    ///
288    /// # Examples
289    ///
290    /// ```rust
291    /// use pyo3::class::basic::CompareOp;
292    /// use pyo3::prelude::*;
293    ///
294    /// # fn main() -> PyResult<()> {
295    /// Python::attach(|py| -> PyResult<()> {
296    ///     let a = 0_u8.into_pyobject(py)?;
297    ///     let b = 42_u8.into_pyobject(py)?;
298    ///     assert!(a.rich_compare(b, CompareOp::Le)?.is_truthy()?);
299    ///     Ok(())
300    /// })?;
301    /// # Ok(())}
302    /// ```
303    fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<Bound<'py, PyAny>>
304    where
305        O: IntoPyObject<'py>;
306
307    /// Computes the negative of self.
308    ///
309    /// Equivalent to the Python expression `-self`.
310    fn neg(&self) -> PyResult<Bound<'py, PyAny>>;
311
312    /// Computes the positive of self.
313    ///
314    /// Equivalent to the Python expression `+self`.
315    fn pos(&self) -> PyResult<Bound<'py, PyAny>>;
316
317    /// Computes the absolute of self.
318    ///
319    /// Equivalent to the Python expression `abs(self)`.
320    fn abs(&self) -> PyResult<Bound<'py, PyAny>>;
321
322    /// Computes `~self`.
323    fn bitnot(&self) -> PyResult<Bound<'py, PyAny>>;
324
325    /// Tests whether this object is less than another.
326    ///
327    /// This is equivalent to the Python expression `self < other`.
328    fn lt<O>(&self, other: O) -> PyResult<bool>
329    where
330        O: IntoPyObject<'py>;
331
332    /// Tests whether this object is less than or equal to another.
333    ///
334    /// This is equivalent to the Python expression `self <= other`.
335    fn le<O>(&self, other: O) -> PyResult<bool>
336    where
337        O: IntoPyObject<'py>;
338
339    /// Tests whether this object is equal to another.
340    ///
341    /// This is equivalent to the Python expression `self == other`.
342    fn eq<O>(&self, other: O) -> PyResult<bool>
343    where
344        O: IntoPyObject<'py>;
345
346    /// Tests whether this object is not equal to another.
347    ///
348    /// This is equivalent to the Python expression `self != other`.
349    fn ne<O>(&self, other: O) -> PyResult<bool>
350    where
351        O: IntoPyObject<'py>;
352
353    /// Tests whether this object is greater than another.
354    ///
355    /// This is equivalent to the Python expression `self > other`.
356    fn gt<O>(&self, other: O) -> PyResult<bool>
357    where
358        O: IntoPyObject<'py>;
359
360    /// Tests whether this object is greater than or equal to another.
361    ///
362    /// This is equivalent to the Python expression `self >= other`.
363    fn ge<O>(&self, other: O) -> PyResult<bool>
364    where
365        O: IntoPyObject<'py>;
366
367    /// Computes `self + other`.
368    fn add<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
369    where
370        O: IntoPyObject<'py>;
371
372    /// Computes `self - other`.
373    fn sub<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
374    where
375        O: IntoPyObject<'py>;
376
377    /// Computes `self * other`.
378    fn mul<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
379    where
380        O: IntoPyObject<'py>;
381
382    /// Computes `self @ other`.
383    fn matmul<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
384    where
385        O: IntoPyObject<'py>;
386
387    /// Computes `self / other`.
388    fn div<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
389    where
390        O: IntoPyObject<'py>;
391
392    /// Computes `self // other`.
393    fn floor_div<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
394    where
395        O: IntoPyObject<'py>;
396
397    /// Computes `self % other`.
398    fn rem<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
399    where
400        O: IntoPyObject<'py>;
401
402    /// Computes `divmod(self, other)`.
403    fn divmod<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
404    where
405        O: IntoPyObject<'py>;
406
407    /// Computes `self << other`.
408    fn lshift<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
409    where
410        O: IntoPyObject<'py>;
411
412    /// Computes `self >> other`.
413    fn rshift<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
414    where
415        O: IntoPyObject<'py>;
416
417    /// Computes `self ** other % modulus` (`pow(self, other, modulus)`).
418    /// `py.None()` may be passed for the `modulus`.
419    fn pow<O1, O2>(&self, other: O1, modulus: O2) -> PyResult<Bound<'py, PyAny>>
420    where
421        O1: IntoPyObject<'py>,
422        O2: IntoPyObject<'py>;
423
424    /// Computes `self & other`.
425    fn bitand<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
426    where
427        O: IntoPyObject<'py>;
428
429    /// Computes `self | other`.
430    fn bitor<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
431    where
432        O: IntoPyObject<'py>;
433
434    /// Computes `self ^ other`.
435    fn bitxor<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
436    where
437        O: IntoPyObject<'py>;
438
439    /// Determines whether this object appears callable.
440    ///
441    /// This is equivalent to Python's [`callable()`][1] function.
442    ///
443    /// # Examples
444    ///
445    /// ```rust
446    /// use pyo3::prelude::*;
447    ///
448    /// # fn main() -> PyResult<()> {
449    /// Python::attach(|py| -> PyResult<()> {
450    ///     let builtins = PyModule::import(py, "builtins")?;
451    ///     let print = builtins.getattr("print")?;
452    ///     assert!(print.is_callable());
453    ///     Ok(())
454    /// })?;
455    /// # Ok(())}
456    /// ```
457    ///
458    /// This is equivalent to the Python statement `assert callable(print)`.
459    ///
460    /// Note that unless an API needs to distinguish between callable and
461    /// non-callable objects, there is no point in checking for callability.
462    /// Instead, it is better to just do the call and handle potential
463    /// exceptions.
464    ///
465    /// [1]: https://docs.python.org/3/library/functions.html#callable
466    fn is_callable(&self) -> bool;
467
468    /// Calls the object.
469    ///
470    /// This is equivalent to the Python expression `self(*args, **kwargs)`.
471    ///
472    /// # Examples
473    ///
474    /// ```rust
475    /// use pyo3::prelude::*;
476    /// use pyo3::types::PyDict;
477    /// use pyo3_ffi::c_str;
478    /// use core::ffi::CStr;
479    ///
480    /// const CODE: &CStr = cr#"
481    /// def function(*args, **kwargs):
482    ///     assert args == ("hello",)
483    ///     assert kwargs == {"cruel": "world"}
484    ///     return "called with args and kwargs"
485    /// "#;
486    ///
487    /// # fn main() -> PyResult<()> {
488    /// Python::attach(|py| {
489    ///     let module = PyModule::from_code(py, CODE, c"func.py", c"")?;
490    ///     let fun = module.getattr("function")?;
491    ///     let args = ("hello",);
492    ///     let kwargs = PyDict::new(py);
493    ///     kwargs.set_item("cruel", "world")?;
494    ///     let result = fun.call(args, Some(&kwargs))?;
495    ///     assert_eq!(result.extract::<String>()?, "called with args and kwargs");
496    ///     Ok(())
497    /// })
498    /// # }
499    /// ```
500    fn call<A>(&self, args: A, kwargs: Option<&Bound<'py, PyDict>>) -> PyResult<Bound<'py, PyAny>>
501    where
502        A: PyCallArgs<'py>;
503
504    /// Calls the object without arguments.
505    ///
506    /// This is equivalent to the Python expression `self()`.
507    ///
508    /// # Examples
509    ///
510    /// ```no_run
511    /// use pyo3::prelude::*;
512    ///
513    /// # fn main() -> PyResult<()> {
514    /// Python::attach(|py| -> PyResult<()> {
515    ///     let module = PyModule::import(py, "builtins")?;
516    ///     let help = module.getattr("help")?;
517    ///     help.call0()?;
518    ///     Ok(())
519    /// })?;
520    /// # Ok(())}
521    /// ```
522    ///
523    /// This is equivalent to the Python expression `help()`.
524    fn call0(&self) -> PyResult<Bound<'py, PyAny>>;
525
526    /// Calls the object with only positional arguments.
527    ///
528    /// This is equivalent to the Python expression `self(*args)`.
529    ///
530    /// # Examples
531    ///
532    /// ```rust
533    /// use pyo3::prelude::*;
534    /// use pyo3_ffi::c_str;
535    /// use core::ffi::CStr;
536    ///
537    /// const CODE: &CStr = cr#"
538    /// def function(*args, **kwargs):
539    ///     assert args == ("hello",)
540    ///     assert kwargs == {}
541    ///     return "called with args"
542    /// "#;
543    ///
544    /// # fn main() -> PyResult<()> {
545    /// Python::attach(|py| {
546    ///     let module = PyModule::from_code(py, CODE, c"func.py", c"")?;
547    ///     let fun = module.getattr("function")?;
548    ///     let args = ("hello",);
549    ///     let result = fun.call1(args)?;
550    ///     assert_eq!(result.extract::<String>()?, "called with args");
551    ///     Ok(())
552    /// })
553    /// # }
554    /// ```
555    fn call1<A>(&self, args: A) -> PyResult<Bound<'py, PyAny>>
556    where
557        A: PyCallArgs<'py>;
558
559    /// Calls a method on the object.
560    ///
561    /// This is equivalent to the Python expression `self.name(*args, **kwargs)`.
562    ///
563    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
564    /// to intern `name`.
565    ///
566    /// # Examples
567    ///
568    /// ```rust
569    /// use pyo3::prelude::*;
570    /// use pyo3::types::PyDict;
571    /// use pyo3_ffi::c_str;
572    /// use core::ffi::CStr;
573    ///
574    /// const CODE: &CStr = cr#"
575    /// class A:
576    ///     def method(self, *args, **kwargs):
577    ///         assert args == ("hello",)
578    ///         assert kwargs == {"cruel": "world"}
579    ///         return "called with args and kwargs"
580    /// a = A()
581    /// "#;
582    ///
583    /// # fn main() -> PyResult<()> {
584    /// Python::attach(|py| {
585    ///     let module = PyModule::from_code(py, CODE, c"a.py", c"")?;
586    ///     let instance = module.getattr("a")?;
587    ///     let args = ("hello",);
588    ///     let kwargs = PyDict::new(py);
589    ///     kwargs.set_item("cruel", "world")?;
590    ///     let result = instance.call_method("method", args, Some(&kwargs))?;
591    ///     assert_eq!(result.extract::<String>()?, "called with args and kwargs");
592    ///     Ok(())
593    /// })
594    /// # }
595    /// ```
596    fn call_method<N, A>(
597        &self,
598        name: N,
599        args: A,
600        kwargs: Option<&Bound<'py, PyDict>>,
601    ) -> PyResult<Bound<'py, PyAny>>
602    where
603        N: IntoPyObject<'py, Target = PyString>,
604        A: PyCallArgs<'py>;
605
606    /// Calls a method on the object without arguments.
607    ///
608    /// This is equivalent to the Python expression `self.name()`.
609    ///
610    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
611    /// to intern `name`.
612    ///
613    /// # Examples
614    ///
615    /// ```rust
616    /// use pyo3::prelude::*;
617    /// use pyo3_ffi::c_str;
618    /// use core::ffi::CStr;
619    ///
620    /// const CODE: &CStr = cr#"
621    /// class A:
622    ///     def method(self, *args, **kwargs):
623    ///         assert args == ()
624    ///         assert kwargs == {}
625    ///         return "called with no arguments"
626    /// a = A()
627    /// "#;
628    ///
629    /// # fn main() -> PyResult<()> {
630    /// Python::attach(|py| {
631    ///     let module = PyModule::from_code(py, CODE, c"a.py", c"")?;
632    ///     let instance = module.getattr("a")?;
633    ///     let result = instance.call_method0("method")?;
634    ///     assert_eq!(result.extract::<String>()?, "called with no arguments");
635    ///     Ok(())
636    /// })
637    /// # }
638    /// ```
639    fn call_method0<N>(&self, name: N) -> PyResult<Bound<'py, PyAny>>
640    where
641        N: IntoPyObject<'py, Target = PyString>;
642
643    /// Calls a method on the object with only positional arguments.
644    ///
645    /// This is equivalent to the Python expression `self.name(*args)`.
646    ///
647    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
648    /// to intern `name`.
649    ///
650    /// # Examples
651    ///
652    /// ```rust
653    /// use pyo3::prelude::*;
654    /// use pyo3_ffi::c_str;
655    /// use core::ffi::CStr;
656    ///
657    /// const CODE: &CStr = cr#"
658    /// class A:
659    ///     def method(self, *args, **kwargs):
660    ///         assert args == ("hello",)
661    ///         assert kwargs == {}
662    ///         return "called with args"
663    /// a = A()
664    /// "#;
665    ///
666    /// # fn main() -> PyResult<()> {
667    /// Python::attach(|py| {
668    ///     let module = PyModule::from_code(py, CODE, c"a.py", c"")?;
669    ///     let instance = module.getattr("a")?;
670    ///     let args = ("hello",);
671    ///     let result = instance.call_method1("method", args)?;
672    ///     assert_eq!(result.extract::<String>()?, "called with args");
673    ///     Ok(())
674    /// })
675    /// # }
676    /// ```
677    fn call_method1<N, A>(&self, name: N, args: A) -> PyResult<Bound<'py, PyAny>>
678    where
679        N: IntoPyObject<'py, Target = PyString>,
680        A: PyCallArgs<'py>;
681
682    /// Returns whether the object is considered to be true.
683    ///
684    /// This is equivalent to the Python expression `bool(self)`.
685    fn is_truthy(&self) -> PyResult<bool>;
686
687    /// Returns whether the object is considered to be None.
688    ///
689    /// This is equivalent to the Python expression `self is None`.
690    fn is_none(&self) -> bool;
691
692    /// Returns true if the sequence or mapping has a length of 0.
693    ///
694    /// This is equivalent to the Python expression `len(self) == 0`.
695    fn is_empty(&self) -> PyResult<bool>;
696
697    /// Gets an item from the collection.
698    ///
699    /// This is equivalent to the Python expression `self[key]`.
700    fn get_item<K>(&self, key: K) -> PyResult<Bound<'py, PyAny>>
701    where
702        K: IntoPyObject<'py>;
703
704    /// Sets a collection item value.
705    ///
706    /// This is equivalent to the Python expression `self[key] = value`.
707    fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
708    where
709        K: IntoPyObject<'py>,
710        V: IntoPyObject<'py>;
711
712    /// Deletes an item from the collection.
713    ///
714    /// This is equivalent to the Python expression `del self[key]`.
715    fn del_item<K>(&self, key: K) -> PyResult<()>
716    where
717        K: IntoPyObject<'py>;
718
719    /// Takes an object and returns an iterator for it. Returns an error if the object is not
720    /// iterable.
721    ///
722    /// This is typically a new iterator but if the argument is an iterator,
723    /// this returns itself.
724    ///
725    /// # Example: Checking a Python object for iterability
726    ///
727    /// ```rust
728    /// use pyo3::prelude::*;
729    /// use pyo3::types::{PyAny, PyNone};
730    ///
731    /// fn is_iterable(obj: &Bound<'_, PyAny>) -> bool {
732    ///     match obj.try_iter() {
733    ///         Ok(_) => true,
734    ///         Err(_) => false,
735    ///     }
736    /// }
737    ///
738    /// Python::attach(|py| {
739    ///     assert!(is_iterable(&vec![1, 2, 3].into_pyobject(py).unwrap()));
740    ///     assert!(!is_iterable(&PyNone::get(py)));
741    /// });
742    /// ```
743    fn try_iter(&self) -> PyResult<Bound<'py, PyIterator>>;
744
745    /// Returns the Python type object for this object's type.
746    fn get_type(&self) -> Bound<'py, PyType>;
747
748    /// Returns the Python type pointer for this object.
749    fn get_type_ptr(&self) -> *mut ffi::PyTypeObject;
750
751    /// Extracts some type from the Python object.
752    ///
753    /// This is a wrapper function around [`FromPyObject::extract()`](crate::FromPyObject::extract).
754    fn extract<'a, T>(&'a self) -> Result<T, T::Error>
755    where
756        T: FromPyObject<'a, 'py>;
757
758    /// Returns the reference count for the Python object.
759    #[deprecated(
760        since = "0.29.0",
761        note = "use `pyo3::ffi::Py_REFCNT(obj.as_ptr())` instead"
762    )]
763    fn get_refcnt(&self) -> isize;
764
765    /// Computes the "repr" representation of self.
766    ///
767    /// This is equivalent to the Python expression `repr(self)`.
768    fn repr(&self) -> PyResult<Bound<'py, PyString>>;
769
770    /// Computes the "str" representation of self.
771    ///
772    /// This is equivalent to the Python expression `str(self)`.
773    fn str(&self) -> PyResult<Bound<'py, PyString>>;
774
775    /// Retrieves the hash code of self.
776    ///
777    /// This is equivalent to the Python expression `hash(self)`.
778    fn hash(&self) -> PyResult<isize>;
779
780    /// Returns the length of the sequence or mapping.
781    ///
782    /// This is equivalent to the Python expression `len(self)`.
783    fn len(&self) -> PyResult<usize>;
784
785    /// Returns the list of attributes of this object.
786    ///
787    /// This is equivalent to the Python expression `dir(self)`.
788    fn dir(&self) -> PyResult<Bound<'py, PyList>>;
789
790    /// Checks whether this object is an instance of type `ty`.
791    ///
792    /// This is equivalent to the Python expression `isinstance(self, ty)`.
793    fn is_instance(&self, ty: &Bound<'py, PyAny>) -> PyResult<bool>;
794
795    /// Checks whether this object is an instance of exactly type `ty` (not a subclass).
796    ///
797    /// This is equivalent to the Python expression `type(self) is ty`.
798    fn is_exact_instance(&self, ty: &Bound<'py, PyAny>) -> bool;
799
800    /// Checks whether this object is an instance of type `T`.
801    ///
802    /// This is equivalent to the Python expression `isinstance(self, T)`,
803    /// if the type `T` is known at compile time.
804    fn is_instance_of<T: PyTypeCheck>(&self) -> bool;
805
806    /// Checks whether this object is an instance of exactly type `T`.
807    ///
808    /// This is equivalent to the Python expression `type(self) is T`,
809    /// if the type `T` is known at compile time.
810    fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool;
811
812    /// Determines if self contains `value`.
813    ///
814    /// This is equivalent to the Python expression `value in self`.
815    fn contains<V>(&self, value: V) -> PyResult<bool>
816    where
817        V: IntoPyObject<'py>;
818
819    /// Return a proxy object that delegates method calls to a parent or sibling class of type.
820    ///
821    /// This is equivalent to the Python expression `super()`
822    fn py_super(&self) -> PyResult<Bound<'py, PySuper>>;
823}
824
825macro_rules! implement_binop {
826    ($name:ident, $c_api:ident, $op:expr) => {
827        #[doc = concat!("Computes `self ", $op, " other`.")]
828        fn $name<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
829        where
830            O: IntoPyObject<'py>,
831        {
832            fn inner<'py>(
833                any: &Bound<'py, PyAny>,
834                other: Borrowed<'_, 'py, PyAny>,
835            ) -> PyResult<Bound<'py, PyAny>> {
836                unsafe { ffi::$c_api(any.as_ptr(), other.as_ptr()).assume_owned_or_err(any.py()) }
837            }
838
839            let py = self.py();
840            inner(
841                self,
842                other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
843            )
844        }
845    };
846}
847
848impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
849    #[inline]
850    fn is<T: AsRef<Py<PyAny>>>(&self, other: T) -> bool {
851        ptr::eq(self.as_ptr(), other.as_ref().as_ptr())
852    }
853
854    fn hasattr<N>(&self, attr_name: N) -> PyResult<bool>
855    where
856        N: IntoPyObject<'py, Target = PyString>,
857    {
858        fn inner<'py>(
859            any: &Bound<'py, PyAny>,
860            attr_name: Borrowed<'_, '_, PyString>,
861        ) -> PyResult<bool> {
862            let result =
863                unsafe { ffi::compat::PyObject_HasAttrWithError(any.as_ptr(), attr_name.as_ptr()) };
864            error_on_minusone(any.py(), result)?;
865            Ok(result > 0)
866        }
867
868        inner(
869            self,
870            attr_name
871                .into_pyobject(self.py())
872                .map_err(Into::into)?
873                .as_borrowed(),
874        )
875    }
876
877    fn getattr<N>(&self, attr_name: N) -> PyResult<Bound<'py, PyAny>>
878    where
879        N: IntoPyObject<'py, Target = PyString>,
880    {
881        fn inner<'py>(
882            any: &Bound<'py, PyAny>,
883            attr_name: Borrowed<'_, '_, PyString>,
884        ) -> PyResult<Bound<'py, PyAny>> {
885            unsafe {
886                ffi::PyObject_GetAttr(any.as_ptr(), attr_name.as_ptr())
887                    .assume_owned_or_err(any.py())
888            }
889        }
890
891        inner(
892            self,
893            attr_name
894                .into_pyobject(self.py())
895                .map_err(Into::into)?
896                .as_borrowed(),
897        )
898    }
899
900    fn getattr_opt<N>(&self, attr_name: N) -> PyResult<Option<Bound<'py, PyAny>>>
901    where
902        N: IntoPyObject<'py, Target = PyString>,
903    {
904        fn inner<'py>(
905            any: &Bound<'py, PyAny>,
906            attr_name: Borrowed<'_, 'py, PyString>,
907        ) -> PyResult<Option<Bound<'py, PyAny>>> {
908            let mut resp_ptr: *mut ffi::PyObject = core::ptr::null_mut();
909            match unsafe {
910                ffi::compat::PyObject_GetOptionalAttr(
911                    any.as_ptr(),
912                    attr_name.as_ptr(),
913                    &mut resp_ptr,
914                )
915            } {
916                // Attribute found, result is a new strong reference
917                1 => Ok(Some(unsafe { Bound::from_owned_ptr(any.py(), resp_ptr) })),
918                // Attribute not found
919                0 => Ok(None),
920                // An error occurred (other than AttributeError)
921                _ => Err(PyErr::fetch(any.py())),
922            }
923        }
924
925        let py = self.py();
926        inner(self, attr_name.into_pyobject_or_pyerr(py)?.as_borrowed())
927    }
928
929    fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
930    where
931        N: IntoPyObject<'py, Target = PyString>,
932        V: IntoPyObject<'py>,
933    {
934        fn inner(
935            any: &Bound<'_, PyAny>,
936            attr_name: Borrowed<'_, '_, PyString>,
937            value: Borrowed<'_, '_, PyAny>,
938        ) -> PyResult<()> {
939            err::error_on_minusone(any.py(), unsafe {
940                ffi::PyObject_SetAttr(any.as_ptr(), attr_name.as_ptr(), value.as_ptr())
941            })
942        }
943
944        let py = self.py();
945        inner(
946            self,
947            attr_name.into_pyobject_or_pyerr(py)?.as_borrowed(),
948            value.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
949        )
950    }
951
952    fn delattr<N>(&self, attr_name: N) -> PyResult<()>
953    where
954        N: IntoPyObject<'py, Target = PyString>,
955    {
956        fn inner(any: &Bound<'_, PyAny>, attr_name: Borrowed<'_, '_, PyString>) -> PyResult<()> {
957            err::error_on_minusone(any.py(), unsafe {
958                ffi::PyObject_DelAttr(any.as_ptr(), attr_name.as_ptr())
959            })
960        }
961
962        let py = self.py();
963        inner(self, attr_name.into_pyobject_or_pyerr(py)?.as_borrowed())
964    }
965
966    fn compare<O>(&self, other: O) -> PyResult<Ordering>
967    where
968        O: IntoPyObject<'py>,
969    {
970        fn inner(any: &Bound<'_, PyAny>, other: Borrowed<'_, '_, PyAny>) -> PyResult<Ordering> {
971            let other = other.as_ptr();
972            // Almost the same as ffi::PyObject_RichCompareBool, but this one doesn't try self == other.
973            // See https://github.com/PyO3/pyo3/issues/985 for more.
974            let do_compare = |other, op| unsafe {
975                ffi::PyObject_RichCompare(any.as_ptr(), other, op)
976                    .assume_owned_or_err(any.py())
977                    .and_then(|obj| obj.is_truthy())
978            };
979            if do_compare(other, ffi::Py_EQ)? {
980                Ok(Ordering::Equal)
981            } else if do_compare(other, ffi::Py_LT)? {
982                Ok(Ordering::Less)
983            } else if do_compare(other, ffi::Py_GT)? {
984                Ok(Ordering::Greater)
985            } else {
986                Err(PyTypeError::new_err(
987                    "PyAny::compare(): All comparisons returned false",
988                ))
989            }
990        }
991
992        let py = self.py();
993        inner(
994            self,
995            other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
996        )
997    }
998
999    fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<Bound<'py, PyAny>>
1000    where
1001        O: IntoPyObject<'py>,
1002    {
1003        fn inner<'py>(
1004            any: &Bound<'py, PyAny>,
1005            other: Borrowed<'_, 'py, PyAny>,
1006            compare_op: CompareOp,
1007        ) -> PyResult<Bound<'py, PyAny>> {
1008            unsafe {
1009                ffi::PyObject_RichCompare(any.as_ptr(), other.as_ptr(), compare_op as c_int)
1010                    .assume_owned_or_err(any.py())
1011            }
1012        }
1013
1014        let py = self.py();
1015        inner(
1016            self,
1017            other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1018            compare_op,
1019        )
1020    }
1021
1022    fn neg(&self) -> PyResult<Bound<'py, PyAny>> {
1023        unsafe { ffi::PyNumber_Negative(self.as_ptr()).assume_owned_or_err(self.py()) }
1024    }
1025
1026    fn pos(&self) -> PyResult<Bound<'py, PyAny>> {
1027        fn inner<'py>(any: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyAny>> {
1028            unsafe { ffi::PyNumber_Positive(any.as_ptr()).assume_owned_or_err(any.py()) }
1029        }
1030
1031        inner(self)
1032    }
1033
1034    fn abs(&self) -> PyResult<Bound<'py, PyAny>> {
1035        fn inner<'py>(any: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyAny>> {
1036            unsafe { ffi::PyNumber_Absolute(any.as_ptr()).assume_owned_or_err(any.py()) }
1037        }
1038
1039        inner(self)
1040    }
1041
1042    fn bitnot(&self) -> PyResult<Bound<'py, PyAny>> {
1043        fn inner<'py>(any: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyAny>> {
1044            unsafe { ffi::PyNumber_Invert(any.as_ptr()).assume_owned_or_err(any.py()) }
1045        }
1046
1047        inner(self)
1048    }
1049
1050    fn lt<O>(&self, other: O) -> PyResult<bool>
1051    where
1052        O: IntoPyObject<'py>,
1053    {
1054        self.rich_compare(other, CompareOp::Lt)
1055            .and_then(|any| any.is_truthy())
1056    }
1057
1058    fn le<O>(&self, other: O) -> PyResult<bool>
1059    where
1060        O: IntoPyObject<'py>,
1061    {
1062        self.rich_compare(other, CompareOp::Le)
1063            .and_then(|any| any.is_truthy())
1064    }
1065
1066    fn eq<O>(&self, other: O) -> PyResult<bool>
1067    where
1068        O: IntoPyObject<'py>,
1069    {
1070        self.rich_compare(other, CompareOp::Eq)
1071            .and_then(|any| any.is_truthy())
1072    }
1073
1074    fn ne<O>(&self, other: O) -> PyResult<bool>
1075    where
1076        O: IntoPyObject<'py>,
1077    {
1078        self.rich_compare(other, CompareOp::Ne)
1079            .and_then(|any| any.is_truthy())
1080    }
1081
1082    fn gt<O>(&self, other: O) -> PyResult<bool>
1083    where
1084        O: IntoPyObject<'py>,
1085    {
1086        self.rich_compare(other, CompareOp::Gt)
1087            .and_then(|any| any.is_truthy())
1088    }
1089
1090    fn ge<O>(&self, other: O) -> PyResult<bool>
1091    where
1092        O: IntoPyObject<'py>,
1093    {
1094        self.rich_compare(other, CompareOp::Ge)
1095            .and_then(|any| any.is_truthy())
1096    }
1097
1098    implement_binop!(add, PyNumber_Add, "+");
1099    implement_binop!(sub, PyNumber_Subtract, "-");
1100    implement_binop!(mul, PyNumber_Multiply, "*");
1101    implement_binop!(matmul, PyNumber_MatrixMultiply, "@");
1102    implement_binop!(div, PyNumber_TrueDivide, "/");
1103    implement_binop!(floor_div, PyNumber_FloorDivide, "//");
1104    implement_binop!(rem, PyNumber_Remainder, "%");
1105    implement_binop!(lshift, PyNumber_Lshift, "<<");
1106    implement_binop!(rshift, PyNumber_Rshift, ">>");
1107    implement_binop!(bitand, PyNumber_And, "&");
1108    implement_binop!(bitor, PyNumber_Or, "|");
1109    implement_binop!(bitxor, PyNumber_Xor, "^");
1110
1111    /// Computes `divmod(self, other)`.
1112    fn divmod<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
1113    where
1114        O: IntoPyObject<'py>,
1115    {
1116        fn inner<'py>(
1117            any: &Bound<'py, PyAny>,
1118            other: Borrowed<'_, 'py, PyAny>,
1119        ) -> PyResult<Bound<'py, PyAny>> {
1120            unsafe {
1121                ffi::PyNumber_Divmod(any.as_ptr(), other.as_ptr()).assume_owned_or_err(any.py())
1122            }
1123        }
1124
1125        let py = self.py();
1126        inner(
1127            self,
1128            other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1129        )
1130    }
1131
1132    /// Computes `self ** other % modulus` (`pow(self, other, modulus)`).
1133    /// `py.None()` may be passed for the `modulus`.
1134    fn pow<O1, O2>(&self, other: O1, modulus: O2) -> PyResult<Bound<'py, PyAny>>
1135    where
1136        O1: IntoPyObject<'py>,
1137        O2: IntoPyObject<'py>,
1138    {
1139        fn inner<'py>(
1140            any: &Bound<'py, PyAny>,
1141            other: Borrowed<'_, 'py, PyAny>,
1142            modulus: Borrowed<'_, 'py, PyAny>,
1143        ) -> PyResult<Bound<'py, PyAny>> {
1144            unsafe {
1145                ffi::PyNumber_Power(any.as_ptr(), other.as_ptr(), modulus.as_ptr())
1146                    .assume_owned_or_err(any.py())
1147            }
1148        }
1149
1150        let py = self.py();
1151        inner(
1152            self,
1153            other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1154            modulus.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1155        )
1156    }
1157
1158    fn is_callable(&self) -> bool {
1159        unsafe { ffi::PyCallable_Check(self.as_ptr()) != 0 }
1160    }
1161
1162    fn call<A>(&self, args: A, kwargs: Option<&Bound<'py, PyDict>>) -> PyResult<Bound<'py, PyAny>>
1163    where
1164        A: PyCallArgs<'py>,
1165    {
1166        if let Some(kwargs) = kwargs {
1167            args.call(
1168                self.as_borrowed(),
1169                kwargs.as_borrowed(),
1170                crate::call::private::Token,
1171            )
1172        } else {
1173            args.call_positional(self.as_borrowed(), crate::call::private::Token)
1174        }
1175    }
1176
1177    #[inline]
1178    fn call0(&self) -> PyResult<Bound<'py, PyAny>> {
1179        unsafe { ffi::compat::PyObject_CallNoArgs(self.as_ptr()).assume_owned_or_err(self.py()) }
1180    }
1181
1182    fn call1<A>(&self, args: A) -> PyResult<Bound<'py, PyAny>>
1183    where
1184        A: PyCallArgs<'py>,
1185    {
1186        args.call_positional(self.as_borrowed(), crate::call::private::Token)
1187    }
1188
1189    #[inline]
1190    fn call_method<N, A>(
1191        &self,
1192        name: N,
1193        args: A,
1194        kwargs: Option<&Bound<'py, PyDict>>,
1195    ) -> PyResult<Bound<'py, PyAny>>
1196    where
1197        N: IntoPyObject<'py, Target = PyString>,
1198        A: PyCallArgs<'py>,
1199    {
1200        if kwargs.is_none() {
1201            self.call_method1(name, args)
1202        } else {
1203            self.getattr(name)
1204                .and_then(|method| method.call(args, kwargs))
1205        }
1206    }
1207
1208    #[inline]
1209    fn call_method0<N>(&self, name: N) -> PyResult<Bound<'py, PyAny>>
1210    where
1211        N: IntoPyObject<'py, Target = PyString>,
1212    {
1213        let py = self.py();
1214        let name = name.into_pyobject_or_pyerr(py)?.into_bound();
1215        unsafe {
1216            ffi::compat::PyObject_CallMethodNoArgs(self.as_ptr(), name.as_ptr())
1217                .assume_owned_or_err(py)
1218        }
1219    }
1220
1221    fn call_method1<N, A>(&self, name: N, args: A) -> PyResult<Bound<'py, PyAny>>
1222    where
1223        N: IntoPyObject<'py, Target = PyString>,
1224        A: PyCallArgs<'py>,
1225    {
1226        let name = name.into_pyobject_or_pyerr(self.py())?;
1227        args.call_method_positional(
1228            self.as_borrowed(),
1229            name.as_borrowed(),
1230            crate::call::private::Token,
1231        )
1232    }
1233
1234    fn is_truthy(&self) -> PyResult<bool> {
1235        let v = unsafe { ffi::PyObject_IsTrue(self.as_ptr()) };
1236        err::error_on_minusone(self.py(), v)?;
1237        Ok(v != 0)
1238    }
1239
1240    #[inline]
1241    fn is_none(&self) -> bool {
1242        unsafe { ptr::eq(ffi::Py_None(), self.as_ptr()) }
1243    }
1244
1245    fn is_empty(&self) -> PyResult<bool> {
1246        self.len().map(|l| l == 0)
1247    }
1248
1249    fn get_item<K>(&self, key: K) -> PyResult<Bound<'py, PyAny>>
1250    where
1251        K: IntoPyObject<'py>,
1252    {
1253        fn inner<'py>(
1254            any: &Bound<'py, PyAny>,
1255            key: Borrowed<'_, 'py, PyAny>,
1256        ) -> PyResult<Bound<'py, PyAny>> {
1257            unsafe {
1258                ffi::PyObject_GetItem(any.as_ptr(), key.as_ptr()).assume_owned_or_err(any.py())
1259            }
1260        }
1261
1262        let py = self.py();
1263        inner(
1264            self,
1265            key.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1266        )
1267    }
1268
1269    fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
1270    where
1271        K: IntoPyObject<'py>,
1272        V: IntoPyObject<'py>,
1273    {
1274        fn inner(
1275            any: &Bound<'_, PyAny>,
1276            key: Borrowed<'_, '_, PyAny>,
1277            value: Borrowed<'_, '_, PyAny>,
1278        ) -> PyResult<()> {
1279            err::error_on_minusone(any.py(), unsafe {
1280                ffi::PyObject_SetItem(any.as_ptr(), key.as_ptr(), value.as_ptr())
1281            })
1282        }
1283
1284        let py = self.py();
1285        inner(
1286            self,
1287            key.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1288            value.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1289        )
1290    }
1291
1292    fn del_item<K>(&self, key: K) -> PyResult<()>
1293    where
1294        K: IntoPyObject<'py>,
1295    {
1296        fn inner(any: &Bound<'_, PyAny>, key: Borrowed<'_, '_, PyAny>) -> PyResult<()> {
1297            err::error_on_minusone(any.py(), unsafe {
1298                ffi::PyObject_DelItem(any.as_ptr(), key.as_ptr())
1299            })
1300        }
1301
1302        let py = self.py();
1303        inner(
1304            self,
1305            key.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1306        )
1307    }
1308
1309    fn try_iter(&self) -> PyResult<Bound<'py, PyIterator>> {
1310        PyIterator::from_object(self)
1311    }
1312
1313    fn get_type(&self) -> Bound<'py, PyType> {
1314        unsafe { PyType::from_borrowed_type_ptr(self.py(), ffi::Py_TYPE(self.as_ptr())) }
1315    }
1316
1317    #[inline]
1318    fn get_type_ptr(&self) -> *mut ffi::PyTypeObject {
1319        unsafe { ffi::Py_TYPE(self.as_ptr()) }
1320    }
1321
1322    fn extract<'a, T>(&'a self) -> Result<T, T::Error>
1323    where
1324        T: FromPyObject<'a, 'py>,
1325    {
1326        FromPyObject::extract(self.as_borrowed())
1327    }
1328
1329    fn get_refcnt(&self) -> isize {
1330        self._get_refcnt()
1331    }
1332
1333    fn repr(&self) -> PyResult<Bound<'py, PyString>> {
1334        unsafe {
1335            ffi::PyObject_Repr(self.as_ptr())
1336                .assume_owned_or_err(self.py())
1337                .cast_into_unchecked()
1338        }
1339    }
1340
1341    fn str(&self) -> PyResult<Bound<'py, PyString>> {
1342        unsafe {
1343            ffi::PyObject_Str(self.as_ptr())
1344                .assume_owned_or_err(self.py())
1345                .cast_into_unchecked()
1346        }
1347    }
1348
1349    fn hash(&self) -> PyResult<isize> {
1350        let v = unsafe { ffi::PyObject_Hash(self.as_ptr()) };
1351        crate::err::error_on_minusone(self.py(), v)?;
1352        Ok(v)
1353    }
1354
1355    fn len(&self) -> PyResult<usize> {
1356        let v = unsafe { ffi::PyObject_Size(self.as_ptr()) };
1357        crate::err::error_on_minusone(self.py(), v)?;
1358        Ok(v as usize)
1359    }
1360
1361    fn dir(&self) -> PyResult<Bound<'py, PyList>> {
1362        unsafe {
1363            ffi::PyObject_Dir(self.as_ptr())
1364                .assume_owned_or_err(self.py())
1365                .cast_into_unchecked()
1366        }
1367    }
1368
1369    #[inline]
1370    fn is_instance(&self, ty: &Bound<'py, PyAny>) -> PyResult<bool> {
1371        let result = unsafe { ffi::PyObject_IsInstance(self.as_ptr(), ty.as_ptr()) };
1372        err::error_on_minusone(self.py(), result)?;
1373        Ok(result == 1)
1374    }
1375
1376    #[inline]
1377    fn is_exact_instance(&self, ty: &Bound<'py, PyAny>) -> bool {
1378        self.get_type().is(ty)
1379    }
1380
1381    #[inline]
1382    fn is_instance_of<T: PyTypeCheck>(&self) -> bool {
1383        T::type_check(self)
1384    }
1385
1386    #[inline]
1387    fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool {
1388        T::is_exact_type_of(self)
1389    }
1390
1391    fn contains<V>(&self, value: V) -> PyResult<bool>
1392    where
1393        V: IntoPyObject<'py>,
1394    {
1395        fn inner(any: &Bound<'_, PyAny>, value: Borrowed<'_, '_, PyAny>) -> PyResult<bool> {
1396            match unsafe { ffi::PySequence_Contains(any.as_ptr(), value.as_ptr()) } {
1397                0 => Ok(false),
1398                1 => Ok(true),
1399                _ => Err(PyErr::fetch(any.py())),
1400            }
1401        }
1402
1403        let py = self.py();
1404        inner(
1405            self,
1406            value.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1407        )
1408    }
1409
1410    fn py_super(&self) -> PyResult<Bound<'py, PySuper>> {
1411        PySuper::new(&self.get_type(), self)
1412    }
1413}
1414
1415impl<'py> Bound<'py, PyAny> {
1416    /// Retrieve an attribute value, skipping the instance dictionary during the lookup but still
1417    /// binding the object to the instance.
1418    ///
1419    /// This is useful when trying to resolve Python's "magic" methods like `__getitem__`, which
1420    /// are looked up starting from the type object.  This returns an `Option` as it is not
1421    /// typically a direct error for the special lookup to fail, as magic methods are optional in
1422    /// many situations in which they might be called.
1423    ///
1424    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
1425    /// to intern `attr_name`.
1426    #[allow(dead_code, reason = "currently only used with num-complex + abi3")]
1427    pub(crate) fn lookup_special<N>(&self, attr_name: N) -> PyResult<Option<Bound<'py, PyAny>>>
1428    where
1429        N: IntoPyObject<'py, Target = PyString>,
1430    {
1431        let py = self.py();
1432        let self_type = self.get_type();
1433        let attr = if let Ok(attr) = self_type.getattr(attr_name) {
1434            attr
1435        } else {
1436            return Ok(None);
1437        };
1438
1439        // Manually resolve descriptor protocol. (Faster than going through Python.)
1440        if let Some(descr_get) = attr.get_type().get_slot(TP_DESCR_GET) {
1441            // attribute is a descriptor, resolve it
1442            unsafe {
1443                descr_get(attr.as_ptr(), self.as_ptr(), self_type.as_ptr())
1444                    .assume_owned_or_err(py)
1445                    .map(Some)
1446            }
1447        } else {
1448            Ok(Some(attr))
1449        }
1450    }
1451
1452    #[inline]
1453    pub(crate) fn _get_refcnt(&self) -> isize {
1454        unsafe { ffi::Py_REFCNT(self.as_ptr()) }
1455    }
1456}
1457
1458#[cfg(test)]
1459mod tests {
1460    use crate::platform::prelude::*;
1461    use crate::{
1462        basic::CompareOp,
1463        test_utils::generate_unique_module_name,
1464        types::{IntoPyDict, PyAny, PyAnyMethods, PyBool, PyInt, PyList, PyModule, PyTypeMethods},
1465        Bound, BoundObject, IntoPyObject, PyTypeInfo, Python,
1466    };
1467    use core::fmt::Debug;
1468    use pyo3_ffi::c_str;
1469
1470    #[test]
1471    fn test_lookup_special() {
1472        Python::attach(|py| {
1473            let module = PyModule::from_code(
1474                py,
1475                cr#"
1476class CustomCallable:
1477    def __call__(self):
1478        return 1
1479
1480class SimpleInt:
1481    def __int__(self):
1482        return 1
1483
1484class InheritedInt(SimpleInt): pass
1485
1486class NoInt: pass
1487
1488class NoDescriptorInt:
1489    __int__ = CustomCallable()
1490
1491class InstanceOverrideInt:
1492    def __int__(self):
1493        return 1
1494instance_override = InstanceOverrideInt()
1495instance_override.__int__ = lambda self: 2
1496
1497class ErrorInDescriptorInt:
1498    @property
1499    def __int__(self):
1500        raise ValueError("uh-oh!")
1501
1502class NonHeapNonDescriptorInt:
1503    # A static-typed callable that doesn't implement `__get__`.  These are pretty hard to come by.
1504    __int__ = int
1505                "#,
1506                c"test.py",
1507                &generate_unique_module_name("test"),
1508            )
1509            .unwrap();
1510
1511            let int = crate::intern!(py, "__int__");
1512            let eval_int =
1513                |obj: Bound<'_, PyAny>| obj.lookup_special(int)?.unwrap().call0()?.extract::<u32>();
1514
1515            let simple = module.getattr("SimpleInt").unwrap().call0().unwrap();
1516            assert_eq!(eval_int(simple).unwrap(), 1);
1517            let inherited = module.getattr("InheritedInt").unwrap().call0().unwrap();
1518            assert_eq!(eval_int(inherited).unwrap(), 1);
1519            let no_descriptor = module.getattr("NoDescriptorInt").unwrap().call0().unwrap();
1520            assert_eq!(eval_int(no_descriptor).unwrap(), 1);
1521            let missing = module.getattr("NoInt").unwrap().call0().unwrap();
1522            assert!(missing.lookup_special(int).unwrap().is_none());
1523            // Note the instance override should _not_ call the instance method that returns 2,
1524            // because that's not how special lookups are meant to work.
1525            let instance_override = module.getattr("instance_override").unwrap();
1526            assert_eq!(eval_int(instance_override).unwrap(), 1);
1527            let descriptor_error = module
1528                .getattr("ErrorInDescriptorInt")
1529                .unwrap()
1530                .call0()
1531                .unwrap();
1532            assert!(descriptor_error.lookup_special(int).is_err());
1533            let nonheap_nondescriptor = module
1534                .getattr("NonHeapNonDescriptorInt")
1535                .unwrap()
1536                .call0()
1537                .unwrap();
1538            assert_eq!(eval_int(nonheap_nondescriptor).unwrap(), 0);
1539        })
1540    }
1541
1542    #[test]
1543    fn test_getattr_opt() {
1544        Python::attach(|py| {
1545            let module = PyModule::from_code(
1546                py,
1547                cr#"
1548class Test:
1549    class_str_attribute = "class_string"
1550
1551    @property
1552    def error(self):
1553        raise ValueError("This is an intentional error")
1554                "#,
1555                c"test.py",
1556                &generate_unique_module_name("test"),
1557            )
1558            .unwrap();
1559
1560            // Get the class Test
1561            let class_test = module.getattr_opt("Test").unwrap().unwrap();
1562
1563            // Test attribute that exist
1564            let cls_attr_str = class_test
1565                .getattr_opt("class_str_attribute")
1566                .unwrap()
1567                .unwrap();
1568            assert_eq!(cls_attr_str.extract::<String>().unwrap(), "class_string");
1569
1570            // Test non-existent attribute
1571            let do_not_exist = class_test.getattr_opt("doNotExist").unwrap();
1572            assert!(do_not_exist.is_none());
1573
1574            // Test error attribute
1575            let instance = class_test.call0().unwrap();
1576            let error = instance.getattr_opt("error");
1577            assert!(error.is_err());
1578            assert!(error
1579                .unwrap_err()
1580                .to_string()
1581                .contains("This is an intentional error"));
1582        });
1583    }
1584
1585    #[test]
1586    fn test_getattr_opt_attribute_error_subclass() {
1587        Python::attach(|py| {
1588            let module = PyModule::from_code(
1589                py,
1590                cr#"
1591class CustomAttrError(AttributeError):
1592    pass
1593
1594class Obj:
1595    @property
1596    def missing(self):
1597        raise CustomAttrError("not here")
1598                "#,
1599                c"test.py",
1600                &generate_unique_module_name("test"),
1601            )
1602            .unwrap();
1603
1604            let obj = module.getattr("Obj").unwrap().call0().unwrap();
1605
1606            // An AttributeError subclass should be treated as "attribute not found"
1607            let result = obj.getattr_opt("missing").unwrap();
1608            assert!(result.is_none());
1609        });
1610    }
1611
1612    #[test]
1613    fn test_call_for_non_existing_method() {
1614        Python::attach(|py| {
1615            let a = py.eval(c"42", None, None).unwrap();
1616            a.call_method0("__str__").unwrap(); // ok
1617            assert!(a.call_method("nonexistent_method", (1,), None).is_err());
1618            assert!(a.call_method0("nonexistent_method").is_err());
1619            assert!(a.call_method1("nonexistent_method", (1,)).is_err());
1620        });
1621    }
1622
1623    #[test]
1624    fn test_call_with_kwargs() {
1625        Python::attach(|py| {
1626            let list = vec![3, 6, 5, 4, 7].into_pyobject(py).unwrap();
1627            let dict = vec![("reverse", true)].into_py_dict(py).unwrap();
1628            list.call_method("sort", (), Some(&dict)).unwrap();
1629            assert_eq!(list.extract::<Vec<i32>>().unwrap(), vec![7, 6, 5, 4, 3]);
1630        });
1631    }
1632
1633    #[test]
1634    fn test_call_method0() {
1635        Python::attach(|py| {
1636            let module = PyModule::from_code(
1637                py,
1638                cr#"
1639class SimpleClass:
1640    def foo(self):
1641        return 42
1642"#,
1643                c_str!(file!()),
1644                &generate_unique_module_name("test_module"),
1645            )
1646            .expect("module creation failed");
1647
1648            let simple_class = module.getattr("SimpleClass").unwrap().call0().unwrap();
1649            assert_eq!(
1650                simple_class
1651                    .call_method0("foo")
1652                    .unwrap()
1653                    .extract::<u32>()
1654                    .unwrap(),
1655                42
1656            );
1657        })
1658    }
1659
1660    #[test]
1661    fn test_type() {
1662        Python::attach(|py| {
1663            let obj = py.eval(c"42", None, None).unwrap();
1664            assert_eq!(obj.get_type().as_type_ptr(), obj.get_type_ptr());
1665        });
1666    }
1667
1668    #[test]
1669    fn test_dir() {
1670        Python::attach(|py| {
1671            let obj = py.eval(c"42", None, None).unwrap();
1672            let dir = py
1673                .eval(c"dir(42)", None, None)
1674                .unwrap()
1675                .cast_into::<PyList>()
1676                .unwrap();
1677            let a = obj
1678                .dir()
1679                .unwrap()
1680                .into_iter()
1681                .map(|x| x.extract::<String>().unwrap());
1682            let b = dir.into_iter().map(|x| x.extract::<String>().unwrap());
1683            assert!(a.eq(b));
1684        });
1685    }
1686
1687    #[test]
1688    fn test_hasattr() {
1689        Python::attach(|py| {
1690            let x = 5i32.into_pyobject(py).unwrap();
1691            assert!(x.is_instance_of::<PyInt>());
1692
1693            assert!(x.hasattr("to_bytes").unwrap());
1694            assert!(!x.hasattr("bbbbbbytes").unwrap());
1695        })
1696    }
1697
1698    #[cfg(feature = "macros")]
1699    #[test]
1700    #[allow(unknown_lints, non_local_definitions)]
1701    fn test_hasattr_error() {
1702        use crate::exceptions::PyValueError;
1703        use crate::prelude::*;
1704
1705        #[pyclass(crate = "crate")]
1706        struct GetattrFail;
1707
1708        #[pymethods(crate = "crate")]
1709        impl GetattrFail {
1710            fn __getattr__(&self, attr: Py<PyAny>) -> PyResult<Py<PyAny>> {
1711                Err(PyValueError::new_err(attr))
1712            }
1713        }
1714
1715        Python::attach(|py| {
1716            let obj = Py::new(py, GetattrFail).unwrap();
1717            let obj = obj.bind(py).as_any();
1718
1719            assert!(obj
1720                .hasattr("foo")
1721                .unwrap_err()
1722                .is_instance_of::<PyValueError>(py));
1723        })
1724    }
1725
1726    #[test]
1727    fn test_nan_eq() {
1728        Python::attach(|py| {
1729            let nan = py.eval(c"float('nan')", None, None).unwrap();
1730            assert!(nan.compare(&nan).is_err());
1731        });
1732    }
1733
1734    #[test]
1735    fn test_any_is_instance_of() {
1736        Python::attach(|py| {
1737            let x = 5i32.into_pyobject(py).unwrap();
1738            assert!(x.is_instance_of::<PyInt>());
1739
1740            let l = vec![&x, &x].into_pyobject(py).unwrap();
1741            assert!(l.is_instance_of::<PyList>());
1742        });
1743    }
1744
1745    #[test]
1746    fn test_any_is_instance() {
1747        Python::attach(|py| {
1748            let l = vec![1i8, 2].into_pyobject(py).unwrap();
1749            assert!(l.is_instance(&py.get_type::<PyList>()).unwrap());
1750        });
1751    }
1752
1753    #[test]
1754    fn test_any_is_exact_instance_of() {
1755        Python::attach(|py| {
1756            let x = 5i32.into_pyobject(py).unwrap();
1757            assert!(x.is_exact_instance_of::<PyInt>());
1758
1759            let t = PyBool::new(py, true);
1760            assert!(t.is_instance_of::<PyInt>());
1761            assert!(!t.is_exact_instance_of::<PyInt>());
1762            assert!(t.is_exact_instance_of::<PyBool>());
1763
1764            let l = vec![&x, &x].into_pyobject(py).unwrap();
1765            assert!(l.is_exact_instance_of::<PyList>());
1766        });
1767    }
1768
1769    #[test]
1770    fn test_any_is_exact_instance() {
1771        Python::attach(|py| {
1772            let t = PyBool::new(py, true);
1773            assert!(t.is_instance(&py.get_type::<PyInt>()).unwrap());
1774            assert!(!t.is_exact_instance(&py.get_type::<PyInt>()));
1775            assert!(t.is_exact_instance(&py.get_type::<PyBool>()));
1776        });
1777    }
1778
1779    #[test]
1780    fn test_any_contains() {
1781        Python::attach(|py| {
1782            let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
1783            let ob = v.into_pyobject(py).unwrap();
1784
1785            let bad_needle = 7i32.into_pyobject(py).unwrap();
1786            assert!(!ob.contains(&bad_needle).unwrap());
1787
1788            let good_needle = 8i32.into_pyobject(py).unwrap();
1789            assert!(ob.contains(&good_needle).unwrap());
1790
1791            let type_coerced_needle = 8f32.into_pyobject(py).unwrap();
1792            assert!(ob.contains(&type_coerced_needle).unwrap());
1793
1794            let n: u32 = 42;
1795            let bad_haystack = n.into_pyobject(py).unwrap();
1796            let irrelevant_needle = 0i32.into_pyobject(py).unwrap();
1797            assert!(bad_haystack.contains(&irrelevant_needle).is_err());
1798        });
1799    }
1800
1801    // This is intentionally not a test, it's a generic function used by the tests below.
1802    fn test_eq_methods_generic<'a, T>(list: &'a [T])
1803    where
1804        T: PartialEq + PartialOrd,
1805        for<'py> &'a T: IntoPyObject<'py>,
1806        for<'py> <&'a T as IntoPyObject<'py>>::Error: Debug,
1807    {
1808        Python::attach(|py| {
1809            for a in list {
1810                for b in list {
1811                    let a_py = a.into_pyobject(py).unwrap().into_any().into_bound();
1812                    let b_py = b.into_pyobject(py).unwrap().into_any().into_bound();
1813
1814                    assert_eq!(
1815                        a.lt(b),
1816                        a_py.lt(&b_py).unwrap(),
1817                        "{} < {} should be {}.",
1818                        a_py,
1819                        b_py,
1820                        a.lt(b)
1821                    );
1822                    assert_eq!(
1823                        a.le(b),
1824                        a_py.le(&b_py).unwrap(),
1825                        "{} <= {} should be {}.",
1826                        a_py,
1827                        b_py,
1828                        a.le(b)
1829                    );
1830                    assert_eq!(
1831                        a.eq(b),
1832                        a_py.eq(&b_py).unwrap(),
1833                        "{} == {} should be {}.",
1834                        a_py,
1835                        b_py,
1836                        a.eq(b)
1837                    );
1838                    assert_eq!(
1839                        a.ne(b),
1840                        a_py.ne(&b_py).unwrap(),
1841                        "{} != {} should be {}.",
1842                        a_py,
1843                        b_py,
1844                        a.ne(b)
1845                    );
1846                    assert_eq!(
1847                        a.gt(b),
1848                        a_py.gt(&b_py).unwrap(),
1849                        "{} > {} should be {}.",
1850                        a_py,
1851                        b_py,
1852                        a.gt(b)
1853                    );
1854                    assert_eq!(
1855                        a.ge(b),
1856                        a_py.ge(&b_py).unwrap(),
1857                        "{} >= {} should be {}.",
1858                        a_py,
1859                        b_py,
1860                        a.ge(b)
1861                    );
1862                }
1863            }
1864        });
1865    }
1866
1867    #[test]
1868    fn test_eq_methods_integers() {
1869        let ints = [-4, -4, 1, 2, 0, -100, 1_000_000];
1870        test_eq_methods_generic::<i32>(&ints);
1871    }
1872
1873    #[test]
1874    fn test_eq_methods_strings() {
1875        let strings = ["Let's", "test", "some", "eq", "methods"];
1876        test_eq_methods_generic::<&str>(&strings);
1877    }
1878
1879    #[test]
1880    fn test_eq_methods_floats() {
1881        let floats = [
1882            -1.0,
1883            2.5,
1884            0.0,
1885            3.0,
1886            core::f64::consts::PI,
1887            10.0,
1888            10.0 / 3.0,
1889            -1_000_000.0,
1890        ];
1891        test_eq_methods_generic::<f64>(&floats);
1892    }
1893
1894    #[test]
1895    fn test_eq_methods_bools() {
1896        let bools = [true, false];
1897        test_eq_methods_generic::<bool>(&bools);
1898    }
1899
1900    #[test]
1901    fn test_rich_compare_type_error() {
1902        Python::attach(|py| {
1903            let py_int = 1i32.into_pyobject(py).unwrap();
1904            let py_str = "1".into_pyobject(py).unwrap();
1905
1906            assert!(py_int.rich_compare(&py_str, CompareOp::Lt).is_err());
1907            assert!(!py_int
1908                .rich_compare(py_str, CompareOp::Eq)
1909                .unwrap()
1910                .is_truthy()
1911                .unwrap());
1912        })
1913    }
1914
1915    #[test]
1916    fn test_is_callable() {
1917        Python::attach(|py| {
1918            assert!(PyList::type_object(py).is_callable());
1919
1920            let not_callable = 5i32.into_pyobject(py).unwrap();
1921            assert!(!not_callable.is_callable());
1922        });
1923    }
1924
1925    #[test]
1926    fn test_is_empty() {
1927        Python::attach(|py| {
1928            let empty_list = PyList::empty(py).into_any();
1929            assert!(empty_list.is_empty().unwrap());
1930
1931            let list = PyList::new(py, vec![1, 2, 3]).unwrap().into_any();
1932            assert!(!list.is_empty().unwrap());
1933
1934            let not_container = 5i32.into_pyobject(py).unwrap();
1935            assert!(not_container.is_empty().is_err());
1936        });
1937    }
1938
1939    #[cfg(feature = "macros")]
1940    #[test]
1941    #[allow(unknown_lints, non_local_definitions)]
1942    fn test_fallible_dir() {
1943        use crate::exceptions::PyValueError;
1944        use crate::prelude::*;
1945
1946        #[pyclass(crate = "crate")]
1947        struct DirFail;
1948
1949        #[pymethods(crate = "crate")]
1950        impl DirFail {
1951            fn __dir__(&self) -> PyResult<Py<PyAny>> {
1952                Err(PyValueError::new_err("uh-oh!"))
1953            }
1954        }
1955
1956        Python::attach(|py| {
1957            let obj = Bound::new(py, DirFail).unwrap();
1958            assert!(obj.dir().unwrap_err().is_instance_of::<PyValueError>(py));
1959        })
1960    }
1961}
⚠️ Internal Docs ⚠️ Not Public API 👉 Official Docs Here