Skip to content

Commit

Permalink
add support for casting std::filesystem::path
Browse files Browse the repository at this point in the history
  • Loading branch information
skoslowski committed Oct 27, 2020
1 parent 0234871 commit 767ac4d
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions include/pybind11/stl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
# include <variant>
# define PYBIND11_HAS_VARIANT 1
# endif
// std::variant
# if defined(PYBIND11_CPP17) && __has_include(<filesystem>)
# include <filesystem>
# define PYBIND11_HAS_FILESYSTEM 1
# endif
#elif defined(_MSC_VER) && defined(PYBIND11_CPP17)
# include <optional>
# include <variant>
Expand Down Expand Up @@ -372,6 +377,43 @@ template <typename... Ts>
struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> { };
#endif

#if PYBIND11_HAS_FILESYSTEM && ((PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 6) || PY_MAJOR_VERSION >= 4)
template <> struct type_caster<std::filesystem::path>
{
public:
PYBIND11_TYPE_CASTER(std::filesystem::path, _("path_like"));

bool load(handle src, bool)
{
auto fs_encoded = reinterpret_steal<object>(PyOS_FSPath(src.ptr()));
if (!fs_encoded)
{
PyErr_Clear();
return false;
}
if (PyBytes_Check(fs_encoded.ptr())) // fs_encoded may be bytes or unicode
fs_encoded = reinterpret_steal<object>(PyUnicode_DecodeFSDefault(PyBytes_AS_STRING(fs_encoded.ptr())));

auto size = Py_ssize_t{};
auto buffer = PyUnicode_AsUTF8AndSize(fs_encoded.ptr(), &size);
if (! buffer)
{
PyErr_Clear();
return false;
}

value = std::filesystem::u8path(buffer, buffer + size);
return true;
}

static handle cast(std::filesystem::path src, return_value_policy /* policy */, handle /* parent */)
{
auto data = src.u8string();
return PyUnicode_DecodeUTF8(data.data(), data.size(), nullptr /* usually means strict */);
}
};
#endif

NAMESPACE_END(detail)

inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
Expand Down

0 comments on commit 767ac4d

Please sign in to comment.