Skip to content

Commit 767ac4d

Browse files
committed
add support for casting std::filesystem::path
1 parent 0234871 commit 767ac4d

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

include/pybind11/stl.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
# include <variant>
4242
# define PYBIND11_HAS_VARIANT 1
4343
# endif
44+
// std::variant
45+
# if defined(PYBIND11_CPP17) && __has_include(<filesystem>)
46+
# include <filesystem>
47+
# define PYBIND11_HAS_FILESYSTEM 1
48+
# endif
4449
#elif defined(_MSC_VER) && defined(PYBIND11_CPP17)
4550
# include <optional>
4651
# include <variant>
@@ -372,6 +377,43 @@ template <typename... Ts>
372377
struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> { };
373378
#endif
374379

380+
#if PYBIND11_HAS_FILESYSTEM && ((PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 6) || PY_MAJOR_VERSION >= 4)
381+
template <> struct type_caster<std::filesystem::path>
382+
{
383+
public:
384+
PYBIND11_TYPE_CASTER(std::filesystem::path, _("path_like"));
385+
386+
bool load(handle src, bool)
387+
{
388+
auto fs_encoded = reinterpret_steal<object>(PyOS_FSPath(src.ptr()));
389+
if (!fs_encoded)
390+
{
391+
PyErr_Clear();
392+
return false;
393+
}
394+
if (PyBytes_Check(fs_encoded.ptr())) // fs_encoded may be bytes or unicode
395+
fs_encoded = reinterpret_steal<object>(PyUnicode_DecodeFSDefault(PyBytes_AS_STRING(fs_encoded.ptr())));
396+
397+
auto size = Py_ssize_t{};
398+
auto buffer = PyUnicode_AsUTF8AndSize(fs_encoded.ptr(), &size);
399+
if (! buffer)
400+
{
401+
PyErr_Clear();
402+
return false;
403+
}
404+
405+
value = std::filesystem::u8path(buffer, buffer + size);
406+
return true;
407+
}
408+
409+
static handle cast(std::filesystem::path src, return_value_policy /* policy */, handle /* parent */)
410+
{
411+
auto data = src.u8string();
412+
return PyUnicode_DecodeUTF8(data.data(), data.size(), nullptr /* usually means strict */);
413+
}
414+
};
415+
#endif
416+
375417
NAMESPACE_END(detail)
376418

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

0 commit comments

Comments
 (0)