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