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