diff --git a/example/example-python-types.cpp b/example/example-python-types.cpp index 5decede9a..429cf5eca 100644 --- a/example/example-python-types.cpp +++ b/example/example-python-types.cpp @@ -139,6 +139,22 @@ public: throw std::runtime_error("This exception was intentionally thrown."); } + py::bytes get_bytes_from_string() { + return std::string("foo"); + } + + py::bytes get_bytes_from_str() { + return py::str(std::string("bar")); + } + + py::str get_str_from_string() { + return std::string("baz"); + } + + py::str get_str_from_bytes() { + return py::bytes(std::string("boo")); + } + static int value; static const int value2; }; @@ -167,6 +183,10 @@ void init_ex_python_types(py::module &m) { .def("pair_passthrough", &ExamplePythonTypes::pair_passthrough, "Return a pair in reversed order") .def("tuple_passthrough", &ExamplePythonTypes::tuple_passthrough, "Return a triple in reversed order") .def("throw_exception", &ExamplePythonTypes::throw_exception, "Throw an exception") + .def("get_bytes_from_string", &ExamplePythonTypes::get_bytes_from_string, "py::bytes from std::string") + .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_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 b77a2c531..f743d8830 100755 --- a/example/example-python-types.py +++ b/example/example-python-types.py @@ -72,3 +72,8 @@ cstats = ConstructorStats.get(ExamplePythonTypes) print("Instances not destroyed:", cstats.alive()) instance = None print("Instances not destroyed:", cstats.alive()) + +print(instance.get_bytes_from_string().decode()) +print(instance.get_bytes_from_str().decode()) +print(instance.get_str_from_string()) +print(instance.get_str_from_bytes()) diff --git a/example/example-python-types.ref b/example/example-python-types.ref index 052cce0ea..6768d714e 100644 --- a/example/example-python-types.ref +++ b/example/example-python-types.ref @@ -28,106 +28,106 @@ Help on class ExamplePythonTypes in module example class EExxaammpplleePPyytthhoonnTTyyppeess(__builtin__.object) | Example 2 documentation - | + | | Methods defined here: - | + | | ____iinniitt____(...) | x.__init__(...) initializes x; see help(type(x)) for signature - | + | | ggeett__aarrrraayy(...) - | + | | Signature : (example.ExamplePythonTypes) -> List[unicode[2]] | Return a C++ array - | + | | ggeett__ddiicctt(...) | Signature : (example.ExamplePythonTypes) -> dict - | + | | Return a Python dictionary - | + | | ggeett__ddiicctt__22(...) - | + | | Signature : (example.ExamplePythonTypes) -> Dict[unicode, unicode] | Return a C++ dictionary - | + | | ggeett__lliisstt(...) | Signature : (example.ExamplePythonTypes) -> list - | + | | Return a Python list - | + | | ggeett__lliisstt__22(...) - | + | | Signature : (example.ExamplePythonTypes) -> List[unicode] | Return a C++ list - | + | | ggeett__sseett(...) | Signature : (example.ExamplePythonTypes) -> set - | + | | Return a Python set - | + | | ggeett__sseett22(...) | Signature : (example.ExamplePythonTypes) -> set - | + | | Return a C++ set - | + | | ppaaiirr__ppaasssstthhrroouugghh(...) - | + | | Signature : (example.ExamplePythonTypes, Tuple[bool, unicode]) -> Tuple[unicode, bool] | Return a pair in reversed order - | + | | pprriinntt__aarrrraayy(...) - | + | | Signature : (example.ExamplePythonTypes, List[unicode[2]]) -> None | Print entries of a C++ array - | + | | pprriinntt__ddiicctt(...) - | + | | Signature : (example.ExamplePythonTypes, dict) -> None | Print entries of a Python dictionary - | + | | pprriinntt__ddiicctt__22(...) - | + | | Signature : (example.ExamplePythonTypes, Dict[unicode, unicode]) -> None | Print entries of a C++ dictionary - | + | | pprriinntt__lliisstt(...) - | + | | Signature : (example.ExamplePythonTypes, list) -> None | Print entries of a Python list - | + | | pprriinntt__lliisstt__22(...) - | + | | Signature : (example.ExamplePythonTypes, List[unicode]) -> None | Print entries of a C++ list - | + | | pprriinntt__sseett(...) - | + | | Signature : (example.ExamplePythonTypes, set) -> None | Print entries of a Python set - | + | | pprriinntt__sseett__22(...) - | + | | Signature : (example.ExamplePythonTypes, Set[unicode]) -> None | Print entries of a C++ set - | + | | tthhrrooww__eexxcceeppttiioonn(...) - | + | | Signature : (example.ExamplePythonTypes) -> None | Throw an exception - | + | | ttuuppllee__ppaasssstthhrroouugghh(...) - | + | | Signature : (example.ExamplePythonTypes, Tuple[bool, unicode, int]) -> Tuple[int, unicode, bool] | Return a triple in reversed order - | + | | ---------------------------------------------------------------------- | Data and other attributes defined here: - | + | | ____nneeww____ = | T.__new__(S, ...) -> a new object with type S, a subtype of T - | + | | nneeww__iinnssttaannccee = | Signature : () -> example.ExamplePythonTypes - | + | | Return an instance __name__(example) = example @@ -138,3 +138,8 @@ __module__(example.ExamplePythonTypes.get_set) = example Instances not destroyed: 1 ### ExamplePythonTypes @ 0x1045b80 destroyed Instances not destroyed: 0 +Destructing ExamplePythonTypes +foo +bar +baz +boo diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index db87b088a..cc0e3a22a 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -339,6 +339,8 @@ inline iterator handle::begin() const { return iterator(PyObject_GetIter(ptr()), inline iterator handle::end() const { return iterator(nullptr, false); } inline detail::args_proxy handle::operator*() const { return detail::args_proxy(*this); } +class bytes; + class str : public object { public: PYBIND11_OBJECT_DEFAULT(str, object, detail::PyUnicode_Check_Permissive) @@ -367,6 +369,8 @@ public: pybind11_fail("Unable to extract string contents! (invalid type)"); return std::string(buffer, (size_t) length); } + + operator bytes() const; }; inline pybind11::str handle::str() const { @@ -395,8 +399,18 @@ public: pybind11_fail("Unable to extract bytes contents!"); return std::string(buffer, (size_t) length); } + + operator pybind11::str() const; }; +inline str::operator bytes() const { + return bytes((std::string) *this); +} + +inline bytes::operator pybind11::str() const { + return pybind11::str((std::string) *this); +} + class none : public object { public: PYBIND11_OBJECT(none, object, detail::PyNone_Check)