|
3 | 3 | use crate::class::basic::CompareOp;
|
4 | 4 | use crate::err::{self, PyDowncastError, PyErr, PyResult};
|
5 | 5 | use crate::exceptions::TypeError;
|
6 |
| -use crate::types::{PyAny, PyDict, PyIterator, PyString, PyTuple, PyType}; |
| 6 | +use crate::types::{PyAny, PyDict, PyIterator, PyList, PyString, PyTuple, PyType}; |
7 | 7 | use crate::{
|
8 | 8 | ffi, AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, Py, PyNativeType, PyObject, PyTryFrom,
|
9 | 9 | Python, ToBorrowedObject, ToPyObject,
|
@@ -212,6 +212,9 @@ pub trait ObjectProtocol {
|
212 | 212 | /// Returns the reference count for the Python object.
|
213 | 213 | fn get_refcnt(&self) -> isize;
|
214 | 214 |
|
| 215 | + /// Returns the list of attributes of this object. |
| 216 | + fn dir(&self) -> &PyList; |
| 217 | + |
215 | 218 | /// Gets the Python builtin value `None`.
|
216 | 219 | #[allow(non_snake_case)] // the Python keyword starts with uppercase
|
217 | 220 | fn None(&self) -> PyObject;
|
@@ -485,6 +488,10 @@ where
|
485 | 488 | unsafe { ffi::Py_REFCNT(self.as_ptr()) }
|
486 | 489 | }
|
487 | 490 |
|
| 491 | + fn dir(&self) -> &PyList { |
| 492 | + unsafe { self.py().from_owned_ptr(ffi::PyObject_Dir(self.as_ptr())) } |
| 493 | + } |
| 494 | + |
488 | 495 | #[allow(non_snake_case)] // the Python keyword starts with uppercase
|
489 | 496 | fn None(&self) -> PyObject {
|
490 | 497 | unsafe { PyObject::from_borrowed_ptr(self.py(), ffi::Py_None()) }
|
@@ -545,4 +552,22 @@ mod test {
|
545 | 552 | let obj = py.eval("42", None, None).unwrap();
|
546 | 553 | assert_eq!(unsafe { obj.get_type().as_type_ptr() }, obj.get_type_ptr())
|
547 | 554 | }
|
| 555 | + |
| 556 | + #[test] |
| 557 | + fn test_dir() { |
| 558 | + let gil = Python::acquire_gil(); |
| 559 | + let py = gil.python(); |
| 560 | + let obj = py.eval("42", None, None).unwrap(); |
| 561 | + let dir = py |
| 562 | + .eval("dir(42)", None, None) |
| 563 | + .unwrap() |
| 564 | + .extract::<&PyList>() |
| 565 | + .unwrap(); |
| 566 | + let a = obj |
| 567 | + .dir() |
| 568 | + .into_iter() |
| 569 | + .map(|x| x.extract::<String>().unwrap()); |
| 570 | + let b = dir.into_iter().map(|x| x.extract::<String>().unwrap()); |
| 571 | + assert!(a.eq(b)); |
| 572 | + } |
548 | 573 | }
|
0 commit comments