diff --git a/docs/changelog.rst b/docs/changelog.rst index def3ceb71e..875b585dc3 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -27,6 +27,7 @@ Breaking changes queued for v2.0.0 (Not yet released) * ``make_iterator()`` improvements for better compatibility with various types (now uses prefix increment operator) * ``arg()`` now accepts a wider range of argument types for default values +* Added ``repr()`` method to the ``handle`` class. * Added support for registering structured dtypes via ``PYBIND11_NUMPY_DTYPE()`` macro. * Added ``PYBIND11_STR_TYPE`` macro which maps to the ``builtins.str`` type. * Added a simplified ``buffer_info`` constructor for 1-dimensional buffers. diff --git a/example/example-python-types.cpp b/example/example-python-types.cpp index 00567931da..55066a8119 100644 --- a/example/example-python-types.cpp +++ b/example/example-python-types.cpp @@ -155,6 +155,11 @@ class ExamplePythonTypes { return (py::str) py::bytes("boo", 3); } + void test_print(const py::object& obj) { + std::cout << obj.str() << std::endl; + std::cout << obj.repr() << std::endl; + } + static int value; static const int value2; }; @@ -187,6 +192,7 @@ void init_ex_python_types(py::module &m) { .def("get_bytes_from_str", &ExamplePythonTypes::get_bytes_from_str, "py::bytes from py::str") .def("get_str_from_string", &ExamplePythonTypes::get_str_from_string, "py::str from std::string") .def("get_str_from_bytes", &ExamplePythonTypes::get_str_from_bytes, "py::str from py::bytes") + .def("test_print", &ExamplePythonTypes::test_print, "test the print function") .def_static("new_instance", &ExamplePythonTypes::new_instance, "Return an instance") .def_readwrite_static("value", &ExamplePythonTypes::value, "Static value member") .def_readonly_static("value2", &ExamplePythonTypes::value2, "Static value member (readonly)") diff --git a/example/example-python-types.py b/example/example-python-types.py index 1184f720a7..11b89bfe2d 100755 --- a/example/example-python-types.py +++ b/example/example-python-types.py @@ -71,6 +71,12 @@ print(instance.get_str_from_string().encode().decode()) print(instance.get_str_from_bytes().encode().decode()) +class A(object): + __str__ = lambda _: 'this is a str' + __repr__ = lambda _: 'this is a repr' + +instance.test_print(A()) + from example import ConstructorStats cstats = ConstructorStats.get(ExamplePythonTypes) diff --git a/example/example-python-types.ref b/example/example-python-types.ref index ab89d7eb5c..d89acb6513 100644 --- a/example/example-python-types.ref +++ b/example/example-python-types.ref @@ -139,6 +139,8 @@ foo bar baz boo +this is a str +this is a repr Instances not destroyed: 1 ### ExamplePythonTypes @ 0x1045b80 destroyed Instances not destroyed: 0 diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index d3895db57f..d25bc3836a 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -38,6 +38,7 @@ class handle { inline detail::accessor attr(handle key) const; inline detail::accessor attr(const char *key) const; inline pybind11::str str() const; + inline pybind11::str repr() const; template T cast() const; template #if __cplusplus > 201103L @@ -383,6 +384,15 @@ inline pybind11::str handle::str() const { return pybind11::str(strValue, false); } +inline pybind11::str handle::repr() const { + PyObject *strValue = PyObject_Repr(m_ptr); +#if PY_MAJOR_VERSION < 3 + PyObject *unicode = PyUnicode_FromEncodedObject(strValue, "utf-8", nullptr); + Py_XDECREF(strValue); strValue = unicode; +#endif + return pybind11::str(strValue, false); +} + class bytes : public object { public: PYBIND11_OBJECT_DEFAULT(bytes, object, PYBIND11_BYTES_CHECK)