Skip to main content

pyo3/types/
any.rs

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