Skip to main content

pyo3/types/
any.rs

1use crate::call::PyCallArgs;
2use crate::class::basic::CompareOp;
3use crate::conversion::{FromPyObject, IntoPyObject};
4use crate::err::{error_on_minusone, PyErr, PyResult};
5use crate::exceptions::PyTypeError;
6use crate::ffi_ptr_ext::FfiPtrExt;
7use crate::impl_::pycell::PyStaticClassObject;
8use crate::instance::Bound;
9use crate::internal::get_slot::TP_DESCR_GET;
10use crate::py_result_ext::PyResultExt;
11use crate::type_object::{PyTypeCheck, PyTypeInfo};
12use crate::types::PySuper;
13use crate::types::{PyDict, PyIterator, PyList, PyString, PyType};
14use crate::{err, ffi, Borrowed, BoundObject, IntoPyObjectExt, Py};
15#[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    #[deprecated(
885        since = "0.29.0",
886        note = "use `pyo3::ffi::Py_REFCNT(obj.as_ptr())` instead"
887    )]
888    fn get_refcnt(&self) -> isize;
889
890    /// Computes the "repr" representation of self.
891    ///
892    /// This is equivalent to the Python expression `repr(self)`.
893    fn repr(&self) -> PyResult<Bound<'py, PyString>>;
894
895    /// Computes the "str" representation of self.
896    ///
897    /// This is equivalent to the Python expression `str(self)`.
898    fn str(&self) -> PyResult<Bound<'py, PyString>>;
899
900    /// Retrieves the hash code of self.
901    ///
902    /// This is equivalent to the Python expression `hash(self)`.
903    fn hash(&self) -> PyResult<isize>;
904
905    /// Returns the length of the sequence or mapping.
906    ///
907    /// This is equivalent to the Python expression `len(self)`.
908    fn len(&self) -> PyResult<usize>;
909
910    /// Returns the list of attributes of this object.
911    ///
912    /// This is equivalent to the Python expression `dir(self)`.
913    fn dir(&self) -> PyResult<Bound<'py, PyList>>;
914
915    /// Checks whether this object is an instance of type `ty`.
916    ///
917    /// This is equivalent to the Python expression `isinstance(self, ty)`.
918    fn is_instance(&self, ty: &Bound<'py, PyAny>) -> PyResult<bool>;
919
920    /// Checks whether this object is an instance of exactly type `ty` (not a subclass).
921    ///
922    /// This is equivalent to the Python expression `type(self) is ty`.
923    fn is_exact_instance(&self, ty: &Bound<'py, PyAny>) -> bool;
924
925    /// Checks whether this object is an instance of type `T`.
926    ///
927    /// This is equivalent to the Python expression `isinstance(self, T)`,
928    /// if the type `T` is known at compile time.
929    fn is_instance_of<T: PyTypeCheck>(&self) -> bool;
930
931    /// Checks whether this object is an instance of exactly type `T`.
932    ///
933    /// This is equivalent to the Python expression `type(self) is T`,
934    /// if the type `T` is known at compile time.
935    fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool;
936
937    /// Determines if self contains `value`.
938    ///
939    /// This is equivalent to the Python expression `value in self`.
940    fn contains<V>(&self, value: V) -> PyResult<bool>
941    where
942        V: IntoPyObject<'py>;
943
944    /// Return a proxy object that delegates method calls to a parent or sibling class of type.
945    ///
946    /// This is equivalent to the Python expression `super()`
947    fn py_super(&self) -> PyResult<Bound<'py, PySuper>>;
948}
949
950macro_rules! implement_binop {
951    ($name:ident, $c_api:ident, $op:expr) => {
952        #[doc = concat!("Computes `self ", $op, " other`.")]
953        fn $name<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
954        where
955            O: IntoPyObject<'py>,
956        {
957            fn inner<'py>(
958                any: &Bound<'py, PyAny>,
959                other: Borrowed<'_, 'py, PyAny>,
960            ) -> PyResult<Bound<'py, PyAny>> {
961                unsafe { ffi::$c_api(any.as_ptr(), other.as_ptr()).assume_owned_or_err(any.py()) }
962            }
963
964            let py = self.py();
965            inner(
966                self,
967                other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
968            )
969        }
970    };
971}
972
973impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
974    #[inline]
975    fn is<T: AsRef<Py<PyAny>>>(&self, other: T) -> bool {
976        ptr::eq(self.as_ptr(), other.as_ref().as_ptr())
977    }
978
979    fn hasattr<N>(&self, attr_name: N) -> PyResult<bool>
980    where
981        N: IntoPyObject<'py, Target = PyString>,
982    {
983        fn inner<'py>(
984            any: &Bound<'py, PyAny>,
985            attr_name: Borrowed<'_, '_, PyString>,
986        ) -> PyResult<bool> {
987            let result =
988                unsafe { ffi::compat::PyObject_HasAttrWithError(any.as_ptr(), attr_name.as_ptr()) };
989            error_on_minusone(any.py(), result)?;
990            Ok(result > 0)
991        }
992
993        inner(
994            self,
995            attr_name
996                .into_pyobject(self.py())
997                .map_err(Into::into)?
998                .as_borrowed(),
999        )
1000    }
1001
1002    fn getattr<N>(&self, attr_name: N) -> PyResult<Bound<'py, PyAny>>
1003    where
1004        N: IntoPyObject<'py, Target = PyString>,
1005    {
1006        fn inner<'py>(
1007            any: &Bound<'py, PyAny>,
1008            attr_name: Borrowed<'_, '_, PyString>,
1009        ) -> PyResult<Bound<'py, PyAny>> {
1010            unsafe {
1011                ffi::PyObject_GetAttr(any.as_ptr(), attr_name.as_ptr())
1012                    .assume_owned_or_err(any.py())
1013            }
1014        }
1015
1016        inner(
1017            self,
1018            attr_name
1019                .into_pyobject(self.py())
1020                .map_err(Into::into)?
1021                .as_borrowed(),
1022        )
1023    }
1024
1025    fn getattr_opt<N>(&self, attr_name: N) -> PyResult<Option<Bound<'py, PyAny>>>
1026    where
1027        N: IntoPyObject<'py, Target = PyString>,
1028    {
1029        fn inner<'py>(
1030            any: &Bound<'py, PyAny>,
1031            attr_name: Borrowed<'_, 'py, PyString>,
1032        ) -> PyResult<Option<Bound<'py, PyAny>>> {
1033            let mut resp_ptr: *mut ffi::PyObject = std::ptr::null_mut();
1034            match unsafe {
1035                ffi::compat::PyObject_GetOptionalAttr(
1036                    any.as_ptr(),
1037                    attr_name.as_ptr(),
1038                    &mut resp_ptr,
1039                )
1040            } {
1041                // Attribute found, result is a new strong reference
1042                1 => Ok(Some(unsafe { Bound::from_owned_ptr(any.py(), resp_ptr) })),
1043                // Attribute not found
1044                0 => Ok(None),
1045                // An error occurred (other than AttributeError)
1046                _ => Err(PyErr::fetch(any.py())),
1047            }
1048        }
1049
1050        let py = self.py();
1051        inner(self, attr_name.into_pyobject_or_pyerr(py)?.as_borrowed())
1052    }
1053
1054    fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
1055    where
1056        N: IntoPyObject<'py, Target = PyString>,
1057        V: IntoPyObject<'py>,
1058    {
1059        fn inner(
1060            any: &Bound<'_, PyAny>,
1061            attr_name: Borrowed<'_, '_, PyString>,
1062            value: Borrowed<'_, '_, PyAny>,
1063        ) -> PyResult<()> {
1064            err::error_on_minusone(any.py(), unsafe {
1065                ffi::PyObject_SetAttr(any.as_ptr(), attr_name.as_ptr(), value.as_ptr())
1066            })
1067        }
1068
1069        let py = self.py();
1070        inner(
1071            self,
1072            attr_name.into_pyobject_or_pyerr(py)?.as_borrowed(),
1073            value.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1074        )
1075    }
1076
1077    fn delattr<N>(&self, attr_name: N) -> PyResult<()>
1078    where
1079        N: IntoPyObject<'py, Target = PyString>,
1080    {
1081        fn inner(any: &Bound<'_, PyAny>, attr_name: Borrowed<'_, '_, PyString>) -> PyResult<()> {
1082            err::error_on_minusone(any.py(), unsafe {
1083                ffi::PyObject_DelAttr(any.as_ptr(), attr_name.as_ptr())
1084            })
1085        }
1086
1087        let py = self.py();
1088        inner(self, attr_name.into_pyobject_or_pyerr(py)?.as_borrowed())
1089    }
1090
1091    fn compare<O>(&self, other: O) -> PyResult<Ordering>
1092    where
1093        O: IntoPyObject<'py>,
1094    {
1095        fn inner(any: &Bound<'_, PyAny>, other: Borrowed<'_, '_, PyAny>) -> PyResult<Ordering> {
1096            let other = other.as_ptr();
1097            // Almost the same as ffi::PyObject_RichCompareBool, but this one doesn't try self == other.
1098            // See https://github.com/PyO3/pyo3/issues/985 for more.
1099            let do_compare = |other, op| unsafe {
1100                ffi::PyObject_RichCompare(any.as_ptr(), other, op)
1101                    .assume_owned_or_err(any.py())
1102                    .and_then(|obj| obj.is_truthy())
1103            };
1104            if do_compare(other, ffi::Py_EQ)? {
1105                Ok(Ordering::Equal)
1106            } else if do_compare(other, ffi::Py_LT)? {
1107                Ok(Ordering::Less)
1108            } else if do_compare(other, ffi::Py_GT)? {
1109                Ok(Ordering::Greater)
1110            } else {
1111                Err(PyTypeError::new_err(
1112                    "PyAny::compare(): All comparisons returned false",
1113                ))
1114            }
1115        }
1116
1117        let py = self.py();
1118        inner(
1119            self,
1120            other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1121        )
1122    }
1123
1124    fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<Bound<'py, PyAny>>
1125    where
1126        O: IntoPyObject<'py>,
1127    {
1128        fn inner<'py>(
1129            any: &Bound<'py, PyAny>,
1130            other: Borrowed<'_, 'py, PyAny>,
1131            compare_op: CompareOp,
1132        ) -> PyResult<Bound<'py, PyAny>> {
1133            unsafe {
1134                ffi::PyObject_RichCompare(any.as_ptr(), other.as_ptr(), compare_op as c_int)
1135                    .assume_owned_or_err(any.py())
1136            }
1137        }
1138
1139        let py = self.py();
1140        inner(
1141            self,
1142            other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1143            compare_op,
1144        )
1145    }
1146
1147    fn neg(&self) -> PyResult<Bound<'py, PyAny>> {
1148        unsafe { ffi::PyNumber_Negative(self.as_ptr()).assume_owned_or_err(self.py()) }
1149    }
1150
1151    fn pos(&self) -> PyResult<Bound<'py, PyAny>> {
1152        fn inner<'py>(any: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyAny>> {
1153            unsafe { ffi::PyNumber_Positive(any.as_ptr()).assume_owned_or_err(any.py()) }
1154        }
1155
1156        inner(self)
1157    }
1158
1159    fn abs(&self) -> PyResult<Bound<'py, PyAny>> {
1160        fn inner<'py>(any: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyAny>> {
1161            unsafe { ffi::PyNumber_Absolute(any.as_ptr()).assume_owned_or_err(any.py()) }
1162        }
1163
1164        inner(self)
1165    }
1166
1167    fn bitnot(&self) -> PyResult<Bound<'py, PyAny>> {
1168        fn inner<'py>(any: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyAny>> {
1169            unsafe { ffi::PyNumber_Invert(any.as_ptr()).assume_owned_or_err(any.py()) }
1170        }
1171
1172        inner(self)
1173    }
1174
1175    fn lt<O>(&self, other: O) -> PyResult<bool>
1176    where
1177        O: IntoPyObject<'py>,
1178    {
1179        self.rich_compare(other, CompareOp::Lt)
1180            .and_then(|any| any.is_truthy())
1181    }
1182
1183    fn le<O>(&self, other: O) -> PyResult<bool>
1184    where
1185        O: IntoPyObject<'py>,
1186    {
1187        self.rich_compare(other, CompareOp::Le)
1188            .and_then(|any| any.is_truthy())
1189    }
1190
1191    fn eq<O>(&self, other: O) -> PyResult<bool>
1192    where
1193        O: IntoPyObject<'py>,
1194    {
1195        self.rich_compare(other, CompareOp::Eq)
1196            .and_then(|any| any.is_truthy())
1197    }
1198
1199    fn ne<O>(&self, other: O) -> PyResult<bool>
1200    where
1201        O: IntoPyObject<'py>,
1202    {
1203        self.rich_compare(other, CompareOp::Ne)
1204            .and_then(|any| any.is_truthy())
1205    }
1206
1207    fn gt<O>(&self, other: O) -> PyResult<bool>
1208    where
1209        O: IntoPyObject<'py>,
1210    {
1211        self.rich_compare(other, CompareOp::Gt)
1212            .and_then(|any| any.is_truthy())
1213    }
1214
1215    fn ge<O>(&self, other: O) -> PyResult<bool>
1216    where
1217        O: IntoPyObject<'py>,
1218    {
1219        self.rich_compare(other, CompareOp::Ge)
1220            .and_then(|any| any.is_truthy())
1221    }
1222
1223    implement_binop!(add, PyNumber_Add, "+");
1224    implement_binop!(sub, PyNumber_Subtract, "-");
1225    implement_binop!(mul, PyNumber_Multiply, "*");
1226    implement_binop!(matmul, PyNumber_MatrixMultiply, "@");
1227    implement_binop!(div, PyNumber_TrueDivide, "/");
1228    implement_binop!(floor_div, PyNumber_FloorDivide, "//");
1229    implement_binop!(rem, PyNumber_Remainder, "%");
1230    implement_binop!(lshift, PyNumber_Lshift, "<<");
1231    implement_binop!(rshift, PyNumber_Rshift, ">>");
1232    implement_binop!(bitand, PyNumber_And, "&");
1233    implement_binop!(bitor, PyNumber_Or, "|");
1234    implement_binop!(bitxor, PyNumber_Xor, "^");
1235
1236    /// Computes `divmod(self, other)`.
1237    fn divmod<O>(&self, other: O) -> PyResult<Bound<'py, PyAny>>
1238    where
1239        O: IntoPyObject<'py>,
1240    {
1241        fn inner<'py>(
1242            any: &Bound<'py, PyAny>,
1243            other: Borrowed<'_, 'py, PyAny>,
1244        ) -> PyResult<Bound<'py, PyAny>> {
1245            unsafe {
1246                ffi::PyNumber_Divmod(any.as_ptr(), other.as_ptr()).assume_owned_or_err(any.py())
1247            }
1248        }
1249
1250        let py = self.py();
1251        inner(
1252            self,
1253            other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1254        )
1255    }
1256
1257    /// Computes `self ** other % modulus` (`pow(self, other, modulus)`).
1258    /// `py.None()` may be passed for the `modulus`.
1259    fn pow<O1, O2>(&self, other: O1, modulus: O2) -> PyResult<Bound<'py, PyAny>>
1260    where
1261        O1: IntoPyObject<'py>,
1262        O2: IntoPyObject<'py>,
1263    {
1264        fn inner<'py>(
1265            any: &Bound<'py, PyAny>,
1266            other: Borrowed<'_, 'py, PyAny>,
1267            modulus: Borrowed<'_, 'py, PyAny>,
1268        ) -> PyResult<Bound<'py, PyAny>> {
1269            unsafe {
1270                ffi::PyNumber_Power(any.as_ptr(), other.as_ptr(), modulus.as_ptr())
1271                    .assume_owned_or_err(any.py())
1272            }
1273        }
1274
1275        let py = self.py();
1276        inner(
1277            self,
1278            other.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1279            modulus.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1280        )
1281    }
1282
1283    fn is_callable(&self) -> bool {
1284        unsafe { ffi::PyCallable_Check(self.as_ptr()) != 0 }
1285    }
1286
1287    fn call<A>(&self, args: A, kwargs: Option<&Bound<'py, PyDict>>) -> PyResult<Bound<'py, PyAny>>
1288    where
1289        A: PyCallArgs<'py>,
1290    {
1291        if let Some(kwargs) = kwargs {
1292            args.call(
1293                self.as_borrowed(),
1294                kwargs.as_borrowed(),
1295                crate::call::private::Token,
1296            )
1297        } else {
1298            args.call_positional(self.as_borrowed(), crate::call::private::Token)
1299        }
1300    }
1301
1302    #[inline]
1303    fn call0(&self) -> PyResult<Bound<'py, PyAny>> {
1304        unsafe { ffi::compat::PyObject_CallNoArgs(self.as_ptr()).assume_owned_or_err(self.py()) }
1305    }
1306
1307    fn call1<A>(&self, args: A) -> PyResult<Bound<'py, PyAny>>
1308    where
1309        A: PyCallArgs<'py>,
1310    {
1311        args.call_positional(self.as_borrowed(), crate::call::private::Token)
1312    }
1313
1314    #[inline]
1315    fn call_method<N, A>(
1316        &self,
1317        name: N,
1318        args: A,
1319        kwargs: Option<&Bound<'py, PyDict>>,
1320    ) -> PyResult<Bound<'py, PyAny>>
1321    where
1322        N: IntoPyObject<'py, Target = PyString>,
1323        A: PyCallArgs<'py>,
1324    {
1325        if kwargs.is_none() {
1326            self.call_method1(name, args)
1327        } else {
1328            self.getattr(name)
1329                .and_then(|method| method.call(args, kwargs))
1330        }
1331    }
1332
1333    #[inline]
1334    fn call_method0<N>(&self, name: N) -> PyResult<Bound<'py, PyAny>>
1335    where
1336        N: IntoPyObject<'py, Target = PyString>,
1337    {
1338        let py = self.py();
1339        let name = name.into_pyobject_or_pyerr(py)?.into_bound();
1340        unsafe {
1341            ffi::compat::PyObject_CallMethodNoArgs(self.as_ptr(), name.as_ptr())
1342                .assume_owned_or_err(py)
1343        }
1344    }
1345
1346    fn call_method1<N, A>(&self, name: N, args: A) -> PyResult<Bound<'py, PyAny>>
1347    where
1348        N: IntoPyObject<'py, Target = PyString>,
1349        A: PyCallArgs<'py>,
1350    {
1351        let name = name.into_pyobject_or_pyerr(self.py())?;
1352        args.call_method_positional(
1353            self.as_borrowed(),
1354            name.as_borrowed(),
1355            crate::call::private::Token,
1356        )
1357    }
1358
1359    fn is_truthy(&self) -> PyResult<bool> {
1360        let v = unsafe { ffi::PyObject_IsTrue(self.as_ptr()) };
1361        err::error_on_minusone(self.py(), v)?;
1362        Ok(v != 0)
1363    }
1364
1365    #[inline]
1366    fn is_none(&self) -> bool {
1367        unsafe { ptr::eq(ffi::Py_None(), self.as_ptr()) }
1368    }
1369
1370    fn is_empty(&self) -> PyResult<bool> {
1371        self.len().map(|l| l == 0)
1372    }
1373
1374    fn get_item<K>(&self, key: K) -> PyResult<Bound<'py, PyAny>>
1375    where
1376        K: IntoPyObject<'py>,
1377    {
1378        fn inner<'py>(
1379            any: &Bound<'py, PyAny>,
1380            key: Borrowed<'_, 'py, PyAny>,
1381        ) -> PyResult<Bound<'py, PyAny>> {
1382            unsafe {
1383                ffi::PyObject_GetItem(any.as_ptr(), key.as_ptr()).assume_owned_or_err(any.py())
1384            }
1385        }
1386
1387        let py = self.py();
1388        inner(
1389            self,
1390            key.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1391        )
1392    }
1393
1394    fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
1395    where
1396        K: IntoPyObject<'py>,
1397        V: IntoPyObject<'py>,
1398    {
1399        fn inner(
1400            any: &Bound<'_, PyAny>,
1401            key: Borrowed<'_, '_, PyAny>,
1402            value: Borrowed<'_, '_, PyAny>,
1403        ) -> PyResult<()> {
1404            err::error_on_minusone(any.py(), unsafe {
1405                ffi::PyObject_SetItem(any.as_ptr(), key.as_ptr(), value.as_ptr())
1406            })
1407        }
1408
1409        let py = self.py();
1410        inner(
1411            self,
1412            key.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1413            value.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1414        )
1415    }
1416
1417    fn del_item<K>(&self, key: K) -> PyResult<()>
1418    where
1419        K: IntoPyObject<'py>,
1420    {
1421        fn inner(any: &Bound<'_, PyAny>, key: Borrowed<'_, '_, PyAny>) -> PyResult<()> {
1422            err::error_on_minusone(any.py(), unsafe {
1423                ffi::PyObject_DelItem(any.as_ptr(), key.as_ptr())
1424            })
1425        }
1426
1427        let py = self.py();
1428        inner(
1429            self,
1430            key.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1431        )
1432    }
1433
1434    fn try_iter(&self) -> PyResult<Bound<'py, PyIterator>> {
1435        PyIterator::from_object(self)
1436    }
1437
1438    fn get_type(&self) -> Bound<'py, PyType> {
1439        unsafe { PyType::from_borrowed_type_ptr(self.py(), ffi::Py_TYPE(self.as_ptr())) }
1440    }
1441
1442    #[inline]
1443    fn get_type_ptr(&self) -> *mut ffi::PyTypeObject {
1444        unsafe { ffi::Py_TYPE(self.as_ptr()) }
1445    }
1446
1447    #[inline]
1448    #[allow(deprecated)]
1449    fn downcast<T>(&self) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
1450    where
1451        T: PyTypeCheck,
1452    {
1453        if T::type_check(self) {
1454            // Safety: type_check is responsible for ensuring that the type is correct
1455            Ok(unsafe { self.cast_unchecked() })
1456        } else {
1457            #[allow(deprecated)]
1458            Err(DowncastError::new(self, T::NAME))
1459        }
1460    }
1461
1462    #[inline]
1463    #[allow(deprecated)]
1464    fn downcast_into<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
1465    where
1466        T: PyTypeCheck,
1467    {
1468        if T::type_check(&self) {
1469            // Safety: type_check is responsible for ensuring that the type is correct
1470            Ok(unsafe { self.cast_into_unchecked() })
1471        } else {
1472            #[allow(deprecated)]
1473            Err(DowncastIntoError::new(self, T::NAME))
1474        }
1475    }
1476
1477    #[inline]
1478    #[allow(deprecated)]
1479    fn downcast_exact<T>(&self) -> Result<&Bound<'py, T>, DowncastError<'_, 'py>>
1480    where
1481        T: PyTypeInfo,
1482    {
1483        if T::is_exact_type_of(self) {
1484            // Safety: is_exact_type_of is responsible for ensuring that the type is correct
1485            Ok(unsafe { self.cast_unchecked() })
1486        } else {
1487            #[allow(deprecated)]
1488            Err(DowncastError::new(self, T::NAME))
1489        }
1490    }
1491
1492    #[inline]
1493    #[allow(deprecated)]
1494    fn downcast_into_exact<T>(self) -> Result<Bound<'py, T>, DowncastIntoError<'py>>
1495    where
1496        T: PyTypeInfo,
1497    {
1498        if T::is_exact_type_of(&self) {
1499            // Safety: is_exact_type_of is responsible for ensuring that the type is correct
1500            Ok(unsafe { self.cast_into_unchecked() })
1501        } else {
1502            #[allow(deprecated)]
1503            Err(DowncastIntoError::new(self, T::NAME))
1504        }
1505    }
1506
1507    #[inline]
1508    unsafe fn downcast_unchecked<T>(&self) -> &Bound<'py, T> {
1509        unsafe { self.cast_unchecked() }
1510    }
1511
1512    #[inline]
1513    unsafe fn downcast_into_unchecked<T>(self) -> Bound<'py, T> {
1514        unsafe { self.cast_into_unchecked() }
1515    }
1516
1517    fn extract<'a, T>(&'a self) -> Result<T, T::Error>
1518    where
1519        T: FromPyObject<'a, 'py>,
1520    {
1521        FromPyObject::extract(self.as_borrowed())
1522    }
1523
1524    fn get_refcnt(&self) -> isize {
1525        self._get_refcnt()
1526    }
1527
1528    fn repr(&self) -> PyResult<Bound<'py, PyString>> {
1529        unsafe {
1530            ffi::PyObject_Repr(self.as_ptr())
1531                .assume_owned_or_err(self.py())
1532                .cast_into_unchecked()
1533        }
1534    }
1535
1536    fn str(&self) -> PyResult<Bound<'py, PyString>> {
1537        unsafe {
1538            ffi::PyObject_Str(self.as_ptr())
1539                .assume_owned_or_err(self.py())
1540                .cast_into_unchecked()
1541        }
1542    }
1543
1544    fn hash(&self) -> PyResult<isize> {
1545        let v = unsafe { ffi::PyObject_Hash(self.as_ptr()) };
1546        crate::err::error_on_minusone(self.py(), v)?;
1547        Ok(v)
1548    }
1549
1550    fn len(&self) -> PyResult<usize> {
1551        let v = unsafe { ffi::PyObject_Size(self.as_ptr()) };
1552        crate::err::error_on_minusone(self.py(), v)?;
1553        Ok(v as usize)
1554    }
1555
1556    fn dir(&self) -> PyResult<Bound<'py, PyList>> {
1557        unsafe {
1558            ffi::PyObject_Dir(self.as_ptr())
1559                .assume_owned_or_err(self.py())
1560                .cast_into_unchecked()
1561        }
1562    }
1563
1564    #[inline]
1565    fn is_instance(&self, ty: &Bound<'py, PyAny>) -> PyResult<bool> {
1566        let result = unsafe { ffi::PyObject_IsInstance(self.as_ptr(), ty.as_ptr()) };
1567        err::error_on_minusone(self.py(), result)?;
1568        Ok(result == 1)
1569    }
1570
1571    #[inline]
1572    fn is_exact_instance(&self, ty: &Bound<'py, PyAny>) -> bool {
1573        self.get_type().is(ty)
1574    }
1575
1576    #[inline]
1577    fn is_instance_of<T: PyTypeCheck>(&self) -> bool {
1578        T::type_check(self)
1579    }
1580
1581    #[inline]
1582    fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool {
1583        T::is_exact_type_of(self)
1584    }
1585
1586    fn contains<V>(&self, value: V) -> PyResult<bool>
1587    where
1588        V: IntoPyObject<'py>,
1589    {
1590        fn inner(any: &Bound<'_, PyAny>, value: Borrowed<'_, '_, PyAny>) -> PyResult<bool> {
1591            match unsafe { ffi::PySequence_Contains(any.as_ptr(), value.as_ptr()) } {
1592                0 => Ok(false),
1593                1 => Ok(true),
1594                _ => Err(PyErr::fetch(any.py())),
1595            }
1596        }
1597
1598        let py = self.py();
1599        inner(
1600            self,
1601            value.into_pyobject_or_pyerr(py)?.into_any().as_borrowed(),
1602        )
1603    }
1604
1605    fn py_super(&self) -> PyResult<Bound<'py, PySuper>> {
1606        PySuper::new(&self.get_type(), self)
1607    }
1608}
1609
1610impl<'py> Bound<'py, PyAny> {
1611    /// Retrieve an attribute value, skipping the instance dictionary during the lookup but still
1612    /// binding the object to the instance.
1613    ///
1614    /// This is useful when trying to resolve Python's "magic" methods like `__getitem__`, which
1615    /// are looked up starting from the type object.  This returns an `Option` as it is not
1616    /// typically a direct error for the special lookup to fail, as magic methods are optional in
1617    /// many situations in which they might be called.
1618    ///
1619    /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
1620    /// to intern `attr_name`.
1621    #[allow(dead_code, reason = "currently only used with num-complex + abi3")]
1622    pub(crate) fn lookup_special<N>(&self, attr_name: N) -> PyResult<Option<Bound<'py, PyAny>>>
1623    where
1624        N: IntoPyObject<'py, Target = PyString>,
1625    {
1626        let py = self.py();
1627        let self_type = self.get_type();
1628        let attr = if let Ok(attr) = self_type.getattr(attr_name) {
1629            attr
1630        } else {
1631            return Ok(None);
1632        };
1633
1634        // Manually resolve descriptor protocol. (Faster than going through Python.)
1635        if let Some(descr_get) = attr.get_type().get_slot(TP_DESCR_GET) {
1636            // attribute is a descriptor, resolve it
1637            unsafe {
1638                descr_get(attr.as_ptr(), self.as_ptr(), self_type.as_ptr())
1639                    .assume_owned_or_err(py)
1640                    .map(Some)
1641            }
1642        } else {
1643            Ok(Some(attr))
1644        }
1645    }
1646
1647    #[inline]
1648    pub(crate) fn _get_refcnt(&self) -> isize {
1649        unsafe { ffi::Py_REFCNT(self.as_ptr()) }
1650    }
1651}
1652
1653#[cfg(test)]
1654mod tests {
1655    use crate::{
1656        basic::CompareOp,
1657        test_utils::generate_unique_module_name,
1658        types::{IntoPyDict, PyAny, PyAnyMethods, PyBool, PyInt, PyList, PyModule, PyTypeMethods},
1659        Bound, BoundObject, IntoPyObject, PyTypeInfo, Python,
1660    };
1661    use pyo3_ffi::c_str;
1662    use std::fmt::Debug;
1663
1664    #[test]
1665    fn test_lookup_special() {
1666        Python::attach(|py| {
1667            let module = PyModule::from_code(
1668                py,
1669                cr#"
1670class CustomCallable:
1671    def __call__(self):
1672        return 1
1673
1674class SimpleInt:
1675    def __int__(self):
1676        return 1
1677
1678class InheritedInt(SimpleInt): pass
1679
1680class NoInt: pass
1681
1682class NoDescriptorInt:
1683    __int__ = CustomCallable()
1684
1685class InstanceOverrideInt:
1686    def __int__(self):
1687        return 1
1688instance_override = InstanceOverrideInt()
1689instance_override.__int__ = lambda self: 2
1690
1691class ErrorInDescriptorInt:
1692    @property
1693    def __int__(self):
1694        raise ValueError("uh-oh!")
1695
1696class NonHeapNonDescriptorInt:
1697    # A static-typed callable that doesn't implement `__get__`.  These are pretty hard to come by.
1698    __int__ = int
1699                "#,
1700                c"test.py",
1701                &generate_unique_module_name("test"),
1702            )
1703            .unwrap();
1704
1705            let int = crate::intern!(py, "__int__");
1706            let eval_int =
1707                |obj: Bound<'_, PyAny>| obj.lookup_special(int)?.unwrap().call0()?.extract::<u32>();
1708
1709            let simple = module.getattr("SimpleInt").unwrap().call0().unwrap();
1710            assert_eq!(eval_int(simple).unwrap(), 1);
1711            let inherited = module.getattr("InheritedInt").unwrap().call0().unwrap();
1712            assert_eq!(eval_int(inherited).unwrap(), 1);
1713            let no_descriptor = module.getattr("NoDescriptorInt").unwrap().call0().unwrap();
1714            assert_eq!(eval_int(no_descriptor).unwrap(), 1);
1715            let missing = module.getattr("NoInt").unwrap().call0().unwrap();
1716            assert!(missing.lookup_special(int).unwrap().is_none());
1717            // Note the instance override should _not_ call the instance method that returns 2,
1718            // because that's not how special lookups are meant to work.
1719            let instance_override = module.getattr("instance_override").unwrap();
1720            assert_eq!(eval_int(instance_override).unwrap(), 1);
1721            let descriptor_error = module
1722                .getattr("ErrorInDescriptorInt")
1723                .unwrap()
1724                .call0()
1725                .unwrap();
1726            assert!(descriptor_error.lookup_special(int).is_err());
1727            let nonheap_nondescriptor = module
1728                .getattr("NonHeapNonDescriptorInt")
1729                .unwrap()
1730                .call0()
1731                .unwrap();
1732            assert_eq!(eval_int(nonheap_nondescriptor).unwrap(), 0);
1733        })
1734    }
1735
1736    #[test]
1737    fn test_getattr_opt() {
1738        Python::attach(|py| {
1739            let module = PyModule::from_code(
1740                py,
1741                cr#"
1742class Test:
1743    class_str_attribute = "class_string"
1744
1745    @property
1746    def error(self):
1747        raise ValueError("This is an intentional error")
1748                "#,
1749                c"test.py",
1750                &generate_unique_module_name("test"),
1751            )
1752            .unwrap();
1753
1754            // Get the class Test
1755            let class_test = module.getattr_opt("Test").unwrap().unwrap();
1756
1757            // Test attribute that exist
1758            let cls_attr_str = class_test
1759                .getattr_opt("class_str_attribute")
1760                .unwrap()
1761                .unwrap();
1762            assert_eq!(cls_attr_str.extract::<String>().unwrap(), "class_string");
1763
1764            // Test non-existent attribute
1765            let do_not_exist = class_test.getattr_opt("doNotExist").unwrap();
1766            assert!(do_not_exist.is_none());
1767
1768            // Test error attribute
1769            let instance = class_test.call0().unwrap();
1770            let error = instance.getattr_opt("error");
1771            assert!(error.is_err());
1772            assert!(error
1773                .unwrap_err()
1774                .to_string()
1775                .contains("This is an intentional error"));
1776        });
1777    }
1778
1779    #[test]
1780    fn test_getattr_opt_attribute_error_subclass() {
1781        Python::attach(|py| {
1782            let module = PyModule::from_code(
1783                py,
1784                cr#"
1785class CustomAttrError(AttributeError):
1786    pass
1787
1788class Obj:
1789    @property
1790    def missing(self):
1791        raise CustomAttrError("not here")
1792                "#,
1793                c"test.py",
1794                &generate_unique_module_name("test"),
1795            )
1796            .unwrap();
1797
1798            let obj = module.getattr("Obj").unwrap().call0().unwrap();
1799
1800            // An AttributeError subclass should be treated as "attribute not found"
1801            let result = obj.getattr_opt("missing").unwrap();
1802            assert!(result.is_none());
1803        });
1804    }
1805
1806    #[test]
1807    fn test_call_for_non_existing_method() {
1808        Python::attach(|py| {
1809            let a = py.eval(c"42", None, None).unwrap();
1810            a.call_method0("__str__").unwrap(); // ok
1811            assert!(a.call_method("nonexistent_method", (1,), None).is_err());
1812            assert!(a.call_method0("nonexistent_method").is_err());
1813            assert!(a.call_method1("nonexistent_method", (1,)).is_err());
1814        });
1815    }
1816
1817    #[test]
1818    fn test_call_with_kwargs() {
1819        Python::attach(|py| {
1820            let list = vec![3, 6, 5, 4, 7].into_pyobject(py).unwrap();
1821            let dict = vec![("reverse", true)].into_py_dict(py).unwrap();
1822            list.call_method("sort", (), Some(&dict)).unwrap();
1823            assert_eq!(list.extract::<Vec<i32>>().unwrap(), vec![7, 6, 5, 4, 3]);
1824        });
1825    }
1826
1827    #[test]
1828    fn test_call_method0() {
1829        Python::attach(|py| {
1830            let module = PyModule::from_code(
1831                py,
1832                cr#"
1833class SimpleClass:
1834    def foo(self):
1835        return 42
1836"#,
1837                c_str!(file!()),
1838                &generate_unique_module_name("test_module"),
1839            )
1840            .expect("module creation failed");
1841
1842            let simple_class = module.getattr("SimpleClass").unwrap().call0().unwrap();
1843            assert_eq!(
1844                simple_class
1845                    .call_method0("foo")
1846                    .unwrap()
1847                    .extract::<u32>()
1848                    .unwrap(),
1849                42
1850            );
1851        })
1852    }
1853
1854    #[test]
1855    fn test_type() {
1856        Python::attach(|py| {
1857            let obj = py.eval(c"42", None, None).unwrap();
1858            assert_eq!(obj.get_type().as_type_ptr(), obj.get_type_ptr());
1859        });
1860    }
1861
1862    #[test]
1863    fn test_dir() {
1864        Python::attach(|py| {
1865            let obj = py.eval(c"42", None, None).unwrap();
1866            let dir = py
1867                .eval(c"dir(42)", None, None)
1868                .unwrap()
1869                .cast_into::<PyList>()
1870                .unwrap();
1871            let a = obj
1872                .dir()
1873                .unwrap()
1874                .into_iter()
1875                .map(|x| x.extract::<String>().unwrap());
1876            let b = dir.into_iter().map(|x| x.extract::<String>().unwrap());
1877            assert!(a.eq(b));
1878        });
1879    }
1880
1881    #[test]
1882    fn test_hasattr() {
1883        Python::attach(|py| {
1884            let x = 5i32.into_pyobject(py).unwrap();
1885            assert!(x.is_instance_of::<PyInt>());
1886
1887            assert!(x.hasattr("to_bytes").unwrap());
1888            assert!(!x.hasattr("bbbbbbytes").unwrap());
1889        })
1890    }
1891
1892    #[cfg(feature = "macros")]
1893    #[test]
1894    #[allow(unknown_lints, non_local_definitions)]
1895    fn test_hasattr_error() {
1896        use crate::exceptions::PyValueError;
1897        use crate::prelude::*;
1898
1899        #[pyclass(crate = "crate")]
1900        struct GetattrFail;
1901
1902        #[pymethods(crate = "crate")]
1903        impl GetattrFail {
1904            fn __getattr__(&self, attr: Py<PyAny>) -> PyResult<Py<PyAny>> {
1905                Err(PyValueError::new_err(attr))
1906            }
1907        }
1908
1909        Python::attach(|py| {
1910            let obj = Py::new(py, GetattrFail).unwrap();
1911            let obj = obj.bind(py).as_any();
1912
1913            assert!(obj
1914                .hasattr("foo")
1915                .unwrap_err()
1916                .is_instance_of::<PyValueError>(py));
1917        })
1918    }
1919
1920    #[test]
1921    fn test_nan_eq() {
1922        Python::attach(|py| {
1923            let nan = py.eval(c"float('nan')", None, None).unwrap();
1924            assert!(nan.compare(&nan).is_err());
1925        });
1926    }
1927
1928    #[test]
1929    fn test_any_is_instance_of() {
1930        Python::attach(|py| {
1931            let x = 5i32.into_pyobject(py).unwrap();
1932            assert!(x.is_instance_of::<PyInt>());
1933
1934            let l = vec![&x, &x].into_pyobject(py).unwrap();
1935            assert!(l.is_instance_of::<PyList>());
1936        });
1937    }
1938
1939    #[test]
1940    fn test_any_is_instance() {
1941        Python::attach(|py| {
1942            let l = vec![1i8, 2].into_pyobject(py).unwrap();
1943            assert!(l.is_instance(&py.get_type::<PyList>()).unwrap());
1944        });
1945    }
1946
1947    #[test]
1948    fn test_any_is_exact_instance_of() {
1949        Python::attach(|py| {
1950            let x = 5i32.into_pyobject(py).unwrap();
1951            assert!(x.is_exact_instance_of::<PyInt>());
1952
1953            let t = PyBool::new(py, true);
1954            assert!(t.is_instance_of::<PyInt>());
1955            assert!(!t.is_exact_instance_of::<PyInt>());
1956            assert!(t.is_exact_instance_of::<PyBool>());
1957
1958            let l = vec![&x, &x].into_pyobject(py).unwrap();
1959            assert!(l.is_exact_instance_of::<PyList>());
1960        });
1961    }
1962
1963    #[test]
1964    fn test_any_is_exact_instance() {
1965        Python::attach(|py| {
1966            let t = PyBool::new(py, true);
1967            assert!(t.is_instance(&py.get_type::<PyInt>()).unwrap());
1968            assert!(!t.is_exact_instance(&py.get_type::<PyInt>()));
1969            assert!(t.is_exact_instance(&py.get_type::<PyBool>()));
1970        });
1971    }
1972
1973    #[test]
1974    fn test_any_contains() {
1975        Python::attach(|py| {
1976            let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
1977            let ob = v.into_pyobject(py).unwrap();
1978
1979            let bad_needle = 7i32.into_pyobject(py).unwrap();
1980            assert!(!ob.contains(&bad_needle).unwrap());
1981
1982            let good_needle = 8i32.into_pyobject(py).unwrap();
1983            assert!(ob.contains(&good_needle).unwrap());
1984
1985            let type_coerced_needle = 8f32.into_pyobject(py).unwrap();
1986            assert!(ob.contains(&type_coerced_needle).unwrap());
1987
1988            let n: u32 = 42;
1989            let bad_haystack = n.into_pyobject(py).unwrap();
1990            let irrelevant_needle = 0i32.into_pyobject(py).unwrap();
1991            assert!(bad_haystack.contains(&irrelevant_needle).is_err());
1992        });
1993    }
1994
1995    // This is intentionally not a test, it's a generic function used by the tests below.
1996    fn test_eq_methods_generic<'a, T>(list: &'a [T])
1997    where
1998        T: PartialEq + PartialOrd,
1999        for<'py> &'a T: IntoPyObject<'py>,
2000        for<'py> <&'a T as IntoPyObject<'py>>::Error: Debug,
2001    {
2002        Python::attach(|py| {
2003            for a in list {
2004                for b in list {
2005                    let a_py = a.into_pyobject(py).unwrap().into_any().into_bound();
2006                    let b_py = b.into_pyobject(py).unwrap().into_any().into_bound();
2007
2008                    assert_eq!(
2009                        a.lt(b),
2010                        a_py.lt(&b_py).unwrap(),
2011                        "{} < {} should be {}.",
2012                        a_py,
2013                        b_py,
2014                        a.lt(b)
2015                    );
2016                    assert_eq!(
2017                        a.le(b),
2018                        a_py.le(&b_py).unwrap(),
2019                        "{} <= {} should be {}.",
2020                        a_py,
2021                        b_py,
2022                        a.le(b)
2023                    );
2024                    assert_eq!(
2025                        a.eq(b),
2026                        a_py.eq(&b_py).unwrap(),
2027                        "{} == {} should be {}.",
2028                        a_py,
2029                        b_py,
2030                        a.eq(b)
2031                    );
2032                    assert_eq!(
2033                        a.ne(b),
2034                        a_py.ne(&b_py).unwrap(),
2035                        "{} != {} should be {}.",
2036                        a_py,
2037                        b_py,
2038                        a.ne(b)
2039                    );
2040                    assert_eq!(
2041                        a.gt(b),
2042                        a_py.gt(&b_py).unwrap(),
2043                        "{} > {} should be {}.",
2044                        a_py,
2045                        b_py,
2046                        a.gt(b)
2047                    );
2048                    assert_eq!(
2049                        a.ge(b),
2050                        a_py.ge(&b_py).unwrap(),
2051                        "{} >= {} should be {}.",
2052                        a_py,
2053                        b_py,
2054                        a.ge(b)
2055                    );
2056                }
2057            }
2058        });
2059    }
2060
2061    #[test]
2062    fn test_eq_methods_integers() {
2063        let ints = [-4, -4, 1, 2, 0, -100, 1_000_000];
2064        test_eq_methods_generic::<i32>(&ints);
2065    }
2066
2067    #[test]
2068    fn test_eq_methods_strings() {
2069        let strings = ["Let's", "test", "some", "eq", "methods"];
2070        test_eq_methods_generic::<&str>(&strings);
2071    }
2072
2073    #[test]
2074    fn test_eq_methods_floats() {
2075        let floats = [
2076            -1.0,
2077            2.5,
2078            0.0,
2079            3.0,
2080            std::f64::consts::PI,
2081            10.0,
2082            10.0 / 3.0,
2083            -1_000_000.0,
2084        ];
2085        test_eq_methods_generic::<f64>(&floats);
2086    }
2087
2088    #[test]
2089    fn test_eq_methods_bools() {
2090        let bools = [true, false];
2091        test_eq_methods_generic::<bool>(&bools);
2092    }
2093
2094    #[test]
2095    fn test_rich_compare_type_error() {
2096        Python::attach(|py| {
2097            let py_int = 1i32.into_pyobject(py).unwrap();
2098            let py_str = "1".into_pyobject(py).unwrap();
2099
2100            assert!(py_int.rich_compare(&py_str, CompareOp::Lt).is_err());
2101            assert!(!py_int
2102                .rich_compare(py_str, CompareOp::Eq)
2103                .unwrap()
2104                .is_truthy()
2105                .unwrap());
2106        })
2107    }
2108
2109    #[test]
2110    fn test_is_callable() {
2111        Python::attach(|py| {
2112            assert!(PyList::type_object(py).is_callable());
2113
2114            let not_callable = 5i32.into_pyobject(py).unwrap();
2115            assert!(!not_callable.is_callable());
2116        });
2117    }
2118
2119    #[test]
2120    fn test_is_empty() {
2121        Python::attach(|py| {
2122            let empty_list = PyList::empty(py).into_any();
2123            assert!(empty_list.is_empty().unwrap());
2124
2125            let list = PyList::new(py, vec![1, 2, 3]).unwrap().into_any();
2126            assert!(!list.is_empty().unwrap());
2127
2128            let not_container = 5i32.into_pyobject(py).unwrap();
2129            assert!(not_container.is_empty().is_err());
2130        });
2131    }
2132
2133    #[cfg(feature = "macros")]
2134    #[test]
2135    #[allow(unknown_lints, non_local_definitions)]
2136    fn test_fallible_dir() {
2137        use crate::exceptions::PyValueError;
2138        use crate::prelude::*;
2139
2140        #[pyclass(crate = "crate")]
2141        struct DirFail;
2142
2143        #[pymethods(crate = "crate")]
2144        impl DirFail {
2145            fn __dir__(&self) -> PyResult<Py<PyAny>> {
2146                Err(PyValueError::new_err("uh-oh!"))
2147            }
2148        }
2149
2150        Python::attach(|py| {
2151            let obj = Bound::new(py, DirFail).unwrap();
2152            assert!(obj.dir().unwrap_err().is_instance_of::<PyValueError>(py));
2153        })
2154    }
2155}
⚠️ Internal Docs ⚠️ Not Public API 👉 Official Docs Here