-
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
feat: setup.py redesign and helpers #2433
Conversation
af17c99
to
b2d0928
Compare
cc035a8
to
2337cfe
Compare
Question for others now or for me later: Are there any things in https://github.com/matplotlib/mplcairo 's setup.py that we might want to include? Is it easy to further adjust the helper we provide to add the specific parts (I think so)? |
(I force-pushed a rebase + a few typo corrections in docs) |
This was intended as a proof of concept; build seems to be the correct replacement. See pypa/pyproject-hooks#83
496f843
to
e541907
Compare
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 had another look at this PR. @ktbarrett, and @henryiii, thanks for these very detailed and helpful explanations above. I think I understand the problem now, and why these changes are necessary.
I feel like the documentation still needs some work, especially the parts in CONTRIBUTING.md
-- this file is full of tooling and packaging jargon. I haven't been working much with these fancy new tools and find parts of the explanation just incomprehensible. It don't think this is a big problem though -- much of the explanation on the PR discussion here explains the subtleties, and that information can be put into a linear structure and replace some of the text that is currently in CONTRIBUTING.md
.
@@ -25,6 +25,13 @@ Usage of the ``PYBIND11_OVERLOAD*`` macros and ``get_overload`` function should | |||
be replaced by ``PYBIND11_OVERRIDE*`` and ``get_override``. In the future, the | |||
old macros may be deprecated and removed. | |||
|
|||
The ``pybind11`` package on PyPI no longer fills the wheel "headers" slot - if | |||
you were using the headers from this slot, they are available by requesting the | |||
``global`` extra, that is, ``pip install "pybind11[global]"``. (Most users will |
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.
Really stupid question: does this mean that there will be two separate packages on PyPI, or is [global]
some kind of flag that affects the behavior of Pip when installing the package?
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. The thing in brackets is called an "extra", short for extra requirements, and is supported everywhere in the Python packaging ecosystem; requirements lists, pip, pyproject.toml, etc. They are commonly used to add [test]
requirements, for example - see Pandas. You'll also see setuptools_scm[toml]
, which is how you ensure you have the toml parser so you can use pyproject.toml
+ setuptools_scm
. It can only enable extra packages as install requirements, not arbitrary changes. The extra requirement it enables in this case is a package called pybind11-global
, which I'll explain above. But this is the public suggestion for adding it.
@YannickJadoul and @wjakob, here's an example of what a dual-source version would look like. You'd have to update the version twice instead of once, but you do get a pretty immediate error in CI or when running setup.py if the versions don't match. I generally like reducing duplication on something that tends to get changed, but it does make things a bit simpler. |
two packages; the "nice" pybind11 package that stores the includes and CMake | ||
files inside the package, that you get access to via functions in the package, | ||
and a `pybind11-global` package that can be included via `pybind11[global]` if | ||
you want the more invasive but discoverable file locations. |
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 intro paragraph is so much better now, thanks for that!
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.
One more stupid question: what does pip install pybind11[global]
do if pybind11
is already installed?
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.
It just installs pybind11-global
. Just as if you wrote pip install pybind11 pybind11-global
and already have pybind11 installed. The only special feature is that they are version-locked (with the bracket syntax) and you get both of them.
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.
Great, thank you for the clarification.
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.
approved by me (modulo having the version number in two places, as discussed on Slack)
Thanks a lot, @henryiii! Especially for the patience and numerous times you re-explained stuff :-) |
Part 1 of ~3 for the Python packaging work (the main part). The other two will be very small (possibly with no code changes in part 3).
Requirements
The requirements to build from source have increased significantly, to build from the sdist have increased slighly, and the universal wheel requirements have not changed.
cmake 3.15+
, ninja or make, and setuptools 30.3.0+; valid compilers.Design:
pybind11
is now a "nice" python package, with files only in thesite-packages/pybind11
dir.headers
slot and (new for pybind11)data
slot that install to your environment root are now only installed if you ask forpybind11[global]
.The core implementation is that there is a develop
setup.py
andpyproject.toml
that work with CMake, but sdists get a much simpler, CMake-freetools/setup_main.py
(ortools/setup_global.py
). (note this trick is required for CMake/non-CMake requirement, not for global/regular. See the first commit if you want to see a version that did not do this, but was much more complex, and didn't solve thepyproject.toml
cmake dependency issue either). Single-sourcing the version depends on this infrastructure, too.Features:
Key highlights are CMake configuration support, setuptools helpers, including new Windows support (when compared to the official example repository), sdist/wheel building on CI, and packaging & setup tests.
__init__.py
scope)python_requires
)pyproject.toml
to ensure CMake is available to build the sdist / wheel from source (note that building from sdist does not require cmake, just from GitHub source)get_cmake_dir()
, see below)Aside on where to put the files
There are three possible places to put the includes (and CMake header files):
pybind11
, and is the best place for access from Python.pybind11-2.6.0.dev1.data/headers
. This is done in versions < 2.6, these are where Python sort-of expects headers (For testing mostly so far). However, since version 2.5 or so, pybind11's function return method 1 locations, since these have some issues. I'm proposing in this PR to move this location to a separate package "pybind11-global
" (or other name)<prefix>/include/Python3.8m/pybind11
usuallypip install pybind11
without a virtual environment.pybind11-2.6.0.dev1.data/data
. This allows "normal" nesting, that is, CMake works correctly. It also is in the ideal place for discovery or manual includes. Added topybind11-global
<prefix>/include/pybind11
and<prefix>/share/cmake/pybind11
.The problem with methods 2 & 3 are that they install to
<prefix>
, which is not always a good idea if you do not use PEP 518 or virtual environments to install pybind11. Brew, for example, throws warnings when unbrewed files are in/user/local
. In part 3, I want to make this work correctly with CMake and Scikit-build-like installs, so having this be discoverable by CMake is important. So I've created a way to produce an alternate package,pybind11-global
, which has methods 2 & 3 and is installed as an extra,pybind11[global]
.Further work
I have part 2 basically ready, which adds a shiny new feature on the shared distutils infrastructure (privately previewed to @YannickJadoul). Part 3 will add testing / instructions for CMake builds based on the python package (possibly with no changes to pybind11 itself). I will also add publish to PyPI to GHA later.
Warning example with pybind11 2.5.0:
Questions
Is
pybind11-inplace
a good name?pybind11-global
,pybind11-alt
, andpybind11-cpp
are some other ideas.pybind11-core
is not a good idea, as that implies thatpybind11
depends on it.Currently
pybind11-global
seems to be winning, switched to that.