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