pyo3/types/
any.rs

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