[go: up one dir, main page]

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