1use crate::class::basic::CompareOp;
2use crate::conversion::{AsPyPointer, FromPyObject, IntoPy, PyTryFrom, ToPyObject};
3use crate::err::{PyDowncastError, PyErr, PyResult};
4use crate::exceptions::{PyAttributeError, PyTypeError};
5use crate::type_object::PyTypeInfo;
6#[cfg(not(PyPy))]
7use crate::types::PySuper;
8use crate::types::{PyDict, PyIterator, PyList, PyString, PyTuple, PyType};
9use crate::{err, ffi, Py, PyNativeType, PyObject, Python};
10use std::cell::UnsafeCell;
11use std::cmp::Ordering;
12use std::os::raw::c_int;
13
14/// Represents any Python object.
15///
16/// It currently only appears as a *reference*, `&PyAny`,
17/// with a lifetime that represents the scope during which the GIL is held.
18///
19/// `PyAny` has some interesting properties, which it shares
20/// with the other [native Python types](crate::types):
21///
22/// - It can only be obtained and used while the GIL is held,
23/// therefore its API does not require a [`Python<'py>`](crate::Python) token.
24/// - It can't be used in situations where the GIL is temporarily released,
25/// such as [`Python::allow_threads`](crate::Python::allow_threads)'s closure.
26/// - The underlying Python object, if mutable, can be mutated through any reference.
27/// - It can be converted to the GIL-independent [`Py`]`<`[`PyAny`]`>`,
28/// allowing it to outlive the GIL scope. However, using [`Py`]`<`[`PyAny`]`>`'s API
29/// *does* require a [`Python<'py>`](crate::Python) token.
30///
31/// It can be cast to a concrete type with PyAny::downcast (for native Python types only)
32/// and FromPyObject::extract. See their documentation for more information.
33///
34/// See [the guide](https://pyo3.rs/latest/types.html) for an explanation
35/// of the different Python object types.
36#[repr(transparent)]
37pub struct PyAny(UnsafeCell<ffi::PyObject>);
38
39unsafe impl AsPyPointer for PyAny {
40 #[inline]
41 fn as_ptr(&self) -> *mut ffi::PyObject {
42 self.0.get()
43 }
44}
45
46#[allow(non_snake_case)]
47// Copied here as the macro does not accept deprecated functions.
48// Originally ffi::object::PyObject_Check, but this is not in the Python C API.
49fn PyObject_Check(_: *mut ffi::PyObject) -> c_int {
50 1
51}
52
53pyobject_native_type_base!(PyAny);
54
55pyobject_native_type_info!(
56 PyAny,
57 pyobject_native_static_type_object!(ffi::PyBaseObject_Type),
58 Some("builtins"),
59 #checkfunction=PyObject_Check
60);
61
62pyobject_native_type_extract!(PyAny);
63
64pyobject_native_type_sized!(PyAny, ffi::PyObject);
65
66impl PyAny {
67 /// Returns whether `self` and `other` point to the same object. To compare
68 /// the equality of two objects (the `==` operator), use [`eq`](PyAny::eq).
69 ///
70 /// This is equivalent to the Python expression `self is other`.
71 #[inline]
72 pub fn is<T: AsPyPointer>(&self, other: &T) -> bool {
73 self.as_ptr() == other.as_ptr()
74 }
75
76 /// Determines whether this object has the given attribute.
77 ///
78 /// This is equivalent to the Python expression `hasattr(self, attr_name)`.
79 ///
80 /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
81 /// to intern `attr_name`.
82 ///
83 /// # Example: `intern!`ing the attribute name
84 ///
85 /// ```
86 /// # use pyo3::{intern, pyfunction, types::PyModule, Python, PyResult};
87 /// #
88 /// #[pyfunction]
89 /// fn has_version(sys: &PyModule) -> PyResult<bool> {
90 /// sys.hasattr(intern!(sys.py(), "version"))
91 /// }
92 /// #
93 /// # Python::with_gil(|py| {
94 /// # let sys = py.import("sys").unwrap();
95 /// # has_version(sys).unwrap();
96 /// # });
97 /// ```
98 pub fn hasattr<N>(&self, attr_name: N) -> PyResult<bool>
99 where
100 N: IntoPy<Py<PyString>>,
101 {
102 fn inner(any: &PyAny, attr_name: Py<PyString>) -> PyResult<bool> {
103 // PyObject_HasAttr suppresses all exceptions, which was the behaviour of `hasattr` in Python 2.
104 // Use an implementation which suppresses only AttributeError, which is consistent with `hasattr` in Python 3.
105 match any._getattr(attr_name) {
106 Ok(_) => Ok(true),
107 Err(err) if err.is_instance_of::<PyAttributeError>(any.py()) => Ok(false),
108 Err(e) => Err(e),
109 }
110 }
111
112 inner(self, attr_name.into_py(self.py()))
113 }
114
115 /// Retrieves an attribute value.
116 ///
117 /// This is equivalent to the Python expression `self.attr_name`.
118 ///
119 /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
120 /// to intern `attr_name`.
121 ///
122 /// # Example: `intern!`ing the attribute name
123 ///
124 /// ```
125 /// # use pyo3::{intern, pyfunction, types::PyModule, PyAny, Python, PyResult};
126 /// #
127 /// #[pyfunction]
128 /// fn version(sys: &PyModule) -> PyResult<&PyAny> {
129 /// sys.getattr(intern!(sys.py(), "version"))
130 /// }
131 /// #
132 /// # Python::with_gil(|py| {
133 /// # let sys = py.import("sys").unwrap();
134 /// # version(sys).unwrap();
135 /// # });
136 /// ```
137 pub fn getattr<N>(&self, attr_name: N) -> PyResult<&PyAny>
138 where
139 N: IntoPy<Py<PyString>>,
140 {
141 fn inner(any: &PyAny, attr_name: Py<PyString>) -> PyResult<&PyAny> {
142 any._getattr(attr_name)
143 .map(|object| object.into_ref(any.py()))
144 }
145
146 inner(self, attr_name.into_py(self.py()))
147 }
148
149 fn _getattr(&self, attr_name: Py<PyString>) -> PyResult<PyObject> {
150 unsafe {
151 Py::from_owned_ptr_or_err(
152 self.py(),
153 ffi::PyObject_GetAttr(self.as_ptr(), attr_name.as_ptr()),
154 )
155 }
156 }
157
158 /// Retrieve an attribute value, skipping the instance dictionary during the lookup but still
159 /// binding the object to the instance.
160 ///
161 /// This is useful when trying to resolve Python's "magic" methods like `__getitem__`, which
162 /// are looked up starting from the type object. This returns an `Option` as it is not
163 /// typically a direct error for the special lookup to fail, as magic methods are optional in
164 /// many situations in which they might be called.
165 ///
166 /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
167 /// to intern `attr_name`.
168 #[allow(dead_code)] // Currently only used with num-complex+abi3, so dead without that.
169 pub(crate) fn lookup_special<N>(&self, attr_name: N) -> PyResult<Option<&PyAny>>
170 where
171 N: IntoPy<Py<PyString>>,
172 {
173 let py = self.py();
174 let self_type = self.get_type();
175 let attr = if let Ok(attr) = self_type.getattr(attr_name) {
176 attr
177 } else {
178 return Ok(None);
179 };
180
181 // Manually resolve descriptor protocol.
182 if cfg!(Py_3_10)
183 || unsafe { ffi::PyType_HasFeature(attr.get_type_ptr(), ffi::Py_TPFLAGS_HEAPTYPE) } != 0
184 {
185 // This is the preferred faster path, but does not work on static types (generally,
186 // types defined in extension modules) before Python 3.10.
187 unsafe {
188 let descr_get_ptr = ffi::PyType_GetSlot(attr.get_type_ptr(), ffi::Py_tp_descr_get);
189 if descr_get_ptr.is_null() {
190 return Ok(Some(attr));
191 }
192 let descr_get: ffi::descrgetfunc = std::mem::transmute(descr_get_ptr);
193 let ret = descr_get(attr.as_ptr(), self.as_ptr(), self_type.as_ptr());
194 py.from_owned_ptr_or_err(ret).map(Some)
195 }
196 } else if let Ok(descr_get) = attr.get_type().getattr(crate::intern!(py, "__get__")) {
197 descr_get.call1((attr, self, self_type)).map(Some)
198 } else {
199 Ok(Some(attr))
200 }
201 }
202
203 /// Sets an attribute value.
204 ///
205 /// This is equivalent to the Python expression `self.attr_name = value`.
206 ///
207 /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
208 /// to intern `name`.
209 ///
210 /// # Example: `intern!`ing the attribute name
211 ///
212 /// ```
213 /// # use pyo3::{intern, pyfunction, types::PyModule, PyAny, Python, PyResult};
214 /// #
215 /// #[pyfunction]
216 /// fn set_answer(ob: &PyAny) -> PyResult<()> {
217 /// ob.setattr(intern!(ob.py(), "answer"), 42)
218 /// }
219 /// #
220 /// # Python::with_gil(|py| {
221 /// # let ob = PyModule::new(py, "empty").unwrap();
222 /// # set_answer(ob).unwrap();
223 /// # });
224 /// ```
225 pub fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()>
226 where
227 N: IntoPy<Py<PyString>>,
228 V: ToPyObject,
229 {
230 fn inner(any: &PyAny, attr_name: Py<PyString>, value: PyObject) -> PyResult<()> {
231 err::error_on_minusone(any.py(), unsafe {
232 ffi::PyObject_SetAttr(any.as_ptr(), attr_name.as_ptr(), value.as_ptr())
233 })
234 }
235
236 let py = self.py();
237 inner(self, attr_name.into_py(py), value.to_object(py))
238 }
239
240 /// Deletes an attribute.
241 ///
242 /// This is equivalent to the Python statement `del self.attr_name`.
243 ///
244 /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
245 /// to intern `attr_name`.
246 pub fn delattr<N>(&self, attr_name: N) -> PyResult<()>
247 where
248 N: IntoPy<Py<PyString>>,
249 {
250 fn inner(any: &PyAny, attr_name: Py<PyString>) -> PyResult<()> {
251 err::error_on_minusone(any.py(), unsafe {
252 ffi::PyObject_DelAttr(any.as_ptr(), attr_name.as_ptr())
253 })
254 }
255
256 inner(self, attr_name.into_py(self.py()))
257 }
258
259 /// Returns an [`Ordering`] between `self` and `other`.
260 ///
261 /// This is equivalent to the following Python code:
262 /// ```python
263 /// if self == other:
264 /// return Equal
265 /// elif a < b:
266 /// return Less
267 /// elif a > b:
268 /// return Greater
269 /// else:
270 /// raise TypeError("PyAny::compare(): All comparisons returned false")
271 /// ```
272 ///
273 /// # Examples
274 ///
275 /// ```rust
276 /// use pyo3::prelude::*;
277 /// use pyo3::types::PyFloat;
278 /// use std::cmp::Ordering;
279 ///
280 /// # fn main() -> PyResult<()> {
281 /// Python::with_gil(|py| -> PyResult<()> {
282 /// let a = PyFloat::new(py, 0_f64);
283 /// let b = PyFloat::new(py, 42_f64);
284 /// assert_eq!(a.compare(b)?, Ordering::Less);
285 /// Ok(())
286 /// })?;
287 /// # Ok(())}
288 /// ```
289 ///
290 /// It will return `PyErr` for values that cannot be compared:
291 ///
292 /// ```rust
293 /// use pyo3::prelude::*;
294 /// use pyo3::types::{PyFloat, PyString};
295 ///
296 /// # fn main() -> PyResult<()> {
297 /// Python::with_gil(|py| -> PyResult<()> {
298 /// let a = PyFloat::new(py, 0_f64);
299 /// let b = PyString::new(py, "zero");
300 /// assert!(a.compare(b).is_err());
301 /// Ok(())
302 /// })?;
303 /// # Ok(())}
304 /// ```
305 pub fn compare<O>(&self, other: O) -> PyResult<Ordering>
306 where
307 O: ToPyObject,
308 {
309 self._compare(other.to_object(self.py()))
310 }
311
312 fn _compare(&self, other: PyObject) -> PyResult<Ordering> {
313 let py = self.py();
314 let other = other.as_ptr();
315 // Almost the same as ffi::PyObject_RichCompareBool, but this one doesn't try self == other.
316 // See https://github.com/PyO3/pyo3/issues/985 for more.
317 let do_compare = |other, op| unsafe {
318 PyObject::from_owned_ptr_or_err(py, ffi::PyObject_RichCompare(self.as_ptr(), other, op))
319 .and_then(|obj| obj.is_true(py))
320 };
321 if do_compare(other, ffi::Py_EQ)? {
322 Ok(Ordering::Equal)
323 } else if do_compare(other, ffi::Py_LT)? {
324 Ok(Ordering::Less)
325 } else if do_compare(other, ffi::Py_GT)? {
326 Ok(Ordering::Greater)
327 } else {
328 Err(PyTypeError::new_err(
329 "PyAny::compare(): All comparisons returned false",
330 ))
331 }
332 }
333
334 /// Tests whether two Python objects obey a given [`CompareOp`].
335 ///
336 /// [`lt`](Self::lt), [`le`](Self::le), [`eq`](Self::eq), [`ne`](Self::ne),
337 /// [`gt`](Self::gt) and [`ge`](Self::ge) are the specialized versions
338 /// of this function.
339 ///
340 /// Depending on the value of `compare_op`, this is equivalent to one of the
341 /// following Python expressions:
342 ///
343 /// | `compare_op` | Python expression |
344 /// | :---: | :----: |
345 /// | [`CompareOp::Eq`] | `self == other` |
346 /// | [`CompareOp::Ne`] | `self != other` |
347 /// | [`CompareOp::Lt`] | `self < other` |
348 /// | [`CompareOp::Le`] | `self <= other` |
349 /// | [`CompareOp::Gt`] | `self > other` |
350 /// | [`CompareOp::Ge`] | `self >= other` |
351 ///
352 /// # Examples
353 ///
354 /// ```rust
355 /// use pyo3::class::basic::CompareOp;
356 /// use pyo3::prelude::*;
357 /// use pyo3::types::PyInt;
358 ///
359 /// # fn main() -> PyResult<()> {
360 /// Python::with_gil(|py| -> PyResult<()> {
361 /// let a: &PyInt = 0_u8.into_py(py).into_ref(py).downcast()?;
362 /// let b: &PyInt = 42_u8.into_py(py).into_ref(py).downcast()?;
363 /// assert!(a.rich_compare(b, CompareOp::Le)?.is_true()?);
364 /// Ok(())
365 /// })?;
366 /// # Ok(())}
367 /// ```
368 pub fn rich_compare<O>(&self, other: O, compare_op: CompareOp) -> PyResult<&PyAny>
369 where
370 O: ToPyObject,
371 {
372 fn inner(slf: &PyAny, other: PyObject, compare_op: CompareOp) -> PyResult<&PyAny> {
373 unsafe {
374 slf.py().from_owned_ptr_or_err(ffi::PyObject_RichCompare(
375 slf.as_ptr(),
376 other.as_ptr(),
377 compare_op as c_int,
378 ))
379 }
380 }
381
382 inner(self, other.to_object(self.py()), compare_op)
383 }
384
385 /// Tests whether this object is less than another.
386 ///
387 /// This is equivalent to the Python expression `self < other`.
388 pub fn lt<O>(&self, other: O) -> PyResult<bool>
389 where
390 O: ToPyObject,
391 {
392 self.rich_compare(other, CompareOp::Lt)?.is_true()
393 }
394
395 /// Tests whether this object is less than or equal to another.
396 ///
397 /// This is equivalent to the Python expression `self <= other`.
398 pub fn le<O>(&self, other: O) -> PyResult<bool>
399 where
400 O: ToPyObject,
401 {
402 self.rich_compare(other, CompareOp::Le)?.is_true()
403 }
404
405 /// Tests whether this object is equal to another.
406 ///
407 /// This is equivalent to the Python expression `self == other`.
408 pub fn eq<O>(&self, other: O) -> PyResult<bool>
409 where
410 O: ToPyObject,
411 {
412 self.rich_compare(other, CompareOp::Eq)?.is_true()
413 }
414
415 /// Tests whether this object is not equal to another.
416 ///
417 /// This is equivalent to the Python expression `self != other`.
418 pub fn ne<O>(&self, other: O) -> PyResult<bool>
419 where
420 O: ToPyObject,
421 {
422 self.rich_compare(other, CompareOp::Ne)?.is_true()
423 }
424
425 /// Tests whether this object is greater than another.
426 ///
427 /// This is equivalent to the Python expression `self > other`.
428 pub fn gt<O>(&self, other: O) -> PyResult<bool>
429 where
430 O: ToPyObject,
431 {
432 self.rich_compare(other, CompareOp::Gt)?.is_true()
433 }
434
435 /// Tests whether this object is greater than or equal to another.
436 ///
437 /// This is equivalent to the Python expression `self >= other`.
438 pub fn ge<O>(&self, other: O) -> PyResult<bool>
439 where
440 O: ToPyObject,
441 {
442 self.rich_compare(other, CompareOp::Ge)?.is_true()
443 }
444
445 /// Determines whether this object appears callable.
446 ///
447 /// This is equivalent to Python's [`callable()`][1] function.
448 ///
449 /// # Examples
450 ///
451 /// ```rust
452 /// use pyo3::prelude::*;
453 ///
454 /// # fn main() -> PyResult<()> {
455 /// Python::with_gil(|py| -> PyResult<()> {
456 /// let builtins = PyModule::import(py, "builtins")?;
457 /// let print = builtins.getattr("print")?;
458 /// assert!(print.is_callable());
459 /// Ok(())
460 /// })?;
461 /// # Ok(())}
462 /// ```
463 ///
464 /// This is equivalent to the Python statement `assert callable(print)`.
465 ///
466 /// Note that unless an API needs to distinguish between callable and
467 /// non-callable objects, there is no point in checking for callability.
468 /// Instead, it is better to just do the call and handle potential
469 /// exceptions.
470 ///
471 /// [1]: https://docs.python.org/3/library/functions.html#callable
472 pub fn is_callable(&self) -> bool {
473 unsafe { ffi::PyCallable_Check(self.as_ptr()) != 0 }
474 }
475
476 /// Calls the object.
477 ///
478 /// This is equivalent to the Python expression `self(*args, **kwargs)`.
479 ///
480 /// # Examples
481 ///
482 /// ```rust
483 /// use pyo3::prelude::*;
484 /// use pyo3::types::PyDict;
485 ///
486 /// const CODE: &str = r#"
487 /// def function(*args, **kwargs):
488 /// assert args == ("hello",)
489 /// assert kwargs == {"cruel": "world"}
490 /// return "called with args and kwargs"
491 /// "#;
492 ///
493 /// # fn main() -> PyResult<()> {
494 /// Python::with_gil(|py| {
495 /// let module = PyModule::from_code(py, CODE, "", "")?;
496 /// let fun = module.getattr("function")?;
497 /// let args = ("hello",);
498 /// let kwargs = PyDict::new(py);
499 /// kwargs.set_item("cruel", "world")?;
500 /// let result = fun.call(args, Some(kwargs))?;
501 /// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
502 /// Ok(())
503 /// })
504 /// # }
505 /// ```
506 pub fn call(
507 &self,
508 args: impl IntoPy<Py<PyTuple>>,
509 kwargs: Option<&PyDict>,
510 ) -> PyResult<&PyAny> {
511 let py = self.py();
512
513 let args = args.into_py(py);
514 let kwargs = kwargs.map_or(std::ptr::null_mut(), |kwargs| kwargs.as_ptr());
515
516 unsafe {
517 let return_value = ffi::PyObject_Call(self.as_ptr(), args.as_ptr(), kwargs);
518 let ret = py.from_owned_ptr_or_err(return_value);
519 ret
520 }
521 }
522
523 /// Calls the object without arguments.
524 ///
525 /// This is equivalent to the Python expression `self()`.
526 ///
527 /// # Examples
528 ///
529 /// ```no_run
530 /// use pyo3::prelude::*;
531 ///
532 /// # fn main() -> PyResult<()> {
533 /// Python::with_gil(|py| -> PyResult<()> {
534 /// let module = PyModule::import(py, "builtins")?;
535 /// let help = module.getattr("help")?;
536 /// help.call0()?;
537 /// Ok(())
538 /// })?;
539 /// # Ok(())}
540 /// ```
541 ///
542 /// This is equivalent to the Python expression `help()`.
543 pub fn call0(&self) -> PyResult<&PyAny> {
544 cfg_if::cfg_if! {
545 if #[cfg(all(
546 not(PyPy),
547 any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // PyObject_CallNoArgs was added to python in 3.9 but to limited API in 3.10
548 ))] {
549 // Optimized path on python 3.9+
550 unsafe {
551 self.py().from_owned_ptr_or_err(ffi::PyObject_CallNoArgs(self.as_ptr()))
552 }
553 } else {
554 self.call((), None)
555 }
556 }
557 }
558
559 /// Calls the object with only positional arguments.
560 ///
561 /// This is equivalent to the Python expression `self(*args)`.
562 ///
563 /// # Examples
564 ///
565 /// ```rust
566 /// use pyo3::prelude::*;
567 ///
568 /// const CODE: &str = r#"
569 /// def function(*args, **kwargs):
570 /// assert args == ("hello",)
571 /// assert kwargs == {}
572 /// return "called with args"
573 /// "#;
574 ///
575 /// # fn main() -> PyResult<()> {
576 /// Python::with_gil(|py| {
577 /// let module = PyModule::from_code(py, CODE, "", "")?;
578 /// let fun = module.getattr("function")?;
579 /// let args = ("hello",);
580 /// let result = fun.call1(args)?;
581 /// assert_eq!(result.extract::<&str>()?, "called with args");
582 /// Ok(())
583 /// })
584 /// # }
585 /// ```
586 pub fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyAny> {
587 self.call(args, None)
588 }
589
590 /// Calls a method on the object.
591 ///
592 /// This is equivalent to the Python expression `self.name(*args, **kwargs)`.
593 ///
594 /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
595 /// to intern `name`.
596 ///
597 /// # Examples
598 ///
599 /// ```rust
600 /// use pyo3::prelude::*;
601 /// use pyo3::types::PyDict;
602 ///
603 /// const CODE: &str = r#"
604 /// class A:
605 /// def method(self, *args, **kwargs):
606 /// assert args == ("hello",)
607 /// assert kwargs == {"cruel": "world"}
608 /// return "called with args and kwargs"
609 /// a = A()
610 /// "#;
611 ///
612 /// # fn main() -> PyResult<()> {
613 /// Python::with_gil(|py| {
614 /// let module = PyModule::from_code(py, CODE, "", "")?;
615 /// let instance = module.getattr("a")?;
616 /// let args = ("hello",);
617 /// let kwargs = PyDict::new(py);
618 /// kwargs.set_item("cruel", "world")?;
619 /// let result = instance.call_method("method", args, Some(kwargs))?;
620 /// assert_eq!(result.extract::<&str>()?, "called with args and kwargs");
621 /// Ok(())
622 /// })
623 /// # }
624 /// ```
625 pub fn call_method<N, A>(&self, name: N, args: A, kwargs: Option<&PyDict>) -> PyResult<&PyAny>
626 where
627 N: IntoPy<Py<PyString>>,
628 A: IntoPy<Py<PyTuple>>,
629 {
630 let py = self.py();
631
632 let callee = self.getattr(name)?;
633 let args: Py<PyTuple> = args.into_py(py);
634 let kwargs = kwargs.map_or(std::ptr::null_mut(), |kwargs| kwargs.as_ptr());
635
636 unsafe {
637 let result_ptr = ffi::PyObject_Call(callee.as_ptr(), args.as_ptr(), kwargs);
638 let result = py.from_owned_ptr_or_err(result_ptr);
639 result
640 }
641 }
642
643 /// Calls a method on the object without arguments.
644 ///
645 /// This is equivalent to the Python expression `self.name()`.
646 ///
647 /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
648 /// to intern `name`.
649 ///
650 /// # Examples
651 ///
652 /// ```rust
653 /// use pyo3::prelude::*;
654 ///
655 /// const CODE: &str = r#"
656 /// class A:
657 /// def method(self, *args, **kwargs):
658 /// assert args == ()
659 /// assert kwargs == {}
660 /// return "called with no arguments"
661 /// a = A()
662 /// "#;
663 ///
664 /// # fn main() -> PyResult<()> {
665 /// Python::with_gil(|py| {
666 /// let module = PyModule::from_code(py, CODE, "", "")?;
667 /// let instance = module.getattr("a")?;
668 /// let result = instance.call_method0("method")?;
669 /// assert_eq!(result.extract::<&str>()?, "called with no arguments");
670 /// Ok(())
671 /// })
672 /// # }
673 /// ```
674 pub fn call_method0<N>(&self, name: N) -> PyResult<&PyAny>
675 where
676 N: IntoPy<Py<PyString>>,
677 {
678 cfg_if::cfg_if! {
679 if #[cfg(all(Py_3_9, not(any(Py_LIMITED_API, PyPy))))] {
680 let py = self.py();
681
682 // Optimized path on python 3.9+
683 unsafe {
684 let name: Py<PyString> = name.into_py(py);
685 let ptr = ffi::PyObject_CallMethodNoArgs(self.as_ptr(), name.as_ptr());
686 py.from_owned_ptr_or_err(ptr)
687 }
688 } else {
689 self.call_method(name, (), None)
690 }
691 }
692 }
693
694 /// Calls a method on the object with only positional arguments.
695 ///
696 /// This is equivalent to the Python expression `self.name(*args)`.
697 ///
698 /// To avoid repeated temporary allocations of Python strings, the [`intern!`] macro can be used
699 /// to intern `name`.
700 ///
701 /// # Examples
702 ///
703 /// ```rust
704 /// use pyo3::prelude::*;
705 ///
706 /// const CODE: &str = r#"
707 /// class A:
708 /// def method(self, *args, **kwargs):
709 /// assert args == ("hello",)
710 /// assert kwargs == {}
711 /// return "called with args"
712 /// a = A()
713 /// "#;
714 ///
715 /// # fn main() -> PyResult<()> {
716 /// Python::with_gil(|py| {
717 /// let module = PyModule::from_code(py, CODE, "", "")?;
718 /// let instance = module.getattr("a")?;
719 /// let args = ("hello",);
720 /// let result = instance.call_method1("method", args)?;
721 /// assert_eq!(result.extract::<&str>()?, "called with args");
722 /// Ok(())
723 /// })
724 /// # }
725 /// ```
726 pub fn call_method1<N, A>(&self, name: N, args: A) -> PyResult<&PyAny>
727 where
728 N: IntoPy<Py<PyString>>,
729 A: IntoPy<Py<PyTuple>>,
730 {
731 self.call_method(name, args, None)
732 }
733
734 /// Returns whether the object is considered to be true.
735 ///
736 /// This is equivalent to the Python expression `bool(self)`.
737 pub fn is_true(&self) -> PyResult<bool> {
738 let v = unsafe { ffi::PyObject_IsTrue(self.as_ptr()) };
739 err::error_on_minusone(self.py(), v)?;
740 Ok(v != 0)
741 }
742
743 /// Returns whether the object is considered to be None.
744 ///
745 /// This is equivalent to the Python expression `self is None`.
746 #[inline]
747 pub fn is_none(&self) -> bool {
748 unsafe { ffi::Py_None() == self.as_ptr() }
749 }
750
751 /// Returns whether the object is Ellipsis, e.g. `...`.
752 ///
753 /// This is equivalent to the Python expression `self is ...`.
754 pub fn is_ellipsis(&self) -> bool {
755 unsafe { ffi::Py_Ellipsis() == self.as_ptr() }
756 }
757
758 /// Returns true if the sequence or mapping has a length of 0.
759 ///
760 /// This is equivalent to the Python expression `len(self) == 0`.
761 pub fn is_empty(&self) -> PyResult<bool> {
762 self.len().map(|l| l == 0)
763 }
764
765 /// Gets an item from the collection.
766 ///
767 /// This is equivalent to the Python expression `self[key]`.
768 pub fn get_item<K>(&self, key: K) -> PyResult<&PyAny>
769 where
770 K: ToPyObject,
771 {
772 fn inner(slf: &PyAny, key: PyObject) -> PyResult<&PyAny> {
773 unsafe {
774 slf.py()
775 .from_owned_ptr_or_err(ffi::PyObject_GetItem(slf.as_ptr(), key.as_ptr()))
776 }
777 }
778
779 inner(self, key.to_object(self.py()))
780 }
781
782 /// Sets a collection item value.
783 ///
784 /// This is equivalent to the Python expression `self[key] = value`.
785 pub fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()>
786 where
787 K: ToPyObject,
788 V: ToPyObject,
789 {
790 fn inner(slf: &PyAny, key: PyObject, value: PyObject) -> PyResult<()> {
791 err::error_on_minusone(slf.py(), unsafe {
792 ffi::PyObject_SetItem(slf.as_ptr(), key.as_ptr(), value.as_ptr())
793 })
794 }
795
796 let py = self.py();
797 inner(self, key.to_object(py), value.to_object(py))
798 }
799
800 /// Deletes an item from the collection.
801 ///
802 /// This is equivalent to the Python expression `del self[key]`.
803 pub fn del_item<K>(&self, key: K) -> PyResult<()>
804 where
805 K: ToPyObject,
806 {
807 fn inner(slf: &PyAny, key: PyObject) -> PyResult<()> {
808 err::error_on_minusone(slf.py(), unsafe {
809 ffi::PyObject_DelItem(slf.as_ptr(), key.as_ptr())
810 })
811 }
812
813 inner(self, key.to_object(self.py()))
814 }
815
816 /// Takes an object and returns an iterator for it.
817 ///
818 /// This is typically a new iterator but if the argument is an iterator,
819 /// this returns itself.
820 pub fn iter(&self) -> PyResult<&PyIterator> {
821 PyIterator::from_object(self)
822 }
823
824 /// Returns the Python type object for this object's type.
825 pub fn get_type(&self) -> &PyType {
826 unsafe { PyType::from_type_ptr(self.py(), ffi::Py_TYPE(self.as_ptr())) }
827 }
828
829 /// Returns the Python type pointer for this object.
830 #[inline]
831 pub fn get_type_ptr(&self) -> *mut ffi::PyTypeObject {
832 unsafe { ffi::Py_TYPE(self.as_ptr()) }
833 }
834
835 /// Downcast this `PyAny` to a concrete Python type or pyclass.
836 ///
837 /// Note that you can often avoid downcasting yourself by just specifying
838 /// the desired type in function or method signatures.
839 /// However, manual downcasting is sometimes necessary.
840 ///
841 /// For extracting a Rust-only type, see [`PyAny::extract`](struct.PyAny.html#method.extract).
842 ///
843 /// # Example: Downcasting to a specific Python object
844 ///
845 /// ```rust
846 /// use pyo3::prelude::*;
847 /// use pyo3::types::{PyDict, PyList};
848 ///
849 /// Python::with_gil(|py| {
850 /// let dict = PyDict::new(py);
851 /// assert!(dict.is_instance_of::<PyAny>());
852 /// let any: &PyAny = dict.as_ref();
853 ///
854 /// assert!(any.downcast::<PyDict>().is_ok());
855 /// assert!(any.downcast::<PyList>().is_err());
856 /// });
857 /// ```
858 ///
859 /// # Example: Getting a reference to a pyclass
860 ///
861 /// This is useful if you want to mutate a `PyObject` that
862 /// might actually be a pyclass.
863 ///
864 /// ```rust
865 /// # fn main() -> Result<(), pyo3::PyErr> {
866 /// use pyo3::prelude::*;
867 ///
868 /// #[pyclass]
869 /// struct Class {
870 /// i: i32,
871 /// }
872 ///
873 /// Python::with_gil(|py| {
874 /// let class: &PyAny = Py::new(py, Class { i: 0 }).unwrap().into_ref(py);
875 ///
876 /// let class_cell: &PyCell<Class> = class.downcast()?;
877 ///
878 /// class_cell.borrow_mut().i += 1;
879 ///
880 /// // Alternatively you can get a `PyRefMut` directly
881 /// let class_ref: PyRefMut<'_, Class> = class.extract()?;
882 /// assert_eq!(class_ref.i, 1);
883 /// Ok(())
884 /// })
885 /// # }
886 /// ```
887 #[inline]
888 pub fn downcast<'p, T>(&'p self) -> Result<&'p T, PyDowncastError<'_>>
889 where
890 T: PyTryFrom<'p>,
891 {
892 <T as PyTryFrom>::try_from(self)
893 }
894
895 /// Downcast this `PyAny` to a concrete Python type or pyclass (but not a subclass of it).
896 ///
897 /// It is almost always better to use [`PyAny::downcast`] because it accounts for Python
898 /// subtyping. Use this method only when you do not want to allow subtypes.
899 ///
900 /// The advantage of this method over [`PyAny::downcast`] is that it is faster. The implementation
901 /// of `downcast_exact` uses the equivalent of the Python expression `type(self) is T`, whereas
902 /// `downcast` uses `isinstance(self, T)`.
903 ///
904 /// For extracting a Rust-only type, see [`PyAny::extract`](struct.PyAny.html#method.extract).
905 ///
906 /// # Example: Downcasting to a specific Python object but not a subtype
907 ///
908 /// ```rust
909 /// use pyo3::prelude::*;
910 /// use pyo3::types::{PyBool, PyLong};
911 ///
912 /// Python::with_gil(|py| {
913 /// let b = PyBool::new(py, true);
914 /// assert!(b.is_instance_of::<PyBool>());
915 /// let any: &PyAny = b.as_ref();
916 ///
917 /// // `bool` is a subtype of `int`, so `downcast` will accept a `bool` as an `int`
918 /// // but `downcast_exact` will not.
919 /// assert!(any.downcast::<PyLong>().is_ok());
920 /// assert!(any.downcast_exact::<PyLong>().is_err());
921 ///
922 /// assert!(any.downcast_exact::<PyBool>().is_ok());
923 /// });
924 /// ```
925 #[inline]
926 pub fn downcast_exact<'p, T>(&'p self) -> Result<&'p T, PyDowncastError<'_>>
927 where
928 T: PyTryFrom<'p>,
929 {
930 <T as PyTryFrom>::try_from_exact(self)
931 }
932
933 /// Converts this `PyAny` to a concrete Python type without checking validity.
934 ///
935 /// # Safety
936 ///
937 /// Callers must ensure that the type is valid or risk type confusion.
938 #[inline]
939 pub unsafe fn downcast_unchecked<'p, T>(&'p self) -> &'p T
940 where
941 T: PyTryFrom<'p>,
942 {
943 <T as PyTryFrom>::try_from_unchecked(self)
944 }
945
946 /// Extracts some type from the Python object.
947 ///
948 /// This is a wrapper function around [`FromPyObject::extract()`].
949 pub fn extract<'a, D>(&'a self) -> PyResult<D>
950 where
951 D: FromPyObject<'a>,
952 {
953 FromPyObject::extract(self)
954 }
955
956 /// Returns the reference count for the Python object.
957 pub fn get_refcnt(&self) -> isize {
958 unsafe { ffi::Py_REFCNT(self.as_ptr()) }
959 }
960
961 /// Computes the "repr" representation of self.
962 ///
963 /// This is equivalent to the Python expression `repr(self)`.
964 pub fn repr(&self) -> PyResult<&PyString> {
965 unsafe {
966 self.py()
967 .from_owned_ptr_or_err(ffi::PyObject_Repr(self.as_ptr()))
968 }
969 }
970
971 /// Computes the "str" representation of self.
972 ///
973 /// This is equivalent to the Python expression `str(self)`.
974 pub fn str(&self) -> PyResult<&PyString> {
975 unsafe {
976 self.py()
977 .from_owned_ptr_or_err(ffi::PyObject_Str(self.as_ptr()))
978 }
979 }
980
981 /// Retrieves the hash code of self.
982 ///
983 /// This is equivalent to the Python expression `hash(self)`.
984 pub fn hash(&self) -> PyResult<isize> {
985 let v = unsafe { ffi::PyObject_Hash(self.as_ptr()) };
986 crate::err::error_on_minusone(self.py(), v)?;
987 Ok(v)
988 }
989
990 /// Returns the length of the sequence or mapping.
991 ///
992 /// This is equivalent to the Python expression `len(self)`.
993 pub fn len(&self) -> PyResult<usize> {
994 let v = unsafe { ffi::PyObject_Size(self.as_ptr()) };
995 crate::err::error_on_minusone(self.py(), v)?;
996 Ok(v as usize)
997 }
998
999 /// Returns the list of attributes of this object.
1000 ///
1001 /// This is equivalent to the Python expression `dir(self)`.
1002 pub fn dir(&self) -> &PyList {
1003 unsafe { self.py().from_owned_ptr(ffi::PyObject_Dir(self.as_ptr())) }
1004 }
1005
1006 /// Checks whether this object is an instance of type `ty`.
1007 ///
1008 /// This is equivalent to the Python expression `isinstance(self, ty)`.
1009 #[inline]
1010 pub fn is_instance(&self, ty: &PyAny) -> PyResult<bool> {
1011 let result = unsafe { ffi::PyObject_IsInstance(self.as_ptr(), ty.as_ptr()) };
1012 err::error_on_minusone(self.py(), result)?;
1013 Ok(result == 1)
1014 }
1015
1016 /// Checks whether this object is an instance of exactly type `ty` (not a subclass).
1017 ///
1018 /// This is equivalent to the Python expression `type(self) is ty`.
1019 #[inline]
1020 pub fn is_exact_instance(&self, ty: &PyAny) -> bool {
1021 self.get_type().is(ty)
1022 }
1023
1024 /// Checks whether this object is an instance of type `T`.
1025 ///
1026 /// This is equivalent to the Python expression `isinstance(self, T)`,
1027 /// if the type `T` is known at compile time.
1028 #[inline]
1029 pub fn is_instance_of<T: PyTypeInfo>(&self) -> bool {
1030 T::is_type_of(self)
1031 }
1032
1033 /// Checks whether this object is an instance of exactly type `T`.
1034 ///
1035 /// This is equivalent to the Python expression `type(self) is T`,
1036 /// if the type `T` is known at compile time.
1037 #[inline]
1038 pub fn is_exact_instance_of<T: PyTypeInfo>(&self) -> bool {
1039 T::is_exact_type_of(self)
1040 }
1041
1042 /// Determines if self contains `value`.
1043 ///
1044 /// This is equivalent to the Python expression `value in self`.
1045 pub fn contains<V>(&self, value: V) -> PyResult<bool>
1046 where
1047 V: ToPyObject,
1048 {
1049 self._contains(value.to_object(self.py()))
1050 }
1051
1052 fn _contains(&self, value: PyObject) -> PyResult<bool> {
1053 match unsafe { ffi::PySequence_Contains(self.as_ptr(), value.as_ptr()) } {
1054 0 => Ok(false),
1055 1 => Ok(true),
1056 _ => Err(PyErr::fetch(self.py())),
1057 }
1058 }
1059
1060 /// Returns a GIL marker constrained to the lifetime of this type.
1061 #[inline]
1062 pub fn py(&self) -> Python<'_> {
1063 PyNativeType::py(self)
1064 }
1065
1066 /// Returns the raw FFI pointer represented by self.
1067 ///
1068 /// # Safety
1069 ///
1070 /// Callers are responsible for ensuring that the pointer does not outlive self.
1071 ///
1072 /// The reference is borrowed; callers should not decrease the reference count
1073 /// when they are finished with the pointer.
1074 #[inline]
1075 pub fn as_ptr(&self) -> *mut ffi::PyObject {
1076 self as *const PyAny as *mut ffi::PyObject
1077 }
1078
1079 /// Returns an owned raw FFI pointer represented by self.
1080 ///
1081 /// # Safety
1082 ///
1083 /// The reference is owned; when finished the caller should either transfer ownership
1084 /// of the pointer or decrease the reference count (e.g. with [`pyo3::ffi::Py_DecRef`](crate::ffi::Py_DecRef)).
1085 #[inline]
1086 pub fn into_ptr(&self) -> *mut ffi::PyObject {
1087 // Safety: self.as_ptr() returns a valid non-null pointer
1088 unsafe { ffi::_Py_NewRef(self.as_ptr()) }
1089 }
1090
1091 /// Return a proxy object that delegates method calls to a parent or sibling class of type.
1092 ///
1093 /// This is equivalent to the Python expression `super()`
1094 #[cfg(not(PyPy))]
1095 pub fn py_super(&self) -> PyResult<&PySuper> {
1096 PySuper::new(self.get_type(), self)
1097 }
1098}
1099
1100#[cfg(test)]
1101mod tests {
1102 use crate::{
1103 types::{IntoPyDict, PyAny, PyBool, PyList, PyLong, PyModule},
1104 Python, ToPyObject,
1105 };
1106
1107 #[test]
1108 fn test_lookup_special() {
1109 Python::with_gil(|py| {
1110 let module = PyModule::from_code(
1111 py,
1112 r#"
1113class CustomCallable:
1114 def __call__(self):
1115 return 1
1116
1117class SimpleInt:
1118 def __int__(self):
1119 return 1
1120
1121class InheritedInt(SimpleInt): pass
1122
1123class NoInt: pass
1124
1125class NoDescriptorInt:
1126 __int__ = CustomCallable()
1127
1128class InstanceOverrideInt:
1129 def __int__(self):
1130 return 1
1131instance_override = InstanceOverrideInt()
1132instance_override.__int__ = lambda self: 2
1133
1134class ErrorInDescriptorInt:
1135 @property
1136 def __int__(self):
1137 raise ValueError("uh-oh!")
1138
1139class NonHeapNonDescriptorInt:
1140 # A static-typed callable that doesn't implement `__get__`. These are pretty hard to come by.
1141 __int__ = int
1142 "#,
1143 "test.py",
1144 "test",
1145 )
1146 .unwrap();
1147
1148 let int = crate::intern!(py, "__int__");
1149 let eval_int =
1150 |obj: &PyAny| obj.lookup_special(int)?.unwrap().call0()?.extract::<u32>();
1151
1152 let simple = module.getattr("SimpleInt").unwrap().call0().unwrap();
1153 assert_eq!(eval_int(simple).unwrap(), 1);
1154 let inherited = module.getattr("InheritedInt").unwrap().call0().unwrap();
1155 assert_eq!(eval_int(inherited).unwrap(), 1);
1156 let no_descriptor = module.getattr("NoDescriptorInt").unwrap().call0().unwrap();
1157 assert_eq!(eval_int(no_descriptor).unwrap(), 1);
1158 let missing = module.getattr("NoInt").unwrap().call0().unwrap();
1159 assert!(missing.lookup_special(int).unwrap().is_none());
1160 // Note the instance override should _not_ call the instance method that returns 2,
1161 // because that's not how special lookups are meant to work.
1162 let instance_override = module.getattr("instance_override").unwrap();
1163 assert_eq!(eval_int(instance_override).unwrap(), 1);
1164 let descriptor_error = module
1165 .getattr("ErrorInDescriptorInt")
1166 .unwrap()
1167 .call0()
1168 .unwrap();
1169 assert!(descriptor_error.lookup_special(int).is_err());
1170 let nonheap_nondescriptor = module
1171 .getattr("NonHeapNonDescriptorInt")
1172 .unwrap()
1173 .call0()
1174 .unwrap();
1175 assert_eq!(eval_int(nonheap_nondescriptor).unwrap(), 0);
1176 })
1177 }
1178
1179 #[test]
1180 fn test_call_for_non_existing_method() {
1181 Python::with_gil(|py| {
1182 let a = py.eval("42", None, None).unwrap();
1183 a.call_method0("__str__").unwrap(); // ok
1184 assert!(a.call_method("nonexistent_method", (1,), None).is_err());
1185 assert!(a.call_method0("nonexistent_method").is_err());
1186 assert!(a.call_method1("nonexistent_method", (1,)).is_err());
1187 });
1188 }
1189
1190 #[test]
1191 fn test_call_with_kwargs() {
1192 Python::with_gil(|py| {
1193 let list = vec![3, 6, 5, 4, 7].to_object(py);
1194 let dict = vec![("reverse", true)].into_py_dict(py);
1195 list.call_method(py, "sort", (), Some(dict)).unwrap();
1196 assert_eq!(list.extract::<Vec<i32>>(py).unwrap(), vec![7, 6, 5, 4, 3]);
1197 });
1198 }
1199
1200 #[test]
1201 fn test_call_method0() {
1202 Python::with_gil(|py| {
1203 let module = PyModule::from_code(
1204 py,
1205 r#"
1206class SimpleClass:
1207 def foo(self):
1208 return 42
1209"#,
1210 file!(),
1211 "test_module",
1212 )
1213 .expect("module creation failed");
1214
1215 let simple_class = module.getattr("SimpleClass").unwrap().call0().unwrap();
1216 assert_eq!(
1217 simple_class
1218 .call_method0("foo")
1219 .unwrap()
1220 .extract::<u32>()
1221 .unwrap(),
1222 42
1223 );
1224 })
1225 }
1226
1227 #[test]
1228 fn test_type() {
1229 Python::with_gil(|py| {
1230 let obj = py.eval("42", None, None).unwrap();
1231 assert_eq!(obj.get_type().as_type_ptr(), obj.get_type_ptr());
1232 });
1233 }
1234
1235 #[test]
1236 fn test_dir() {
1237 Python::with_gil(|py| {
1238 let obj = py.eval("42", None, None).unwrap();
1239 let dir = py
1240 .eval("dir(42)", None, None)
1241 .unwrap()
1242 .downcast::<PyList>()
1243 .unwrap();
1244 let a = obj
1245 .dir()
1246 .into_iter()
1247 .map(|x| x.extract::<String>().unwrap());
1248 let b = dir.into_iter().map(|x| x.extract::<String>().unwrap());
1249 assert!(a.eq(b));
1250 });
1251 }
1252
1253 #[test]
1254 fn test_hasattr() {
1255 Python::with_gil(|py| {
1256 let x = 5.to_object(py).into_ref(py);
1257 assert!(x.is_instance_of::<PyLong>());
1258
1259 assert!(x.hasattr("to_bytes").unwrap());
1260 assert!(!x.hasattr("bbbbbbytes").unwrap());
1261 })
1262 }
1263
1264 #[cfg(feature = "macros")]
1265 #[test]
1266 fn test_hasattr_error() {
1267 use crate::exceptions::PyValueError;
1268 use crate::prelude::*;
1269
1270 #[pyclass(crate = "crate")]
1271 struct GetattrFail;
1272
1273 #[pymethods(crate = "crate")]
1274 impl GetattrFail {
1275 fn __getattr__(&self, attr: PyObject) -> PyResult<PyObject> {
1276 Err(PyValueError::new_err(attr))
1277 }
1278 }
1279
1280 Python::with_gil(|py| {
1281 let obj = Py::new(py, GetattrFail).unwrap();
1282 let obj = obj.as_ref(py).as_ref();
1283
1284 assert!(obj
1285 .hasattr("foo")
1286 .unwrap_err()
1287 .is_instance_of::<PyValueError>(py));
1288 })
1289 }
1290
1291 #[test]
1292 fn test_nan_eq() {
1293 Python::with_gil(|py| {
1294 let nan = py.eval("float('nan')", None, None).unwrap();
1295 assert!(nan.compare(nan).is_err());
1296 });
1297 }
1298
1299 #[test]
1300 fn test_any_is_instance_of() {
1301 Python::with_gil(|py| {
1302 let x = 5.to_object(py).into_ref(py);
1303 assert!(x.is_instance_of::<PyLong>());
1304
1305 let l = vec![x, x].to_object(py).into_ref(py);
1306 assert!(l.is_instance_of::<PyList>());
1307 });
1308 }
1309
1310 #[test]
1311 fn test_any_is_instance() {
1312 Python::with_gil(|py| {
1313 let l = vec![1u8, 2].to_object(py).into_ref(py);
1314 assert!(l.is_instance(py.get_type::<PyList>()).unwrap());
1315 });
1316 }
1317
1318 #[test]
1319 fn test_any_is_exact_instance_of() {
1320 Python::with_gil(|py| {
1321 let x = 5.to_object(py).into_ref(py);
1322 assert!(x.is_exact_instance_of::<PyLong>());
1323
1324 let t = PyBool::new(py, true);
1325 assert!(t.is_instance_of::<PyLong>());
1326 assert!(!t.is_exact_instance_of::<PyLong>());
1327 assert!(t.is_exact_instance_of::<PyBool>());
1328
1329 let l = vec![x, x].to_object(py).into_ref(py);
1330 assert!(l.is_exact_instance_of::<PyList>());
1331 });
1332 }
1333
1334 #[test]
1335 fn test_any_is_exact_instance() {
1336 Python::with_gil(|py| {
1337 let t = PyBool::new(py, true);
1338 assert!(t.is_instance(py.get_type::<PyLong>()).unwrap());
1339 assert!(!t.is_exact_instance(py.get_type::<PyLong>()));
1340 assert!(t.is_exact_instance(py.get_type::<PyBool>()));
1341 });
1342 }
1343
1344 #[test]
1345 fn test_any_contains() {
1346 Python::with_gil(|py| {
1347 let v: Vec<i32> = vec![1, 1, 2, 3, 5, 8];
1348 let ob = v.to_object(py).into_ref(py);
1349
1350 let bad_needle = 7i32.to_object(py);
1351 assert!(!ob.contains(&bad_needle).unwrap());
1352
1353 let good_needle = 8i32.to_object(py);
1354 assert!(ob.contains(&good_needle).unwrap());
1355
1356 let type_coerced_needle = 8f32.to_object(py);
1357 assert!(ob.contains(&type_coerced_needle).unwrap());
1358
1359 let n: u32 = 42;
1360 let bad_haystack = n.to_object(py).into_ref(py);
1361 let irrelevant_needle = 0i32.to_object(py);
1362 assert!(bad_haystack.contains(&irrelevant_needle).is_err());
1363 });
1364 }
1365
1366 // This is intentionally not a test, it's a generic function used by the tests below.
1367 fn test_eq_methods_generic<T>(list: &[T])
1368 where
1369 T: PartialEq + PartialOrd + ToPyObject,
1370 {
1371 Python::with_gil(|py| {
1372 for a in list {
1373 for b in list {
1374 let a_py = a.to_object(py).into_ref(py);
1375 let b_py = b.to_object(py).into_ref(py);
1376
1377 assert_eq!(
1378 a.lt(b),
1379 a_py.lt(b_py).unwrap(),
1380 "{} < {} should be {}.",
1381 a_py,
1382 b_py,
1383 a.lt(b)
1384 );
1385 assert_eq!(
1386 a.le(b),
1387 a_py.le(b_py).unwrap(),
1388 "{} <= {} should be {}.",
1389 a_py,
1390 b_py,
1391 a.le(b)
1392 );
1393 assert_eq!(
1394 a.eq(b),
1395 a_py.eq(b_py).unwrap(),
1396 "{} == {} should be {}.",
1397 a_py,
1398 b_py,
1399 a.eq(b)
1400 );
1401 assert_eq!(
1402 a.ne(b),
1403 a_py.ne(b_py).unwrap(),
1404 "{} != {} should be {}.",
1405 a_py,
1406 b_py,
1407 a.ne(b)
1408 );
1409 assert_eq!(
1410 a.gt(b),
1411 a_py.gt(b_py).unwrap(),
1412 "{} > {} should be {}.",
1413 a_py,
1414 b_py,
1415 a.gt(b)
1416 );
1417 assert_eq!(
1418 a.ge(b),
1419 a_py.ge(b_py).unwrap(),
1420 "{} >= {} should be {}.",
1421 a_py,
1422 b_py,
1423 a.ge(b)
1424 );
1425 }
1426 }
1427 });
1428 }
1429
1430 #[test]
1431 fn test_eq_methods_integers() {
1432 let ints = [-4, -4, 1, 2, 0, -100, 1_000_000];
1433 test_eq_methods_generic(&ints);
1434 }
1435
1436 #[test]
1437 fn test_eq_methods_strings() {
1438 let strings = ["Let's", "test", "some", "eq", "methods"];
1439 test_eq_methods_generic(&strings);
1440 }
1441
1442 #[test]
1443 fn test_eq_methods_floats() {
1444 let floats = [
1445 -1.0,
1446 2.5,
1447 0.0,
1448 3.0,
1449 std::f64::consts::PI,
1450 10.0,
1451 10.0 / 3.0,
1452 -1_000_000.0,
1453 ];
1454 test_eq_methods_generic(&floats);
1455 }
1456
1457 #[test]
1458 fn test_eq_methods_bools() {
1459 let bools = [true, false];
1460 test_eq_methods_generic(&bools);
1461 }
1462
1463 #[test]
1464 fn test_is_ellipsis() {
1465 Python::with_gil(|py| {
1466 let v = py
1467 .eval("...", None, None)
1468 .map_err(|e| e.display(py))
1469 .unwrap();
1470
1471 assert!(v.is_ellipsis());
1472
1473 let not_ellipsis = 5.to_object(py).into_ref(py);
1474 assert!(!not_ellipsis.is_ellipsis());
1475 });
1476 }
1477}
1478