-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Splitting out pybind11/stl/filesystem.h. #3077
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
Conversation
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 ```
#ifdef __has_include | ||
# if defined(PYBIND11_CPP17) && __has_include(<filesystem>) && \ | ||
PY_VERSION_HEX >= 0x03060000 | ||
# include <filesystem> | ||
# define PYBIND11_HAS_FILESYSTEM 1 | ||
# endif | ||
#endif |
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.
Just a thought, do we need this PYBIND11_HAS_FILESYSTEM
now? If I include <stl/filesystem.h>
do I want it to silently not cast things instead of getting a compile-time 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.
(If not, it should be moved to the include in the test ;) )
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.
(If not, it should be moved to the include in the test ;) )
Copying my question from the slack channel here:
In this first pass, I simply kept the #ifdef block defining PYBIND11_HAS_FILESYSTEM in the header file. Does that still make sense? Would it be better to move that to the test? — It seem useful to keep it in the header, so others can easily use it if available without having to do anything much otherwise, but I'm not sure how this shakes out best.
Ideally we'd give people a choice? Bail out with a compile-time error or have them handle the runtime error.
It's not really great if we lead users down the path of copy-pasting the __has_include
logic from the test.
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.
But do users want "works if available" behavior for this? (The answer may be yes) It seems a little weird if your package only accepts pathlib.Path
arguments if it was compiled in C++17 mode on some compilers. And only allows you to return std::filesystem on Python 3 (though that I'm less worried about). I'm guessing there will be some extra work most users will have to do to make sure this works (including requiring macOS 10.15+), so forcing the user to explicit might be better.
That is, I expect most users will either make an effort to support std::filesystem/pathlib everywhere, or they will not support it, but very few will support it if available. But could easily be wrong. I don't find the "auto" selection of C++ level all that useful either (setuptools helpers), but some users want it.
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'm okay to leave it as is, a user (who looks at the source) can check PYBIND11_HAS_FILESYSTEM
if they want. But I'm also okay to (re)move it to the tests.
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.
__has_include
is not actually a C++17 feature, it's a C++20 one. Though I think all major compilers added it very early, but still, maybe it's best to remove this and just #include
filesystem and let the failure happen if it's not available, rather than calling #error
. This then makes PYBIND11_HAS_FILESYSTEM
rather weird, though.
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.
@henryiii This page suggest it is a C++17 feature though? https://en.cppreference.com/w/cpp/preprocessor/include
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.
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.
__has_include
currently appears in 10 source code locations on master (see below).
If think for this PR it's important to stay focused on the one problem we want to solve as soon as possible: users shouldn't be forced to work on the link options if they don't actually want to use the new caster. I'll update the PR description accordingly.
include/pybind11/cast.h:# if defined(__has_include)
include/pybind11/cast.h:# if __has_include(<string_view>)
include/pybind11/stl.h:#ifdef __has_include
include/pybind11/stl.h:# if defined(PYBIND11_CPP17) && __has_include(<optional>)
include/pybind11/stl.h:# if defined(PYBIND11_CPP14) && (__has_include(<experimental/optional>) && \
include/pybind11/stl.h: !__has_include(<optional>))
include/pybind11/stl.h:# if defined(PYBIND11_CPP17) && __has_include(<variant>)
include/pybind11/stl.h:# if defined(PYBIND11_CPP17) && __has_include(<filesystem>) && \
include/pybind11/detail/common.h:#if defined(__has_include)
include/pybind11/detail/common.h:# if __has_include(<version>)
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.
Yes, @Skylion007 is correct, I was muddling has_include with feature test macros - probably shouldn't comment on things while in a conference. :)
This plans seems fine, we need to fix this, then we can polish and or document a bit more later if needed.
include/pybind11/stl/filesystem.h
Outdated
if (PyErr_Occurred()) { | ||
PyErr_Clear(); | ||
return false; | ||
} else { |
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.
else after return is not ideal style.
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.
Yes, it's called "guard" style to put the short returning branch at the top without an else, and it's preferable.
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.
@henryiii Plan on enabling a clang-tidy check for this soon.
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.
else after return is not ideal style.
Done.
Need to fix some of the pip tests. |
There's a place or two where this needs to be added to the Python build system too. I'd do a quick |
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.
Edit the lists as @henryiii suggested.
include/pybind11/stl/filesystem.h
Outdated
if (PyErr_Occurred()) { | ||
PyErr_Clear(); | ||
return false; | ||
} else { |
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.
@henryiii Plan on enabling a clang-tidy check for this soon.
I tried that already but apparently I need to do something more involved because |
One Python 2 failure is our random known flake, the other is just the packaging test (which happens to be Python 2 as well), which tests the file list. We already have some directories (like detail) so whatever we do for that should work? |
This now passes interactively: ``` pytest tests/extra_python_package/ ```
No good deed gets unpunished ... I think I finally figured it out. (I overlooked the tools directory longer than I'd like to admit.) |
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
Happy day, the mac os straggler made it :-) @henryiii I hope this PR is final now, could you please review and approve if this looks good to you? |
I don't think any of the CI's are going to catch this, but with clang before 9 and gcc before 9 (or any clang with stdlibc++ before before 9) you also need to link with https://github.com/oxen-io/lokinet/blob/dev/cmake/check_for_std_filesystem.cmake is some cmake code we wrote to deal with figuring out the linking mess. |
There is a cmake community module for FileSystem: https://github.com/vector-of-bool/CMakeCM/blob/master/modules/FindFilesystem.cmake |
This is why I liked just making it an error if It's not our responsibility to provide support for filesystem for the user, just for allowing conversion if a user already supports it. IMO. But docs on how to use it, including links to CMake modules that do the linking, etc, are fine and useful. (and the above caveats). |
Yes exactly. This is the issue meant to be solved by this PR.
These could be nice follow-on PRs. |
Unfortunately PR #2730 forces users of pybind11/stl.h to link against
-lstdc++fs
(or similar, depending on the platform) even if they don't actually use the new type caster. This issue is resolved here by moving the new type caster to pybind11/stl/filesystem.h. Thestd::filessytem
-related link options will be needed only if the new header is included.Further refinements of the cmake files (see PR comments) is beyond the scope of this PR and left for follow-on PRs.
Example breakage due to PR #2730: https://github.com/deepmind/open_spiel/runs/2999582108
This PR is 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:
NOTE: The #2730 change log entry was edited after this PR was merged.