Revive: PEP 396 -- Module Version Numbers ?

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. 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 I see some interest from this group. 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. Or maybe this is a settled issue in setuptools, and we just need to change the status of the PEP. 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 setuptools/egg/pip metadata, and requiring setuptools.pkg_resources 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 setuptools and pip) Or should this be brought up on The Distutils-SIG list? -CHB ,-- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

On Mon, Apr 12, 2021 at 12:29 PM Thomas Grainger <tagrain@gmail.com> wrote:
I prefer to use importlib.metadata.version("dist-name")
For my part, I don't like that approach -- I really believe in KISS. That requires a pile of infrastructure to be in place -- compared to a simple attribute in a package. It just makes so much more sense (to me ;-) ) to have a simple way to ask a package what version it is, and to set the version when you make a package. I've been struggling with setuptools mingling build, install, and run time behavior for years (decades!) and i've never liked it. That being said, it's 13 years after that PEP 396 was written, and things have gotten better, including importlib.metadata being in the standard library now, though it does say: """ Note: This functionality is provisional and may deviate from the usual version semantics of the standard library. """ So -- 13 years later and we're still struggling. I don't know what it takes to get everything in place for importlib.metadata to work, so I'll go take a look. Anyway, my real goals are to get something "Official" standardized, and for that something to be: - Simple and easy to use, both for package authors and package users. - Doable with standard tools, ideally in the stdlib -- and particularly not requiring any non-stdlib tools at runtime (like the old pkg_resources). It seems that may have been solved by importlib, but let's not have it be provisional then! And the fact is, that PEP's been provisional for 13 years, and __version__ is widely, but certainly not universally, adopted. We really should get a pronouncement on this one way or another. Thanks, -CHB
-- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

On Mon, 12 Apr 2021 at 19:52, Christopher Barker <pythonchb@gmail.com> wrote:
Having a __version__ attribute is fairly common these days, but definitely not universal even now. So the PEP still has a place, IMO. But a lot has changed in the last 13 years. Python packaging is built very much on packages having versions these days, so the *distribution* version (as covered in https://packaging.python.org/specifications/core-metadata/) is essential. And with importlib.metadata, that version is introspectable at runtime. But that's different from a *package* version as exposed via __version__. And I suspect there's still some debate over whether we need the two, so I wouldn't assume the PEP is self-evidently a good thing. There's a bunch of straightforward updating that needs to be done (all of the PEPs that this one references have since been superseded, and in the case off package metadata, it's no longer standardised via a PEP but at https://packaging.python.org/specifications/core-metadata/). Also, you should look at https://packaging.python.org/guides/single-sourcing-package-version/. The whole question of how to derive the distribution version from the package version is quite complex, with a number of common solutions, and also a number of people who will argue that you *shouldn't* single-source, but should just copy the value into the two places. The section of the PEP that covers this needs rewriting, and possibly even omitting, as there is no "standard" answer. As another data point, flit *requires* that the package has a __version__ attribute. FWIW, I'm personally ambivalent on the subject - having a __version__ feels like it's probably a good thing, but it's very rare that I actually care in practice as a package consumer, so as a package creator it feels a bit like boilerplate that I add "for the sake of it". I'd suggest keeping the scope of the PEP fairly limited - opinions vary in this area, and are held fairly strongly, so you'd stand more chance of getting something accepted if you keep things focused on the basics.
Or should this be brought up on The Distutils-SIG list?
(That's the packaging category on Discourse these days). Honestly, I don't really know. It *could* be a packaging interoperability standard, but the rules it includes about stdlib modules push it into core python territory. And packaging standards tend to be more about distribution-level metadata than package-level. I suspect the best thing to do would be to check with the SC on their view, and if they want to toss it in my direction, I'm happy to make the decision. Sorry, but I'd rather not be a sponsor for this, as I'm pretty busy with other things at the moment. But I hope this helps. Paul

Thanks Paul,
Having a __version__ attribute is fairly common these days, but definitely not universal even now. So the PEP still has a place, IMO.
Indeed -- I really think it needs to be finalized one way or another.
If I decide to move forward on this, I'll need to get up to speed on all that, particularly the distinction between a "distribution" and a "package". My instinct, from years of experience, is that distinction is most important for large systems, but adds complication for smaller, simpler packages, so I do hope that we can come up with something that's simple for the simple cases. In a practical way, I know a lot of folks get confused when the name of a package is different than what you import, e.g. pip install beautifulsoup4
import bs4
I presume you would use "beautifulsoup4" as the dist_name with importlib.metadata ? (see-- I don't even know for sure, that's how much I need to catch up! ) And I suspect there's still some debate over whether
we need the two, so I wouldn't assume the PEP is self-evidently a good thing.
I'm sure -- but what I DO think is "self-evidently a good thing." is to not have a dangling differed PEP on this -- let's make a decision and move on! There's a bunch of straightforward updating that needs to be done indeed.
I agree here -- I think what needs to be official is what is In an installed package/distribution -- not how it gets there. But I do think the standard approach should be easy to do, even without special tools. As another data point, flit *requires* that the package has a
__version__ attribute.
Ahh -- that is a helpful motivator.
I am absolutely the opposite here -- as a consumer, I very much use __version__ frequently, and as a package creator, I avoid the fancy stuff and just put a __version__ in my packages :-) I'd suggest keeping the scope of the PEP fairly limited - opinions
Agreed.
Or should this be brought up on The Distutils-SIG list?
(That's the packaging category on Discourse these days).
OK, OK, I guess I'll need to finally join that ;-)
indeed, and that's actually the point here. However, I suspect that the core devs will strongly rely on PyPA's thoughts on the matter.
How does one "check with the SC"? A post to python-dev? Sorry, but I'd rather not be a sponsor for this, as I'm pretty busy
with other things at the moment. But I hope this helps.
It sure does, thanks. -CHB -- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

On Tue, 13 Apr 2021 at 18:14, Christopher Barker <pythonchb@gmail.com> wrote:
I agree here -- I think what needs to be official is what is In an installed package/distribution -- not how it gets there. But I do think the standard approach should be easy to do, even without special tools.
That's already standardised. See https://packaging.python.org/specifications/recording-installed-packages/ It describes how all the package (technically "distribution"[1]) metadata gets stored, and where. What it doesn't do, is make any statements about what should go in the files that make up that distribution. That's where this PEP differs, as it is specifically looking at that.
As both a core dev and the packaging PEP-delegate, I'll try to avoid holding self-contradictory opinions on the matter ;-)
I think there's a SC issue tracker - check in the devguide about the lifecycle of a PEP (or ask your PEP sponsor :-)) Paul [1] Yes, terminology gets confusing. We *tried* to formalise it but people couldn't get used to the distinctions so we gave up and went with the general mood which is to work out what you mean by context.

12.04.21 21:49, Christopher Barker пише:
If I have a time I finish my large patch for getting rid of __version__ and other outdated variables. It was approved previously (https://mail.python.org/archives/list/python-dev@python.org/thread/KBU4EU2JU...). It is not simple, because it should be treated on case by case basis, and there are several groups of similar cases, so finally it will resulted in a series of PRs.

On Tue, Apr 13, 2021 at 1:29 PM Serhiy Storchaka <storchaka@gmail.com> wrote:
12.04.21 21:49, Christopher Barker пише:
Yes, it would be nice to clean that up, thanks. And the PEP does say that stdlib modules should not have a __version__. Though what happens in the stdlib is mostly separate from this PEP anyway. -CHB
-- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

On Mon, Apr 12, 2021 at 12:29 PM Thomas Grainger <tagrain@gmail.com> wrote:
I prefer to use importlib.metadata.version("dist-name")
For my part, I don't like that approach -- I really believe in KISS. That requires a pile of infrastructure to be in place -- compared to a simple attribute in a package. It just makes so much more sense (to me ;-) ) to have a simple way to ask a package what version it is, and to set the version when you make a package. I've been struggling with setuptools mingling build, install, and run time behavior for years (decades!) and i've never liked it. That being said, it's 13 years after that PEP 396 was written, and things have gotten better, including importlib.metadata being in the standard library now, though it does say: """ Note: This functionality is provisional and may deviate from the usual version semantics of the standard library. """ So -- 13 years later and we're still struggling. I don't know what it takes to get everything in place for importlib.metadata to work, so I'll go take a look. Anyway, my real goals are to get something "Official" standardized, and for that something to be: - Simple and easy to use, both for package authors and package users. - Doable with standard tools, ideally in the stdlib -- and particularly not requiring any non-stdlib tools at runtime (like the old pkg_resources). It seems that may have been solved by importlib, but let's not have it be provisional then! And the fact is, that PEP's been provisional for 13 years, and __version__ is widely, but certainly not universally, adopted. We really should get a pronouncement on this one way or another. Thanks, -CHB
-- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

On Mon, 12 Apr 2021 at 19:52, Christopher Barker <pythonchb@gmail.com> wrote:
Having a __version__ attribute is fairly common these days, but definitely not universal even now. So the PEP still has a place, IMO. But a lot has changed in the last 13 years. Python packaging is built very much on packages having versions these days, so the *distribution* version (as covered in https://packaging.python.org/specifications/core-metadata/) is essential. And with importlib.metadata, that version is introspectable at runtime. But that's different from a *package* version as exposed via __version__. And I suspect there's still some debate over whether we need the two, so I wouldn't assume the PEP is self-evidently a good thing. There's a bunch of straightforward updating that needs to be done (all of the PEPs that this one references have since been superseded, and in the case off package metadata, it's no longer standardised via a PEP but at https://packaging.python.org/specifications/core-metadata/). Also, you should look at https://packaging.python.org/guides/single-sourcing-package-version/. The whole question of how to derive the distribution version from the package version is quite complex, with a number of common solutions, and also a number of people who will argue that you *shouldn't* single-source, but should just copy the value into the two places. The section of the PEP that covers this needs rewriting, and possibly even omitting, as there is no "standard" answer. As another data point, flit *requires* that the package has a __version__ attribute. FWIW, I'm personally ambivalent on the subject - having a __version__ feels like it's probably a good thing, but it's very rare that I actually care in practice as a package consumer, so as a package creator it feels a bit like boilerplate that I add "for the sake of it". I'd suggest keeping the scope of the PEP fairly limited - opinions vary in this area, and are held fairly strongly, so you'd stand more chance of getting something accepted if you keep things focused on the basics.
Or should this be brought up on The Distutils-SIG list?
(That's the packaging category on Discourse these days). Honestly, I don't really know. It *could* be a packaging interoperability standard, but the rules it includes about stdlib modules push it into core python territory. And packaging standards tend to be more about distribution-level metadata than package-level. I suspect the best thing to do would be to check with the SC on their view, and if they want to toss it in my direction, I'm happy to make the decision. Sorry, but I'd rather not be a sponsor for this, as I'm pretty busy with other things at the moment. But I hope this helps. Paul

Thanks Paul,
Having a __version__ attribute is fairly common these days, but definitely not universal even now. So the PEP still has a place, IMO.
Indeed -- I really think it needs to be finalized one way or another.
If I decide to move forward on this, I'll need to get up to speed on all that, particularly the distinction between a "distribution" and a "package". My instinct, from years of experience, is that distinction is most important for large systems, but adds complication for smaller, simpler packages, so I do hope that we can come up with something that's simple for the simple cases. In a practical way, I know a lot of folks get confused when the name of a package is different than what you import, e.g. pip install beautifulsoup4
import bs4
I presume you would use "beautifulsoup4" as the dist_name with importlib.metadata ? (see-- I don't even know for sure, that's how much I need to catch up! ) And I suspect there's still some debate over whether
we need the two, so I wouldn't assume the PEP is self-evidently a good thing.
I'm sure -- but what I DO think is "self-evidently a good thing." is to not have a dangling differed PEP on this -- let's make a decision and move on! There's a bunch of straightforward updating that needs to be done indeed.
I agree here -- I think what needs to be official is what is In an installed package/distribution -- not how it gets there. But I do think the standard approach should be easy to do, even without special tools. As another data point, flit *requires* that the package has a
__version__ attribute.
Ahh -- that is a helpful motivator.
I am absolutely the opposite here -- as a consumer, I very much use __version__ frequently, and as a package creator, I avoid the fancy stuff and just put a __version__ in my packages :-) I'd suggest keeping the scope of the PEP fairly limited - opinions
Agreed.
Or should this be brought up on The Distutils-SIG list?
(That's the packaging category on Discourse these days).
OK, OK, I guess I'll need to finally join that ;-)
indeed, and that's actually the point here. However, I suspect that the core devs will strongly rely on PyPA's thoughts on the matter.
How does one "check with the SC"? A post to python-dev? Sorry, but I'd rather not be a sponsor for this, as I'm pretty busy
with other things at the moment. But I hope this helps.
It sure does, thanks. -CHB -- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython

On Tue, 13 Apr 2021 at 18:14, Christopher Barker <pythonchb@gmail.com> wrote:
I agree here -- I think what needs to be official is what is In an installed package/distribution -- not how it gets there. But I do think the standard approach should be easy to do, even without special tools.
That's already standardised. See https://packaging.python.org/specifications/recording-installed-packages/ It describes how all the package (technically "distribution"[1]) metadata gets stored, and where. What it doesn't do, is make any statements about what should go in the files that make up that distribution. That's where this PEP differs, as it is specifically looking at that.
As both a core dev and the packaging PEP-delegate, I'll try to avoid holding self-contradictory opinions on the matter ;-)
I think there's a SC issue tracker - check in the devguide about the lifecycle of a PEP (or ask your PEP sponsor :-)) Paul [1] Yes, terminology gets confusing. We *tried* to formalise it but people couldn't get used to the distinctions so we gave up and went with the general mood which is to work out what you mean by context.

12.04.21 21:49, Christopher Barker пише:
If I have a time I finish my large patch for getting rid of __version__ and other outdated variables. It was approved previously (https://mail.python.org/archives/list/python-dev@python.org/thread/KBU4EU2JU...). It is not simple, because it should be treated on case by case basis, and there are several groups of similar cases, so finally it will resulted in a series of PRs.

On Tue, Apr 13, 2021 at 1:29 PM Serhiy Storchaka <storchaka@gmail.com> wrote:
12.04.21 21:49, Christopher Barker пише:
Yes, it would be nice to clean that up, thanks. And the PEP does say that stdlib modules should not have a __version__. Though what happens in the stdlib is mostly separate from this PEP anyway. -CHB
-- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
participants (4)
-
Christopher Barker
-
Paul Moore
-
Serhiy Storchaka
-
Thomas Grainger