From 90bc912ebd57787aee718b18c267ffb35ba6c966 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 00:04:13 +1000 Subject: [PATCH 01/56] Add initial exploded-dependencies spec for PEP-621 PEP --- pep-9999.rst | 225 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 pep-9999.rst diff --git a/pep-9999.rst b/pep-9999.rst new file mode 100644 index 00000000000..a67c9498554 --- /dev/null +++ b/pep-9999.rst @@ -0,0 +1,225 @@ +PEP: 9999 +Title: Dependency specification in pyproject.toml using an exploded TOML table +Author: Laurie Opperman +Status: Draft +Type: Standards Track +Content-Type: text/x-rst +Created: 02-09-2020 +Post-History: TBD + + +Abstract +======== + +This PEP specifies how to write a project's dependencies in a +``pyproject.toml`` file for packaging-related tools to consume using the fields +defined in :pep:`621`, as an alternative to the :pep:`508`-based approach +defined in :pep:`631`. Specifically, the tables ``project.dependencies`` and +``project.optional-dependencies`` are defined. + + +Rationale +========= + +Most of this is taken from discussions in the `PEP 621 dependencies topic`_. +This has elements from `Pipfile`_, `Poetry`_, `Dart's dependencies`_ and +`Rust's Cargo`_. A `comparison document`_ shows advantages and disadvantages +between this format and :pep:`508`-style specifiers. + +One example is the need to allow for specifying distributions in multiple +dependencies (environment markers will choose the appropriate dependency). + +.. _PEP 621 dependencies topic: https://discuss.python.org/t/pep-621-how-to-specify-dependencies/4599 +.. _Pipfile: https://github.com/pypa/pipfile +.. _Poetry: https://python-poetry.org/docs/dependency-specification/ +.. _Dart's dependencies: https://dart.dev/tools/pub/dependencies +.. _Rust's Cargo: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html +.. _comparison document: https://github.com/uranusjr/packaging-metadata-comparisons/blob/master/topics/dependency-entries.md + + +Specification +============= + +As in :pep:`621`, if metadata is improperly specified then tools MUST raise an +error. The metadata MUST conform to the `toml`_ specification. + +To reduce confusion with this document being a specification for specifying +dependencies, the word "requirement" is used to mean a :pep:`508` dependency +specification. + +The following tables are added to the added to the ``project`` table specified +in :pep:`621`. + +.. _toml: https://toml.io/ + +.. _dependencies-spec: + +dependencies +------------ + +Format: table + +The keys inside this table are the names of the required distribution. The +values can be either a `requirement table <#requirement-table>`_ or an array of +requirement tables. + +It is an error to specify an empty array ``[]`` as a value. + +.. _requirement-table: + +Requirement table +^^^^^^^^^^^^^^^^^ + +The keys of the requirement table are as follows: + +- ``version`` (string): a :pep:`440` version specifier, which is a comma- + delimited list of version specifier clauses. The string MUST be non-empty. + +- ``extras`` (array of strings): a list of :pep:`508` extras declarations for + the distribution. The list MUST be non-empty. + +- ``markers`` (string): a :pep:`508` environment marker expression. The string + MUST be non-empty. + +- ``url`` (string): the URL of a web-based artifact to install and satisfy the + requirement. + +- ``git`` (string): similar to ``url``, the identifier of a web-hosted VCS + repository to checkout to install and satisfy the requirement. A tag, commit + or branch can be explicitly specified by appending its identifier prefixed + with an at sign "@", otherwise the default branch is used. + +The ``url``, ``git`` and ``versions`` keys MUST NOT be specified +simultaneously, as they logically conflict with each other in the requirement. + +An empty requirement table ``{}`` places no restriction on the requirement. + +optional-dependencies +--------------------- + +Format: table + +The keys inside this table are the names of the project's :pep:`508` extras. +The values each specify the list of requirements required by the extra, and are +tables. These requirement lists are described with the same as +`the dependencies specification <#dependencies-spec>`_ above. + + +Examples +======== + +Inline table:: + + [project] + dependences = { flask = {}, django = {}, numpy.version = '~=1.18' } + +Inline tables:: + + [project.dependences] + flask = {} + django = {} + requests = { version = '>= 2.8.1, == 2.8.*', extras = [ 'security', 'tests' ], markers = 'python_version < "2.7"' } + pip = { url = 'https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' } + numpy.version = '~=1.18' + pytest = [ + { version = '<6', markers = 'python_version < "3.5"' }, + { version = '>=6', markers = 'python_version >= "3.5"' }, + ] + +Standard tables:: + + [project.dependencies.flask] + + [project.dependencies.django] + + [project.dependencies.requests] + version = '>= 2.8.1, == 2.8.*' + extras = [ 'security', 'tests' ] + markers = 'python_version < "2.7"' + + [project.dependencies.pip] + url = 'https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' + + [project.dependencies.numpy] + version = '~=1.18' + + [[project.dependencies.pytest]] + versions = '<6' + markers = 'python_version < "3.5"' + + [[project.dependencies.pytest]] + versions = '>=6' + markers = 'python_version >= "3.5"' + +In homage to :pep:`631`, the following is an equivalent dependencies +specification for `docker-compose`_:: + + [project.dependencies] + cached-property = { version = '>= 1.2.0, < 2' } + distro = { version = '>= 1.2.0, < 2' } + docker = { extras = [ 'ssh' ], version = '>= 4.2.2, < 5' } + docopt.version = '>= 0.6.1, < 1' + jsonschema.version = '>= 2.5.1, < 4' + PyYAML.version = '>= 3.10, < 6' + python-dotenv = { version = '>= 0.13.0, < 1' } + requests = { version = '>= 2.20.0, < 3' } + + # Conditional + 'backports.shutil_get_terminal_size' = { version = '== 1.0.0', markers = 'python_version < "3.3"' } + colorama.version = '>= 0.4, < 1' + colorama.markers = 'sys_platform == "win32"' + + [project.dependencies.texttable] + version = '>= 0.9.0, < 2' + + [project.dependencies.websocket-client] + version = '>= 0.32.0, < 1' + + [project.dependencies.'backports.ssl_match_hostname'] + version = '>= 3.5, < 4' + markers = 'python_version < "3.5"' + + [project.dependencies.colorama] + version = '>= 0.4, < 1' + markers = 'sys_platform == "win32"' + + [project.dependencies.enum34] + version = '>= 1.0.4, < 2' + markers = 'python_version < "3.4"' + + [project.dependencies.ipaddress] + version = '>= 1.0.16, < 2' + markers = 'python_version < "3.3"' + + [project.dependencies.subprocess32] + version = '>= 3.5.4, < 4' + markers = 'python_version < "3.2"' + + [project.optional-dependencies] + socks = { PySocks = { version = '>= 1.5.6, != 1.5.7, < 2' ] } } + + [project.optional-dependencies.tests] + ddt = { version = '>= 1.2.2, < 2' } + pytest = { version = '< 6' ] } + mock = { version = '>= 1.0.1, < 4' } + + [project.optional-dependencies.tests.mock] + markers = 'python_version < "3.4"' + +.. _docker-compose: https://github.com/docker/compose/blob/789bfb0e8b2e61f15f423d371508b698c64b057f/setup.py#L28-L61 + + +Copyright +========= + +This document is placed in the public domain or under the +CC0-1.0-Universal license, whichever is more permissive. + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: From 5834a7918f7fc136b7ff2e2638a51ec2afbb3622 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 00:07:18 +1000 Subject: [PATCH 02/56] Remove requirement-table reference --- pep-9999.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index a67c9498554..d15044109fb 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -60,13 +60,11 @@ dependencies Format: table The keys inside this table are the names of the required distribution. The -values can be either a `requirement table <#requirement-table>`_ or an array of -requirement tables. +values can be either a requirement table or an array of requirement tables +(below). It is an error to specify an empty array ``[]`` as a value. -.. _requirement-table: - Requirement table ^^^^^^^^^^^^^^^^^ From 73f80422e6bff51a391d58b4ec9d73d542c402b2 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 00:33:51 +1000 Subject: [PATCH 03/56] Fix email --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index d15044109fb..dbe146467e0 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -1,6 +1,6 @@ PEP: 9999 Title: Dependency specification in pyproject.toml using an exploded TOML table -Author: Laurie Opperman +Author: Laurie Opperman Status: Draft Type: Standards Track Content-Type: text/x-rst From 1725ae4beed54618366e5b9961f93b4919e54411 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 19:18:02 +1000 Subject: [PATCH 04/56] Add note on why markers weren't split --- pep-9999.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index dbe146467e0..b5fb26eb0a3 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -29,6 +29,12 @@ between this format and :pep:`508`-style specifiers. One example is the need to allow for specifying distributions in multiple dependencies (environment markers will choose the appropriate dependency). +Some dependency specifications, as in `Poetry`_, separate the :pep:`508` +environment markers into separate keys in the requirement. This loses the +general Python-like syntax for environment markers, and also removes the +ability to logically combines the markers with grouped `and` and `or` +operations. + .. _PEP 621 dependencies topic: https://discuss.python.org/t/pep-621-how-to-specify-dependencies/4599 .. _Pipfile: https://github.com/pypa/pipfile .. _Poetry: https://python-poetry.org/docs/dependency-specification/ From 8f8a5ac709d14c2f172a8d6d15ae565a3bea9999 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 19:44:42 +1000 Subject: [PATCH 05/56] Add depenencies-array to rejected ideas --- pep-9999.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index b5fb26eb0a3..d5d213e9cc1 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -213,6 +213,15 @@ specification for `docker-compose`_:: .. _docker-compose: https://github.com/docker/compose/blob/789bfb0e8b2e61f15f423d371508b698c64b057f/setup.py#L28-L61 +Rejected Ideas +============== + +- Using an array for `dependencies` instead of a table, in order to have each + element only be a table (with a `name` key) and no arrays of requirement + tables. This was very verbose and restrictive in the TOML format, and having + multiple requirements for a given distribution isn't very common. + + Copyright ========= From bad0a73653b58ede43f1427b3658159c304865e3 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 20:37:41 +1000 Subject: [PATCH 06/56] Switch to 'direct' table for direct references --- pep-9999.rst | 53 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index d5d213e9cc1..37de6231402 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -35,6 +35,10 @@ general Python-like syntax for environment markers, and also removes the ability to logically combines the markers with grouped `and` and `or` operations. +The ``direct`` key closely aligns with :pep:`610` and :pep:`440`'s direct +references as to reduce differences in the packaging ecosystem and rely on +previous work in specification. + .. _PEP 621 dependencies topic: https://discuss.python.org/t/pep-621-how-to-specify-dependencies/4599 .. _Pipfile: https://github.com/pypa/pipfile .. _Poetry: https://python-poetry.org/docs/dependency-specification/ @@ -85,19 +89,32 @@ The keys of the requirement table are as follows: - ``markers`` (string): a :pep:`508` environment marker expression. The string MUST be non-empty. -- ``url`` (string): the URL of a web-based artifact to install and satisfy the - requirement. - -- ``git`` (string): similar to ``url``, the identifier of a web-hosted VCS - repository to checkout to install and satisfy the requirement. A tag, commit - or branch can be explicitly specified by appending its identifier prefixed - with an at sign "@", otherwise the default branch is used. +- ``direct`` (table): see below -The ``url``, ``git`` and ``versions`` keys MUST NOT be specified +The ``version`` and ``direct`` keys MUST NOT be specified simultaneously, as they logically conflict with each other in the requirement. An empty requirement table ``{}`` places no restriction on the requirement. +direct +****** + +This is inspired by :pep:`610` and :pep:`440`'s direct references. The table +can have the following keys: + +- ``url`` (string, *required*): the URL of the artifact or VCS repository to + install and satisfy the requirement. If a VCS revision, a revision identifier + MAY be appended after an at-sign "@". Revision identifiers are suggested in + :pep:`610`. + +- ``vcs`` (string): if (and only if) specified, the URL points to a VCS + repository. The value is the name of the VCS used, as suggested in + :pep:`610`. + +- ``hash`` (string): the hash of the retrieved artifact, prefixed with the + hash algorithm and an equals-sign "=". Hash algorithms are recommended in + :pep:`610`. + optional-dependencies --------------------- @@ -123,7 +140,8 @@ Inline tables:: flask = {} django = {} requests = { version = '>= 2.8.1, == 2.8.*', extras = [ 'security', 'tests' ], markers = 'python_version < "2.7"' } - pip = { url = 'https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' } + pip = { direct = { url = 'https://github.com/pypa/pip/archive/1.3.1.zip', hash = 'sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' } } + sphinx = { direct = { vcs = 'git', url = 'ssh://git@github.com/sphinx-doc/sphinx.git' } } numpy.version = '~=1.18' pytest = [ { version = '<6', markers = 'python_version < "3.5"' }, @@ -142,7 +160,12 @@ Standard tables:: markers = 'python_version < "2.7"' [project.dependencies.pip] - url = 'https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' + url = 'https://github.com/pypa/pip/archive/1.3.1.zip' + hash = sha1=da9234ee9982d4bbb3c72346a6de940a148ea686 + + [project.dependencies.sphinx.direct] + vcs = 'git' + url = 'ssh://git@github.com/sphinx-doc/sphinx.git' [project.dependencies.numpy] version = '~=1.18' @@ -222,6 +245,16 @@ Rejected Ideas multiple requirements for a given distribution isn't very common. +Open Issues +=========== + +- Split VCS revision from URL into a separate key, such as ``revision``, in the + ``direct`` table. This would increase verbosity, but could make parsing and + automated updating more straight-forward. +- Split hash type from hash value in the ``direct`` table. As above, increases + verbosity but also programmatic ease. + + Copyright ========= From ecd83f53eff88991f445fe61adf80d49fc92821b Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 20:38:04 +1000 Subject: [PATCH 07/56] Fix incorrect 'version' keys in example --- pep-9999.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 37de6231402..d798bb27a06 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -171,11 +171,11 @@ Standard tables:: version = '~=1.18' [[project.dependencies.pytest]] - versions = '<6' + version = '<6' markers = 'python_version < "3.5"' [[project.dependencies.pytest]] - versions = '>=6' + version = '>=6' markers = 'python_version >= "3.5"' In homage to :pep:`631`, the following is an equivalent dependencies From 5e021c1c36c1d4c17ca7bf7fb9e81b6f061e7bf5 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 20:50:07 +1000 Subject: [PATCH 08/56] Add motivation to contrast with the PEP-508 string implementation --- pep-9999.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index d798bb27a06..74874b1b5c9 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -18,6 +18,29 @@ defined in :pep:`631`. Specifically, the tables ``project.dependencies`` and ``project.optional-dependencies`` are defined. +Motivation +========== + +There are multiple benefits to using TOML tables and other data-types to +represent requirements rather then :pep:`508` strings: + +- Easy initial validation via the TOML syntax. + +- Easy secondary validation using a schema, for example a `JSON Schema`_. + +- Potential for users to guess the keys of given features, rather than + memorising a syntax. + +- Users of multiple other popular languages may already be familiar with the + TOML syntax. + +- TOML directly represents the same data structures as in JSON, and therefore a + sub-set of Python literals, so users can understand the hierarchy and type of + value + +.. _JSON Schema: https://json-schema.org/ + + Rationale ========= From 97140362cf42ec9a6bf0650a08c65c57527b3475 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 20:55:03 +1000 Subject: [PATCH 09/56] Add open-issue note on environment-marker keys --- pep-9999.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index 74874b1b5c9..ca477116200 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -274,9 +274,15 @@ Open Issues - Split VCS revision from URL into a separate key, such as ``revision``, in the ``direct`` table. This would increase verbosity, but could make parsing and automated updating more straight-forward. + - Split hash type from hash value in the ``direct`` table. As above, increases verbosity but also programmatic ease. +- Making each :pep:`508` environment marker as a key (or child-table key) in + the requirement. This arguably increases readability and ease of parsing, + however the ability to have nested groups of ``and`` and ``or`` operations + on the markers is lost. + Copyright ========= From d9c0264f7305d310c1cbe6418b3bbb7784f478ae Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 21:00:49 +1000 Subject: [PATCH 10/56] Add open-issue notes on removing 'optional-dependencies' table --- pep-9999.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index ca477116200..a71316bd4d0 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -283,6 +283,20 @@ Open Issues however the ability to have nested groups of ``and`` and ``or`` operations on the markers is lost. +- Removing the ``optional-dependencies`` table in favour of both including an + ``optional`` key in the requirement and an ``extras`` table which specifies + which (optional) requirements are needed for a project's extra. This reduces + the number of table with the same specification (to 1), but distances some of + the requirement's properties (which extra(s) it belongs to), groups required + and optional dependencies together (possibly mixed), and there may not be a + simple way to choose a requirement when a distribution has multiple + requirements. + +- Remove the ``optional-dependencies`` table in favour of including a + ``for-extras`` key in the requirement. This reduces the number of table with + the same specification (to 1), but groups required and optional dependencies + together (possibly mixed). + Copyright ========= From df0f10623938e08a75b0d04a6bf57279a6b75691 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 21:09:49 +1000 Subject: [PATCH 11/56] Fix 'pip' keys in standard-table example --- pep-9999.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index a71316bd4d0..e617fa5c994 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -164,7 +164,7 @@ Inline tables:: django = {} requests = { version = '>= 2.8.1, == 2.8.*', extras = [ 'security', 'tests' ], markers = 'python_version < "2.7"' } pip = { direct = { url = 'https://github.com/pypa/pip/archive/1.3.1.zip', hash = 'sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' } } - sphinx = { direct = { vcs = 'git', url = 'ssh://git@github.com/sphinx-doc/sphinx.git' } } + sphinx.direct = { vcs = 'git', url = 'ssh://git@github.com/sphinx-doc/sphinx.git' } numpy.version = '~=1.18' pytest = [ { version = '<6', markers = 'python_version < "3.5"' }, @@ -183,8 +183,8 @@ Standard tables:: markers = 'python_version < "2.7"' [project.dependencies.pip] - url = 'https://github.com/pypa/pip/archive/1.3.1.zip' - hash = sha1=da9234ee9982d4bbb3c72346a6de940a148ea686 + direct.url = 'https://github.com/pypa/pip/archive/1.3.1.zip' + direct.hash = 'sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' [project.dependencies.sphinx.direct] vcs = 'git' From da510f9614e3eac3c10922030720052a61de6e06 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Thu, 3 Sep 2020 21:15:16 +1000 Subject: [PATCH 12/56] Fix dependencies key name in examples --- pep-9999.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index e617fa5c994..b5b0262c01e 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -155,11 +155,11 @@ Examples Inline table:: [project] - dependences = { flask = {}, django = {}, numpy.version = '~=1.18' } + dependencies = { flask = {}, django = {}, numpy.version = '~=1.18' } Inline tables:: - [project.dependences] + [project.dependencies] flask = {} django = {} requests = { version = '>= 2.8.1, == 2.8.*', extras = [ 'security', 'tests' ], markers = 'python_version < "2.7"' } From c3493a08a90f841e12f1aa066ff6e1e857dbab43 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sun, 6 Sep 2020 19:48:47 +1000 Subject: [PATCH 13/56] Allow version specifiers as requirement specifiers --- pep-9999.rst | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index b5b0262c01e..98fe831f48c 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -93,10 +93,16 @@ dependencies Format: table The keys inside this table are the names of the required distribution. The -values can be either a requirement table or an array of requirement tables -(below). +values can have one of the following types: -It is an error to specify an empty array ``[]`` as a value. +- string: the requirement is defined only by a version requirement, with same + specification as ``version`` in the requirement table. + +- table: a requirement table. + +- array: an array of requirement tables. + +It is an error to specify an empty array ``[]`` or string ``''`` as a value. Requirement table ^^^^^^^^^^^^^^^^^ @@ -155,7 +161,7 @@ Examples Inline table:: [project] - dependencies = { flask = {}, django = {}, numpy.version = '~=1.18' } + dependencies = { flask = {}, django = {}, numpy = '~=1.18' } Inline tables:: @@ -165,7 +171,7 @@ Inline tables:: requests = { version = '>= 2.8.1, == 2.8.*', extras = [ 'security', 'tests' ], markers = 'python_version < "2.7"' } pip = { direct = { url = 'https://github.com/pypa/pip/archive/1.3.1.zip', hash = 'sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' } } sphinx.direct = { vcs = 'git', url = 'ssh://git@github.com/sphinx-doc/sphinx.git' } - numpy.version = '~=1.18' + numpy = '~=1.18' pytest = [ { version = '<6', markers = 'python_version < "3.5"' }, { version = '>=6', markers = 'python_version >= "3.5"' }, From 2a05613713ae100ebfbbaf1abf482c29761dd3f9 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sun, 6 Sep 2020 19:50:50 +1000 Subject: [PATCH 14/56] Include more arguments against separate 'revision' field --- pep-9999.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 98fe831f48c..b717d5b0cb7 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -279,7 +279,9 @@ Open Issues - Split VCS revision from URL into a separate key, such as ``revision``, in the ``direct`` table. This would increase verbosity, but could make parsing and - automated updating more straight-forward. + automated updating more straight-forward. In addition, having ``revision`` + only allowed when ``vcs`` is already provided could add to the complexity of + both users reading and tools parsing. - Split hash type from hash value in the ``direct`` table. As above, increases verbosity but also programmatic ease. From ea97aed614bb2111774bdbe53d455638b3fd3a37 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sun, 6 Sep 2020 19:56:12 +1000 Subject: [PATCH 15/56] Reject alternate definitions of extra requirements --- pep-9999.rst | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index b717d5b0cb7..b46bf6a7307 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -273,6 +273,24 @@ Rejected Ideas tables. This was very verbose and restrictive in the TOML format, and having multiple requirements for a given distribution isn't very common. +- Removing the ``optional-dependencies`` table in favour of both including an + ``optional`` key in the requirement and an ``extras`` table which specifies + which (optional) requirements are needed for a project's extra. This reduces + the number of table with the same specification (to 1) and allows for + requirements to be specified once but used in multiple extras, but distances + some of the requirement's properties (which extra(s) it belongs to), groups + required and optional dependencies together (possibly mixed), and there may + not be a simple way to choose a requirement when a distribution has multiple + requirements. This was rejected as ``optional-dependencies`` has already been + accepted in :pep:`621`. + +- Remove the ``optional-dependencies`` table in favour of including a + ``for-extras`` key in the requirement. This reduces the number of table with + the same specification (to 1) and allows for requirements to be specified + once but used in multiple extras, but groups required and optional + dependencies together (possibly mixed). This was rejected as + ``optional-dependencies`` has already been accepted in :pep:`621`. + Open Issues =========== @@ -291,20 +309,6 @@ Open Issues however the ability to have nested groups of ``and`` and ``or`` operations on the markers is lost. -- Removing the ``optional-dependencies`` table in favour of both including an - ``optional`` key in the requirement and an ``extras`` table which specifies - which (optional) requirements are needed for a project's extra. This reduces - the number of table with the same specification (to 1), but distances some of - the requirement's properties (which extra(s) it belongs to), groups required - and optional dependencies together (possibly mixed), and there may not be a - simple way to choose a requirement when a distribution has multiple - requirements. - -- Remove the ``optional-dependencies`` table in favour of including a - ``for-extras`` key in the requirement. This reduces the number of table with - the same specification (to 1), but groups required and optional dependencies - together (possibly mixed). - Copyright ========= From 3f7daaa146350b1dfc293f95b0f789d579521c37 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sun, 6 Sep 2020 19:58:12 +1000 Subject: [PATCH 16/56] Make note about 'file' protocol for direct requirements --- pep-9999.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index b46bf6a7307..11969c41348 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -134,7 +134,8 @@ can have the following keys: - ``url`` (string, *required*): the URL of the artifact or VCS repository to install and satisfy the requirement. If a VCS revision, a revision identifier MAY be appended after an at-sign "@". Revision identifiers are suggested in - :pep:`610`. + :pep:`610`. Note that `file://` is the prefix used for packages to be + retrieved from the local filesystem. - ``vcs`` (string): if (and only if) specified, the URL points to a VCS repository. The value is the name of the VCS used, as suggested in From 1fd5245f64fc3e59837759bfed27398030074f6e Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sun, 6 Sep 2020 20:07:31 +1000 Subject: [PATCH 17/56] Show consistent examples --- pep-9999.rst | 97 ++++++++++------------------------------------------ 1 file changed, 19 insertions(+), 78 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 11969c41348..29f2bd87b40 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -159,109 +159,50 @@ tables. These requirement lists are described with the same as Examples ======== -Inline table:: - - [project] - dependencies = { flask = {}, django = {}, numpy = '~=1.18' } - -Inline tables:: +Full example:: [project.dependencies] flask = {} django = {} requests = { version = '>= 2.8.1, == 2.8.*', extras = [ 'security', 'tests' ], markers = 'python_version < "2.7"' } pip = { direct = { url = 'https://github.com/pypa/pip/archive/1.3.1.zip', hash = 'sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' } } - sphinx.direct = { vcs = 'git', url = 'ssh://git@github.com/sphinx-doc/sphinx.git' } + sphinx = { direct = { vcs = 'git', url = 'ssh://git@github.com/sphinx-doc/sphinx.git' } } numpy = '~=1.18' pytest = [ { version = '<6', markers = 'python_version < "3.5"' }, { version = '>=6', markers = 'python_version >= "3.5"' }, ] -Standard tables:: - - [project.dependencies.flask] - - [project.dependencies.django] - - [project.dependencies.requests] - version = '>= 2.8.1, == 2.8.*' - extras = [ 'security', 'tests' ] - markers = 'python_version < "2.7"' - - [project.dependencies.pip] - direct.url = 'https://github.com/pypa/pip/archive/1.3.1.zip' - direct.hash = 'sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' - - [project.dependencies.sphinx.direct] - vcs = 'git' - url = 'ssh://git@github.com/sphinx-doc/sphinx.git' - - [project.dependencies.numpy] - version = '~=1.18' - - [[project.dependencies.pytest]] - version = '<6' - markers = 'python_version < "3.5"' - - [[project.dependencies.pytest]] - version = '>=6' - markers = 'python_version >= "3.5"' - In homage to :pep:`631`, the following is an equivalent dependencies specification for `docker-compose`_:: [project.dependencies] - cached-property = { version = '>= 1.2.0, < 2' } - distro = { version = '>= 1.2.0, < 2' } + cached-property = '>= 1.2.0, < 2' + distro = '>= 1.2.0, < 2' docker = { extras = [ 'ssh' ], version = '>= 4.2.2, < 5' } - docopt.version = '>= 0.6.1, < 1' - jsonschema.version = '>= 2.5.1, < 4' - PyYAML.version = '>= 3.10, < 6' - python-dotenv = { version = '>= 0.13.0, < 1' } - requests = { version = '>= 2.20.0, < 3' } + docopt = '>= 0.6.1, < 1' + jsonschema = '>= 2.5.1, < 4' + PyYAML = '>= 3.10, < 6' + python-dotenv = '>= 0.13.0, < 1' + requests = '>= 2.20.0, < 3' + texttable = '>= 0.9.0, < 2' + websocket-client = '>= 0.32.0, < 1' # Conditional 'backports.shutil_get_terminal_size' = { version = '== 1.0.0', markers = 'python_version < "3.3"' } - colorama.version = '>= 0.4, < 1' - colorama.markers = 'sys_platform == "win32"' - - [project.dependencies.texttable] - version = '>= 0.9.0, < 2' - - [project.dependencies.websocket-client] - version = '>= 0.32.0, < 1' - - [project.dependencies.'backports.ssl_match_hostname'] - version = '>= 3.5, < 4' - markers = 'python_version < "3.5"' - - [project.dependencies.colorama] - version = '>= 0.4, < 1' - markers = 'sys_platform == "win32"' + 'backports.ssl_match_hostname' = { version = '>= 3.5, < 4', markers = 'python_version < "3.5"' } + colorama = { version = '>= 0.4, < 1', markers = 'sys_platform == "win32"' } + enum34 = { version = '>= 1.0.4, < 2', markers = 'python_version < "3.4"' } + ipaddress = { '>= 1.0.16, < 2', markers = 'python_version < "3.3"' } + subprocess32 = { version = '>= 3.5.4, < 4', markers = 'python_version < "3.2"' } - [project.dependencies.enum34] - version = '>= 1.0.4, < 2' - markers = 'python_version < "3.4"' - - [project.dependencies.ipaddress] - version = '>= 1.0.16, < 2' - markers = 'python_version < "3.3"' - - [project.dependencies.subprocess32] - version = '>= 3.5.4, < 4' - markers = 'python_version < "3.2"' - - [project.optional-dependencies] - socks = { PySocks = { version = '>= 1.5.6, != 1.5.7, < 2' ] } } + [project.optional-dependencies.socks] + PySocks = { version = '>= 1.5.6, != 1.5.7, < 2' ] } [project.optional-dependencies.tests] ddt = { version = '>= 1.2.2, < 2' } pytest = { version = '< 6' ] } - mock = { version = '>= 1.0.1, < 4' } - - [project.optional-dependencies.tests.mock] - markers = 'python_version < "3.4"' + mock = { version = '>= 1.0.1, < 4', markers = 'python_version < "3.4"' } .. _docker-compose: https://github.com/docker/compose/blob/789bfb0e8b2e61f15f423d371508b698c64b057f/setup.py#L28-L61 From bdd34f5a66d9b5fe17c871ab0230cba606454c59 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sun, 6 Sep 2020 20:45:28 +1000 Subject: [PATCH 18/56] Add example implementation for conversion to PEP 508 --- pep-9999.rst | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index 29f2bd87b40..156c7fa0bd0 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -156,6 +156,52 @@ tables. These requirement lists are described with the same as `the dependencies specification <#dependencies-spec>`_ above. +Reference implementation +======================== + +Tools will need to convert this format to :pep`508` requirement strings. Below +is an example implementation of that conversion (assuming validation is already +performed):: + + def convert_requirement_to_pep508(name, requirement): + if isinstance(requirement, str): + requirement = {"version": requirement} + pep508 = name + if "extras" in requirement: + pep508 += " [" + ", ".join(requirement["extras"]) + "]" + if "version" in requirement: + pep508 += " " + requirement["version"] + if "direct" in requirement: + pep508 += " @ " + if "vcs" in requirement["direct"]: + pep508 += requirement["direct"]["vcs"] + "+" + pep508 += requirement["direct"]["url"] + if "hash" in requirement["direct"]: + pep508 += "#" + requirement["direct"]["hash"] + if "markers" in requirement: + pep508 += "; " + requirement["markers"] + return pep508 + + + def convert_requirements_to_pep508(dependencies): + pep508s = [] + for name, req in dependencies.items(): + if isinstance(req, list): + for sub_req in req: + pep508s.append(convert_requirement_to_pep508(name, sub_req)) + else: + pep508s.append(convert_requirement_to_pep508(name, req)) + return pep508s + + + def convert_project_requirements_to_pep508(project): + reqs = convert_requirements_to_pep508(project.get("dependencies", {})) + extras = {} + for name, extra_deps in project.get("optional-dependencies", {}).items(): + extras[name] = convert_requirements_to_pep508(extra_deps) + return reqs, extras + + Examples ======== From 60d194d4454dddb19691eaaec22a54d1e337c8de Mon Sep 17 00:00:00 2001 From: Pradyun Gedam <3275593+pradyunsg@users.noreply.github.com> Date: Tue, 8 Sep 2020 05:02:34 +0530 Subject: [PATCH 19/56] Syntax highlighting (#1) --- pep-9999.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 156c7fa0bd0..ee09209e5bb 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -159,9 +159,11 @@ tables. These requirement lists are described with the same as Reference implementation ======================== -Tools will need to convert this format to :pep`508` requirement strings. Below +Tools will need to convert this format to :pep:`508` requirement strings. Below is an example implementation of that conversion (assuming validation is already -performed):: +performed): + +.. code-block:: python def convert_requirement_to_pep508(name, requirement): if isinstance(requirement, str): @@ -205,7 +207,9 @@ performed):: Examples ======== -Full example:: +Full example: + +.. code-block:: toml [project.dependencies] flask = {} @@ -220,7 +224,9 @@ Full example:: ] In homage to :pep:`631`, the following is an equivalent dependencies -specification for `docker-compose`_:: +specification for `docker-compose`_: + +.. code-block:: toml [project.dependencies] cached-property = '>= 1.2.0, < 2' From 70f6c9ba1c2cd78b20d0b0e051d6f577e9a2b8e7 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Tue, 8 Sep 2020 01:33:36 +0200 Subject: [PATCH 20/56] Cleanup TOML example snippets (#2) --- pep-9999.rst | 56 ++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index ee09209e5bb..05dd28c082a 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -212,15 +212,15 @@ Full example: .. code-block:: toml [project.dependencies] - flask = {} - django = {} - requests = { version = '>= 2.8.1, == 2.8.*', extras = [ 'security', 'tests' ], markers = 'python_version < "2.7"' } - pip = { direct = { url = 'https://github.com/pypa/pip/archive/1.3.1.zip', hash = 'sha1=da9234ee9982d4bbb3c72346a6de940a148ea686' } } - sphinx = { direct = { vcs = 'git', url = 'ssh://git@github.com/sphinx-doc/sphinx.git' } } - numpy = '~=1.18' + flask = { } + django = { } + requests = { version = ">= 2.8.1, == 2.8.*", extras = ["security", "tests"], markers = "python_version < '2.7'" } + pip = { direct = { url = "https://github.com/pypa/pip/archive/1.3.1.zip", hash = "sha1=da9234ee9982d4bbb3c72346a6de940a148ea686" } } + sphinx = { direct = { vcs = "git", url = "ssh://git@github.com/sphinx-doc/sphinx.git" } } + numpy = "~=1.18" pytest = [ - { version = '<6', markers = 'python_version < "3.5"' }, - { version = '>=6', markers = 'python_version >= "3.5"' }, + { version = "<6", markers = "python_version < '3.5'" }, + { version = ">=6", markers = "python_version >= '3.5'" }, ] In homage to :pep:`631`, the following is an equivalent dependencies @@ -229,32 +229,32 @@ specification for `docker-compose`_: .. code-block:: toml [project.dependencies] - cached-property = '>= 1.2.0, < 2' - distro = '>= 1.2.0, < 2' - docker = { extras = [ 'ssh' ], version = '>= 4.2.2, < 5' } - docopt = '>= 0.6.1, < 1' - jsonschema = '>= 2.5.1, < 4' - PyYAML = '>= 3.10, < 6' - python-dotenv = '>= 0.13.0, < 1' - requests = '>= 2.20.0, < 3' - texttable = '>= 0.9.0, < 2' - websocket-client = '>= 0.32.0, < 1' + cached-property = ">= 1.2.0, < 2" + distro = ">= 1.2.0, < 2" + docker = { extras = ["ssh"], version = ">= 4.2.2, < 5" } + docopt = ">= 0.6.1, < 1" + jsonschema = ">= 2.5.1, < 4" + PyYAML = ">= 3.10, < 6" + python-dotenv = ">= 0.13.0, < 1" + requests = ">= 2.20.0, < 3" + texttable = ">= 0.9.0, < 2" + websocket-client = ">= 0.32.0, < 1" # Conditional - 'backports.shutil_get_terminal_size' = { version = '== 1.0.0', markers = 'python_version < "3.3"' } - 'backports.ssl_match_hostname' = { version = '>= 3.5, < 4', markers = 'python_version < "3.5"' } - colorama = { version = '>= 0.4, < 1', markers = 'sys_platform == "win32"' } - enum34 = { version = '>= 1.0.4, < 2', markers = 'python_version < "3.4"' } - ipaddress = { '>= 1.0.16, < 2', markers = 'python_version < "3.3"' } - subprocess32 = { version = '>= 3.5.4, < 4', markers = 'python_version < "3.2"' } + "backports.shutil_get_terminal_size" = { version = "== 1.0.0", markers = "python_version < '3.3'" } + "backports.ssl_match_hostname" = { version = ">= 3.5, < 4", markers = "python_version < '3.5'" } + colorama = { version = ">= 0.4, < 1", markers = "sys_platform == 'win32'" } + enum34 = { version = ">= 1.0.4, < 2", markers = "python_version < '3.4'" } + ipaddress = { version = ">= 1.0.16, < 2", markers = "python_version < '3.3'" } + subprocess32 = { version = ">= 3.5.4, < 4", markers = "python_version < '3.2'" } [project.optional-dependencies.socks] - PySocks = { version = '>= 1.5.6, != 1.5.7, < 2' ] } + PySocks = { version = ">= 1.5.6, != 1.5.7, < 2" } [project.optional-dependencies.tests] - ddt = { version = '>= 1.2.2, < 2' } - pytest = { version = '< 6' ] } - mock = { version = '>= 1.0.1, < 4', markers = 'python_version < "3.4"' } + ddt = { version = ">= 1.2.2, < 2" } + pytest = { version = "< 6" } + mock = { version = ">= 1.0.1, < 4", markers = "python_version < '3.4'" } .. _docker-compose: https://github.com/docker/compose/blob/789bfb0e8b2e61f15f423d371508b698c64b057f/setup.py#L28-L61 From 471960ee8e0429ea6c51b07d338492454ac73d6d Mon Sep 17 00:00:00 2001 From: Laurie O Date: Tue, 8 Sep 2020 09:58:20 +1000 Subject: [PATCH 21/56] Move direct-reference keys to top-level --- pep-9999.rst | 78 +++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 05dd28c082a..622124e42a5 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -58,8 +58,8 @@ general Python-like syntax for environment markers, and also removes the ability to logically combines the markers with grouped `and` and `or` operations. -The ``direct`` key closely aligns with :pep:`610` and :pep:`440`'s direct -references as to reduce differences in the packaging ecosystem and rely on +The direct-reference keys closely align with and utilise pep:`610` and +:pep:`440` as to reduce differences in the packaging ecosystem and rely on previous work in specification. .. _PEP 621 dependencies topic: https://discuss.python.org/t/pep-621-how-to-specify-dependencies/4599 @@ -118,33 +118,32 @@ The keys of the requirement table are as follows: - ``markers`` (string): a :pep:`508` environment marker expression. The string MUST be non-empty. -- ``direct`` (table): see below - -The ``version`` and ``direct`` keys MUST NOT be specified -simultaneously, as they logically conflict with each other in the requirement. - -An empty requirement table ``{}`` places no restriction on the requirement. - -direct -****** - -This is inspired by :pep:`610` and :pep:`440`'s direct references. The table -can have the following keys: - -- ``url`` (string, *required*): the URL of the artifact or VCS repository to - install and satisfy the requirement. If a VCS revision, a revision identifier - MAY be appended after an at-sign "@". Revision identifiers are suggested in - :pep:`610`. Note that `file://` is the prefix used for packages to be +- ``url`` (string): the URL of the artifact to install and satisfy the + requirement. Note that ``file://`` is the prefix used for packages to be retrieved from the local filesystem. -- ``vcs`` (string): if (and only if) specified, the URL points to a VCS - repository. The value is the name of the VCS used, as suggested in - :pep:`610`. +- ``git``, ``hg``, ``bzr`` or ``svn`` (string): the URL of a VCS repository to + to clone, whose tree will be installed to satisfy the requirement. Further + VCS keys will be added via amendments to :pep:`610`, however tools can opt to + support other VCS's using their command-line command prior to the acceptance + of the amendment. + +- ``revision`` (string): the identifier for a specific revision of the + specified VCS repository to check-out before installtion. Users MUST only + provide this when one of ``git``, ``hg``, ``bzr``, ``svn``, or another VCS + key is used to identify the distribution to install. Revision identifiers are + suggested in :pep:`610`. - ``hash`` (string): the hash of the retrieved artifact, prefixed with the hash algorithm and an equals-sign "=". Hash algorithms are recommended in :pep:`610`. +At most one of the following keys can be specified simultaneously, as they +logically conflict with each other in the requirement: ``version``, ``url``, +``git``, ``hg``, ``bzr``, ``svn``, and any other VCS key. + +An empty requirement table ``{}`` places no restriction on the requirement. + optional-dependencies --------------------- @@ -173,13 +172,17 @@ performed): pep508 += " [" + ", ".join(requirement["extras"]) + "]" if "version" in requirement: pep508 += " " + requirement["version"] - if "direct" in requirement: - pep508 += " @ " - if "vcs" in requirement["direct"]: - pep508 += requirement["direct"]["vcs"] + "+" - pep508 += requirement["direct"]["url"] - if "hash" in requirement["direct"]: - pep508 += "#" + requirement["direct"]["hash"] + if "url" in requirement: + pep508 += " @ " + requirement["url"] + if "hash" in requirement: + pep508 += "#" + requirement["hash"] + for vcs in ("git", "hg", "bzr", "svn"): + if vcs in requirement: + pep508 += " @ " + vcs + "+" requirement[vcs] + if "revision" in requirement: + pep508 += "@" + revision + if "hash" in requirement: + pep508 += "#" + requirement["hash"] if "markers" in requirement: pep508 += "; " + requirement["markers"] return pep508 @@ -215,8 +218,8 @@ Full example: flask = { } django = { } requests = { version = ">= 2.8.1, == 2.8.*", extras = ["security", "tests"], markers = "python_version < '2.7'" } - pip = { direct = { url = "https://github.com/pypa/pip/archive/1.3.1.zip", hash = "sha1=da9234ee9982d4bbb3c72346a6de940a148ea686" } } - sphinx = { direct = { vcs = "git", url = "ssh://git@github.com/sphinx-doc/sphinx.git" } } + pip = { url = "https://github.com/pypa/pip/archive/1.3.1.zip", hash = "sha1=da9234ee9982d4bbb3c72346a6de940a148ea686" } + sphinx = { git = "ssh://git@github.com/sphinx-doc/sphinx.git" } numpy = "~=1.18" pytest = [ { version = "<6", markers = "python_version < '3.5'" }, @@ -285,17 +288,16 @@ Rejected Ideas dependencies together (possibly mixed). This was rejected as ``optional-dependencies`` has already been accepted in :pep:`621`. +- Include the direct-reference keys in a ``direct`` table, have the VCS + specified as the value of a ``vcs`` key. This was more explicit and easier to + include in a JSON-schema validation, but was decided to be too verbose and + not as readable. + Open Issues =========== -- Split VCS revision from URL into a separate key, such as ``revision``, in the - ``direct`` table. This would increase verbosity, but could make parsing and - automated updating more straight-forward. In addition, having ``revision`` - only allowed when ``vcs`` is already provided could add to the complexity of - both users reading and tools parsing. - -- Split hash type from hash value in the ``direct`` table. As above, increases +- Split hash type from hash value in the requirement table. Increases verbosity but also programmatic ease. - Making each :pep:`508` environment marker as a key (or child-table key) in From 77f64208bed5b0abe57de2744dacbacd79065db5 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Tue, 8 Sep 2020 10:22:27 +1000 Subject: [PATCH 22/56] Re-open 'for-extra' key issue --- pep-9999.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 622124e42a5..7af7ef3de0f 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -281,13 +281,6 @@ Rejected Ideas requirements. This was rejected as ``optional-dependencies`` has already been accepted in :pep:`621`. -- Remove the ``optional-dependencies`` table in favour of including a - ``for-extras`` key in the requirement. This reduces the number of table with - the same specification (to 1) and allows for requirements to be specified - once but used in multiple extras, but groups required and optional - dependencies together (possibly mixed). This was rejected as - ``optional-dependencies`` has already been accepted in :pep:`621`. - - Include the direct-reference keys in a ``direct`` table, have the VCS specified as the value of a ``vcs`` key. This was more explicit and easier to include in a JSON-schema validation, but was decided to be too verbose and @@ -305,6 +298,13 @@ Open Issues however the ability to have nested groups of ``and`` and ``or`` operations on the markers is lost. +- Including a required ``for-extra`` key in extra requirements, which specifies + the extra for which the requirement is required for. This allows the + ``optional-dependencies`` table to be the same type as ``dependencies`` + (table of requirements), and matches the ``extra`` environment marker. The + user then needs to specify the extra for each requirement, where typos can + cause a mis-specification of the project's extras. + Copyright ========= From aafed716838a42e8a25252e857a1b5f0810641d8 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Tue, 8 Sep 2020 10:24:36 +1000 Subject: [PATCH 23/56] Remove hash from requirement --- pep-9999.rst | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 7af7ef3de0f..233d0de6595 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -134,10 +134,6 @@ The keys of the requirement table are as follows: key is used to identify the distribution to install. Revision identifiers are suggested in :pep:`610`. -- ``hash`` (string): the hash of the retrieved artifact, prefixed with the - hash algorithm and an equals-sign "=". Hash algorithms are recommended in - :pep:`610`. - At most one of the following keys can be specified simultaneously, as they logically conflict with each other in the requirement: ``version``, ``url``, ``git``, ``hg``, ``bzr``, ``svn``, and any other VCS key. @@ -174,15 +170,11 @@ performed): pep508 += " " + requirement["version"] if "url" in requirement: pep508 += " @ " + requirement["url"] - if "hash" in requirement: - pep508 += "#" + requirement["hash"] for vcs in ("git", "hg", "bzr", "svn"): if vcs in requirement: pep508 += " @ " + vcs + "+" requirement[vcs] if "revision" in requirement: pep508 += "@" + revision - if "hash" in requirement: - pep508 += "#" + requirement["hash"] if "markers" in requirement: pep508 += "; " + requirement["markers"] return pep508 @@ -218,7 +210,7 @@ Full example: flask = { } django = { } requests = { version = ">= 2.8.1, == 2.8.*", extras = ["security", "tests"], markers = "python_version < '2.7'" } - pip = { url = "https://github.com/pypa/pip/archive/1.3.1.zip", hash = "sha1=da9234ee9982d4bbb3c72346a6de940a148ea686" } + pip = { url = "https://github.com/pypa/pip/archive/1.3.1.zip" } sphinx = { git = "ssh://git@github.com/sphinx-doc/sphinx.git" } numpy = "~=1.18" pytest = [ @@ -286,13 +278,13 @@ Rejected Ideas include in a JSON-schema validation, but was decided to be too verbose and not as readable. +- Include hash in direct-reference requirements. This was only for package + lock-files, and didn't really have a place in the project's metadata. + Open Issues =========== -- Split hash type from hash value in the requirement table. Increases - verbosity but also programmatic ease. - - Making each :pep:`508` environment marker as a key (or child-table key) in the requirement. This arguably increases readability and ease of parsing, however the ability to have nested groups of ``and`` and ``or`` operations From aa1b287b225948c25c92634a506c109b1d3d2052 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Tue, 8 Sep 2020 10:26:13 +1000 Subject: [PATCH 24/56] Add work-around for environment marker keys drawback --- pep-9999.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index 233d0de6595..9ea5bf464d1 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -290,6 +290,9 @@ Open Issues however the ability to have nested groups of ``and`` and ``or`` operations on the markers is lost. + A solution to this is to still allow the ``markers`` key, with which the + key-specified environment markers and ``and``'d with the result of. + - Including a required ``for-extra`` key in extra requirements, which specifies the extra for which the requirement is required for. This allows the ``optional-dependencies`` table to be the same type as ``dependencies`` From bd29e2de7daca32c11022364c006af3be16223a2 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Tue, 8 Sep 2020 18:27:17 +1000 Subject: [PATCH 25/56] Allow empty string to for any-version --- pep-9999.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 9ea5bf464d1..c11b5fdb4d2 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -96,13 +96,13 @@ The keys inside this table are the names of the required distribution. The values can have one of the following types: - string: the requirement is defined only by a version requirement, with same - specification as ``version`` in the requirement table. + specification as ``version`` in the requirement table, except allowing the + empty string ``""`` to place no restriction on the version. - table: a requirement table. -- array: an array of requirement tables. - -It is an error to specify an empty array ``[]`` or string ``''`` as a value. +- array: an array of requirement tables. It is an error to specify an empty + array ``[]`` as a value. Requirement table ^^^^^^^^^^^^^^^^^ From 375aea5bddef742a7b3cc6565e50eae9aa54ff1a Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 00:43:44 +0000 Subject: [PATCH 26/56] Allow environment markers as keys (#5) * Allow environment markers as keys * Add white-space before marker separator in PEP 508 conversion * Add note on reason for marker key transformation * Add note on 'extra' marker --- pep-9999.rst | 88 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index c11b5fdb4d2..3a3aec49995 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -52,11 +52,10 @@ between this format and :pep:`508`-style specifiers. One example is the need to allow for specifying distributions in multiple dependencies (environment markers will choose the appropriate dependency). -Some dependency specifications, as in `Poetry`_, separate the :pep:`508` -environment markers into separate keys in the requirement. This loses the -general Python-like syntax for environment markers, and also removes the -ability to logically combines the markers with grouped `and` and `or` -operations. +The environment markers are modelled from `Poetry`_ and `Pipfile`_, and the +ability to specify environment markers in keys was allowed due to the +improved ease-of-use. The decision to convert underscores ``_`` to hyphens +``-`` was made to keep keys consistent with the rest of :pep:`621`. The direct-reference keys closely align with and utilise pep:`610` and :pep:`440` as to reduce differences in the packaging ecosystem and rely on @@ -140,6 +139,26 @@ logically conflict with each other in the requirement: ``version``, ``url``, An empty requirement table ``{}`` places no restriction on the requirement. +Environment markers +******************* + +All of the :pep:`508` environment marker variables are allowed as keys in the +requirement table, with underscores ``_`` replace with hyphens ``-``. The +values are strings which consitute the remainder of the environment marker. + +As an example, for the environment marker ``python_version < "2.7"``, the +following is included in the requirement table: + +.. code-block:: toml + + python-version = "< '2.7'" + +All of these environment markers must be satisfied, in addition to the value of +the ``markers`` key, for a requirement to be included. + +The ``extra`` marker must not be confused with the ``extras`` key defined +above. + optional-dependencies --------------------- @@ -175,8 +194,33 @@ performed): pep508 += " @ " + vcs + "+" requirement[vcs] if "revision" in requirement: pep508 += "@" + revision + markers = "" + for variable in ( + "os_name", + "sys_platform", + "platform_machine", + "platform_python_implementation", + "platform_release", + "platform_system", + "platform_version", + "python_version", + "python_full_version", + "implementation_name", + "implementation_version", + "extra", + ): + key = variable.replace("_", "-") + if key in requirement: + if markers: + markers += " and " + markers += variable + " " + requirement[key] if "markers" in requirement: - pep508 += "; " + requirement["markers"] + markers_explicit = requirement["markers"] + if markers: + markers_explicit = " and (" + markers_explicit + ")" + markers += markers_explicit + if markers: + pep508 += " ; " + markers return pep508 @@ -209,13 +253,13 @@ Full example: [project.dependencies] flask = { } django = { } - requests = { version = ">= 2.8.1, == 2.8.*", extras = ["security", "tests"], markers = "python_version < '2.7'" } + requests = { version = ">= 2.8.1, == 2.8.*", extras = ["security", "tests"], python-version = "< '2.7'" } pip = { url = "https://github.com/pypa/pip/archive/1.3.1.zip" } sphinx = { git = "ssh://git@github.com/sphinx-doc/sphinx.git" } numpy = "~=1.18" pytest = [ - { version = "<6", markers = "python_version < '3.5'" }, - { version = ">=6", markers = "python_version >= '3.5'" }, + { version = "<6", python-version = "< '3.5'" }, + { version = ">=6", python-version = ">= '3.5'" }, ] In homage to :pep:`631`, the following is an equivalent dependencies @@ -236,12 +280,12 @@ specification for `docker-compose`_: websocket-client = ">= 0.32.0, < 1" # Conditional - "backports.shutil_get_terminal_size" = { version = "== 1.0.0", markers = "python_version < '3.3'" } - "backports.ssl_match_hostname" = { version = ">= 3.5, < 4", markers = "python_version < '3.5'" } - colorama = { version = ">= 0.4, < 1", markers = "sys_platform == 'win32'" } - enum34 = { version = ">= 1.0.4, < 2", markers = "python_version < '3.4'" } - ipaddress = { version = ">= 1.0.16, < 2", markers = "python_version < '3.3'" } - subprocess32 = { version = ">= 3.5.4, < 4", markers = "python_version < '3.2'" } + "backports.shutil_get_terminal_size" = { version = "== 1.0.0", python-version = "< '3.3'" } + "backports.ssl_match_hostname" = { version = ">= 3.5, < 4", python-version = "< '3.5'" } + colorama = { version = ">= 0.4, < 1", sys-platform = "== 'win32'" } + enum34 = { version = ">= 1.0.4, < 2", python-version = "< '3.4'" } + ipaddress = { version = ">= 1.0.16, < 2", python-version = "< '3.3'" } + subprocess32 = { version = ">= 3.5.4, < 4", python-version = "< '3.2'" } [project.optional-dependencies.socks] PySocks = { version = ">= 1.5.6, != 1.5.7, < 2" } @@ -281,17 +325,17 @@ Rejected Ideas - Include hash in direct-reference requirements. This was only for package lock-files, and didn't really have a place in the project's metadata. +- Only allowing environment markers in ``markers`` key. The environment marker + keys allows for increases in readability and ease of parsing for common + cases, with no major drawbacks. + Open Issues =========== -- Making each :pep:`508` environment marker as a key (or child-table key) in - the requirement. This arguably increases readability and ease of parsing, - however the ability to have nested groups of ``and`` and ``or`` operations - on the markers is lost. - - A solution to this is to still allow the ``markers`` key, with which the - key-specified environment markers and ``and``'d with the result of. +- Prefixing all environment-marker keys with ``if-``. This increases verbosity, + but makes environment-markers less likely to conflict with future keys and + better states the intention of these keys. - Including a required ``for-extra`` key in extra requirements, which specifies the extra for which the requirement is required for. This allows the From 16e65a6397248e5a94a813c66e1481f6dbf3cd9c Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 10:48:54 +1000 Subject: [PATCH 27/56] Revert "Allow environment markers as keys (#5)" This reverts commit 375aea5bddef742a7b3cc6565e50eae9aa54ff1a. --- pep-9999.rst | 88 +++++++++++++--------------------------------------- 1 file changed, 22 insertions(+), 66 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 3a3aec49995..c11b5fdb4d2 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -52,10 +52,11 @@ between this format and :pep:`508`-style specifiers. One example is the need to allow for specifying distributions in multiple dependencies (environment markers will choose the appropriate dependency). -The environment markers are modelled from `Poetry`_ and `Pipfile`_, and the -ability to specify environment markers in keys was allowed due to the -improved ease-of-use. The decision to convert underscores ``_`` to hyphens -``-`` was made to keep keys consistent with the rest of :pep:`621`. +Some dependency specifications, as in `Poetry`_, separate the :pep:`508` +environment markers into separate keys in the requirement. This loses the +general Python-like syntax for environment markers, and also removes the +ability to logically combines the markers with grouped `and` and `or` +operations. The direct-reference keys closely align with and utilise pep:`610` and :pep:`440` as to reduce differences in the packaging ecosystem and rely on @@ -139,26 +140,6 @@ logically conflict with each other in the requirement: ``version``, ``url``, An empty requirement table ``{}`` places no restriction on the requirement. -Environment markers -******************* - -All of the :pep:`508` environment marker variables are allowed as keys in the -requirement table, with underscores ``_`` replace with hyphens ``-``. The -values are strings which consitute the remainder of the environment marker. - -As an example, for the environment marker ``python_version < "2.7"``, the -following is included in the requirement table: - -.. code-block:: toml - - python-version = "< '2.7'" - -All of these environment markers must be satisfied, in addition to the value of -the ``markers`` key, for a requirement to be included. - -The ``extra`` marker must not be confused with the ``extras`` key defined -above. - optional-dependencies --------------------- @@ -194,33 +175,8 @@ performed): pep508 += " @ " + vcs + "+" requirement[vcs] if "revision" in requirement: pep508 += "@" + revision - markers = "" - for variable in ( - "os_name", - "sys_platform", - "platform_machine", - "platform_python_implementation", - "platform_release", - "platform_system", - "platform_version", - "python_version", - "python_full_version", - "implementation_name", - "implementation_version", - "extra", - ): - key = variable.replace("_", "-") - if key in requirement: - if markers: - markers += " and " - markers += variable + " " + requirement[key] if "markers" in requirement: - markers_explicit = requirement["markers"] - if markers: - markers_explicit = " and (" + markers_explicit + ")" - markers += markers_explicit - if markers: - pep508 += " ; " + markers + pep508 += "; " + requirement["markers"] return pep508 @@ -253,13 +209,13 @@ Full example: [project.dependencies] flask = { } django = { } - requests = { version = ">= 2.8.1, == 2.8.*", extras = ["security", "tests"], python-version = "< '2.7'" } + requests = { version = ">= 2.8.1, == 2.8.*", extras = ["security", "tests"], markers = "python_version < '2.7'" } pip = { url = "https://github.com/pypa/pip/archive/1.3.1.zip" } sphinx = { git = "ssh://git@github.com/sphinx-doc/sphinx.git" } numpy = "~=1.18" pytest = [ - { version = "<6", python-version = "< '3.5'" }, - { version = ">=6", python-version = ">= '3.5'" }, + { version = "<6", markers = "python_version < '3.5'" }, + { version = ">=6", markers = "python_version >= '3.5'" }, ] In homage to :pep:`631`, the following is an equivalent dependencies @@ -280,12 +236,12 @@ specification for `docker-compose`_: websocket-client = ">= 0.32.0, < 1" # Conditional - "backports.shutil_get_terminal_size" = { version = "== 1.0.0", python-version = "< '3.3'" } - "backports.ssl_match_hostname" = { version = ">= 3.5, < 4", python-version = "< '3.5'" } - colorama = { version = ">= 0.4, < 1", sys-platform = "== 'win32'" } - enum34 = { version = ">= 1.0.4, < 2", python-version = "< '3.4'" } - ipaddress = { version = ">= 1.0.16, < 2", python-version = "< '3.3'" } - subprocess32 = { version = ">= 3.5.4, < 4", python-version = "< '3.2'" } + "backports.shutil_get_terminal_size" = { version = "== 1.0.0", markers = "python_version < '3.3'" } + "backports.ssl_match_hostname" = { version = ">= 3.5, < 4", markers = "python_version < '3.5'" } + colorama = { version = ">= 0.4, < 1", markers = "sys_platform == 'win32'" } + enum34 = { version = ">= 1.0.4, < 2", markers = "python_version < '3.4'" } + ipaddress = { version = ">= 1.0.16, < 2", markers = "python_version < '3.3'" } + subprocess32 = { version = ">= 3.5.4, < 4", markers = "python_version < '3.2'" } [project.optional-dependencies.socks] PySocks = { version = ">= 1.5.6, != 1.5.7, < 2" } @@ -325,17 +281,17 @@ Rejected Ideas - Include hash in direct-reference requirements. This was only for package lock-files, and didn't really have a place in the project's metadata. -- Only allowing environment markers in ``markers`` key. The environment marker - keys allows for increases in readability and ease of parsing for common - cases, with no major drawbacks. - Open Issues =========== -- Prefixing all environment-marker keys with ``if-``. This increases verbosity, - but makes environment-markers less likely to conflict with future keys and - better states the intention of these keys. +- Making each :pep:`508` environment marker as a key (or child-table key) in + the requirement. This arguably increases readability and ease of parsing, + however the ability to have nested groups of ``and`` and ``or`` operations + on the markers is lost. + + A solution to this is to still allow the ``markers`` key, with which the + key-specified environment markers and ``and``'d with the result of. - Including a required ``for-extra`` key in extra requirements, which specifies the extra for which the requirement is required for. This allows the From ffb0dad0e0a3253014b1acce763011330e3356bb Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 10:55:05 +1000 Subject: [PATCH 28/56] Defer the environment marker keys idea --- pep-9999.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index c11b5fdb4d2..f56a5682e38 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -281,18 +281,16 @@ Rejected Ideas - Include hash in direct-reference requirements. This was only for package lock-files, and didn't really have a place in the project's metadata. +- Making each :pep:`508` environment marker as a key (or child-table key) in + the requirement. This arguably increases readability and ease of parsing. + The ``markers`` key would still be allowed for more advanced specification, + with which the key-specified environment markers are ``and``'d with the + result of. This was deferred as more design needs to be undertaken. + Open Issues =========== -- Making each :pep:`508` environment marker as a key (or child-table key) in - the requirement. This arguably increases readability and ease of parsing, - however the ability to have nested groups of ``and`` and ``or`` operations - on the markers is lost. - - A solution to this is to still allow the ``markers`` key, with which the - key-specified environment markers and ``and``'d with the result of. - - Including a required ``for-extra`` key in extra requirements, which specifies the extra for which the requirement is required for. This allows the ``optional-dependencies`` table to be the same type as ``dependencies`` From 22741e41668a777c7f920ec12d03e19ea2412696 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 01:02:35 +0000 Subject: [PATCH 29/56] Convert optional-deps to table of reqs with extra key (#4) * Convert optional-deps to table of reqs with extra key * Fix optional-dependencies in docker-compose example * Add note on 'for-extras' key --- pep-9999.rst | 53 +++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index f56a5682e38..c932b188d89 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -85,8 +85,6 @@ in :pep:`621`. .. _toml: https://toml.io/ -.. _dependencies-spec: - dependencies ------------ @@ -104,6 +102,8 @@ values can have one of the following types: - array: an array of requirement tables. It is an error to specify an empty array ``[]`` as a value. +.. _requirement-spec: + Requirement table ^^^^^^^^^^^^^^^^^ @@ -145,10 +145,19 @@ optional-dependencies Format: table -The keys inside this table are the names of the project's :pep:`508` extras. -The values each specify the list of requirements required by the extra, and are -tables. These requirement lists are described with the same as -`the dependencies specification <#dependencies-spec>`_ above. +The keys inside this table are the names of an extra's required distribution. +The values can have one of the following types: + +- table: a requirement table. + +- array: an array of requirement tables. + +These requirement tables have +`the same specification as above <#requirement-spec>`_, with the addition of +the following required key: + +- ``for-extra`` (string): the name of the :pep:`508` extra that this + requirement is required for. Reference implementation @@ -243,13 +252,11 @@ specification for `docker-compose`_: ipaddress = { version = ">= 1.0.16, < 2", markers = "python_version < '3.3'" } subprocess32 = { version = ">= 3.5.4, < 4", markers = "python_version < '3.2'" } - [project.optional-dependencies.socks] - PySocks = { version = ">= 1.5.6, != 1.5.7, < 2" } - - [project.optional-dependencies.tests] - ddt = { version = ">= 1.2.2, < 2" } - pytest = { version = "< 6" } - mock = { version = ">= 1.0.1, < 4", markers = "python_version < '3.4'" } + [project.optional-dependencies] + PySocks = { version = ">= 1.5.6, != 1.5.7, < 2", for-extra = "socks" } + ddt = { version = ">= 1.2.2, < 2", for-extra = "tests" } + pytest = { version = "< 6", for-extra = "tests" } + mock = { version = ">= 1.0.1, < 4", markers = "python_version < '3.4'", for-extra = "tests" } .. _docker-compose: https://github.com/docker/compose/blob/789bfb0e8b2e61f15f423d371508b698c64b057f/setup.py#L28-L61 @@ -281,22 +288,22 @@ Rejected Ideas - Include hash in direct-reference requirements. This was only for package lock-files, and didn't really have a place in the project's metadata. +- Have the ``optional-dependencies`` be a table of dependency tables for each + extra, with the table name being the extra's name. This made + ``optional-dependencies`` a different type (table of tables of requirements) + from ``dependencies`` (table of requirements), which could be jarring for + users and harder to parse. + - Making each :pep:`508` environment marker as a key (or child-table key) in the requirement. This arguably increases readability and ease of parsing. The ``markers`` key would still be allowed for more advanced specification, with which the key-specified environment markers are ``and``'d with the result of. This was deferred as more design needs to be undertaken. - -Open Issues -=========== - -- Including a required ``for-extra`` key in extra requirements, which specifies - the extra for which the requirement is required for. This allows the - ``optional-dependencies`` table to be the same type as ``dependencies`` - (table of requirements), and matches the ``extra`` environment marker. The - user then needs to specify the extra for each requirement, where typos can - cause a mis-specification of the project's extras. +- Replacing the `for-extra` key with `for-extras`, with the value being an + array of extras to makr the requirement a dependency for. This reduces some + duplication, but in this case that duplication makes explicit which extras + have which dependencies. Copyright From febb95466b01c702d1a70c2bf24f6876708d976d Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Wed, 9 Sep 2020 03:12:03 +0200 Subject: [PATCH 30/56] Add PEP 508 compatibility examples (#3) * Add PEP 508 compatibility examples Initial set of examples demonstrating compatibility with PEP 508. * Fix typo in example version constraint * Add a note for version only dependency * Add missing new line * Update vcs examples * Fix markers example * Fix missing markers * Replace for-extras with for-extra --- pep-9999.rst | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index c932b188d89..d81542a39d6 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -261,6 +261,172 @@ specification for `docker-compose`_: .. _docker-compose: https://github.com/docker/compose/blob/789bfb0e8b2e61f15f423d371508b698c64b057f/setup.py#L28-L61 +Compatibility Examples +====================== + +The authors of this PEP recognises that various tools need to both read +from and write to this format for dependency specification. This section +aims to provide direct comparison with and examples for translating to/from +the currently used standard, :pep:`508`. + +.. note:: + + For simplicity and clarity, various ways in which TOML allows you to specify each + specification is not represented. These examples use the standard inline representation. + + For example, while following are considered equivalent in TOML, we choose the + second form for the examples in this section. + + .. code-block:: toml + + aiohttp.version = "== 3.6.2" + aiohttp = { version = "== 3.6.2" } + + +Version Constrained Dependencies +-------------------------------- + +**No Version Constraint** + +.. code-block:: + + aiohttp + + +.. code-block:: toml + + aiohttp = {} + +**Simple Version Constraint** + +.. code-block:: + + aiohttp (>= 3.6.2, < 4.0.0) + + +.. code-block:: toml + + aiohttp = { version = ">= 3.6.2, < 4.0.0" } + + +.. note:: + + This can, for conciseness, be also represented as a string. + + .. code-block:: toml + + aiohttp = ">= 3.6.2, < 4.0.0" + + + +Direct Reference Dependencies +----------------------------- + +**URL Dependency** + +.. code-block:: + + aiohttp @ https://files.pythonhosted.org/packages/97/d1/1cc7a1f84097d7abdc6c09ee8d2260366f081f8e82da36ebb22a25cdda9f/aiohttp-3.6.2-cp35-cp35m-macosx_10_13_x86_64.whl + + +.. code-block:: toml + + aiohttp = { url = "https://files.pythonhosted.org/packages/97/d1/1cc7a1f84097d7abdc6c09ee8d2260366f081f8e82da36ebb22a25cdda9f/aiohttp-3.6.2-cp35-cp35m-macosx_10_13_x86_64.whl" } + +**VCS Dependency** + +.. code-block:: + + aiohttp @ git+ssh://git@github.com:aio-libs/aiohttp.git@master + + +.. code-block:: toml + + aiohttp = { git = "git@github.com:aio-libs/aiohttp.git", revision = "master" } + + +Environment Markers +------------------- + +.. code-block:: + + aiohttp (>= 3.6.1) ; python_version >= '3.8' + + +.. code-block:: toml + + aiohttp = { version = ">= 3.6.1", markers = "python_version >= '3.8'" } + + +A silightly extended example of the above, where a particular version of ``aiohttp`` is required based on the interpreter version. + +.. code-block:: + + aiohttp (>= 3.6.1) ; python_version >= '3.8' + aiohttp (>= 3.0.0, < 3.6.1) ; python_version < '3.8' + + +.. code-block:: toml + + aiohttp = [ + { version = ">= 3.6.1", markers = "python_version >= '3.8'" }, + { version = ">= 3.0.0, < 3.6.1", markers = "python_version < '3.8'" } + ] + + +Package Extras +-------------- + +**Specifying dependency for a package extra** + +.. code-block:: + + aiohttp (>= 3.6.2) ; extra == 'http' + + +.. code-block:: toml + + aiohttp = { version = ">= 3.6.2", for-extra = "http" } + +**Using extras from a dependency** + +.. code-block:: + + aiohttp [speedups] (>= 3.6.2) + + +.. code-block:: toml + + aiohttp = { version = ">= 3.6.2", extras = ["speedups"] } + + +Complex Examples +---------------- + +**Version Constraint** + +.. code-block:: + + aiohttp [speedups] (>=3.6.2) ; python_version >= '3.8' and extra == 'http' + + +.. code-block:: toml + + aiohttp = { version = ">= 3.6.2", extras = ["speedups"], markers = "python_version >= '3.8'", for-extra = "http" } + + +**Direct Reference (VCS)** + +.. code-block:: + + aiohttp [speedups] @ git+ssh://git@github.com:aio-libs/aiohttp.git@master ; python_version >= '3.8' and extra == 'http' + + +.. code-block:: toml + + aiohttp = { git = "git@github.com:aio-libs/aiohttp.git", revision = "master", extras = ["speedups"], markers = "python_version >= '3.8'", for-extra = "http" } + + Rejected Ideas ============== From a69fa93b68f5e7cc71c33824fb703358c59f2cea Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 11:24:18 +1000 Subject: [PATCH 31/56] Typo fix, indentation as spaces --- pep-9999.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index d81542a39d6..890f696ef1e 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -277,10 +277,10 @@ the currently used standard, :pep:`508`. For example, while following are considered equivalent in TOML, we choose the second form for the examples in this section. - .. code-block:: toml + .. code-block:: toml - aiohttp.version = "== 3.6.2" - aiohttp = { version = "== 3.6.2" } + aiohttp.version = "== 3.6.2" + aiohttp = { version = "== 3.6.2" } Version Constrained Dependencies @@ -315,7 +315,7 @@ Version Constrained Dependencies .. code-block:: toml - aiohttp = ">= 3.6.2, < 4.0.0" + aiohttp = ">= 3.6.2, < 4.0.0" @@ -358,7 +358,7 @@ Environment Markers aiohttp = { version = ">= 3.6.1", markers = "python_version >= '3.8'" } -A silightly extended example of the above, where a particular version of ``aiohttp`` is required based on the interpreter version. +A slightly extended example of the above, where a particular version of ``aiohttp`` is required based on the interpreter version. .. code-block:: From d742168c70adc147cf4c0dbaf6e4a52f832b8ae4 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 11:30:31 +1000 Subject: [PATCH 32/56] Fix example conversion for 'for-extra' key --- pep-9999.rst | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 890f696ef1e..ec66e970962 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -184,27 +184,41 @@ performed): pep508 += " @ " + vcs + "+" requirement[vcs] if "revision" in requirement: pep508 += "@" + revision + extra = None + if "for-extra" in requirement: + extra = requirement["for-extra"] if "markers" in requirement: - pep508 += "; " + requirement["markers"] - return pep508 + markers = requirement["markers"] + if extra: + markers = "extra = '" + extra + "' and (" + markers + ")" + pep508 += "; " + markers + return pep508, extra def convert_requirements_to_pep508(dependencies): pep508s = [] + extras = [] for name, req in dependencies.items(): if isinstance(req, list): for sub_req in req: - pep508s.append(convert_requirement_to_pep508(name, sub_req)) + pep508, extra = convert_requirement_to_pep508(name, sub_req) + pep508s.append(pep508) + if extra: + extras.append(extra) else: - pep508s.append(convert_requirement_to_pep508(name, req)) - return pep508s + pep508, extra = convert_requirement_to_pep508(name, sub_req) + pep508s.append(pep508) + if extra: + extras.append(extra) + return pep508s, extras def convert_project_requirements_to_pep508(project): - reqs = convert_requirements_to_pep508(project.get("dependencies", {})) - extras = {} - for name, extra_deps in project.get("optional-dependencies", {}).items(): - extras[name] = convert_requirements_to_pep508(extra_deps) + reqs, _ = convert_requirements_to_pep508(project.get("dependencies", {})) + optional_reqs, extras = convert_requirements_to_pep508( + project.get("optional-dependencies", {}) + ) + reqs += optional_reqs return reqs, extras From 109d4e8ea731b09db25423ccd2fc2ff1c27f0ba5 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 11:51:38 +1000 Subject: [PATCH 33/56] Improve note on multiple requirements for the same project --- pep-9999.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index ec66e970962..12c66eeb200 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -49,8 +49,9 @@ This has elements from `Pipfile`_, `Poetry`_, `Dart's dependencies`_ and `Rust's Cargo`_. A `comparison document`_ shows advantages and disadvantages between this format and :pep:`508`-style specifiers. -One example is the need to allow for specifying distributions in multiple -dependencies (environment markers will choose the appropriate dependency). +In the specification of multiple requirements with the same distribution name +(where environment markers choose the appropriate dependency), the chosen +solution is similar to `Poetry`_'s, where an array of requirements is allowed. Some dependency specifications, as in `Poetry`_, separate the :pep:`508` environment markers into separate keys in the requirement. This loses the From 9266677c4fac92b6d876c900dd0319f6f288a93f Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 11:52:33 +1000 Subject: [PATCH 34/56] Remove note on environment marker keys in rationale (already in rejected-ideas) --- pep-9999.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 12c66eeb200..5f9944a4188 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -53,12 +53,6 @@ In the specification of multiple requirements with the same distribution name (where environment markers choose the appropriate dependency), the chosen solution is similar to `Poetry`_'s, where an array of requirements is allowed. -Some dependency specifications, as in `Poetry`_, separate the :pep:`508` -environment markers into separate keys in the requirement. This loses the -general Python-like syntax for environment markers, and also removes the -ability to logically combines the markers with grouped `and` and `or` -operations. - The direct-reference keys closely align with and utilise pep:`610` and :pep:`440` as to reduce differences in the packaging ecosystem and rely on previous work in specification. From 2bfad0f7d333dc5dfc323885373f72fb82c62791 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 11:55:33 +1000 Subject: [PATCH 35/56] Note requirement keys are optional --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 5f9944a4188..6cfd660c699 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -102,7 +102,7 @@ values can have one of the following types: Requirement table ^^^^^^^^^^^^^^^^^ -The keys of the requirement table are as follows: +The keys of the requirement table are as follows (all are optional): - ``version`` (string): a :pep:`440` version specifier, which is a comma- delimited list of version specifier clauses. The string MUST be non-empty. From 5531d87a5507233ad32131c41eeb3ee04f602c05 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Wed, 9 Sep 2020 11:57:37 +1000 Subject: [PATCH 36/56] Add optional dependencies to full example --- pep-9999.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index 6cfd660c699..7662dae5e33 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -236,6 +236,13 @@ Full example: { version = ">=6", markers = "python_version >= '3.5'" }, ] + [project.optional-dependencies] + pytest-timout = { for-extra = "dev" } + pytest-mock = [ + { version = "<6", markers = "python_version < '3.5'", for-extra = "dev" }, + { version = ">=6", markers = "python_version >= '3.5'", for-extra = "dev" }, + ] + In homage to :pep:`631`, the following is an equivalent dependencies specification for `docker-compose`_: From 4f3f3664d82bc81a79f4d92cb8c44c91102cd262 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Fri, 11 Sep 2020 08:26:59 +1000 Subject: [PATCH 37/56] Explicitly only allow URLs for VCS repository paths --- pep-9999.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 7662dae5e33..51687a6c026 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -117,7 +117,8 @@ The keys of the requirement table are as follows (all are optional): requirement. Note that ``file://`` is the prefix used for packages to be retrieved from the local filesystem. -- ``git``, ``hg``, ``bzr`` or ``svn`` (string): the URL of a VCS repository to +- ``git``, ``hg``, ``bzr`` or ``svn`` (string): the URL of a VCS repository + (as specified in :pep:`440`) to clone, whose tree will be installed to satisfy the requirement. Further VCS keys will be added via amendments to :pep:`610`, however tools can opt to support other VCS's using their command-line command prior to the acceptance @@ -353,12 +354,12 @@ Direct Reference Dependencies .. code-block:: - aiohttp @ git+ssh://git@github.com:aio-libs/aiohttp.git@master + aiohttp @ git+ssh://git@github.com/aio-libs/aiohttp.git@master .. code-block:: toml - aiohttp = { git = "git@github.com:aio-libs/aiohttp.git", revision = "master" } + aiohttp = { git = "ssh://git@github.com/aio-libs/aiohttp.git", revision = "master" } Environment Markers @@ -435,12 +436,12 @@ Complex Examples .. code-block:: - aiohttp [speedups] @ git+ssh://git@github.com:aio-libs/aiohttp.git@master ; python_version >= '3.8' and extra == 'http' + aiohttp [speedups] @ git+ssh://git@github.com/aio-libs/aiohttp.git@master ; python_version >= '3.8' and extra == 'http' .. code-block:: toml - aiohttp = { git = "git@github.com:aio-libs/aiohttp.git", revision = "master", extras = ["speedups"], markers = "python_version >= '3.8'", for-extra = "http" } + aiohttp = { git = "ssh://git@github.com/aio-libs/aiohttp.git", revision = "master", extras = ["speedups"], markers = "python_version >= '3.8'", for-extra = "http" } Rejected Ideas From 0c18b61e6981076031594169c53439c978b75098 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Fri, 11 Sep 2020 08:31:27 +1000 Subject: [PATCH 38/56] Remove syntax highlighting --- pep-9999.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 51687a6c026..e94a32a7010 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -163,7 +163,7 @@ Tools will need to convert this format to :pep:`508` requirement strings. Below is an example implementation of that conversion (assuming validation is already performed): -.. code-block:: python +.. code-block:: def convert_requirement_to_pep508(name, requirement): if isinstance(requirement, str): @@ -223,7 +223,7 @@ Examples Full example: -.. code-block:: toml +.. code-block:: [project.dependencies] flask = { } @@ -247,7 +247,7 @@ Full example: In homage to :pep:`631`, the following is an equivalent dependencies specification for `docker-compose`_: -.. code-block:: toml +.. code-block:: [project.dependencies] cached-property = ">= 1.2.0, < 2" @@ -294,7 +294,7 @@ the currently used standard, :pep:`508`. For example, while following are considered equivalent in TOML, we choose the second form for the examples in this section. - .. code-block:: toml + .. code-block:: aiohttp.version = "== 3.6.2" aiohttp = { version = "== 3.6.2" } @@ -310,7 +310,7 @@ Version Constrained Dependencies aiohttp -.. code-block:: toml +.. code-block:: aiohttp = {} @@ -321,7 +321,7 @@ Version Constrained Dependencies aiohttp (>= 3.6.2, < 4.0.0) -.. code-block:: toml +.. code-block:: aiohttp = { version = ">= 3.6.2, < 4.0.0" } @@ -330,7 +330,7 @@ Version Constrained Dependencies This can, for conciseness, be also represented as a string. - .. code-block:: toml + .. code-block:: aiohttp = ">= 3.6.2, < 4.0.0" @@ -346,7 +346,7 @@ Direct Reference Dependencies aiohttp @ https://files.pythonhosted.org/packages/97/d1/1cc7a1f84097d7abdc6c09ee8d2260366f081f8e82da36ebb22a25cdda9f/aiohttp-3.6.2-cp35-cp35m-macosx_10_13_x86_64.whl -.. code-block:: toml +.. code-block:: aiohttp = { url = "https://files.pythonhosted.org/packages/97/d1/1cc7a1f84097d7abdc6c09ee8d2260366f081f8e82da36ebb22a25cdda9f/aiohttp-3.6.2-cp35-cp35m-macosx_10_13_x86_64.whl" } @@ -357,7 +357,7 @@ Direct Reference Dependencies aiohttp @ git+ssh://git@github.com/aio-libs/aiohttp.git@master -.. code-block:: toml +.. code-block:: aiohttp = { git = "ssh://git@github.com/aio-libs/aiohttp.git", revision = "master" } @@ -370,7 +370,7 @@ Environment Markers aiohttp (>= 3.6.1) ; python_version >= '3.8' -.. code-block:: toml +.. code-block:: aiohttp = { version = ">= 3.6.1", markers = "python_version >= '3.8'" } @@ -383,7 +383,7 @@ A slightly extended example of the above, where a particular version of ``aiohtt aiohttp (>= 3.0.0, < 3.6.1) ; python_version < '3.8' -.. code-block:: toml +.. code-block:: aiohttp = [ { version = ">= 3.6.1", markers = "python_version >= '3.8'" }, @@ -401,7 +401,7 @@ Package Extras aiohttp (>= 3.6.2) ; extra == 'http' -.. code-block:: toml +.. code-block:: aiohttp = { version = ">= 3.6.2", for-extra = "http" } @@ -412,7 +412,7 @@ Package Extras aiohttp [speedups] (>= 3.6.2) -.. code-block:: toml +.. code-block:: aiohttp = { version = ">= 3.6.2", extras = ["speedups"] } @@ -427,7 +427,7 @@ Complex Examples aiohttp [speedups] (>=3.6.2) ; python_version >= '3.8' and extra == 'http' -.. code-block:: toml +.. code-block:: aiohttp = { version = ">= 3.6.2", extras = ["speedups"], markers = "python_version >= '3.8'", for-extra = "http" } @@ -439,7 +439,7 @@ Complex Examples aiohttp [speedups] @ git+ssh://git@github.com/aio-libs/aiohttp.git@master ; python_version >= '3.8' and extra == 'http' -.. code-block:: toml +.. code-block:: aiohttp = { git = "ssh://git@github.com/aio-libs/aiohttp.git", revision = "master", extras = ["speedups"], markers = "python_version >= '3.8'", for-extra = "http" } From 238976584c61682f5ee83e51ae877e9b47be651e Mon Sep 17 00:00:00 2001 From: Laurie O Date: Fri, 11 Sep 2020 08:37:06 +1000 Subject: [PATCH 39/56] Remove post-history --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index e94a32a7010..973d892a4fe 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -5,7 +5,7 @@ Status: Draft Type: Standards Track Content-Type: text/x-rst Created: 02-09-2020 -Post-History: TBD +Post-History: Abstract From ec974b7cc344d89607fd1a6e573a75678b180c3e Mon Sep 17 00:00:00 2001 From: Laurie O Date: Fri, 11 Sep 2020 08:38:02 +1000 Subject: [PATCH 40/56] Add Arun to authors --- pep-9999.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 973d892a4fe..934c907bc89 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -1,6 +1,7 @@ PEP: 9999 Title: Dependency specification in pyproject.toml using an exploded TOML table -Author: Laurie Opperman +Author: Laurie Opperman , + Arun Babu Neelicattu Status: Draft Type: Standards Track Content-Type: text/x-rst From 6580e7a49bedcf321355578238b10c1f5bea53de Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 01:04:16 +0000 Subject: [PATCH 41/56] Assign PEP number 633 Co-authored-by: Brett Cannon --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 934c907bc89..b803999cf1d 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -1,4 +1,4 @@ -PEP: 9999 +PEP: 633 Title: Dependency specification in pyproject.toml using an exploded TOML table Author: Laurie Opperman , Arun Babu Neelicattu From 74ea8335b1339b56fb973be073ff4d5b77d99534 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 01:05:12 +0000 Subject: [PATCH 42/56] Add Brett as sponsor, set discussions link Co-authored-by: Brett Cannon --- pep-9999.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index b803999cf1d..bc76b0f7b9c 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -2,6 +2,8 @@ PEP: 633 Title: Dependency specification in pyproject.toml using an exploded TOML table Author: Laurie Opperman , Arun Babu Neelicattu +Sponsor: Brett Cannon +Discussions-To: https://discuss.python.org/t/dependency-specification-in-pyproject-toml-using-an-exploded-toml-table/5123/ Status: Draft Type: Standards Track Content-Type: text/x-rst From 0b7e2aca0712a6d539ee4c57814d1e5de11ce5ef Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 01:05:40 +0000 Subject: [PATCH 43/56] Set post history Co-authored-by: Brett Cannon --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index bc76b0f7b9c..7b0266690ef 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -8,7 +8,7 @@ Status: Draft Type: Standards Track Content-Type: text/x-rst Created: 02-09-2020 -Post-History: +Post-History: 2020-09-02 Abstract From a795290ce793becf8f1c3879da06dbcff46521ff Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 01:06:18 +0000 Subject: [PATCH 44/56] Update created date format Co-authored-by: Brett Cannon --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 7b0266690ef..9272dc73b74 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -7,7 +7,7 @@ Discussions-To: https://discuss.python.org/t/dependency-specification-in-pyproje Status: Draft Type: Standards Track Content-Type: text/x-rst -Created: 02-09-2020 +Created: 2020-09-02 Post-History: 2020-09-02 From 92df91d4c46307838631a5f378103031841b6099 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 01:06:57 +0000 Subject: [PATCH 45/56] Remove specific mention on which tables are defined Co-authored-by: Brett Cannon --- pep-9999.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 9272dc73b74..b985e80b829 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -17,8 +17,7 @@ Abstract This PEP specifies how to write a project's dependencies in a ``pyproject.toml`` file for packaging-related tools to consume using the fields defined in :pep:`621`, as an alternative to the :pep:`508`-based approach -defined in :pep:`631`. Specifically, the tables ``project.dependencies`` and -``project.optional-dependencies`` are defined. +defined in :pep:`631`. Motivation From 6e97975c89cde12a5defd82c855be72b526f2b0b Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 01:09:19 +0000 Subject: [PATCH 46/56] Format TOML mentions in all-caps Co-authored-by: Brett Cannon --- pep-9999.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index b985e80b829..77d3df9cc31 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -71,7 +71,7 @@ Specification ============= As in :pep:`621`, if metadata is improperly specified then tools MUST raise an -error. The metadata MUST conform to the `toml`_ specification. +error. The metadata MUST conform to the `TOML`_ specification. To reduce confusion with this document being a specification for specifying dependencies, the word "requirement" is used to mean a :pep:`508` dependency @@ -80,7 +80,7 @@ specification. The following tables are added to the added to the ``project`` table specified in :pep:`621`. -.. _toml: https://toml.io/ +.. _TOML: https://toml.io/ dependencies ------------ From d493d65f478926cf99c9a2abfd160da23c017df3 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 01:10:00 +0000 Subject: [PATCH 47/56] Code-format table-name headings Co-authored-by: Brett Cannon --- pep-9999.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 77d3df9cc31..804833d4401 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -82,8 +82,8 @@ in :pep:`621`. .. _TOML: https://toml.io/ -dependencies ------------- +``dependencies`` +---------------- Format: table @@ -138,8 +138,8 @@ logically conflict with each other in the requirement: ``version``, ``url``, An empty requirement table ``{}`` places no restriction on the requirement. -optional-dependencies ---------------------- +``optional-dependencies`` +-------------------------- Format: table From f7191f80c6f4d70138dec20c94ef1fc452eec3ed Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 01:10:44 +0000 Subject: [PATCH 48/56] Use RF 2119 language Co-authored-by: Brett Cannon --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 804833d4401..b759696a7af 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -122,7 +122,7 @@ The keys of the requirement table are as follows (all are optional): - ``git``, ``hg``, ``bzr`` or ``svn`` (string): the URL of a VCS repository (as specified in :pep:`440`) to clone, whose tree will be installed to satisfy the requirement. Further - VCS keys will be added via amendments to :pep:`610`, however tools can opt to + VCS keys will be added via amendments to :pep:`610`, however tools MAY opt to support other VCS's using their command-line command prior to the acceptance of the amendment. From 63fea79b4f56ba44d440dff937342962c03c372c Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 01:14:52 +0000 Subject: [PATCH 49/56] Typo fix Co-authored-by: Brett Cannon --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index b759696a7af..42a9ff9ff49 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -283,7 +283,7 @@ specification for `docker-compose`_: Compatibility Examples ====================== -The authors of this PEP recognises that various tools need to both read +The authors of this PEP recognise that various tools need to both read from and write to this format for dependency specification. This section aims to provide direct comparison with and examples for translating to/from the currently used standard, :pep:`508`. From e61c423ae968cccdeeb13b92e915126f4448d656 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 22:33:04 +1000 Subject: [PATCH 50/56] Explicitly re-mention empty-string as no constraint --- pep-9999.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 42a9ff9ff49..48991e459f7 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -136,7 +136,8 @@ At most one of the following keys can be specified simultaneously, as they logically conflict with each other in the requirement: ``version``, ``url``, ``git``, ``hg``, ``bzr``, ``svn``, and any other VCS key. -An empty requirement table ``{}`` places no restriction on the requirement. +An empty requirement table ``{}`` places no restriction on the requirement, in +addition to the empty string ``""``. ``optional-dependencies`` -------------------------- From f5ee3bc3c7afbee0b69d9f7688fafe65e89eaf71 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 22:33:46 +1000 Subject: [PATCH 51/56] Mark first example as artificial --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 48991e459f7..022588c14c9 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -224,7 +224,7 @@ performed): Examples ======== -Full example: +Full artificial example: .. code-block:: From 246bf03cc7382745a92e84f5de35dc3d8c6f700d Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 22:45:39 +1000 Subject: [PATCH 52/56] Changes rejected-ideas list to subsections --- pep-9999.rst | 101 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/pep-9999.rst b/pep-9999.rst index 022588c14c9..7e40222047f 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -450,46 +450,67 @@ Complex Examples Rejected Ideas ============== -- Using an array for `dependencies` instead of a table, in order to have each - element only be a table (with a `name` key) and no arrays of requirement - tables. This was very verbose and restrictive in the TOML format, and having - multiple requirements for a given distribution isn't very common. - -- Removing the ``optional-dependencies`` table in favour of both including an - ``optional`` key in the requirement and an ``extras`` table which specifies - which (optional) requirements are needed for a project's extra. This reduces - the number of table with the same specification (to 1) and allows for - requirements to be specified once but used in multiple extras, but distances - some of the requirement's properties (which extra(s) it belongs to), groups - required and optional dependencies together (possibly mixed), and there may - not be a simple way to choose a requirement when a distribution has multiple - requirements. This was rejected as ``optional-dependencies`` has already been - accepted in :pep:`621`. - -- Include the direct-reference keys in a ``direct`` table, have the VCS - specified as the value of a ``vcs`` key. This was more explicit and easier to - include in a JSON-schema validation, but was decided to be too verbose and - not as readable. - -- Include hash in direct-reference requirements. This was only for package - lock-files, and didn't really have a place in the project's metadata. - -- Have the ``optional-dependencies`` be a table of dependency tables for each - extra, with the table name being the extra's name. This made - ``optional-dependencies`` a different type (table of tables of requirements) - from ``dependencies`` (table of requirements), which could be jarring for - users and harder to parse. - -- Making each :pep:`508` environment marker as a key (or child-table key) in - the requirement. This arguably increases readability and ease of parsing. - The ``markers`` key would still be allowed for more advanced specification, - with which the key-specified environment markers are ``and``'d with the - result of. This was deferred as more design needs to be undertaken. - -- Replacing the `for-extra` key with `for-extras`, with the value being an - array of extras to makr the requirement a dependency for. This reduces some - duplication, but in this case that duplication makes explicit which extras - have which dependencies. +Switch to an array for ``dependencies`` +--------------------------------------- + +Use an array instead of a table in order to have each element only be a table +(with a ``name`` key) and no arrays of requirement tables. This was very +verbose and restrictive in the TOML format, and having multiple requirements +for a given distribution isn't very common. + +Replace ``optional-dependencies`` with ``extras`` +------------------------------------------------- + +Remove the ``optional-dependencies`` table in favour of both including an +``optional`` key in the requirement and an ``extras`` table which specifies +which (optional) requirements are needed for a project's extra. This reduces +the number of table with the same specification (to 1) and allows for +requirements to be specified once but used in multiple extras, but distances +some of the requirement's properties (which extra(s) it belongs to), groups +required and optional dependencies together (possibly mixed), and there may not +be a simple way to choose a requirement when a distribution has multiple +requirements. This was rejected as ``optional-dependencies`` has already been +accepted in :pep:`621`. + +``direct`` table in requirement +------------------------------- + +Include the direct-reference keys in a ``direct`` table, have the VCS specified +as the value of a ``vcs`` key. This was more explicit and easier to include in +a JSON-schema validation, but was decided to be too verbose and not as +readable. + +Include hash +------------ + +Include hash in direct-reference requirements. This was only for package +lock-files, and didn't really have a place in the project's metadata. + +Dependency tables for each extra +-------------------------------- + +Have the ``optional-dependencies`` be a table of dependency tables for each +extra, with the table name being the extra's name. This made +``optional-dependencies`` a different type (table of tables of requirements) +from ``dependencies`` (table of requirements), which could be jarring for users +and harder to parse. + +Environment marker keys +----------------------- + +Make each :pep:`508` environment marker as a key (or child-table key) in +the requirement. This arguably increases readability and ease of parsing. +The ``markers`` key would still be allowed for more advanced specification, +with which the key-specified environment markers are ``and``'d with the +result of. This was deferred as more design needs to be undertaken. + +Multiple extras which one requirement can satisfy +------------------------------------------------- + +Replace the ``for-extra`` key with ``for-extras``, with the value being an +array of extras to make the requirement a dependency for. This reduces some +duplication, but in this case that duplication makes explicit which extras +have which dependencies. Copyright From 62bd3e09c8affe7f87f06c8c05603034d99043c7 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 22:46:21 +1000 Subject: [PATCH 53/56] Improve definition of 'for-extra' --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 7e40222047f..a6ac7bb8fa1 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -508,7 +508,7 @@ Multiple extras which one requirement can satisfy ------------------------------------------------- Replace the ``for-extra`` key with ``for-extras``, with the value being an -array of extras to make the requirement a dependency for. This reduces some +array of extras which the requirement satisfies. This reduces some duplication, but in this case that duplication makes explicit which extras have which dependencies. From d3c79701023087b77f36e3c39c44420b0d2d931c Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 22:49:05 +1000 Subject: [PATCH 54/56] Add note on unknown keys --- pep-9999.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pep-9999.rst b/pep-9999.rst index a6ac7bb8fa1..10a6749e5c8 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -139,6 +139,9 @@ logically conflict with each other in the requirement: ``version``, ``url``, An empty requirement table ``{}`` places no restriction on the requirement, in addition to the empty string ``""``. +Any keys provided which are not specified in this document MUST cause an error +in parsing. + ``optional-dependencies`` -------------------------- From 7ebe5b19593dd7004a4f69765a0f302f5ac387f0 Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 22:58:26 +1000 Subject: [PATCH 55/56] Update wording on table names in PEP 621 --- pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-9999.rst b/pep-9999.rst index 10a6749e5c8..56c2a618175 100644 --- a/pep-9999.rst +++ b/pep-9999.rst @@ -473,7 +473,7 @@ some of the requirement's properties (which extra(s) it belongs to), groups required and optional dependencies together (possibly mixed), and there may not be a simple way to choose a requirement when a distribution has multiple requirements. This was rejected as ``optional-dependencies`` has already been -accepted in :pep:`621`. +used in the :pep:`621` draft. ``direct`` table in requirement ------------------------------- From ef0d461af058d29784ca9450539cd1f319bbd2df Mon Sep 17 00:00:00 2001 From: Laurie O Date: Sat, 12 Sep 2020 23:00:20 +1000 Subject: [PATCH 56/56] Rename to PEP 633 --- pep-9999.rst => pep-0633.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pep-9999.rst => pep-0633.rst (100%) diff --git a/pep-9999.rst b/pep-0633.rst similarity index 100% rename from pep-9999.rst rename to pep-0633.rst