-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a std::filesystem::path <-> os.PathLike caster. #2730
Conversation
I have been using such a caster for quite a while now and find it very useful. Looking at this PR
|
Thanks for pointing this out, I was not aware of that. I can confirm this is needed e.g. to make variant casters work. OTOH it looks like the docs at https://pybind11.readthedocs.io/en/stable/advanced/cast/custom.html#custom-type-casters are wrong? The example AFAICT the only relevant failing tests occur with versions of clang for which is it still necessary to link |
Looks like PyPy is actually broken per https://foss.heptapod.net/pypy/pypy/-/issues/3168. I just ifdef'd it out for now... |
Without looking into it in detail, would it be best to put this into I'm a fan, just trying to avoid any issues with disruption; users should not be required to link to the filesystem lib if they don't use it. If it only requires linking with the filesystem if really is used, then ignore this and it can stay here. |
Is clang 8 considered "pretty recent"? I guess it is.
Templates aren't instantiated if they aren't actually used. This should PR should be safe, though I can't guarantee.
It would definitely make |
Yes, for exactly the reason @bstaletic mentions; I think that's a good one. This might also be the moment to think about another PR where |
First attempt of that was 3 years ago in #1210. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An annoying question: is this something that should be in pybind11, rather than say ... an external plugin pybind11_filesystem
? I was first skeptical about this, but the actual implementation is rather clean/small, so I guess I'm OK with this.
I'd like to see pybind11 evolve to a more "plugin-based" architecture, but I guess this specific feature isn't a huge burden to maintain?
I wanted to suggest thinking about pathlib2
, for Python 2 (and PyPy 2, which isn't deprecated), but PyPy doesn't work, currently, ofc. And in Python 2 we still lack os.PathLike
and __fspath__
?
Next question: does this also accept strings? If not, should strings be accepted, maybe if convert == true
in load
? If they already are, a test on this would be nice.
Finally, a request: could this be turned into an abstraction like optional_caster
? Basically, this would rename the current caster, and just have template <> struct type_caster<std::filesystem::path> : public path_caster<std::filesystem::path> {};
.
This would allow for other C++ path-like type to quickly opt-in to this behavior, if they support a minimal interface (be constructible/assignable from std::string
and having .native()
or so).
This is just about the first thing I thought of. I'd do it boost-style, where you have: stl.h
stl/optional.h
stl/filesystem.h
stl/... Then |
That's indeed exactly the proposal of #1210 (long outdated and full of conflicts by now, ofc), and yes, that seems perfect to me :-) But so maybe we can keep this PR in |
Thanks for the reviews.
|
Indeed, let's keep this for another PR.
Thanks, I think that looks good! Potentially,
OK, fair enough; given that this is new functionality, I can live with not having this for Python 2 and 3.5, I think. Thanks for clarifying this further! |
Personally, I don't see a need for that. |
I think the only relevant failure remaining is with clang10, which is missing an explicit linking to -lc++fs. Any suggestions on how to achieve that? (my cmake-fu is pretty weak...) |
|
Uhmmm... Either way, this is how I've solved the problem in my project. |
Thanks, looks like everything is working now :) |
elseif(${STD_FS_NO_LIB_NEEDED}) | ||
set(STD_FS_LIB "") | ||
else() | ||
message(WARNING "Unknown compiler - not passing -lstdc++fs") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is likely wrong. The try_compile
failed in all three cases and we're going *shrug* "let's try it anyway!", so should probably be a fatal error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so? We could be on a compiler that doesn't support C++17 at all, in which case we'll be just fine, everything filesystem-related will be ifdef'd out anyways?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. My project received complaints from users hitting this branch, but I unconditionally depend on <filesystem>
. Maybe still wrap the whole block in an if ( standard is 17 )
or whatever the spelling is for cmake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this have to be done as part of this PR? TBH I'm not so comfortable with cmake...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can’t be done in CMake in general, too many ways someone could set the std level, though since it’s our tests we can do it. I can look at this later if it’s needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll throw in peanut-gallery 2 cents: Looks good for a starting point! Can address acute defects after merge?
Kindly bumping? |
rebased |
This also passed Google-internal global testing. Merging! |
I believe this broke support for building wheels that set anything less than macOS 10.15 (10.9 is the default, 10.12 is "safe", but 10.15 is painfully new). I thought I asked for this to be placed in a separate file? See #2730 (comment) |
I have tried to add things like this before to CLI11, and it's really hard to get right, especially for features that depend on compiled libraries being linked (like libfs), since you can't detect that at header time. Putting this in a separate file would have avoided this and made it opt in. |
Example of a broken build: https://github.com/deepmind/open_spiel/runs/2999582108 |
Sorry I missed that, with so many approvals I was thinking "What could possibly go wrong?" |
I clearly said exactly what could go wrong, it was just ignored. :P |
I told the open_spiel folks about this mishap. |
Just pull it out into a file and make it opt-in by including the file, say |
To solve breakages like: https://github.com/deepmind/open_spiel/runs/2999582108 Mostly following the suggestion here: pybind#2730 (comment) Except using pybind11/stl/filesystem.h instead of pybind11/stlfs.h, as decided via chat. stl.h restored to the exact state before merging PR pybind#2730 via: ``` git checkout 733f8de stl.h ```
* Splitting out pybind11/stl/filesystem.h. To solve breakages like: https://github.com/deepmind/open_spiel/runs/2999582108 Mostly following the suggestion here: #2730 (comment) Except using pybind11/stl/filesystem.h instead of pybind11/stlfs.h, as decided via chat. stl.h restored to the exact state before merging PR #2730 via: ``` git checkout 733f8de stl.h ``` * Properly including new stl subdirectory in pip wheel config. This now passes interactively: ``` pytest tests/extra_python_package/ ``` * iwyu cleanup. iwyuh.py -c -std=c++17 -DPYBIND11_TEST_BOOST -Ipybind11/include -I/usr/include/python3.9 -I/usr/include/eigen3 include/pybind11/stl/filesystem.h * Adding PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL. * Eliminating else after return.
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]> Signed-off-by: Trevor Gamblin <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]> Signed-off-by: Trevor Gamblin <[email protected]>
v2.7.0 (Jul 16, 2021) --------------------- New features: * Enable ``py::implicitly_convertible<py::none, ...>`` for ``py::class_``-wrapped types. `#3059 <https://github.com/pybind/pybind11/pull/3059>`_ * Allow function pointer extraction from overloaded functions. `#2944 <https://github.com/pybind/pybind11/pull/2944>`_ * NumPy: added ``.char_()`` to type which gives the NumPy public ``char`` result, which also distinguishes types by bit length (unlike ``.kind()``). `#2864 <https://github.com/pybind/pybind11/pull/2864>`_ * Add ``pybind11::bytearray`` to manipulate ``bytearray`` similar to ``bytes``. `#2799 <https://github.com/pybind/pybind11/pull/2799>`_ * ``pybind11/stl/filesystem.h`` registers a type caster that, on C++17/Python 3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any ``os.PathLike`` to ``std::filesystem::path``. `#2730 <https://github.com/pybind/pybind11/pull/2730>`_ * A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``. `#3120 <https://github.com/pybind/pybind11/pull/3120>`_ Signed-off-by: Zheng Ruoqin <[email protected]> Signed-off-by: Khem Raj <[email protected]> Signed-off-by: Trevor Gamblin <[email protected]>
Description
On C++17/Py3.6+, convert std::filesystem::path to pathlib.Path and os.PathLike to std::filesystem::path.
I don't know whether std::filesystem::path gets much usage, but pathlib.Path is certainly getting quite popular, so having a way to auto-handle it would be nice.
Suggested changelog entry: