Mailing List Archive

Revive PEP 396 -- Module Version Numbers ?
I've already asked on python-ideas, but it was suggested that as there's a
PEP already, it's time to move this along. So here's the pitch.

Over the years, I've seen __version__ used very broadly but not *quite* in
all packages. I've always known it was a convention, not a requirement. But
it turns out it's not even a "official" convention.

But it really would be nice if there was a consistent way that I could
count on to get the version of a package at run time from the package
itself.

Turns out this was suggested in PEP 396 -- and deferred almost 13 years ago!

https://www.python.org/dev/peps/pep-0396/

In the status note, it says:

"""
Further exploration of the concepts covered in this PEP has been deferred
for lack of a current champion interested in promoting the goals of the PEP
and collecting and incorporating feedback, and with sufficient available
time to do so effectively.
"""

Well, I may be willing to be that champion, if a core dev is willing to
sponsor.

And, well, after 13 years, we've seen __version__ be very broadly, though
certainly not universally used.

Honestly, I haven't looked to see to what extent setuptools supports it,
but will, of course, do so if folks think this is worth pursuing. And the
PyPA has moved toward "distribution" meta data, preliminarily supported by
importlib.metadata.version.

So maybe this is a settled issue, and we just need to change the status of
the PEP.

But for my part, I FAR prefer the version info to be embedded in the code
of the package in a simple way, rather than hiding among the metadata, and
requiring importlib.metadata.version to get a version at runtime.

I note that PEP8 uses __version__ as an example of a "module level dunder"
-- but only suggests where it should be put, not how it be used :-)

Of course, there will be a need to update the PEP to match current
practice, and if it is me doing it, I'd make it very simple

So what do you'all think? After thirteen years, it would be nice to put
this to bed.

I think the next step is to see if I can find a sponsor :-)

-CHB


--
Christopher Barker, PhD (Chris)

Python Language Consulting
- Teaching
- Scientific Software Development
- Desktop GUI and Web Development
- wxPython, numpy, scipy, Cython
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, Apr 14, 2021 at 7:48 AM Christopher Barker <pythonchb@gmail.com> wrote:
> So what do you'all think? After thirteen years, it would be nice to put this to bed.

There are two main use cases for versions:

* Display them to the user
* Compare versions to check if one is newer, older or the same

I dislike using strings for comparison. You need to use
packaging.version for that:
https://packaging.pypa.io/en/latest/version.html

Many C libraries provide the version as a number of as 3 numbers
(major, minor, micro). In its C API, Python provides all of them:

* PY_VERSION_HEX: single number
* (PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION,
PY_RELEASE_LEVEL, PY_RELEASE_SERIAL): as 5 numbers
* PY_VERSION: string

In my Python projects, I like to provide the version as a tuple which
can be used directly for comparison: version_a <= version_b. Example:

VERSION = (2, 2, 1)
__version__ = '.'.join(map(str, VERSION))

The tuple might contain strings like "beta" or "rc", as soon as
comparison makes sense ;-) Sadly, such tuple is no standardized. Which
part is the major version? How to format it as a string?

Good luck with trying to standardize that ;-)

Victor
--
Night gathers, and now my watch begins. It shall not end until my death.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/MBBYB5AWX76O3TOUFATRKSU2QND2TPKS/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, 14 Apr 2021 at 13:28, Victor Stinner <vstinner@python.org> wrote:
> There are two main use cases for versions:
>
> * Display them to the user
> * Compare versions to check if one is newer, older or the same
>
> I dislike using strings for comparison. You need to use
> packaging.version for that:
> https://packaging.pypa.io/en/latest/version.html

Agreed, programmatic use should really conform to PEP 440 versioning,
as implemented in packaging.version, if it's to align with existing
packaging standards (which currently focus on *project* versions
rather than package versions, but the distinction is not something we
should be making a big deal of).

> Many C libraries provide the version as a number of as 3 numbers
> (major, minor, micro). In its C API, Python provides all of them:
>
> * PY_VERSION_HEX: single number
> * (PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION,
> PY_RELEASE_LEVEL, PY_RELEASE_SERIAL): as 5 numbers
> * PY_VERSION: string
>
> In my Python projects, I like to provide the version as a tuple which
> can be used directly for comparison: version_a <= version_b. Example:
>
> VERSION = (2, 2, 1)
> __version__ = '.'.join(map(str, VERSION))
>
> The tuple might contain strings like "beta" or "rc", as soon as
> comparison makes sense ;-) Sadly, such tuple is no standardized. Which
> part is the major version? How to format it as a string?
>
> Good luck with trying to standardize that ;-)

Agreed. We should stick to PEP 440 format strings, and not try to
dictate other formats like (named) tuples.

But does the PEP want to cover programmatic use *at all*? It would be
possible to define __version__ as "a human-readable string in PEP 440
format" and note that any use other than for display to a person is
outside the scope of the PEP. That's closer in spirit to the 13-year
old version we currently have, but it does miss an opportunity as we
now do have a standard version class ("standard" in the sense of "a
packaging standard", but not "in the stdlib").

Paul
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/5LFCLXIPXF3PO6PZ5ZLS7TD2OE4U35OD/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
> In my Python projects, I like to provide the version as a tuple which
> can be used directly for comparison

To add to this, comparing tuples doesn't always work well for projects
where multiple release lines are maintained simultaneously, e.g.
user-facing changes introduced in minor/point releases across several major
versions. People use version numbers in wildly different ways.

Barney

On Wed, 14 Apr 2021 at 13:26, Victor Stinner <vstinner@python.org> wrote:

> On Wed, Apr 14, 2021 at 7:48 AM Christopher Barker <pythonchb@gmail.com>
> wrote:
> > So what do you'all think? After thirteen years, it would be nice to put
> this to bed.
>
> There are two main use cases for versions:
>
> * Display them to the user
> * Compare versions to check if one is newer, older or the same
>
> I dislike using strings for comparison. You need to use
> packaging.version for that:
> https://packaging.pypa.io/en/latest/version.html
>
> Many C libraries provide the version as a number of as 3 numbers
> (major, minor, micro). In its C API, Python provides all of them:
>
> * PY_VERSION_HEX: single number
> * (PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION,
> PY_RELEASE_LEVEL, PY_RELEASE_SERIAL): as 5 numbers
> * PY_VERSION: string
>
> In my Python projects, I like to provide the version as a tuple which
> can be used directly for comparison: version_a <= version_b. Example:
>
> VERSION = (2, 2, 1)
> __version__ = '.'.join(map(str, VERSION))
>
> The tuple might contain strings like "beta" or "rc", as soon as
> comparison makes sense ;-) Sadly, such tuple is no standardized. Which
> part is the major version? How to format it as a string?
>
> Good luck with trying to standardize that ;-)
>
> Victor
> --
> Night gathers, and now my watch begins. It shall not end until my death.
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-leave@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/MBBYB5AWX76O3TOUFATRKSU2QND2TPKS/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
I recently encountered this, which is very useful, but only for a
human-readable perspective.

>>> import vaex
>>> vaex.__version__
{'vaex': '4.1.0', 'vaex-core': '4.1.0', 'vaex-viz': '0.5.0', 'vaex-hdf5':
'0.7.0', 'vaex-server': '0.4.0', 'vaex-astro': '0.8.0', 'vaex-jupyter':
'0.6.0', 'vaex-ml': '0.11.1'}



On Wed, Apr 14, 2021 at 2:01 PM Barney Gale <barney.gale@gmail.com> wrote:

> > In my Python projects, I like to provide the version as a tuple which
> > can be used directly for comparison
>
> To add to this, comparing tuples doesn't always work well for projects
> where multiple release lines are maintained simultaneously, e.g.
> user-facing changes introduced in minor/point releases across several major
> versions. People use version numbers in wildly different ways.
>
> Barney
>
> On Wed, 14 Apr 2021 at 13:26, Victor Stinner <vstinner@python.org> wrote:
>
>> On Wed, Apr 14, 2021 at 7:48 AM Christopher Barker <pythonchb@gmail.com>
>> wrote:
>> > So what do you'all think? After thirteen years, it would be nice to put
>> this to bed.
>>
>> There are two main use cases for versions:
>>
>> * Display them to the user
>> * Compare versions to check if one is newer, older or the same
>>
>> I dislike using strings for comparison. You need to use
>> packaging.version for that:
>> https://packaging.pypa.io/en/latest/version.html
>>
>> Many C libraries provide the version as a number of as 3 numbers
>> (major, minor, micro). In its C API, Python provides all of them:
>>
>> * PY_VERSION_HEX: single number
>> * (PY_MAJOR_VERSION, PY_MINOR_VERSION, PY_MICRO_VERSION,
>> PY_RELEASE_LEVEL, PY_RELEASE_SERIAL): as 5 numbers
>> * PY_VERSION: string
>>
>> In my Python projects, I like to provide the version as a tuple which
>> can be used directly for comparison: version_a <= version_b. Example:
>>
>> VERSION = (2, 2, 1)
>> __version__ = '.'.join(map(str, VERSION))
>>
>> The tuple might contain strings like "beta" or "rc", as soon as
>> comparison makes sense ;-) Sadly, such tuple is no standardized. Which
>> part is the major version? How to format it as a string?
>>
>> Good luck with trying to standardize that ;-)
>>
>> Victor
>> --
>> Night gathers, and now my watch begins. It shall not end until my death.
>> _______________________________________________
>> Python-Dev mailing list -- python-dev@python.org
>> To unsubscribe send an email to python-dev-leave@python.org
>> https://mail.python.org/mailman3/lists/python-dev.python.org/
>> Message archived at
>> https://mail.python.org/archives/list/python-dev@python.org/message/MBBYB5AWX76O3TOUFATRKSU2QND2TPKS/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-leave@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/4XWIWIKDJJRWVKNGIOENJ2ZJVQR4PP23/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


--
The dead increasingly dominate and strangle both the living and the
not-yet born. Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, Apr 14, 2021 at 7:48 AM David Mertz <mertz@gnosis.cx> wrote:

> >>> vaex.__version__
> {'vaex': '4.1.0', 'vaex-core': '4.1.0', 'vaex-viz': '0.5.0', 'vaex-hdf5':
> '0.7.0', 'vaex-server': '0.4.0', 'vaex-astro': '0.8.0', 'vaex-jupyter':
> '0.6.0', 'vaex-ml': '0.11.1'}
>

Well, THAT is a great argument for some official standardization!

There is sometimes a need for that sort of thing, but I think it's best
handled by either putting __version__ in each sub_package, or having a
different attribute altogether.

-CHB

--
Christopher Barker, PhD (Chris)

Python Language Consulting
- Teaching
- Scientific Software Development
- Desktop GUI and Web Development
- wxPython, numpy, scipy, Cython
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
Simon,

I'm not sure your note made it to the list -- bringing it back on.

On Wed, Apr 14, 2021 at 1:15 AM Simon Cross <hodgestar+pythondev@gmail.com>
wrote:

> I would be +1 on having a small PEP like this one to give __version__
> an official blessing and some well-defined expected behaviour.
>
> I don't have a deep opinion on the specifics of the specification, but
> I'm guessing they should be thought about again even if the answers
> end up being the same. Quite a lot has changed in the Python ecosystem
> in the last 13 years.
>

Yes indeed. Critically, over on the packaging side, standardization of
versioning specs.

-CHB

--
Christopher Barker, PhD (Chris)

Python Language Consulting
- Teaching
- Scientific Software Development
- Desktop GUI and Web Development
- wxPython, numpy, scipy, Cython
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
Agreed!

I was trying to figure out why an API from Vaex 3.x was no longer working,
and to my human eye, this quickly pointed me at the issue. However as a
way to automatically check for versions, this is a mess. I have no idea
what additional keys the next version might add or remove, for example.
I'm not even sure if this is dynamically determined based on optional
components being installed or not.

Providing this kind of information *somehow* feels like a useful thing to
do. But .__version__ is probably not the right way to do it.

On Wed, Apr 14, 2021 at 5:08 PM Christopher Barker <pythonchb@gmail.com>
wrote:

> On Wed, Apr 14, 2021 at 7:48 AM David Mertz <mertz@gnosis.cx> wrote:
>
>> >>> vaex.__version__
>> {'vaex': '4.1.0', 'vaex-core': '4.1.0', 'vaex-viz': '0.5.0', 'vaex-hdf5':
>> '0.7.0', 'vaex-server': '0.4.0', 'vaex-astro': '0.8.0', 'vaex-jupyter':
>> '0.6.0', 'vaex-ml': '0.11.1'}
>>
>
> Well, THAT is a great argument for some official standardization!
>
> There is sometimes a need for that sort of thing, but I think it's best
> handled by either putting __version__ in each sub_package, or having a
> different attribute altogether.
>
> -CHB
>
> --
> Christopher Barker, PhD (Chris)
>
> Python Language Consulting
> - Teaching
> - Scientific Software Development
> - Desktop GUI and Web Development
> - wxPython, numpy, scipy, Cython
>


--
The dead increasingly dominate and strangle both the living and the
not-yet born. Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, Apr 14, 2021 at 5:24 AM Victor Stinner <vstinner@python.org> wrote:

> There are two main use cases for versions:
>
> * Display them to the user
> * Compare versions to check if one is newer, older or the same
>
> I dislike using strings for comparison. You need to use
> packaging.version for that:
> https://packaging.pypa.io/en/latest/version.html


Yes, though it looks a little too heavyweight to be required, nifty
features like ``is_prerelease` is going pretty far.

On the other hand, maybe no harm in all that, as long as:

- It's easy to do the easy stuff (which is looks like it is)
- It would be added to the stdlib

However, there is a lot of code out there that's already using strings for
__version__, so it would be a real shame if we had to ask everyone to
upgrade. And Version isn't going to be in older versions of the Python
stdlib, so hard to make code compatible.

But: If we make a Version object that can be compared to (confoming)
strings then there might be a path forward.


> In my Python projects, I like to provide the version as a tuple which
> can be used directly for comparison: version_a <= version_b. Example:
>

Yes, and tuples are already built in to Python, so an easier lift than
adding the Version object.

Another possible issue: using Version would require an extra import in many
module initializations -- is that a performance issue that would matter?

In any case, I think the PEP should specify a standard for what is in
__version__

And ideally it would be backward compatible with strings, which are the
most commonly used currently.

And conform to PEP 440

Sadly, such tuple is no standardized. Which
> part is the major version? How to format it as a string?
>
> Good luck with trying to standardize that ;-)
>

well, PEP 440 gets us close -- and I *think* compliant strings could be
unambiguously converted to-from tuples.

Anyway, the question now for me is whether this is worth any more of my
time.

So:
- Is there someone willing to sponsor?
- Do folks generally think there's a chance of it being accepted without a
huge debate and expansion of scope.

If the answers are not yes, I can better spend my Python time of other
things.

BTW: one source of hope:

__version__ strings are pretty common, but, as evidenced already by this
brief discussion, it's not by any means a universal standard -- so we
really can't break anything that already works in any universal way.

What i mean by that is that anything done here might break someone's
special use case of __version__ (Like the one David Mertz identified), but
that scheme only works with that one package's code anyway. There are no
general tools that expect that scheme.

And it could be preserved by making a subclass of Version (Or str) that was
also a mapping :-)

- CHB



--
Christopher Barker, PhD (Chris)

Python Language Consulting
- Teaching
- Scientific Software Development
- Desktop GUI and Web Development
- wxPython, numpy, scipy, Cython
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, Apr 14, 2021 at 5:44 PM Christopher Barker <pythonchb@gmail.com>
wrote:

> Another possible issue: using Version would require an extra import in
> many module initializations -- is that a performance issue that would
> matter?
>

I like having a `Version` object that is easily importable in the standard
library. I think it should relatively polymorphic. I.e. it should accept
a module or package as an argument, but also should accept a string or a
tuple. Maybe other objects from which one could reasonably extract a
version.

In particular, I think initializing this object with a module object should
at least look for a .__version__ attribute, and appropriately case either a
string (that looks sufficiently version-like) or a tuple. I think that if
it doesn't succeed, it should become some sort of "cannot determine" object
that is neither less than nor greater than any other Version object. In
particular, the Vaex example with a dictionary of versions of each
component should probably just become this "cannot determine" value (but as
an instance of Version).

--
The dead increasingly dominate and strangle both the living and the
not-yet born. Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On 4/14/2021 12:38 PM, Christopher Barker wrote:
>
>
> Anyway, the question now for me is whether this is worth any more of
> my time.
>
> So:
> - Is there someone willing to sponsor?
> - Do folks generally think there's a chance of it being accepted
> without a huge debate and expansion of scope.
>
I think that before these can be answered, you need to decide why this
needs to be standardized. I don't see any reason to standardize it
unless there's some programmatic use for these version strings. If it's
just the user poking around on the REPL, then I think the status quo is
fine. I've read the PEP, and the User Stories section talks about user
convenience, not programmatic access.

I also think the distribution version is more useful than any
__version__ information in each module/package. I realize this
information might not be available, depending on how the code was
installed (say, just by copying some files into the right place).

Eric
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Apr 13, 2021, at 22:40, Christopher Barker <pythonchb@gmail.com> wrote:
>
> Turns out this was suggested in PEP 396 -- and deferred almost 13 years ago!
>
> https://www.python.org/dev/peps/pep-0396/

I’d forgotten that this PEP was in Deferred state. I think it should be rejected and I plan on making that change. importlib.metadata is a much better approach to programmatically determining package versions.

https://docs.python.org/3/library/importlib.metadata.html#distribution-versions

-Barry
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, 14 Apr 2021 at 18:01, David Mertz <mertz@gnosis.cx> wrote:
>
> On Wed, Apr 14, 2021 at 5:44 PM Christopher Barker <pythonchb@gmail.com> wrote:
>>
>> Another possible issue: using Version would require an extra import in many module initializations -- is that a performance issue that would matter?
>
>
> I like having a `Version` object that is easily importable in the standard library. I think it should relatively polymorphic. I.e. it should accept a module or package as an argument, but also should accept a string or a tuple. Maybe other objects from which one could reasonably extract a version.

If it's not basically equivalent to packaging.version.Version (and
based on PEP 440) then we'll be creating a nightmare of confusion,
because PEP 440 versions are fundamental to packaging.

> In particular, I think initializing this object with a module object should at least look for a .__version__ attribute, and appropriately case either a string (that looks sufficiently version-like) or a tuple. I think that if it doesn't succeed, it should become some sort of "cannot determine" object that is neither less than nor greater than any other Version object. In particular, the Vaex example with a dictionary of versions of each component should probably just become this "cannot determine" value (but as an instance of Version).

What's wrong with Version(module.__version__)? And if the __version__
attribute isn't a valid version, raise an exception? That's what
packaging.version does, and it's worked fine for the packaging
ecosystem. Is there a benefit that justifies being different here?

Can I remind people that the packaging community have done a *huge*
amount of work designing and standardising concepts like version
identifiers, version comparisons and constraints, etc. (PEPs 440 and
508). Understanding those standards should really be the basic
starting point for any discussion like this.

Paul
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/U2PUBZZ2AULMULLESO3LZ74MCRV7BQ3G/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, 14 Apr 2021 at 18:04, Eric V. Smith <eric@trueblade.com> wrote:
>> Anyway, the question now for me is whether this is worth any more of my time.
>>
>> So:
>> - Is there someone willing to sponsor?
>> - Do folks generally think there's a chance of it being accepted without a huge debate and expansion of scope.
>>
>> I think that before these can be answered, you need to decide why this needs to be standardized. I don't see any reason to standardize it unless there's some programmatic use for these version strings. If it's just the user poking around on the REPL, then I think the status quo is fine. I've read the PEP, and the User Stories section talks about user convenience, not programmatic access.
>
> I also think the distribution version is more useful than any __version__ information in each module/package. I realize this information might not be available, depending on how the code was installed (say, just by copying some files into the right place).

Agreed. The original PEP was very limited, just proposing a string
value for user convenience, with no programmatic interface. Doing
anything more than that is opening up a whole load of complexity and
compatibility (with packaging) that no-one has expressed any need for.

The distribution version (exposed via importlib.metadata) is the
correct thing to use for anything programmatic.

Paul

PS I see Barry plans on rejecting the PEP, which I think is probably
the right decision, given the way this thread has developed.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/MQIFSJYQYCY4YBHVECJ7H2WR443EE32W/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, Apr 14, 2021 at 4:19 PM Paul Moore <p.f.moore@gmail.com> wrote:

> PS I see Barry plans on rejecting the PEP, which I think is probably
> the right decision, given the way this thread has developed.
>

Barry makes good plans.

Putting the version into the sources is a bit of an anti-pattern. IMO.


-Fred

--
Fred L. Drake, Jr. <fred at fdrake.net>
"There is nothing more uncommon than common sense."
--Frank Lloyd Wright
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, Apr 14, 2021 at 9:12 PM Paul Moore <p.f.moore@gmail.com> wrote:

> If it's not basically equivalent to packaging.version.Version (and
> based on PEP 440) then we'll be creating a nightmare of confusion,
> because PEP 440 versions are fundamental to packaging.
>

Are you suggesting that users should have to install an external module to
tell what version of packages they are using?!

What's wrong with Version(module.__version__)? And if the __version__
> attribute isn't a valid version, raise an exception? That's what
> packaging.version does, and it's worked fine for the packaging
> ecosystem. Is there a benefit that justifies being different here?
>

Doesn't that seem really, really painful to use in an interactive shell?
This is honestly (a simplified version of) what I tried in trying to learn
packaging.version.Version. It was not a good experience:

% conda create -n test python=3.9 pandas
[...]
% conda activate test
% python
>>> import packaging
ModuleNotFoundError: No module named 'packaging'
^D
% pip install packaging
[...]
% python
>>> import packaging
>>> import panda, numpy, re, statistics
>>> packaging.version.Version(pandas)
AttributeError: module 'packaging' has no attribute 'version'
>>> from packaging.version import Version
>>> Version(pandas)
TypeError: expected string or bytes-like object
>>> Version(pandas.__version__)
<Version('1.2.4')>
>>> Version(statistics.__version__)
AttributeError: module 'statistics' has no attribute '__version__'
>>> Version(re.__version__)
<Version('2.2.1')>
>>> import vaex
>>> Version(vaex.__version__)
TypeError: expected string or bytes-like object

I cannot find a case where the more verbose spelling is ever nicer than
just referencing `mod.__version__` directly for such exploration. Yes, I
get that formal packaging has different needs. But here it just seems like
a lot more work to get a lot less information back.

--
The dead increasingly dominate and strangle both the living and the
not-yet born. Vampiric capital and undead corporate persons abuse
the lives and control the thoughts of homo faber. Ideas, once born,
become abortifacients against new conceptions.
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, 14 Apr 2021 at 21:59, David Mertz <mertz@gnosis.cx> wrote:
>
> On Wed, Apr 14, 2021 at 9:12 PM Paul Moore <p.f.moore@gmail.com> wrote:
>>
>> If it's not basically equivalent to packaging.version.Version (and
>> based on PEP 440) then we'll be creating a nightmare of confusion,
>> because PEP 440 versions are fundamental to packaging.
>
> Are you suggesting that users should have to install an external module to tell what version of packages they are using?!

No. To tell what version of a package they are using, a string is sufficient.

They only need a version object if they want to do additional
processing (like comparing versions, or checking whether a version
meets a constraint).

Given that the packaging ecosystem already has a canonical version
object (provided by the packaging library), which has been used and
tested extensively in many environments, inventing a different API
seems at best ill-advised. Whether the stdlib needs a version object.
rather than leaving that functionality to a 3rd party library, is the
same question that comes up for *any* functionality that's proposed
for the stdlib, and I have no particular opinion in this case.

>> What's wrong with Version(module.__version__)? And if the __version__
>> attribute isn't a valid version, raise an exception? That's what
>> packaging.version does, and it's worked fine for the packaging
>> ecosystem. Is there a benefit that justifies being different here?
>
> Doesn't that seem really, really painful to use in an interactive shell? This is honestly (a simplified version of) what I tried in trying to learn packaging.version.Version. It was not a good experience:

It's designed for programmatic use, not interactive use, yes. But
that's sort of my point, why do you want anything more than the bare
string in the REPL? What are you planning on doing with it?

Paul
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/6424E3GOVU463R7SOFQQXCWKV2M3LZRV/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, 14 Apr 2021 22:23:44 +0100
Paul Moore <p.f.moore@gmail.com> wrote:
> On Wed, 14 Apr 2021 at 21:59, David Mertz <mertz@gnosis.cx> wrote:
> >
> > On Wed, Apr 14, 2021 at 9:12 PM Paul Moore <p.f.moore@gmail.com> wrote:
> >>
> >> If it's not basically equivalent to packaging.version.Version (and
> >> based on PEP 440) then we'll be creating a nightmare of confusion,
> >> because PEP 440 versions are fundamental to packaging.
> >
> > Are you suggesting that users should have to install an external module to tell what version of packages they are using?!
>
> No. To tell what version of a package they are using, a string is sufficient.
>
> They only need a version object if they want to do additional
> processing (like comparing versions, or checking whether a version
> meets a constraint).
>
> Given that the packaging ecosystem already has a canonical version
> object (provided by the packaging library), which has been used and
> tested extensively in many environments, inventing a different API
> seems at best ill-advised. Whether the stdlib needs a version object.
> rather than leaving that functionality to a 3rd party library, is the
> same question that comes up for *any* functionality that's proposed
> for the stdlib, and I have no particular opinion in this case.

Tangentially, until now projects could use distutils's LooseVersion if
they wanted to compare version numbers reliably. With distutils being
deprecated, they'll have to either depending on packaging (which is a
large dependency just for comparison version numbers) or vendor
packaging's Version class (which is doable but still some bothersome
additional work).

Regards

Antoine.


_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/T4J2JD454XP3ZGULM777H5EG5Z3WVNMJ/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
Seems like this is something that should make its way into stdlib?

On Thu, 2021-04-15 at 00:15 +0200, Antoine Pitrou wrote:
> On Wed, 14 Apr 2021 22:23:44 +0100
> Paul Moore <p.f.moore@gmail.com> wrote:
> > On Wed, 14 Apr 2021 at 21:59, David Mertz <mertz@gnosis.cx> wrote:
> > >
> > > On Wed, Apr 14, 2021 at 9:12 PM Paul Moore <p.f.moore@gmail.com>
> > > wrote: 
> > > >
> > > > If it's not basically equivalent to packaging.version.Version
> > > > (and
> > > > based on PEP 440) then we'll be creating a nightmare of
> > > > confusion,
> > > > because PEP 440 versions are fundamental to packaging. 
> > >
> > > Are you suggesting that users should have to install an external
> > > module to tell what version of packages they are using?! 
> >
> > No. To tell what version of a package they are using, a string is
> > sufficient.
> >
> > They only need a version object if they want to do additional
> > processing (like comparing versions, or checking whether a version
> > meets a constraint).
> >
> > Given that the packaging ecosystem already has a canonical version
> > object (provided by the packaging library), which has been used and
> > tested extensively in many environments, inventing a different API
> > seems at best ill-advised. Whether the stdlib needs a version
> > object.
> > rather than leaving that functionality to a 3rd party library, is
> > the
> > same question that comes up for *any* functionality that's proposed
> > for the stdlib, and I have no particular opinion in this case.
>
> Tangentially, until now projects could use distutils's LooseVersion
> if
> they wanted to compare version numbers reliably.  With distutils
> being
> deprecated, they'll have to either depending on packaging (which is a
> large dependency just for comparison version numbers) or vendor
> packaging's Version class (which is doable but still some bothersome
> additional work).
>
> Regards
>
> Antoine.
>
>
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-leave@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/T4J2JD454XP3ZGULM777H5EG5Z3WVNMJ/
> Code of Conduct: http://python.org/psf/codeofconduct/
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
Paul Moore wrote:
> What's wrong with Version(module.__version__)? And if the __version__
> attribute isn't a valid version, raise an exception?

I don't have a deep answer, but I do think __version__ should be specified (or at least mentioned) at https://docs.python.org/3/reference/datamodel.html

At the moment, I can't even find a listing of possible __dunder__ attributes, though I'm almost sure I've seen one in the past.

-jJ
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/AG344CLSKM7BDOYP3CWGXGBNFSPWVQU4/
Code of Conduct: http://python.org/psf/codeofconduct/
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
https://docs.python.org/3/reference/datamodel.html

On Wed, 2021-04-14 at 22:56 +0000, Jim J. Jewett wrote:
> Paul Moore wrote:
> > What's wrong with Version(module.__version__)? And if the
> > __version__
> > attribute isn't a valid version, raise an exception?
>
> I don't have a deep answer, but I do think __version__ should be
> specified (or at least mentioned) at
> https://docs.python.org/3/reference/datamodel.html
>
> At the moment, I can't even find a listing of possible __dunder__
> attributes, though I'm almost sure I've seen one in the past.
>
> -jJ
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-leave@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/AG344CLSKM7BDOYP3CWGXGBNFSPWVQU4/
> Code of Conduct: http://python.org/psf/codeofconduct/
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, Apr 14, 2021 at 7:04 PM Jim J. Jewett <jimjjewett@gmail.com> wrote:

> I don't have a deep answer, but I do think __version__ should be specified
> (or at least mentioned) at
> https://docs.python.org/3/reference/datamodel.html


Given the intent to reject PEP 394, I can't imagine any good would come of
that.

Drop a __version__ in your modules if you find it valuable, but otherwise,
there's nothing to do here.


-Fred

--
Fred L. Drake, Jr. <fred at fdrake.net>
"There is nothing more uncommon than common sense."
--Frank Lloyd Wright
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, Apr 14, 2021 at 12:10 PM Barry Warsaw <barry@python.org> wrote:

I’d forgotten that this PEP was in Deferred state. I think it should be
> rejected and I plan on making that change. importlib.metadata is a much
> better approach to programmatically determining package versions.
>
>
> https://docs.python.org/3/library/importlib.metadata.html#distribution-versions


Barry,

You wrote the original PEP, so of course you can withdraw it (or reject
it), but...

Are you sure? See this discussion, I don't think it's as simple as all that.

Honestly, I'm still kind of confused about a "distribution" vs a package or
module, but in general, it seems to me that the packaging community has
done a great job of building a system that can accommodate a lot of
complexity, but as they say:

The easy things should be easy, and the hard things should be possible.

And the full process of using packaging and distributions, and a Version
object and all that is not so easy anymore --at least compared to putting:

__version__ = "1.2.3"

in a package __init__.py.

Anyway, a couple points:

1) it seems self-evident that it would be easier for the whole community if
"how to declare", and "how to find" the version of a package was
standardized: "there's only one way to do it"

1b) It seems like a really good idea that the (or one of the) official
recommended way to do it is supported in the standard library itself, and
using a string is pretty easy to support :-) -- do we really want people to
have to install a third party package to set or get the version of a simple
module?

2) __version__ strings are already pretty darn common -- maybe more common
than proper distribution metadata? -- are we saying that everyone should
stop doing that?

3) I don't know that having __version__ strings is incompatible with
packging.version.Version or importlib.metadata.version

4) Yes, there are real advantages to the more complex system for
programmatically working with versions. But there are real advantages to
something simple for human readability / interactive use -- and, frankly,
simple scripting. See David Mertz's recent post -- I went through a similar
process in iPython.

Consider this analogy: if I want to know what version of git I have
installed, I can run:

$ git --version

And that's a convention adhered to by many *nix command line tools. Would
we all really be happier if we had to go use an rpm or deb or homebrew, or
?? command to see what package i have installed? I think this is similar --
while a good distribution management system is a good thing, it's also good
if I can tell something about the version of a package/module from
the package itself.

With regard to having both __version__ and importlib.metadata.version, see
beautiful soup for example:

In [10]: import beautifulsoup4
...
ModuleNotFoundError: No module named 'beautifulsoup4'

oops, that's not what the importable module is called. So:

In [11]: import bs4

That worked -- now, what version is it?

In [12]: importlib.metadata.version('bs4')
---------------------------------------------------------------------------
PackageNotFoundError Traceback (most recent call last)
...
PackageNotFoundError: bs4

[*]

That didn't work -- I guess I need to use the distribution name:

In [13]: importlib.metadata.version('beautifulsoup4')
Out[13]: '4.9.3'

OK, that worked.

But I imported "bs4", so what if I do this?

In [14]: bs4.__version__
Out[14]: '4.9.3'

Ah yes, that worked too.

So I guess what I'm suggesting is that we officially recommend that folks
do what the BeautifulSoup folks, and many others, are already doing. In
many (most) cases, the distribution name and the importable package name
are the same, but this does accommodate both.

[*] One other annoyance to importlib.metadata.version is that in addition
to having to import importlib to use it, I also need to use
importlib.metadata.PackageNotFoundError if I want to trap the exception.

BTW: I'm not making that last point up -- I recently updated some in-house
code (that someone else had written) in a web app that presented the
version of various packages core to the system. We had just refactor and
one of these packages what now optional, but the whole system was crashing
on that darn PackageNotFoundError. I ended up jsut commenting out that
package, rather than dealing with how to catch the exception and deal with
it properly. I would have so much rathered a simple:

try:
import the_package
the_pacakge_version = the_package.__version__
except
the_package_version = None

Granted, it's not that hard to "do it right", but I still like things
simple :-)

Anyway, as the original PEP author is no longer supportive, this is dead in
the water unless another core dev is interested in sponsoring this (or a
new) PEP. If not, I can stop wasting my and everyone else's time.

-Chris

--
Christopher Barker, PhD (Chris)

Python Language Consulting
- Teaching
- Scientific Software Development
- Desktop GUI and Web Development
- wxPython, numpy, scipy, Cython
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
On Wed, Apr 14, 2021 at 2:23 PM Paul Moore <p.f.moore@gmail.com> wrote:

> >> because PEP 440 versions are fundamental to packaging.
> >
> > Are you suggesting that users should have to install an external module
> to tell what version of packages they are using?!
>
> No. To tell what version of a package they are using, a string is
> sufficient.
>

exactly -- if we do anything at all here, it should probably be at least.

if you provide a __version__ attribute, it should be a PEP 440 compliant
string.

That would at least make the use __version__ a touch more consistent.

The next, more controversial, step would be to suggest that people SHOULD
provide a __version__string on all top-level packages. I would like that --
the current situation where many, but not all packages have __version__ is
really annoying.

They only need a version object if they want to do additional
> processing (like comparing versions, or checking whether a version
> meets a constraint).
>

And indeed, we could add the ability for packaging.version.Version objects
to be able to compare themselves with compatible strings -- I think that
would be pretty handy.

Given that the packaging ecosystem already has a canonical version
> object (provided by the packaging library), which has been used and
> tested extensively in many environments, inventing a different API
> seems at best ill-advised.


absolutely.


> Whether the stdlib needs a version object.
> rather than leaving that functionality to a 3rd party library, is the
> same question that comes up for *any* functionality that's proposed
> for the stdlib, and I have no particular opinion in this case.
>

I don't think it's the same as any functionality -- if we do want to better
standardize package versioning in Python, and I think we should, then the
Version object may become something useful to, and maybe even needed by,
virtually every third party package. Which makes it a pretty prime
candidate for the stdlib.

Alternatively, the packaging package is pretty small, but if it grows, it
might be good to split out the run-time vs build-time pieces.

It's designed for programmatic use, not interactive use, yes. But
> that's sort of my point, why do you want anything more than the bare
> string in the REPL? What are you planning on doing with it?
>

there is something in between the REPL and full on system development --
something simple for quickly scripts is nice too. But a simple standardised
version string is fine for that.

-CHB


--
Christopher Barker, PhD (Chris)

Python Language Consulting
- Teaching
- Scientific Software Development
- Desktop GUI and Web Development
- wxPython, numpy, scipy, Cython
Re: Revive PEP 396 -- Module Version Numbers ? [ In reply to ]
Paul Bryan:
> Seems like this is something that should make its way into stdlib?

In the last 10 years, the trend is more to remove anything related to
packaging *outside* the stdlib :-) Since it's evolving way faster than
Python releases and the stdlib cannot be updated once installed, I
don't think that it's a good idea.

On Thu, Apr 15, 2021 at 12:22 AM Antoine Pitrou <antoine@python.org> wrote:
> Tangentially, until now projects could use distutils's LooseVersion if
> they wanted to compare version numbers reliably. With distutils being
> deprecated, they'll have to either depending on packaging (which is a
> large dependency just for comparison version numbers) or vendor
> packaging's Version class (which is doable but still some bothersome
> additional work).

If packaging is too big and if packaging maintainters like the idea,
maybe packaging.version could be moved into a dedicated package? I
didn't look if it makes sense from a technical point of view.

$ wc -l packaging/version.py packaging/_structures.py
556 packaging/version.py
86 packaging/_structures.py
642 total

version.py uses _structures.py (InfinityType, NegativeInfinityType).

Victor
--
Night gathers, and now my watch begins. It shall not end until my death.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/GT6NZDIKA222ADKKSJN7W4WZROMAIRDF/
Code of Conduct: http://python.org/psf/codeofconduct/

1 2  View All