pyo3/types/
any.rs

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