Skip to main content

pyo3/types/
any.rs

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