PEP for specifying build dependencies
Donald, Nathaniel, and I have finished our proposed PEP for specifying a
projects' build dependencies. The PEP is being kept at
https://github.com/brettcannon/build-deps-pep, so if you find spelling
mistakes and grammatical errors please feel free to send a PR to fix them.
The only open issue in the PEP at the moment is the bikeshedding topic of
what to name the sub-section containing the requirements: `[package.build]`
or `[package.build-system]` (we couldn't reach consensus among the three of
us on this). Otherwise the three of us are rather happy with the way the
PEP has turned out and look forward to this being the first step towards
allowing projects to customize their build process better!
-----
PEP: NNN
Title: Specifying build dependencies for Python Software Packages
Version: $Revision$
Last-Modified: $Date$
Author: Brett Cannon
On Tue, May 10, 2016 at 5:39 PM, Brett Cannon
Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
Thanks Brett!
The only open issue in the PEP at the moment is the bikeshedding topic of what to name the sub-section containing the requirements: `[package.build]` or `[package.build-system]` (we couldn't reach consensus among the three of us on this).
To maybe help nudge initial bikeshedding on this in useful directions, the main arguments (IIUC) were: In favor of "build-system": setup.py is used for more than just the strict "build" (source tree/sdist -> wheel) phase. For example, setup.py is also used to do VCS checkout -> sdist. And it seems likely that the new build system abstraction thing will grow similar capabilities at some point. So calling the section just "build" might be misleading. In favor of "build": it's just shorter and reads better. Maybe there's a third option that's even better -- [package.automation] ? Maybe it doesn't matter that much :-) -n -- Nathaniel J. Smith -- https://vorpus.org
On Tue, May 10, 2016 at 8:24 PM, Nathaniel Smith
On Tue, May 10, 2016 at 5:39 PM, Brett Cannon
wrote: Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
Thanks Brett!
The only open issue in the PEP at the moment is the bikeshedding topic of what to name the sub-section containing the requirements: `[package.build]` or `[package.build-system]` (we couldn't reach consensus among the three of us on this).
To maybe help nudge initial bikeshedding on this in useful directions, the main arguments (IIUC) were:
In favor of "build-system": setup.py is used for more than just the strict "build" (source tree/sdist -> wheel) phase. For example, setup.py is also used to do VCS checkout -> sdist. And it seems likely that the new build system abstraction thing will grow similar capabilities at some point. So calling the section just "build" might be misleading.
In favor of "build": it's just shorter and reads better.
Maybe there's a third option that's even better -- [package.automation] ?
Maybe it doesn't matter that much :-)
I think "build-system" is more descriptive and the more descriptive we can be, the better. (Think of choosing descriptive method and attribute names as well as variables.)
On May 10, 2016, at 9:43 PM, Ian Cordasco
wrote: On Tue, May 10, 2016 at 8:24 PM, Nathaniel Smith
wrote: On Tue, May 10, 2016 at 5:39 PM, Brett Cannon
wrote: Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
Thanks Brett!
The only open issue in the PEP at the moment is the bikeshedding topic of what to name the sub-section containing the requirements: `[package.build]` or `[package.build-system]` (we couldn't reach consensus among the three of us on this).
To maybe help nudge initial bikeshedding on this in useful directions, the main arguments (IIUC) were:
In favor of "build-system": setup.py is used for more than just the strict "build" (source tree/sdist -> wheel) phase. For example, setup.py is also used to do VCS checkout -> sdist. And it seems likely that the new build system abstraction thing will grow similar capabilities at some point. So calling the section just "build" might be misleading.
In favor of "build": it's just shorter and reads better.
Maybe there's a third option that's even better -- [package.automation] ?
Maybe it doesn't matter that much :-)
I think "build-system" is more descriptive and the more descriptive we can be, the better. (Think of choosing descriptive method and attribute names as well as variables.)
I’m in favor of “build”, mostly because I think [package.build-system] requires = [“setuptools”, “wheel”] is uglier than [package.build] requires = [“setuptools, “wheel”] and I think for 99% of people the distinction is going to be lost anyways. That being said, I think either one is OK. ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
On Tue, May 10, 2016 at 8:47 PM, Donald Stufft
On May 10, 2016, at 9:43 PM, Ian Cordasco
wrote: I think "build-system" is more descriptive and the more descriptive we can be, the better. (Think of choosing descriptive method and attribute names as well as variables.) I’m in favor of “build”, mostly because I think
[package.build-system] requires = [“setuptools”, “wheel”]
is uglier than
Oh, absolutely it's ugly, but reading it aloud is what makes me prefer it. "The package's build-system requires setuptools, and wheel" Granted, Ruby is the perfect example of trying to make something read perfectly like English being a terrible idea when taken to extremes, but I don't think that will happen here. Other than that, the PEP looks fine. I'm anti-TOML but for reasons that don't deserve being brought up on the mailing list. It's the best option of a bunch of bad options. The rest of the PEP looks great.
On 11 May 2016 at 12:39, Brett Cannon
Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
The only open issue in the PEP at the moment is the bikeshedding topic of what to name the sub-section containing the requirements: `[package.build]` or `[package.build-system]` (we couldn't reach consensus among the three of us on this). Otherwise the three of us are rather happy with the way the PEP has turned out and look forward to this being the first step towards allowing projects to customize their build process better!
I find calling this build dependencies confusing, but perhaps thats just me.
Right now the work flow is this:
unpack tarball
run setup.py egg-info
introspect that for dependencies
download and install such dependencies (recursively) [ in future, it
would resolve ]
run setup.py install || setup.py wheel
install
1) What would pip do when it encounters one of these files?
unpack tarball
introspect and prepare an isolated environment with the specified dependencies
run setup.py egg_info
download and install such runtime dependencies (recursively) [ in
future, it would resolve ]
run setup.py install || setup.py wheel
install
?
Right now setup.py dependencies are turing complete, and its a useful
escape valve - this design seems to have no provision for that
(previous designs we've had here have had that). If the declared
dependencies are merely those needed to be able to invoke the build
system, rather than those needed to be able to successfully build, it
would preserve that escape valve.
2) what do we expect setuptools to do here? Is it reasonable to
introspect this file and union it with setup_requires?
3) Why does this specify ' what dependencies are required to go from
source checkout to built wheel' ? - build systems also run tests,
generate docs and man pages, produce other artifacts. Perhaps making
either the target more specific (wheel_requires = ...) or the
description less specific ('dependencies required to invoke the build
system') would be good.
I am not suggesting that we model all the things a build system might
do: thats YAGNI at best, scope creep at worst.
-Rob
--
Robert Collins
On May 10, 2016, at 9:27 PM, Robert Collins
wrote: On 11 May 2016 at 12:39, Brett Cannon
wrote: Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
The only open issue in the PEP at the moment is the bikeshedding topic of what to name the sub-section containing the requirements: `[package.build]` or `[package.build-system]` (we couldn't reach consensus among the three of us on this). Otherwise the three of us are rather happy with the way the PEP has turned out and look forward to this being the first step towards allowing projects to customize their build process better!
I find calling this build dependencies confusing, but perhaps thats just me.
Right now the work flow is this:
unpack tarball run setup.py egg-info introspect that for dependencies download and install such dependencies (recursively) [ in future, it would resolve ] run setup.py install || setup.py wheel install
1) What would pip do when it encounters one of these files? unpack tarball introspect and prepare an isolated environment with the specified dependencies run setup.py egg_info download and install such runtime dependencies (recursively) [ in future, it would resolve ] run setup.py install || setup.py wheel install
?
Yes
Right now setup.py dependencies are turing complete, and its a useful escape valve - this design seems to have no provision for that (previous designs we've had here have had that). If the declared dependencies are merely those needed to be able to invoke the build system, rather than those needed to be able to successfully build, it would preserve that escape valve.
I think the way this will eventually end up going, is that when we get to the point of adding that next PEP that allows us to swap out setup.py for a totally different interface, is that we'll add something like bootstrap_requires or something, and do something like "If package.build.requires exists, we'll use that for build dependencies, else we'll invoke some API in the ABS to get them". Thus this lets us do the simple thing now, and in the future we can layer on additional things in a backwards compatabile way that *also* keeps the simple case simple and allows the advanced case to happen.
2) what do we expect setuptools to do here? Is it reasonable to introspect this file and union it with setup_requires?
I think setuptools should just ignore this file when invoking setup.py directly (maybe raise an error if something doesn’t exist) because I think the common pattern is going to be using real, top level imports of the stuff depended on here so it won’t have a chance to setup_requires them prior to executing. I think that easy_install should behave similarly to pip though.
3) Why does this specify ' what dependencies are required to go from source checkout to built wheel' ? - build systems also run tests, generate docs and man pages, produce other artifacts. Perhaps making either the target more specific (wheel_requires = ...) or the description less specific ('dependencies required to invoke the build system') would be good.
I think the description just wasn't fully thought out. I believe that "dependencies to invoke the build system" is closer to what I've been viewing this as (particularly since with setup.py the way it is, it's hard to differentiate between the different "roles" of why you might be invoking setup.py). ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
On Tue, May 10, 2016 at 6:45 PM, Donald Stufft
I think the way this will eventually end up going, is that when we get to the point of adding that next PEP that allows us to swap out setup.py for a totally different interface, is that we'll add something like bootstrap_requires or something, and do something like "If package.build.requires exists, we'll use that for build dependencies, else we'll invoke some API in the ABS to get them".
Hmm, it's not something we have to decide now, but given this roadmap: Now: - a way to specify static requirements before running setup.py Later: - (definitely) a static method for specifying requirements that need to be fulfilled before running the build backend at all ("bootstrap requirements") - (probably) a way to dynamically query the build backend for extra requirements before building a wheel - (maybe) some sort of optimization where we skip the dynamic query if the right static configuration is provided ...I think the simplest way to manage the transition is if we make the-thing-we're-adding-now map to the future "bootstrap requirements". That way we won't have to change the semantics at all. And if we decide we want some sort of static-build-requirements-optimization thing we can make that the new key that we add later. -n -- Nathaniel J. Smith -- https://vorpus.org
On Tue, May 10, 2016 at 6:27 PM, Robert Collins
If the declared dependencies are merely those needed to be able to invoke the build system, rather than those needed to be able to successfully build, it would preserve that escape valve.
My understanding is that this is exactly the intention -- these are the requirements you need before you can run setup.py or whatever replaces setup.py; it doesn't stop us from providing something like PEP 516/517's build requirements. [Reminder for those following along: in the current PEP 516/517 drafts, the sequence goes like: (1) pip consults the static list of "bootstrap" requirements, and makes those available, (2) pip invokes the build backend to ask it if it has any dynamic "build" requirements, (3) pip makes those available, (4) pip invokes the build backend again to run the actual build. So Robert's being bothered at the implication that this PEP might do away with steps (2)-(3).] The awkward bit is that this distinction really only makes sense in "phase 2", once we add the pluggable build backend stuff. The PEP's written to target "phase 1", where we're still assuming setup.py as the only build system, so we're going from "no working build requirements" to "working static build requirements". That doesn't stop us from taking the next step later. I guess the PEP text introduction could be clearer about this somehow. -n -- Nathaniel J. Smith -- https://vorpus.org
On 05/10/2016 05:39 PM, Brett Cannon wrote:
Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies.
Looks great! Thanks to all three of you! +1 to build-system. It's entirely possible to have other sections with the word 'build' in them, so it's better to be more explicit now. -- ~Ethan~
On 05/10/2016 08:39 PM, Brett Cannon wrote:
The build dependencies will be stored in a file named ``pyproject.toml``
[...snip...]
A top-level ``[package]`` table will represent details specific to the package that the project contains.
[...snip...]
Rejected Ideas ==============
pypackage.toml & pypackaging.toml Name conflation of what a "package" is (project versus namespace).
I know this is in the rejected ideas, but I'd like to point out that there is an inconsistency here that bothers me. If the top-level namespace in the file is going to be "package" then it makes sense to me that the file would also be named "py*package*.yaml". It seems like the term "package", while possibly running into the the "conflation issue", is a pretty solid term to build on. * Python *Packaging* Authority (PyPA) * http://python-*packaging*-user-guide.readthedocs.io/en/latest/ * http://the-hitchhikers-guide-to-*packaging*.readthedocs.io/en/latest/introdu... * docs.python-guide.org/en/latest/shipping/*packaging*/ * Top-level [*package*] namespace for the pep * From the PEP "This PEP specifies how Python software*packages* should specify their build dependencies" * "As of March 2013, the Python *packaging* ecosystem is currently in a rather confusing state." [1] Given the proliferation of the term "package" in describing exactly what this file is about, I'd really like to see the file name reconsidered to be "pypackag[e|ing].toml". Python "packaging", at least in the discussions I follow and am involved is, is becoming _the term_ to refer to this part of the Python ecosystem. IMO, the term "project" is more ambiguous, it could possibly refer to a lot of things. So, IMO, if you are just weighing the two terms on possibility for misunderstanding, "packaging" may get docked a point for being conflated with a python top-level module namespace but project should equally get docked a point for just being too generic AND another point for not matching the top-level config namespace of the file. If you add in the fact that "packaging" is used frequently in the Python ecosystem now to refer to the process of bundling up and installing a python source tree, that's like +5 for "pypackag[e|ing].toml". And, if the case of conflation still feels strong, then surly using "pypackaging.toml" would have to remove most of the confusion. Although, I'd prefer "pypackage.toml" myself. I suppose, if its possible the file would ever have a different top-level config namespace other than "package" so that information related to non-packaging issues could possible end up here (like maybe tox or flake8 starting to read config from here instead of from setup.cfg) then I don't think I'd feel as strongly about "pyproject.toml" being too generic. Although, we could be a bit cagy and make a play on "crate" by using a synonym "carton" (carton.toml, pycarton.toml) which, interestingly, sometimes hold eggs. ;) Thanks. [1] http://python-notes.curiousefficiency.org/en/latest/pep_ideas/core_packaging... *Randy Syring* Husband | Father | Redeemed Sinner /"For what does it profit a man to gain the whole world and forfeit his soul?" (Mark 8:36 ESV)/
On May 10, 2016 20:53, "Randy Syring"
[...]
I suppose, if its possible the file would ever have a different top-level
config namespace other than "package" so that information related to non-packaging issues could possible end up here (like maybe tox or flake8 starting to read config from here instead of from setup.cfg) then I don't think I'd feel as strongly about "pyproject.toml" being too generic. Look again :-) "All other top-level keys and tables are reserved for future use by other PEPs except for the ``[tool]`` table. Within that table, tools can have users specify configuration data as long as they use a sub-table within ``[tool]``, e.g. the `flit https://pypi.python.org/pypi/flit`_ tool might store its configuration in ``[tool.flit]``. We need some mechanism to allocate names within the ``tool.*`` namespace, to make sure that different projects don't attempt to use the same sub-table and collide. Our rule is that a project can use the subtable ``tool.$NAME`` if, and only if, they own the entry for ``$NAME`` in the Cheeseshop/PyPI. " (Maybe should be more prominent I guess?) -n
On 11 May 2016 at 10:39, Brett Cannon
Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
The only open issue in the PEP at the moment is the bikeshedding topic of what to name the sub-section containing the requirements: `[package.build]` or `[package.build-system]` (we couldn't reach consensus among the three of us on this). Otherwise the three of us are rather happy with the way the PEP has turned out and look forward to this being the first step towards allowing projects to customize their build process better!
I prefer [package.build-system]. My rationale for that is that the build system may have *its own* configuration mechanism, separate from this file, and I don't want people to get confused between a project's "build settings" and its "build system identification". Take the default case: for a distutils/setuptools based project, the actual build settings are the arguments to setup() in setup.py, *not* these new settings in pyproject.toml. By contrast, the settings in [package.build-system] are the ones that tell pip and other installers what is needed to make "setup.py bdist_wheel" work (and, in the future, will tell them when to invoke something other than "setup.py bdist_wheel" to do the binary build)
For the vast majority of Python projects that rely upon setuptools, the ``pyproject.toml`` file will be::
[package.build-system] requires = ['setuptools', 'wheel'] # PEP 508 specifications.
It would be worthwhile showing an example of using the new mechanism to bootstrap a project that relies on numpy.distutils.
Open Issues ===========
Name of the build-related sub-table -----------------------------------
The authors of this PEP couldn't decide between the names ``[package.build]`` and ``[package.build-system]``, and so it is an open issue over which one to go with.
"package.build-system", for the reason given above (i.e. "build" conflicts with the project's actual build settings).
Rejected Ideas ==============
Other semantic version key names --------------------------------
Names other than ``semantics-version`` were considered to represent the version of semantics that the configuration file was written for. Both ``configuration-version`` and ``metadata-version`` were both considered, but were rejected due to how people may confuse the key as representing a version of the files contents instead of the version of semantics that the file is interpreted under.
Would you be open to using schema-version rather than semantic-version, and then formally defining the format via jsonschema and/or JSL [1]? Cheers, Nick. [1] The latter is like an ORM for jsonschema: https://pypi.python.org/pypi/jsl -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Wed, May 11, 2016 at 12:11 AM, Nick Coghlan
On 11 May 2016 at 10:39, Brett Cannon
wrote: [...] For the vast majority of Python projects that rely upon setuptools, the ``pyproject.toml`` file will be::
[package.build-system] requires = ['setuptools', 'wheel'] # PEP 508 specifications.
It would be worthwhile showing an example of using the new mechanism to bootstrap a project that relies on numpy.distutils.
It's just that with "numpy" added, but sure. @Brett: I also just noticed reading the example above that you're using single-quotes for strings in the TOML instead of double-quote strings, which is a bit odd -- single quote strings in TOML are the same as raw strings in Python, which does work for this case but probably isn't the example we want to set.
Rejected Ideas ==============
Other semantic version key names --------------------------------
Names other than ``semantics-version`` were considered to represent the version of semantics that the configuration file was written for. Both ``configuration-version`` and ``metadata-version`` were both considered, but were rejected due to how people may confuse the key as representing a version of the files contents instead of the version of semantics that the file is interpreted under.
Would you be open to using schema-version rather than semantic-version, and then formally defining the format via jsonschema and/or JSL [1]?
I kinda like the semantics-version name (schema = structure, semantics = structure + interpretation), and I'm not sure what the name of that key has to do with defining a json schema, but anyway, here's a first-pass json schema :-) https://gist.github.com/njsmith/89021cd9ef1a6724579229de164d02d2 (NOTE that that schema's written to check that a file matches the currently defined spec, and should NOT be used to validate real pyproject.toml files, because the additionalProperties: false keys will cause it to error out on future backwards-compatible changes.) -n -- Nathaniel J. Smith -- https://vorpus.org
On Wed, 11 May 2016 17:11:54 +1000
Nick Coghlan
Take the default case: for a distutils/setuptools based project, the actual build settings are the arguments to setup() in setup.py, *not* these new settings in pyproject.toml. By contrast, the settings in [package.build-system] are the ones that tell pip and other installers what is needed to make "setup.py bdist_wheel" work (and, in the future, will tell them when to invoke something other than "setup.py bdist_wheel" to do the binary build)
Side question: if the build system needs configuring, is a user-provided configuration file really the best place to do so? People will end up having to copy and paste a bunch of configuration directives that are not directly relevant to their own project (also those directives will need maintaining as a build tool may evolve its dependencies over time). Alternative: have a single "build system" configuration directive: [package.build-system] tool = "foopackage:fooexe" ... which instructs the runner to install dependency "foopackage", and then invoking "fooexe" with a single well-known option (e.g. "--pybuild-bootstrap-config") produces a JSON file on stdout describing how to invoke precisely the tool for each build scenario (sdist, wheel, etc.). Regards Antoine.
On 11 May 2016 at 19:27, Antoine Pitrou
On Wed, 11 May 2016 17:11:54 +1000 Nick Coghlan
wrote: Take the default case: for a distutils/setuptools based project, the actual build settings are the arguments to setup() in setup.py, *not* these new settings in pyproject.toml. By contrast, the settings in [package.build-system] are the ones that tell pip and other installers what is needed to make "setup.py bdist_wheel" work (and, in the future, will tell them when to invoke something other than "setup.py bdist_wheel" to do the binary build)
Side question: if the build system needs configuring, is a user-provided configuration file really the best place to do so? People will end up having to copy and paste a bunch of configuration directives that are not directly relevant to their own project (also those directives will need maintaining as a build tool may evolve its dependencies over time).
When I say "build system configuration" in the context of distutils/setuptools, I mean things like: * MANIFEST.in * non-dependency related setup() arguments (packages, package_dir, py_modules, ext_modules, namespace_packages, entry_points, include_package_data, zip_safe, etc) * the Extension class and its parameters: https://docs.python.org/2/distutils/setupscript.html#describing-extension-mo... Those are the settings that actually tell the build system what to build and (in some cases) how to build it.
Alternative: have a single "build system" configuration directive:
[package.build-system]
tool = "foopackage:fooexe"
... which instructs the runner to install dependency "foopackage", and then invoking "fooexe" with a single well-known option (e.g. "--pybuild-bootstrap-config") produces a JSON file on stdout describing how to invoke precisely the tool for each build scenario (sdist, wheel, etc.).
Specifying alternate build systems likely won't be far behind this PEP (since that's what PEPs 516 and 517 were about), but we decided it made sense to split the two discussions (i.e. figuring out the static configuration basics, then figuring out how to eliminate the need for setup.py shims) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Thu, 12 May 2016 00:20:32 +1000
Nick Coghlan
When I say "build system configuration" in the context of distutils/setuptools, I mean things like:
* MANIFEST.in * non-dependency related setup() arguments (packages, package_dir, py_modules, ext_modules, namespace_packages, entry_points, include_package_data, zip_safe, etc) * the Extension class and its parameters: https://docs.python.org/2/distutils/setupscript.html#describing-extension-mo...
Those are the settings that actually tell the build system what to build and (in some cases) how to build it.
That's confusing :-) You should really call it "build configuration". Regards Antoine.
Thanks for the suggested bikeshed topic. Clever!
I like build also. "package build requires". I see that build is what you
used in the example [rejected] file formats. To me further segmentation
between build systems and the actual build that the build system effects is
something you might do to avoid the cost of installing a dependency that
might not actually be needed during that phase. IMO installation of an
occasional extra package is a fair price to pay if it reduces the number of
concepts in the system.
On Wed, May 11, 2016 at 10:26 AM Antoine Pitrou
On Thu, 12 May 2016 00:20:32 +1000 Nick Coghlan
wrote: When I say "build system configuration" in the context of distutils/setuptools, I mean things like:
* MANIFEST.in * non-dependency related setup() arguments (packages, package_dir, py_modules, ext_modules, namespace_packages, entry_points, include_package_data, zip_safe, etc) * the Extension class and its parameters:
https://docs.python.org/2/distutils/setupscript.html#describing-extension-mo...
Those are the settings that actually tell the build system what to build and (in some cases) how to build it.
That's confusing :-) You should really call it "build configuration".
Regards
Antoine. _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org https://mail.python.org/mailman/listinfo/distutils-sig
On 12 May 2016 at 00:26, Antoine Pitrou
On Thu, 12 May 2016 00:20:32 +1000 Nick Coghlan
wrote: When I say "build system configuration" in the context of distutils/setuptools, I mean things like:
* MANIFEST.in * non-dependency related setup() arguments (packages, package_dir, py_modules, ext_modules, namespace_packages, entry_points, include_package_data, zip_safe, etc) * the Extension class and its parameters: https://docs.python.org/2/distutils/setupscript.html#describing-extension-mo...
Those are the settings that actually tell the build system what to build and (in some cases) how to build it.
That's confusing :-) You should really call it "build configuration".
Gah, that's what I *meant* to write. Unfortunately, I put the extra word in there without noticing, rendering the entire message thoroughly confusing. To be clear: * "build system configuration": telling other tools what's needed to invoke the build system * "build configuration": actually telling the build system what it needs to do The build system config is the part the PEP proposes to start moving to pyproject.toml (with support for non-setup.py based invocation deferred to a later PEP). The build config itself will remain in tool dependent locations (e.g. setup.py, setup.cfg, flit.ini). If any build config were to move to pyproject.toml, it would be via the [tool.<name>] mechanism, and be a decision for the developers of the build tool concerned, rather than needing to be the topic of a PEP. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On 11 May 2016 at 01:39, Brett Cannon
Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
The only open issue in the PEP at the moment is the bikeshedding topic of what to name the sub-section containing the requirements: `[package.build]` or `[package.build-system]` (we couldn't reach consensus among the three of us on this). Otherwise the three of us are rather happy with the way the PEP has turned out and look forward to this being the first step towards allowing projects to customize their build process better!
+1 on the PEP as a whole - good work, all of you! On the requirements sub-section, I have a mild preference for [package.build-system] (but a stronger preference for not bikeshedding, so I'm OK with either :-)) One thought, I understand that many projects assume they can import particular Python modules in setup.py (numpy is a common one AIUI, for getting the C header location). Would it be worth specifically calling that out as a legitimate usage (it's not just to define the tools you need to do the build, but also to specify the build environment in general) and giving an example? Paul
Since you can easily read the PEP at
https://github.com/brettcannon/build-deps-pep in a nice, rendered format I
won't repost the whole thing, but here are the changes I have made based on
the comments so far.
1. I rephrased throughout the PEP to not explicitly say this is for
building wheels (for Robert). I was just trying to tie the PEP into what
happens today, not what we plan to have happen in the future.
2. Fixed the quotation marks on the TOML examples (for Nathaniel). It's
just habit from Python why I did it the way I did.
3. Reworked the Abstract to the following (for Robert):
"""
This PEP specifies how Python software packages should specify what
dependencies they have in order to execute their chosen build system.
As part of this specification, a new configuration file is introduced
for software packages to use to specify their build dependencies (with
the expectation that the same configuration file will be used for
future configuration details).
"""
4. Added a bit to the end of the Rationale section about where this fits in
future plans (for Robert):
"""
To provide more context and motivation for this PEP, think of the
(rough) steps required to produce a built artifact for a project:
1. The source checkout of the project.
2. Installation of the build system.
3. Execute the build system.
This PEP covers step #2. It is fully expected that a future PEP will
cover step #3, including how to have the build system dynamically
specify more dependencies that the build system requires to perform
its job. The purpose of this PEP though, is to specify the minimal set
of requirements for the build system to simply begin execution.
"""
5. Added a JSON Schema for the resulting data (for Nick because he must be
writing a lot of specs at work recently if he needs typing information for
2 fields :). This is based on Nathaniel's initial work, but I made the
"requires" key a requirement when [package.build-system] is defined. I did
not change the name of the key to "schema-version" for the reasons
Nathaniel outlined in his response to Nick on the topic.
{
"$schema": "http://json-schema.org/schema#",
"type": "object",
"additionalProperties": false,
"properties": {
"package": {
"type": "object",
"additionalProperties": false,
"properties": {
"semantics-version": {
"type": "integer",
"default": 1
},
"build-system": {
"type": "object",
"additionalProperties": false,
"properties": {
"requires": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": ["requires"]
}
}
},
"tool": {
"type": "object"
}
}
}
I didn't add an example using 'distutils.numpy' as Nick asked because it's
just the same example as in the PEP but with one field changed; IOW it
doesn't really add anything. I also didn't rename the file as Randy argued
for because the file is for the project, not just the package(s) the
project contains ("package" is an overloaded term and I don't want to
contribute to that with the filename; I can live with the build details
being in relation to a package in the project and thus named [package], but
other things that may end up in this file might not relate to any package
in the project).
On Tue, 10 May 2016 at 17:39 Brett Cannon
Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
The only open issue in the PEP at the moment is the bikeshedding topic of what to name the sub-section containing the requirements: `[package.build]` or `[package.build-system]` (we couldn't reach consensus among the three of us on this). Otherwise the three of us are rather happy with the way the PEP has turned out and look forward to this being the first step towards allowing projects to customize their build process better!
So far the votes for this open issue are: build-system: 1. Nathaniel 2. Ian 3. Ethan 4. Nick 5. Paul build: 1. Donald 2. Daniel build-configuration (write-in candidate): 1. Antoine
On Wed, 11 May 2016 18:32:30 +0000
Brett Cannon
The only open issue in the PEP at the moment is the bikeshedding topic of what to name the sub-section containing the requirements: `[package.build]` or `[package.build-system]` (we couldn't reach consensus among the three of us on this). Otherwise the three of us are rather happy with the way the PEP has turned out and look forward to this being the first step towards allowing projects to customize their build process better!
So far the votes for this open issue are:
build-system:
1. Nathaniel 2. Ian 3. Ethan 4. Nick 5. Paul
build:
1. Donald 2. Daniel
build-configuration (write-in candidate):
1. Antoine
Ha :) I like "build" actually. Regards Antoine.
On 12 May 2016 at 06:32, Brett Cannon
Since you can easily read the PEP at https://github.com/brettcannon/build-deps-pep in a nice, rendered format I won't repost the whole thing, but here are the changes I have made based on the comments so far.
1. I rephrased throughout the PEP to not explicitly say this is for building wheels (for Robert). I was just trying to tie the PEP into what happens today, not what we plan to have happen in the future.
2. Fixed the quotation marks on the TOML examples (for Nathaniel). It's just habit from Python why I did it the way I did.
3. Reworked the Abstract to the following (for Robert):
Thanks Brett.
-Rob
--
Robert Collins
On Wed, 11 May 2016 at 12:37 Robert Collins
Since you can easily read the PEP at https://github.com/brettcannon/build-deps-pep in a nice, rendered
On 12 May 2016 at 06:32, Brett Cannon
wrote: format I won't repost the whole thing, but here are the changes I have made based on the comments so far.
1. I rephrased throughout the PEP to not explicitly say this is for building wheels (for Robert). I was just trying to tie the PEP into what happens today, not what we plan to have happen in the future.
2. Fixed the quotation marks on the TOML examples (for Nathaniel). It's just habit from Python why I did it the way I did.
3. Reworked the Abstract to the following (for Robert):
Thanks Brett.
Welcome! Just like all of you, I want to get this PEP right as it's the foundational one to start us down the road of *finally* getting building untangled in a way we're all happy and excited about! -Brett
-Rob
-- Robert Collins
Distinguished Technologist HP Converged Cloud
On 05/11/2016 02:32 PM, Brett Cannon wrote:
I also didn't rename the file as Randy argued for because the file is for the project, not just the package(s) the project contains ("package" is an overloaded term and I don't want to contribute to that with the filename; I can live with the build details being in relation to a package in the project and thus named [package], but other things that may end up in this file might not relate to any package in the project).
This makes sense, thanks for your consideration. *Randy Syring* Husband | Father | Redeemed Sinner /"For what does it profit a man to gain the whole world and forfeit his soul?" (Mark 8:36 ESV)/
On Wed, May 11, 2016 at 11:32 AM, Brett Cannon
the file is for the project, not just the package(s) the project contains ("package" is an overloaded term and I don't want to contribute to that with the filename; I can live with the build details being in relation to a package in the project and thus named [package], but other things that may end up in this file might not relate to any package in the project).
We went back and forth on the overloaded "package" name a bit while drafting too, and eventually just gave up and went ahead because it's not that important. To me this feels similar to situations I've encountered in the past, where I've spent a bunch of time debating between two things, and it turned out that the reason we couldn't agree was because both proposals were wrong and a third solution was much better :-). I still don't think the [package] name part is worth arguing about much, but throwing this out there in case it turns out to be that "third way" that suddenly makes everyone go "a-ha!": If you think about it, really the stuff in [package.build-system] is there to tell pip how to run the build system. It's associated with building the project/package, sure, but that's not what makes it special -- everything that goes in this file will be associated with building or developing the project/package: [tool.flit], [tool.coverage], [tool.pytest], [tool.tox], whatever. The build-system stuff could easily and comfortably have gone into [tool.pip.build-system] instead... *except* that we don't want it to be specific to pip, we want it to be a piece of shared/common configuration that's defined by a shared process (PEPs) and used by *multiple* tools. That's why it doesn't belong in [tool.pip]. Or another way to put it, contrasting [tool.*] versus [package.*] is kinda weird, because those categories aren't actually contradictory -- it's like having categories [red] versus [square]. So, proposal: maybe we should rename the [package] namespace to something that reflects what distinguishes it from [tool], like: [standard.build-system] or [common.build-system] or [shared.build-system] -n -- Nathaniel J. Smith -- https://vorpus.org
On Wed, 11 May 2016 at 16:01 Nathaniel Smith
the file is for the project, not just the package(s) the project contains ("package" is an overloaded term and I don't want to contribute to that with the filename; I can live with the build details being in relation to a package in the project and thus named [package], but other things
On Wed, May 11, 2016 at 11:32 AM, Brett Cannon
wrote: [...] that may end up in this file might not relate to any package in the project).
We went back and forth on the overloaded "package" name a bit while drafting too, and eventually just gave up and went ahead because it's not that important.
To me this feels similar to situations I've encountered in the past, where I've spent a bunch of time debating between two things, and it turned out that the reason we couldn't agree was because both proposals were wrong and a third solution was much better :-).
I still don't think the [package] name part is worth arguing about much, but throwing this out there in case it turns out to be that "third way" that suddenly makes everyone go "a-ha!":
If you think about it, really the stuff in [package.build-system] is there to tell pip how to run the build system. It's associated with building the project/package, sure, but that's not what makes it special -- everything that goes in this file will be associated with building or developing the project/package: [tool.flit], [tool.coverage], [tool.pytest], [tool.tox], whatever. The build-system stuff could easily and comfortably have gone into [tool.pip.build-system] instead... *except* that we don't want it to be specific to pip, we want it to be a piece of shared/common configuration that's defined by a shared process (PEPs) and used by *multiple* tools. That's why it doesn't belong in [tool.pip].
Or another way to put it, contrasting [tool.*] versus [package.*] is kinda weird, because those categories aren't actually contradictory -- it's like having categories [red] versus [square].
So, proposal: maybe we should rename the [package] namespace to something that reflects what distinguishes it from [tool], like:
[standard.build-system]
or
[common.build-system]
or
[shared.build-system]
or [base.build-system] or [super.build-system] I'm +1 on base, super, or common, +0 on standard, -0 on shared.
On May 11, 2016, at 9:08 PM, Brett Cannon
wrote: On Wed, 11 May 2016 at 16:01 Nathaniel Smith
mailto:njs@pobox.com> wrote: On Wed, May 11, 2016 at 11:32 AM, Brett Cannon mailto:brett@python.org> wrote: [...] the file is for the project, not just the package(s) the project contains ("package" is an overloaded term and I don't want to contribute to that with the filename; I can live with the build details being in relation to a package in the project and thus named [package], but other things that may end up in this file might not relate to any package in the project).
We went back and forth on the overloaded "package" name a bit while drafting too, and eventually just gave up and went ahead because it's not that important.
To me this feels similar to situations I've encountered in the past, where I've spent a bunch of time debating between two things, and it turned out that the reason we couldn't agree was because both proposals were wrong and a third solution was much better :-).
I still don't think the [package] name part is worth arguing about much, but throwing this out there in case it turns out to be that "third way" that suddenly makes everyone go "a-ha!":
If you think about it, really the stuff in [package.build-system] is there to tell pip how to run the build system. It's associated with building the project/package, sure, but that's not what makes it special -- everything that goes in this file will be associated with building or developing the project/package: [tool.flit], [tool.coverage], [tool.pytest], [tool.tox], whatever. The build-system stuff could easily and comfortably have gone into [tool.pip.build-system] instead... *except* that we don't want it to be specific to pip, we want it to be a piece of shared/common configuration that's defined by a shared process (PEPs) and used by *multiple* tools. That's why it doesn't belong in [tool.pip].
Or another way to put it, contrasting [tool.*] versus [package.*] is kinda weird, because those categories aren't actually contradictory -- it's like having categories [red] versus [square].
So, proposal: maybe we should rename the [package] namespace to something that reflects what distinguishes it from [tool], like:
[standard.build-system]
or
[common.build-system]
or
[shared.build-system]
or
[base.build-system]
or
[super.build-system]
I'm +1 on base, super, or common, +0 on standard, -0 on shared. _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org mailto:Distutils-SIG@python.org https://mail.python.org/mailman/listinfo/distutils-sig https://mail.python.org/mailman/listinfo/distutils-sig
I don't like any of these options nearly as much as [package] TBH. I don’t think that base, super, common, standard, or shared are any less ambiguous than package (in fact I think they are _more_ ambigious). I don't really think of it as package vs tool, I think of it as an implicit <standard stuff> vs an explicit <third party stuff>. I think it makes the file uglier to have the <standard stuff> explicit, particularly since I think the example should really be something like: [standard.package.build-system] requires = ["setuptools", "wheel"] [tool.flake8] ... Because the value of the [package] namespace isn't that it separates us from the [tool] namespace (we could get that easily without it), but that it separates us from *other*, non packaging related but "standard" stuff that might be added in the future. The value of the [tool] namespace isn't that it doesn't make sense for a [flit] and a [package] to be at the same level, but rather that we have no idea what keys people might use there (and indeed, `package` is taken on PyPI) but that it allows us to separate the wild west of "anything goes" from the strictly defined the rest of the file. IOW, the reason to omit the [standard] namespace and the reason to include the [tool] namespace is practicality being purity and designing this file first for humans to edit it, and only second for machines to access it and some sort of semantic purity a distant third. ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
On May 11, 2016 6:33 PM, "Donald Stufft"
[...]
I don't like any of these options nearly as much as [package] TBH. I don’t think that base, super, common, standard, or shared are any less
package (in fact I think they are _more_ ambigious).
I don't really think of it as package vs tool, I think of it as an implicit <standard stuff> vs an explicit <third party stuff>. I think it makes the file uglier to have the <standard stuff> explicit, particularly since I think
ambiguous than the
example should really be something like:
[standard.package.build-system] requires = ["setuptools", "wheel"]
[tool.flake8] ...
Because the value of the [package] namespace isn't that it separates us from the [tool] namespace (we could get that easily without it), but that it separates us from *other*, non packaging related but "standard" stuff that might be added in the future.
Can you give an example of something that would go in your hypothetical implicit a pyproject.tml [standard] section, but that would not be related to configuring that project's package/packages and thus go into [package]? Partly asking because I'm not sure what the difference is between a "project" and a "package", partly because if we can articulate a clear guideline then that'd be useful for the future. -n
On May 11, 2016, at 9:45 PM, Nathaniel Smith
wrote: On May 11, 2016 6:33 PM, "Donald Stufft"
mailto:donald@stufft.io> wrote: [...]
I don't like any of these options nearly as much as [package] TBH. I don’t think that base, super, common, standard, or shared are any less ambiguous than package (in fact I think they are _more_ ambigious).
I don't really think of it as package vs tool, I think of it as an implicit <standard stuff> vs an explicit <third party stuff>. I think it makes the file uglier to have the <standard stuff> explicit, particularly since I think the example should really be something like:
[standard.package.build-system] requires = ["setuptools", "wheel"]
[tool.flake8] ...
Because the value of the [package] namespace isn't that it separates us from the [tool] namespace (we could get that easily without it), but that it separates us from *other*, non packaging related but "standard" stuff that might be added in the future.
Can you give an example of something that would go in your hypothetical implicit a pyproject.tml [standard] section, but that would not be related to configuring that project's package/packages and thus go into [package]? Partly asking because I'm not sure what the difference is between a "project" and a "package", partly because if we can articulate a clear guideline then that'd be useful for the future.
-n
This is somewhat of a contrived example because I’m not sure how useful it would be to have a standard representation of it, but one possible example is PEP8 (the actual PEP not the tool on PyPI) linters and what rules they follow that would allow people to use arbitrary linters against a code base (which may or may not be a “package” in the PyPI/pip/PyPA sense) but is just a chunk of code sitting in a directory. A less contrived answer is that I simply don’t know, but it feels like the “cost” of introducing the [package] top level is pretty low (a total of 8 additional characters per table) and in my head it has some meaning (this is the stuff for a Python distributable package, that you could, but maybe don’t, ship on PyPI and install with pip). I view the “project” as a superset of that, where part of configuring a “project” may include configuring the package side of things (assuming it is even a package and it isn’t just some arbitrary code in a dir) but might also include other things. On the other hand, I feel like `[standard]` or whatever isn’t really meaningful as anything other than “the stuff that isn’t in [tool]”, which makes me feel like adding it in is mostly a purity thing and the cost (a total of 9 extra characters per table) doesn’t seem worth it since any human will be able to trivially identify the set of things which are not in the tool namespace, and computers can also do that pretty easily (although slightly clumsily). Now, you could argue that the [package] keyword is superfluous and in reality it’s highly unlikely that we ever get anything major that would ever sit as a sibling to it (besides tool) and thus it doesn’t make sense to pay the cost of those extra 8 characters when it is probably going to be the only non-tool value ever. Personally I think hedging our bets and leaving the door open for that possibility is a nice thing to do when the cost is so low. However, I don’t think it’d be unreasonable or silly to make the other trade off and just say that having it isn’t valuable and just stick [build-system] at the top level along with [tool.*] and say that if we ever come up with something that is not related to a package (in the PyPA sense) that it really won’t be that big of a deal to just have it live beside stuff like [build-system]. So I think we should either have: [package.build-system] requires = [“setuptools”, “wheel”] [tool.flake8] … OR [build-system] requires = [“setuptools”, “wheel”] [tool.flake8] … but I don’t think trying to make the parsed tree fit some “correct” hierarchy of data types when you consider the [tool] section (which really only exists to prevent collisions, otherwise we’d just let people stick [flake8] etc at the top level) is worth it. ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
On Wed, May 11, 2016 at 7:22 PM, Donald Stufft
Now, you could argue that the [package] keyword is superfluous and in reality it’s highly unlikely that we ever get anything major that would ever sit as a sibling to it (besides tool) and thus it doesn’t make sense to pay the cost of those extra 8 characters when it is probably going to be the only non-tool value ever. Personally I think hedging our bets and leaving the door open for that possibility is a nice thing to do when the cost is so low. However, I don’t think it’d be unreasonable or silly to make the other trade off and just say that having it isn’t valuable and just stick [build-system] at the top level along with [tool.*] and say that if we ever come up with something that is not related to a package (in the PyPA sense) that it really won’t be that big of a deal to just have it live beside stuff like [build-system].
So I think we should either have:
[package.build-system] requires = [“setuptools”, “wheel”]
[tool.flake8] …
OR
[build-system] requires = [“setuptools”, “wheel”]
[tool.flake8] …
but I don’t think trying to make the parsed tree fit some “correct” hierarchy of data types when you consider the [tool] section (which really only exists to prevent collisions, otherwise we’d just let people stick [flake8] etc at the top level) is worth it.
FTR, to the extent that I object to [package] it's nothing to do with character count and purity, and instead to do with it being a bit confusing / poor UI, because as we've seen no-one's really sure what a "package" is. It's not a huge deal, but it might create some user confusion and future-PEP-author confusion. My preference ordering: [common.build-system] = [build-system] > [package.build-system] > nothing -n -- Nathaniel J. Smith -- https://vorpus.org
On 12 May 2016 at 11:33, Donald Stufft
I don't really think of it as package vs tool, I think of it as an implicit <standard stuff> vs an explicit <third party stuff>. I think it makes the file uglier to have the <standard stuff> explicit, particularly since I think the example should really be something like:
[standard.package.build-system] requires = ["setuptools", "wheel"]
[tool.flake8] ...
Because the value of the [package] namespace isn't that it separates us from the [tool] namespace (we could get that easily without it), but that it separates us from *other*, non packaging related but "standard" stuff that might be added in the future.
In that case though: 1. semantics-version isn't about the package, it's about the pyproject.toml file itself. 2. build-system feels like it could readily be top level as well, regardless of what other sections we added later That would make the example in the PEP =============== semantics-version = 1 # Optional; defaults to 1. [build-system] requires = ["setuptools", "wheel"] # PEP 508 specifications. =============== So I'm not clear on what the [package] namespace is buying us over just having [build-system] as a top level namespace (it would be different with a section name of "build" - for that, [package.build] reads nicely, and you can mostly ignore that it creates a nested namespace TOML. As noted elsewhere, I don't like "build" though - we're not configuring the build, we're specifying what's needed to run the build system in the first place). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Thanks for your work !
For what it's worth, I also think that:
- semantics-version (or maybe pyproject-version ? to mimic the
Wheel-Version of the WHEEL file) should be a top level value;
- [build-system]
requires = ["setuptools", "wheel"]
reads nicely and better than [package.build-system]
Regards,
Xavier
On Thu, May 12, 2016 at 9:01 AM, Nick Coghlan
I don't really think of it as package vs tool, I think of it as an implicit <standard stuff> vs an explicit <third party stuff>. I think it makes the file uglier to have the <standard stuff> explicit, particularly since I think
example should really be something like:
[standard.package.build-system] requires = ["setuptools", "wheel"]
[tool.flake8] ...
Because the value of the [package] namespace isn't that it separates us from the [tool] namespace (we could get that easily without it), but that it separates us from *other*, non packaging related but "standard" stuff
On 12 May 2016 at 11:33, Donald Stufft
wrote: the that might be added in the future.
In that case though:
1. semantics-version isn't about the package, it's about the pyproject.toml file itself. 2. build-system feels like it could readily be top level as well, regardless of what other sections we added later
That would make the example in the PEP =============== semantics-version = 1 # Optional; defaults to 1.
[build-system] requires = ["setuptools", "wheel"] # PEP 508 specifications. ===============
So I'm not clear on what the [package] namespace is buying us over just having [build-system] as a top level namespace (it would be different with a section name of "build" - for that, [package.build] reads nicely, and you can mostly ignore that it creates a nested namespace TOML. As noted elsewhere, I don't like "build" though - we're not configuring the build, we're specifying what's needed to run the build system in the first place).
Cheers, Nick.
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org https://mail.python.org/mailman/listinfo/distutils-sig
On Thu, May 12, 2016 at 12:01 AM, Nick Coghlan
On 12 May 2016 at 11:33, Donald Stufft
wrote: I don't really think of it as package vs tool, I think of it as an implicit <standard stuff> vs an explicit <third party stuff>. I think it makes the file uglier to have the <standard stuff> explicit, particularly since I think the example should really be something like:
[standard.package.build-system] requires = ["setuptools", "wheel"]
[tool.flake8] ...
Because the value of the [package] namespace isn't that it separates us from the [tool] namespace (we could get that easily without it), but that it separates us from *other*, non packaging related but "standard" stuff that might be added in the future.
In that case though:
1. semantics-version isn't about the package, it's about the pyproject.toml file itself. 2. build-system feels like it could readily be top level as well, regardless of what other sections we added later
That would make the example in the PEP =============== semantics-version = 1 # Optional; defaults to 1.
[build-system] requires = ["setuptools", "wheel"] # PEP 508 specifications. ===============
So I'm not clear on what the [package] namespace is buying us over just having [build-system] as a top level namespace (it would be different with a section name of "build" - for that, [package.build] reads nicely, and you can mostly ignore that it creates a nested namespace TOML. As noted elsewhere, I don't like "build" though - we're not configuring the build, we're specifying what's needed to run the build system in the first place).
When we were spitballing the draft, I think where [package] originally came from was the idea that having semantics-version at the top level is not actually useful -- most tools will only care about the semantics of the [tool.whatever] table and the only PEP change that would affect them is if we for some reason redefined the [tool] table itself. Which we aren't going to do. But if semantics-version is top-level, then presumably everyone has to check for it and error out if it changes. So bumping semantics-version would cause all these tools to error out, even though the part of the file that they actually care about didn't change, which would mean in practice we would just never actually bump the semantics-version because the flag day would be too painful. Introducing a [package] level and pushing semantics-version down inside [package] insulates from that. ...Given how complicated this is ending up being, I'm sorta inclined to just drop semantics-version. It's only in there as a "hey why not it doesn't hurt" thing. I can't imagine any situation in which we'd actually bump the semantics version. If we need to make some incompatible change we'll actually do it by adding a [build-system-2] or something, and specify that [build-system] and [build-system-2] are both allowed in the same file, and if both are present then new tools should ignore [build-system] -- way smoother and backwards-compatible. -n -- Nathaniel J. Smith -- https://vorpus.org
On 12 May 2016 at 10:07, Nathaniel Smith
...Given how complicated this is ending up being, I'm sorta inclined to just drop semantics-version. It's only in there as a "hey why not it doesn't hurt" thing. I can't imagine any situation in which we'd actually bump the semantics version. If we need to make some incompatible change we'll actually do it by adding a [build-system-2] or something, and specify that [build-system] and [build-system-2] are both allowed in the same file, and if both are present then new tools should ignore [build-system] -- way smoother and backwards-compatible.
That does seem like a simpler solution. I'd like to think that most changes we'd make to the file format could be done in a backward-compatible manner - new values that default appropriately, detectable changes to existing values (like a single string value becomes a list, just allow a string and treat it as a 1-element list). If we have to make breaking changes, using a new name (either at the section level like you suggest, or at the individual item level) seems perfectly acceptable. And if we don't need semantics-version in the [package] section, we can promote [build-system] to top level and just have 2 top level items, [build-system] and [tools]. Seems clean and manageable to me. Paul
I'm not sure that is an issue: if the version is bumped, this won't happen
overnight.
Why would projects/tools not have the time to update and support
semantic-version 1 and 2 ?
On Thu, May 12, 2016 at 11:07 AM, Nathaniel Smith
On 12 May 2016 at 11:33, Donald Stufft
wrote: I don't really think of it as package vs tool, I think of it as an implicit <standard stuff> vs an explicit <third party stuff>. I think it makes
file uglier to have the <standard stuff> explicit, particularly since I
example should really be something like:
[standard.package.build-system] requires = ["setuptools", "wheel"]
[tool.flake8] ...
Because the value of the [package] namespace isn't that it separates us from the [tool] namespace (we could get that easily without it), but that it separates us from *other*, non packaging related but "standard" stuff
On Thu, May 12, 2016 at 12:01 AM, Nick Coghlan
wrote: the think the that might be added in the future.
In that case though:
1. semantics-version isn't about the package, it's about the pyproject.toml file itself. 2. build-system feels like it could readily be top level as well, regardless of what other sections we added later
That would make the example in the PEP =============== semantics-version = 1 # Optional; defaults to 1.
[build-system] requires = ["setuptools", "wheel"] # PEP 508 specifications. ===============
So I'm not clear on what the [package] namespace is buying us over just having [build-system] as a top level namespace (it would be different with a section name of "build" - for that, [package.build] reads nicely, and you can mostly ignore that it creates a nested namespace TOML. As noted elsewhere, I don't like "build" though - we're not configuring the build, we're specifying what's needed to run the build system in the first place).
When we were spitballing the draft, I think where [package] originally came from was the idea that having semantics-version at the top level is not actually useful -- most tools will only care about the semantics of the [tool.whatever] table and the only PEP change that would affect them is if we for some reason redefined the [tool] table itself. Which we aren't going to do. But if semantics-version is top-level, then presumably everyone has to check for it and error out if it changes. So bumping semantics-version would cause all these tools to error out, even though the part of the file that they actually care about didn't change, which would mean in practice we would just never actually bump the semantics-version because the flag day would be too painful. Introducing a [package] level and pushing semantics-version down inside [package] insulates from that.
...Given how complicated this is ending up being, I'm sorta inclined to just drop semantics-version. It's only in there as a "hey why not it doesn't hurt" thing. I can't imagine any situation in which we'd actually bump the semantics version. If we need to make some incompatible change we'll actually do it by adding a [build-system-2] or something, and specify that [build-system] and [build-system-2] are both allowed in the same file, and if both are present then new tools should ignore [build-system] -- way smoother and backwards-compatible.
-n
-- Nathaniel J. Smith -- https://vorpus.org _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org https://mail.python.org/mailman/listinfo/distutils-sig
On 12 May 2016 at 19:07, Nathaniel Smith
When we were spitballing the draft, I think where [package] originally came from was the idea that having semantics-version at the top level is not actually useful -- most tools will only care about the semantics of the [tool.whatever] table and the only PEP change that would affect them is if we for some reason redefined the [tool] table itself. Which we aren't going to do. But if semantics-version is top-level, then presumably everyone has to check for it and error out if it changes. So bumping semantics-version would cause all these tools to error out, even though the part of the file that they actually care about didn't change, which would mean in practice we would just never actually bump the semantics-version because the flag day would be too painful. Introducing a [package] level and pushing semantics-version down inside [package] insulates from that.
...Given how complicated this is ending up being, I'm sorta inclined to just drop semantics-version. It's only in there as a "hey why not it doesn't hurt" thing. I can't imagine any situation in which we'd actually bump the semantics version. If we need to make some incompatible change we'll actually do it by adding a [build-system-2] or something, and specify that [build-system] and [build-system-2] are both allowed in the same file, and if both are present then new tools should ignore [build-system] -- way smoother and backwards-compatible.
We could also keep semantics-version, and just put it inside [build-system]. Either way, by allowing access to the [tool.*] namespace without any other version check, the key constraint we're placing on ourselves is a commitment to only making backwards compatible changes at the top level of the schema definition, and that should be a feasible promise to keep. While I can't conceive of an eventuality where we'd need to break such a promise, even if we did, the change could be indicated by switching to a different filename. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On May 12, 2016, at 8:31 AM, Nick Coghlan
wrote: We could also keep semantics-version, and just put it inside [build-system].
Either way, by allowing access to the [tool.*] namespace without any other version check, the key constraint we're placing on ourselves is a commitment to only making backwards compatible changes at the top level of the schema definition, and that should be a feasible promise to keep. While I can't conceive of an eventuality where we'd need to break such a promise, even if we did, the change could be indicated by switching to a different filename.
I don't think we should put it inside of [build-system], largely because I think the chances we ever need to increment the version is very small, and I feel like putting it inside of [build-system] means we'll then need one for any other top level key we put in. Each additional one is additional complexity and increases the chance that some tool doesn't accurately check every single one of them. Putting it inside of [package] made some sense, because that was going to be a container for all of the things that one particular group of people (distutils-sig / PyPA) "managed" or cared about but I think that putting it on each individual sub section is just overkill. We can easily stick it at the top level of the file and just explicitly state that the [tool.*] namespace is exempt from deriving any sort of meaning from the semantics-version value. I think that is easier to not screw up (only one check, vs N checks) and I think that it looks nicer too from a human writing/editing POV if we ever do bump the version and force people to write it out: semantics-version = 2 [build-system] requires = [ "setuptools", "pip", ] [test-runner] # Just an example command = "py.test --strict" requires = [ "pytest", ] [tool.pip] index-url = "https://index.example.com/simple/" But honestly, I'm of the opinion we could probably just ditch it. I don't think it'll be hard to maintain compatibility within the keywords we pick in this file and I worry that by including it in something that we expect humans to write, we provide an incentive to using it when perhaps we could think up a better, backwards compatible syntax. The main argument in favor of adding it now with an implicit default of `1` is that if I'm wrong and we end up needing it, including it now will mean that projects are actively checking the version number so we can safely increase it with the desired effect. If we don't include it now, then even if we add it at a later date nothing will be checking to see if that changed or not. ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
On Thu, 12 May 2016 at 05:43 Donald Stufft
On May 12, 2016, at 8:31 AM, Nick Coghlan
wrote: We could also keep semantics-version, and just put it inside [build-system].
Either way, by allowing access to the [tool.*] namespace without any other version check, the key constraint we're placing on ourselves is a commitment to only making backwards compatible changes at the top level of the schema definition, and that should be a feasible promise to keep. While I can't conceive of an eventuality where we'd need to break such a promise, even if we did, the change could be indicated by switching to a different filename.
I don't think we should put it inside of [build-system], largely because I think the chances we ever need to increment the version is very small, and I feel like putting it inside of [build-system] means we'll then need one for any other top level key we put in. Each additional one is additional complexity and increases the chance that some tool doesn't accurately check every single one of them. Putting it inside of [package] made some sense, because that was going to be a container for all of the things that one particular group of people (distutils-sig / PyPA) "managed" or cared about but I think that putting it on each individual sub section is just overkill.
Everything that Nathaniel and Donald said is accurate about the discussion we had offline while drafting the PEP. Top-of-file was originally proposed by me but was viewed as too broad, hence the namespacing of the bits PyPA controlled and putting the field in there. We also considered per-table, but that seemed like overkill.
We can easily stick it at the top level of the file and just explicitly state that the [tool.*] namespace is exempt from deriving any sort of meaning from the semantics-version value. I think that is easier to not screw up (only one check, vs N checks) and I think that it looks nicer too from a human writing/editing POV if we ever do bump the version and force people to write it out:
I had originally proposed that but I think we didn't like the wording of it or the possibility of someone not realizing that the scoping of the field was special-cased to everything *not* in [tool].
semantics-version = 2
[build-system] requires = [ "setuptools", "pip", ]
[test-runner] # Just an example command = "py.test --strict" requires = [ "pytest", ]
[tool.pip] index-url = "https://index.example.com/simple/"
But honestly, I'm of the opinion we could probably just ditch it. I don't think it'll be hard to maintain compatibility within the keywords we pick in this file and I worry that by including it in something that we expect humans to write, we provide an incentive to using it when perhaps we could think up a better, backwards compatible syntax. The main argument in favor of adding it now with an implicit default of `1` is that if I'm wrong and we end up needing it, including it now will mean that projects are actively checking the version number so we can safely increase it with the desired effect. If we don't include it now, then even if we add it at a later date nothing will be checking to see if that changed or not.
Both Donald and Nathaniel say to drop it, and since I put it in just to be overly cautious I'm fine with dropping it. So unless Nick says "semantics-version or death!", I agree w/ my co-authors and would update the PEP to say: 1. no semantics-version 2. [build-system] instead of [package.build-system]
On 05/12/2016 12:33 PM, Brett Cannon wrote:
Both Donald and Nathaniel say to drop it, and since I put it in just to be overly cautious I'm fine with dropping it. So unless Nick says "semantics-version or death!", I agree w/ my co-authors and would update the PEP to say:
1. no semantics-version 2. [build-system] instead of [package.build-system]
FWIW, as a someone who is not highly involved, but following this discussion b/c I maintain projects/packages, I like the simplicity and readability of this. +1 *Randy Syring* Husband | Father | Redeemed Sinner /"For what does it profit a man to gain the whole world and forfeit his soul?" (Mark 8:36 ESV)/
On 13 May 2016 at 02:33, Brett Cannon
Both Donald and Nathaniel say to drop it, and since I put it in just to be overly cautious I'm fine with dropping it. So unless Nick says "semantics-version or death!", I agree w/ my co-authors and would update the PEP to say:
1. no semantics-version 2. [build-system] instead of [package.build-system]
I think both of those changes are improvements - having to change the filename is a reasonable disincentive against making breaking changes, and with just the two sections initially being defined ([build-system] and [tool.*]) it makes sense to have them both at the top level. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Thu, 12 May 2016 at 20:52 Nick Coghlan
Both Donald and Nathaniel say to drop it, and since I put it in just to be overly cautious I'm fine with dropping it. So unless Nick says "semantics-version or death!", I agree w/ my co-authors and would update
On 13 May 2016 at 02:33, Brett Cannon
wrote: the PEP to say:
1. no semantics-version 2. [build-system] instead of [package.build-system]
I think both of those changes are improvements - having to change the filename is a reasonable disincentive against making breaking changes, and with just the two sections initially being defined ([build-system] and [tool.*]) it makes sense to have them both at the top level.
Seems everyone is in agreement then. I'll update the PEP and send out a new draft later today.
One other question: Is it just examples or is "build" being defined as "build a wheel"? i.e. there are times one might want to build a package without building a wheel -- just it install it yourself, or to put it in another package format -- conda, rpm, what have you. In conda's case, building a wheel, and then installing it would work fine, but I'm not sure we want to lock that down as the only way to build a package. Granted, if all it means is that someone will download an unnecessary dependency, big deal. I'm also a bit confused about whether we're trying to specify the dependencies required simply to run the build tool itself, or the dependencies required to actually do the build -- or the latter being saved for another day? -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
On Fri, 13 May 2016 at 11:34 Chris Barker
One other question:
Is it just examples or is "build" being defined as "build a wheel"?
Just an example (clarified previously). -Brett
i.e. there are times one might want to build a package without building a wheel -- just it install it yourself, or to put it in another package format -- conda, rpm, what have you.
In conda's case, building a wheel, and then installing it would work fine, but I'm not sure we want to lock that down as the only way to build a package.
Granted, if all it means is that someone will download an unnecessary dependency, big deal.
I'm also a bit confused about whether we're trying to specify the dependencies required simply to run the build tool itself, or the dependencies required to actually do the build -- or the latter being saved for another day?
The minimal requirements to execute the build system. Providing some way to specify more dependencies in some dynamic fashion and the like is for another PEP. -Brett
-CHB
--
Christopher Barker, Ph.D. Oceanographer
Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov
On May 13, 2016 11:34 AM, "Chris Barker"
One other question:
Is it just examples or is "build" being defined as "build a wheel"?
i.e. there are times one might want to build a package without building a
wheel -- just it install it yourself, or to put it in another package format -- conda, rpm, what have you.
In conda's case, building a wheel, and then installing it would work
fine, but I'm not sure we want to lock that down as the only way to build a package. As Brett already clarified, this pep is just about how you get to the point of being able to start the build system; it doesn't care what the build system actually outputs. But, the plan *is* to make wheels the standard way to build packages -- that will be in the next pep :-). I'm not sure I'd call it "lock down", because there's nothing that will stop you running setup.py bdist_rpm or whatever. But our goal is to reach the point where package authors get a choice of what build system to use, and there's no guarantee that every build system will implement bdist_rpm. So, the plan is to require all build systems to be able to output wheels, and then debian or conda-build or whoever will convert the wheel into whatever final package format they want. This is way more scalable than requiring N different build systems to each be able to output M different formats for N*M code paths. And if wheels aren't sufficient, well, we can add stuff to the spec :-) -n
On Fri, May 13, 2016 at 1:09 PM, Nathaniel Smith
But, the plan *is* to make wheels the standard way to build packages -- that will be in the next pep :-). I'm not sure I'd call it "lock down", because there's nothing that will stop you running setup.py bdist_rpm or whatever. But our goal is to reach the point where package authors get a choice of what build system to use, and there's no guarantee that every build system will implement bdist_rpm.
hmm -- this really feels like mingling packaging and building.
Does making sure everything builds a wheel help systems like rpm and the like? Honestly I have no idea. I do know that conda is very is very much designed to not care at all how a package is build or installed, as long as it can be installed -- so if a wheel is built and then that wheel is installed, that all the same to conda. But is that the case for everything else? I absolutely agree that we shouldn't expect a bdist_rpm and the like -- in fact, those should all be deprecated. but maybe a "install" that goes from source to installed package, without passing through a wheel? or maybe not -- I really don't know rpm or deb or anything else well enough to know.
So, the plan is to require all build systems to be able to output wheels, and then debian or conda-build or whoever will convert the wheel into whatever final package format they want.
easy for conda -- not sure about the others.... hmm -- homebrew builds from source, so as long as you have a way to install the wheel you built, it'll be fine (much like conda, but without ever making a package) -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
On 14 May 2016 at 06:31, Chris Barker
On Fri, May 13, 2016 at 1:09 PM, Nathaniel Smith
wrote: But, the plan *is* to make wheels the standard way to build packages -- that will be in the next pep :-). I'm not sure I'd call it "lock down", because there's nothing that will stop you running setup.py bdist_rpm or whatever. But our goal is to reach the point where package authors get a choice of what build system to use, and there's no guarantee that every build system will implement bdist_rpm.
hmm -- this really feels like mingling packaging and building.
Does making sure everything builds a wheel help systems like rpm and the like? Honestly I have no idea.
Yes, it does. The reason is that separating the build system from the deployment system is normal practice in those tools, but not the case with approaches like "./setup.py install". Direct invocation of the latter also loses semantic information about the package contents that may be relevant for Filesystem Hierarchy Standard compliance purposes. When the upstream installation process is instead broken up into "build a binary artifact" and "install a binary artifact", that brings a few benefits: - the fact that the build system and the deployment target may be different machines can be handled upstream - we get a new metadata source (the binary artifact format) that can be used in tools like pyp2rpm - the semantic information about file types is captured in the binary artifact Over time, what this means is that distros can move away from the current practice of defining a packaging configuration once, and then updating it manually when rebasing to a new upstream release, in favour of automatically generating the downstream packaging config, and submitting patches to the upstream project to improve the built binary artifact as necessary (patching it locally in the meantime). That's not something that's going to happen quickly, but you can see the foundations of it being laid as people start trying to do things like automatically rebuild all of PyPI as RPMs. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Thanks for working on this PEP. I've updated my setup-requires implementation to use the toml file instead of setup.cfg. It should match the PEP, give it a try! https://bitbucket.org/dholth/setup-requires Do you have a favorite toml implementation? On Sat, May 14, 2016 at 6:33 PM Chris Barker - NOAA Federal < chris.barker@noaa.gov> wrote:
When the upstream installation process is instead broken up into "build a binary artifact" and "install a binary artifact", that brings a few benefits:
Great -- thanks for the detailed explanation. Sounds like a good plan, then.
-CHB _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org https://mail.python.org/mailman/listinfo/distutils-sig
On 11.05.2016 02:39, Brett Cannon wrote:
Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
probably too late or out of scope for this pep. However the distro packaging for python packages recommends to run the testsuite during the package build. Would it be possible to extend this pep to test depends, or maybe track this as a separate pep? Matthias
On 12 May 2016 at 08:22, Matthias Klose
On 11.05.2016 02:39, Brett Cannon wrote:
Donald, Nathaniel, and I have finished our proposed PEP for specifying a projects' build dependencies. The PEP is being kept at https://github.com/brettcannon/build-deps-pep, so if you find spelling mistakes and grammatical errors please feel free to send a PR to fix them.
probably too late or out of scope for this pep. However the distro packaging for python packages recommends to run the testsuite during the package build. Would it be possible to extend this pep to test depends, or maybe track this as a separate pep?
It's covered as well- this is general purpose 'what is needed to run
setup.py' - once you can run setup.py, you can machine interrogate any
further dependencies.
-Rob
--
Robert Collins
On May 11, 2016, at 4:27 PM, Robert Collins
wrote: probably too late or out of scope for this pep. However the distro packaging for python packages recommends to run the testsuite during the package build. Would it be possible to extend this pep to test depends, or maybe track this as a separate pep?
It's covered as well- this is general purpose 'what is needed to run setup.py' - once you can run setup.py, you can machine interrogate any further dependencies.
It’s not *exactly* covered— I mean people could stick test dependencies in this new field but I don’t think that setuptools actually exposes the test_requires in any meaningful way (nor do I think people actually use setuptools test support that consistently). So setuptools could get better support for testing dependencies independently of this PEP *or* another PEP could add a similar section that layered ontop of this. It’s definitely out of scope for this particular PEP though. ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
On 12 May 2016 at 08:46, Donald Stufft
On May 11, 2016, at 4:27 PM, Robert Collins
wrote: probably too late or out of scope for this pep. However the distro packaging for python packages recommends to run the testsuite during the package build. Would it be possible to extend this pep to test depends, or maybe track this as a separate pep?
It's covered as well- this is general purpose 'what is needed to run setup.py' - once you can run setup.py, you can machine interrogate any further dependencies.
It’s not *exactly* covered— I mean people could stick test dependencies in this new field but I don’t think that setuptools actually exposes the test_requires in any meaningful way (nor do I think people actually use setuptools test support that consistently). So setuptools could get better support for testing dependencies independently of this PEP *or* another PEP could add a similar section that layered ontop of this. It’s definitely out of scope for this particular PEP though.
Right - in more detail though:
tox using projects:
- set it to setuptools, wheel and any other 'needed to run setup.py
sdist' things. Then tox will work - and its list is generally plain
text that packagers can introspect, install separately and run the tox
commands directly.
setup.py test using projects:
- a small setuptools entrypoint can be written to allow
introspecting test_requires, so we just need to set the requires as
for the tox case
etc.
-Rob
--
Robert Collins
participants (15)
-
Antoine Pitrou
-
Brett Cannon
-
Chris Barker
-
Chris Barker - NOAA Federal
-
Daniel Holth
-
Donald Stufft
-
Ethan Furman
-
Ian Cordasco
-
Matthias Klose
-
Nathaniel Smith
-
Nick Coghlan
-
Paul Moore
-
Randy Syring
-
Robert Collins
-
Xavier Fernandez