PEP440 Version Specifier Syntax
Currently PEP440 has a version specifier syntax like ``foo (2,~=2,==2,!=2,>=2,<=2,>2,<2)``. This is a hold over from PEP 345 of which I cannot locate a rationale for this change. I believe that we should revert this syntax back to the setuptools style of ``foo~=2,==2,!=2,>=2,<=2,>2,<2``. This change represents a backwards incompatible change to how dependencies are specified for dubious benefits. * It requires that users learn a new syntax for little/no benefit to them. * It requires the use of quoting if you use this syntax on the shell. We are depending on the space + parentheses in order to enable: * A default comparison operator. This is ~= if the leading version is < 1980 or >= if the leading version is >= 1980. * The direct reference syntax, which is ``foo (from https://...)``. On these, I think that we should also remove the default comparison idea. It originally started out as a shorthand for ~= but it was realized that this is going to do wrong thing for date base releases so it was later changed so that it does ~= or >= depending on the leading version. However it's still going to do the wrong thing for a wide variety of projects. The current selector for which you get (~= or >=) is based off of the leading version, however there are a lot of projects which this detection simply won't work for. One instance of a project where it won't is Twisted which has date based releases but instead of using 2014.0 they do 14.0. While we could mandate to Twisted (and anyone else) that if they want to do date based they need to use YYYY and not YY as their leading version, it'll still do the wrong thing for any rolling release which does not use a date based release scheme. For instance a scheme that simply does an incrementing version counter. I think that the default operator is born out of an attempt to be prescriptive about what meanings people put in their versions. I believe that the inability to provide a default that is always going to be correct with all sane schemes points to the idea that guessing in the face of ambiguity is still a bad idea and we should just require that people be explicit. If we assume that we're going to ditch the default comparison operator the only thing left that _requires_ the ``foo (==2.0)`` syntax is the direct reference syntax (``foo (from https://...)``). For this I think the downsides of the new syntax outweigh the minor benefits in syntax. I would suggest that we just define an operator that means direct reference. Something like ``foo@https://...`` could be reasonable and even has a decent verbal representation in the form of "foo at https://...". This does have the downside that it might be somewhat confusing if there is an "@" in the URL we are referencing. So what do people think? Drop the default comparison operator idea? Drop the new syntax and continue using the old? ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
On 19 May 2014 23:44, "Donald Stufft" <donald@stufft.io> wrote:
Currently PEP440 has a version specifier syntax like ``foo (2,~=2,==2,!=2,>=2,<=2,>2,<2)``. This is a hold over from PEP 345 of which I cannot locate a rationale for this change.
It's at least in part to reduce ambiguity when listing multiple dependencies as a list, rather than as line separated: foo(~=2,!=2.3.x), bar(~=3,!=3.5.4.x) That's why my initial reaction to the various aspects of the proposal was: +1 to dropping the default comparison operator now we have "~=" as an explicit spelling +1 for dropping the space between the package name and the opening parenthesis (to be honest, I thought it was already at least optional , but the PEP may not make that clear) +0 for making the parentheses optional when only using a single comparison operator -0.5 for making the parentheses optional when using multiple comparison operators On reflection, however, I'm switching back to "-1" for the latter two points. That's a UI issue for user facing formats that has no place in the data interchange specification. By contrast, the space is entirely redundant given the parentheses, so it makes sense to me to drop it from the interchange format. Allowing users to optionally include whitespace in version specifiers then joins the ability to omit the parentheses as a tooling UI decision that doesn't apply to the interchange standards. Remember, the metadata PEPs are about specifying the *normalised* forms that are exchanged between automated tools. User facing tools are free to be more liberal in what they accept and handle the normalisation on their users' behalf. Cheers, Nick.
On May 19, 2014, at 7:15 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On 19 May 2014 23:44, "Donald Stufft" <donald@stufft.io> wrote:
Currently PEP440 has a version specifier syntax like ``foo (2,~=2,==2,!=2,>=2,<=2,>2,<2)``. This is a hold over from PEP 345 of which I cannot locate a rationale for this change.
It's at least in part to reduce ambiguity when listing multiple dependencies as a list, rather than as line separated:
foo(~=2,!=2.3.x), bar(~=3,!=3.5.4.x)
That's why my initial reaction to the various aspects of the proposal was:
+1 to dropping the default comparison operator now we have "~=" as an explicit spelling +1 for dropping the space between the package name and the opening parenthesis (to be honest, I thought it was already at least optional , but the PEP may not make that clear) +0 for making the parentheses optional when only using a single comparison operator -0.5 for making the parentheses optional when using multiple comparison operators
On reflection, however, I'm switching back to "-1" for the latter two points. That's a UI issue for user facing formats that has no place in the data interchange specification. By contrast, the space is entirely redundant given the parentheses, so it makes sense to me to drop it from the interchange format. Allowing users to optionally include whitespace in version specifiers then joins the ability to omit the parentheses as a tooling UI decision that doesn't apply to the interchange standards.
Remember, the metadata PEPs are about specifying the *normalised* forms that are exchanged between automated tools. User facing tools are free to be more liberal in what they accept and handle the normalisation on their users' behalf
Are we planning on putting these someplace where we can't unambiguously parse them? AFAIK in both the key:value form and the JSON form of the metadata are perfectly capable (and it is in fact no different processing wise) of handling them. AFAICT we're never going to rely on adhoc parsing here, at least we shouldn't, so we don't need any help from the specifier in discerning between two different ones. Even if this is for the interchange format there is value in having it consistent both for the benefit of the humans reading the interchange format and for the benefit of the tooling so that they don't have to maintain two different code paths to parse these. ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
Are we planning on putting these someplace where we can't unambiguously
them? AFAIK in both the key:value form and the JSON form of the metadata are perfectly capable (and it is in fact no different processing wise) of handling them. AFAICT we're never going to rely on adhoc parsing here, at least we shouldn't, so we don't need any help from the specifier in discerning between two different ones.
Even if this is for the interchange format there is value in having it consistent both for the benefit of the humans reading the interchange
On 20 May 2014 10:30, "Donald Stufft" <donald@stufft.io> wrote: parse format
and for the benefit of the tooling so that they don't have to maintain two different code paths to parse these.
As in, have the "no parens" option be the normalised form and leave it to tools like d2to1 to strip the parens when necessary? I guess that would work. All the cases of accepting version specifiers for multiple dependencies in PEP 426 use a JSON list now, so the individual version specifiers always have surrounding quotes. The parenthesis requirement made more sense in the absence of that higher level structure. Cheers, Nick.
----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372
DCFA
On May 19, 2014, at 8:57 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On 20 May 2014 10:30, "Donald Stufft" <donald@stufft.io> wrote:
Are we planning on putting these someplace where we can't unambiguously parse them? AFAIK in both the key:value form and the JSON form of the metadata are perfectly capable (and it is in fact no different processing wise) of handling them. AFAICT we're never going to rely on adhoc parsing here, at least we shouldn't, so we don't need any help from the specifier in discerning between two different ones.
Even if this is for the interchange format there is value in having it consistent both for the benefit of the humans reading the interchange format and for the benefit of the tooling so that they don't have to maintain two different code paths to parse these.
As in, have the "no parens" option be the normalised form and leave it to tools like d2to1 to strip the parens when necessary?
I guess that would work. All the cases of accepting version specifiers for multiple dependencies in PEP 426 use a JSON list now, so the individual version specifiers always have surrounding quotes. The parenthesis requirement made more sense in the absence of that higher level structure.
Yea, I don’t see us _needing_ the parens for anything, we have proper structured metadata now and it provides some consistency. Tools that want to use the old format from Metadata 1.2 would need to translate of course, but that is always the case when you have a tool that is designed for one format being moved to another. I think a major benefit here is that the setuptools style is by far the dominant format so it moves the “must translate” case to the outlier of things that were early adopters for distutils2 format and lets the common case be the easy case. ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
participants (2)
-
Donald Stufft
-
Nick Coghlan