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