DRAFT PEP 396 - module version number
Hi distutilizers! At Pycon, I signed up to write an informational PEP on module version numbers. There have been some email discussion since then, and while I haven't completely worked my way through all those messages yet, I think I have covered the important top-level issues. I'm posting my current draft (as yet uncommitted to the new hg repository) here before taking it to python-dev. I'd love to get your feedback about any aspect of the PEP, but especially on deriving module version numbers from setup.cfg files, and on including them in metadata at build time (as opposed to installation time). Also, I'd appreciate any corrections based on my misunderstanding of distutils2/packaging and the relevant PEPs. Current draft attached below. Remember, this is an informational PEP, so its purpose is to codify best practices. Module authors will continue to have the freedom to do whatever they want. Cheers, -Barry PEP: 396 Title: Module Version Numbers Version: $Revision: 65628 $ Last-Modified: $Date: 2008-08-10 09:59:20 -0400 (Sun, 10 Aug 2008) $ Author: Barry Warsaw <barry@python.org> Status: Draft Type: Informational Content-Type: text/x-rst Created: 2011-03-16 Post-History: Abstract ======== Given that it is useful and common to specify version numbers for Python modules, and given that different ways of doing this have grown organically within the Python community, it is useful to establish standard conventions for module authors to adhere to and reference. This informational PEP describes best practices for Python module authors who want to define the version number of their Python module. Conformance with this PEP is optional, however other Python tools (such as `distutils2` [1]_) may be adapted to use the conventions defined here. User Stories ============ Alice is writing a new module, called ``alice.py``, which she wants to share with other Python developers. ``alice.py`` is a simple module and lives in one file. Alice wants to specify a version number so that her users can tell which version they are using. Because her module lives entirely in one file, she wants to add the version number to that file. Bob has written a module called ``bob.py`` which he has shared with many users. ``bob.py`` contains a version number for the convenience of his users. Bob learns about the Cheeseshop [2]_, and adds some simple packaging using classic distutils so that he can upload *The Bob Package* to the Cheeseshop. Because ``bob.py`` already specifies a version number which his users can access programmatically, he wants the same API to continue to work even though his users now get it from the Cheeseshop. Carole maintains several namespace packages, each of which are independently developed and distributed. In order for her users to properly specify dependencies on the right versions of her packages, she specifies the version numbers in the namespace package's ``setup.py`` file. Because Carol wants to have to update one version number per package, she specifies the version number in her module and has the ``setup.py`` extract the module version number at *sdist* tarball build time. David maintains a package in the standard library, and also produces standalone versions for other versions of Python. The standard library copy defines the version number in the module, and this same version number is used for the standalone distributions as well. Rationale ========= Python modules, both in the standard library and available from third parties, have long included version numbers. There are established de-facto standards for describing version numbers, and many ad-hoc ways have grown organically over the years. Often, version numbers can be retrieved from a module programmatically, by importing the module and inspecting an attribute. Classic Python distutils ``setup()`` functions [3]_ describe a ``version`` argument where the package's version number can be specified. PEP 8 [4]_ describes the use of a module attribute called ``__version__`` for recording "Subversion, CVS, or RCS" version strings using keyword expansion. In the PEP author's own email archives, the earliest example of the use of an ``__version__`` module attribute by independent module developers dates back to 1995. Another example of version information is the sqlite3 [5]_ library with its ``sqlite_version_info``, ``version``, and ``version_info`` attributes. It may not be immediately obvious which attribute contains a version number for the module, and which contains a version number for the underlying SQLite3 library. This informational PEP codifies established practice, and recommends standard ways of describing module version numbers, along with some use cases for when -- and when *not* -- to include them. Its adoption is purely voluntary, but other tools in the Python universe may support the standards defined herein. Specification ============= #. In general, modules in the standard library SHOULD NOT have version numbers. They implicitly carry the version number of the Python release they are included in. #. On a case-by-case basis, standard library modules which are also distributed as standalone packages for other Python versions MAY include a module version number when included in the standard library, and SHOULD include a version number when packaged separately. #. When a module includes a version number, it SHOULD be available in the ``__version__`` attribute on that module. #. For modules which are also packages, the top level module namespace SHOULD include the ``__version__`` attribute. #. For modules which live inside a namespace package, the sub-package name SHOULD include the ``__version__`` attribute. The namespace module itself SHOULD NOT include its own ``__version__`` attribute. #. The ``__version__`` attribute's value SHOULD be a simple string. #. Module version numbers SHOULD conform to the normalized version format specified in PEP 386 [6]_. #. Module version numbers SHOULD NOT contain version control system supplied revision numbers, or any other semantically different version numbers (e.g. underlying library version number). #. Wherever a ``__version__`` attribute exists, a module MAY also include a ``__version_info__`` attribute, containing a tuple representation of the module version number, for easy comparisons. #. ``__version_info__`` SHOULD be of the format returned by PEP 386's ``parse_version()`` function. #. The ``version`` attribute in a classic distutils ``setup.py`` file, or the ``Version`` metadata field in a PEP 345 [7]_ SHOULD be derived from the ``__version__`` field, or vice versa. Examples ======== Retrieving the version number from a third party package:: >>> import bzrlib >>> bzrlib.__version__ '2.3.0' Retrieving the version number from a standard library package that is also distributed as a standalone module:: >>> import email >>> email.__version__ '5.1.0' Version numbers for namespace packages:: >>> import flufl.i18n >>> import flufl.enum >>> import flufl.lock >>> print flufl.i18n.__version__ 1.0.4 >>> print flufl.enum.__version__ 3.1 >>> print flufl.lock.__version__ 2.1 >>> import flufl >>> flufl.__version__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'module' object has no attribute '__version__' >>> Deriving ======== Module version numbers can appear in at least two places, and sometimes more. For example, in accordance with this PEP, they are available programmatically on the module's ``__version__`` attribute. They also need to be specified in either the classic distutils ``setup()`` function, as the ``version`` attribute in a ``setup.py``, or in the distutils2 ``setup.cfg`` file's ``version`` keyword, and they need to get into the PEP 345 package metadata, preferably at *sdist* package build-time. It's also desirable for module authors to only have to specify the version number once, and have all the other uses derive from this single definition. While there are any number of ways this could be done, this section describes one possible approach, for each scenario. Let's say Elle adds this attribute to her module, ``elle.py``:: __version__ = '3.1.1' Classic distutils ----------------- In classic distutils, the simplest way to add this version to the ``setup()`` function in ``setup.py`` is to do something like this:: from elle import __version__ setup(name='elle', version=__version__) In the PEP author's experience however, this can fail in some cases, such as when the module uses automatic Python 3 conversion via the ``2to3`` program. In that case, it's not much more difficult to write a little code to parse the ``__version__`` from the file rather than importing it:: import re DEFAULT_VERSION_RE = re.compile(r'(?P<version>\d+\.\d(?:\.\d+)?)') def get_version(filename, pattern=None): if pattern is None: cre = DEFAULT_VERSION_RE else: cre = re.compile(pattern) with open(filename) as fp: for line in fp: if line.startswith('__version__'): mo = cre.search(line) assert mo, 'No valid __version__ string found' return mo.group('version') raise AssertionError('No __version__ assignment found') setup(name='elle', version=get_version('elle.py')) Distutils2 ---------- Because the distutils2 style ``setup.cfg`` is declarative, we can't run any code to extract the ``__version__`` attribute, either via import or via parsing. This PEP suggests a special key be allowed for the ``version`` field in a ``setup.cfg`` file to indicate "get the version from this file". Something like this might work:: [metadata] version: parse:elle.py where ``parse`` means to use a parsing method similar to the above, on the file named after the colon. The exact recipe for doing this will be discussed in the appropriate distutils2 development forum. An alternative is to only define the version number in setup.cfg and use the ``pkgutil`` module [8]_ to make it available programmatically. E.g. in ``elle.py``:: from distutils2._backport import pkgutil __version__ = pkgutil.get_distribution('elle').metadata['version'] Static egg info =============== For distutils2, it is highly desirable to place the version information into the egg metadata at build-time rather than install-time. This way, the metadata will be available for introspection even when the code is not installed. For example, a package's metadata can be made available via a simple HTTP GET operation on a URL within the package's presence on the Cheeseshop. References ========== .. [1] Distutils2 documentation (http://distutils2.notmyidea.org/) .. [2] The Cheeseshop (Python Package Index) (http://pypi.python.org) .. [3] http://docs.python.org/distutils/setupscript.html .. [4] PEP 8, Style Guide for Python Code (http://www.python.org/dev/peps/pep-0008) .. [5] sqlite3 module documentation (http://docs.python.org/library/sqlite3.html) .. [6] PEP 386, Changing the version comparison module in Distutils (http://www.python.org/dev/peps/pep-0386/) .. [7] PEP 345, Metadata for Python Software Packages 1.2 (http://www.python.org/dev/peps/pep-0345/#version) .. [8] pkgutil - Package utilities (http://distutils2.notmyidea.org/library/pkgutil.html) Copyright ========= This document has been placed in the public domain. .. Local Variables: mode: indented-text indent-tabs-mode: nil sentence-end-double-space: t fill-column: 70 coding: utf-8 End:
`distutils2` [1]_) may be adapted to use the conventions defined here. Nit: I never rely on docutils/sphinx default role (using a bare `text` without explicit :role:), cause I never remember what it is, and the
Hi Barry, Thanks for writing this PEP. I’m +1 on the general idea, but not on all sections. I agree with all text that I haven’t quoted; quoted parts are commented with my reservations, suggested amendments and typo fixes. Martin and Alexis are directly cc’d because I have asked them to confirm or reply to two things that I wasn’t sure about. produced text may not be what you thought it would.
Alice is writing a new module, called ``alice.py``, which she wants to share with other Python developers. ``alice.py`` is a simple module and lives in one file. You should call the module alice and the file alice.py to eliminate weirdness. (Ditto for other examples throughout the PEP.)
Bob learns about the Cheeseshop [2]_, and adds some simple packaging using classic distutils so that he can upload *The Bob Package* to the Cheeseshop. I know that the referenced PEP 345 call these things “software packages”, but let’s try to use consistent terminology. See threads starting at http://mail.python.org/pipermail/distutils-sig/2011-March/017438.html and http://mail.python.org/pipermail/distutils-sig/2011-March/017450.html .
Carole maintains several namespace packages, each of which are independently developed and distributed. I am not sure we should advertise setuptools namespace packages, given that standardization is under way (PEP 382). On one hand it would be childish not to acknowledge that setuptools is widely used, on the other hand in this particular time and place I think we should wait for official namespace packages to be implemented and talk about those. That said, even if the mechanism changes, the packaging-related parts won’t, so the story is useful. Make that +0 after all.
at *sdist* tarball build time. Do non-UNIX people understand “tarball”? You could remove it or replace it with “archive”.
David maintains a package in the standard library, and also produces standalone versions for other versions of Python. Thoughtful hat tip :)
Often, version numbers can be retrieved from a module programmatically, by importing the module and inspecting an attribute. Classic Python distutils ``setup()`` functions [3]_ describe a ``version`` argument where the package's version number can be specified. See above for package vs. distribution terminology.
This makes me think: It is obvious to us that Python packages are a type of Python modules, but the PEP could mention that near the beginning, to make clear that your PEP is relevant to any kind of module, whatever its physical incarnation.
of an ``__version__`` module attribute by independent module s/an/a/
Another example of version information is the sqlite3 [5]_ library the sqlite3 module
This informational PEP codifies established practice, and recommends standard ways of describing module version numbers, along with some use cases for when -- and when *not* -- to include them. Its adoption is purely voluntary, but other tools in the Python universe may support the standards defined herein. You say “other tools“ without having referred to tools before, I find it confusing (I’m not a native speaker, however). The text could mention here that official tools will have opt-in support for the PEP:
Its adoption is purely voluntary; the packaging tools in the standard library will provide optional support for the standards defined herein (see section XX), and other tools in the Python universe may comply too.
#. On a case-by-case basis, standard library modules which are also distributed as standalone packages for other Python versions MAY Problematic “packages” again. What about this: “which are also released in standalone form for other Python versions”?
#. For modules which are also packages, the top level module namespace SHOULD include the ``__version__`` attribute. Just a remark: I don’t remember ever reading the term “top-level module namespace”. It’s not hard to understand, but it might be helpful to some readers if you add “(i.e. the :file:`{somepackage}/__init__.py` file)”. (The brackets will cause the enclosed text to be marked up as replaceable text, just a nicety.)
#. For modules which live inside a namespace package, the sub-package name SHOULD include the ``__version__`` attribute. I think this works with both setuptools and PEP 382 namespace packages, which is nice (see above questioning).
The namespace module itself SHOULD NOT include its own ``__version__`` attribute. I guess this makes sense for setuptools namespace packages, but from my understanding of PEP 382, it is possible to have a Python package that is a namespace package and has submodules. (I hope Martin will correct me if needed.) This thing (“portion” in PEP 382 lingo) should be allowed to declare a version IMO.
#. The ``__version__`` attribute's value SHOULD be a simple string. What’s a non-simple string? This may be only me, but here I think you tried to be simple and had the opposite effect. I’d just use the simple “a string” or the precise “a string (str object in 3.x)”.
#. The ``version`` attribute in a classic distutils ``setup.py`` file, or the ``Version`` metadata field in a PEP 345 [7]_ SHOULD be derived from the ``__version__`` field, or vice versa. “In a PEP 345” what? :) file, I guess.
I think this part should either take a position, that is choose one way instead of vaguely telling about two ways, or be removed, given that the section Deriving has the same info.
They also need to be specified in either the classic distutils ``setup()`` function, as the ``version`` attribute in a ``setup.py``, or in the distutils2 ``setup.cfg`` file's ``version`` keyword, I’d say the setup.py has a version argument and the setup.cfg has a version key.
they need to get into the PEP 345 package metadata, preferably at *sdist* package build-time. s/package metadata/metadata/; s/*sdist* package/*sdist*/
In the PEP author's experience however, this can fail in some cases, such as when the module uses automatic Python 3 conversion via the ``2to3`` program. Just to make this 100% explicit, you could add “because the setup.py script is executed by Python 3 before the elle module has been converted”.
In that case, it's not much more difficult to write a little code to parse the ``__version__`` from the file rather than The function could be simplified (use re.search, hard-code the re), but that’s very minor.
Because the distutils2 style ``setup.cfg`` is declarative, we can't run any code to extract the ``__version__`` attribute, either via import or via parsing. This PEP suggests a special key be allowed for the ``version`` field in a ``setup.cfg`` file to indicate "get the version from this file". With my distutils2 hat on, I recommend a KISS approach similar to what’s done for the long description: just define another key in the setup.cfg specification:
[metadata] version-from-file: elle.py
An alternative is to only define the version number in setup.cfg and use the ``pkgutil`` module [8]_ to make it available programmatically. E.g. in ``elle.py``::
from distutils2._backport import pkgutil __version__ = pkgutil.get_distribution('elle').metadata['version'] One of the main complaint against setuptools is that having to change your application code because of the packaging tool used was not a good idea. Having to use require instead of import or resource_whatever instead of open (or get_data, the most sadly underused function in the stdlib) because you use setuptools instead of distutils was a bad thing.
As stated in the PEP, having a __version__ attribute in the module is common, so my opinion is that making the packaging tool use that info is the Right Thing™, and having the dependency in the reverse sense is wrong. I don’t see a problem with having harmless duplication in the *installed* system, once in elle.__version__ and once in the pkgutil metadata database. (FWIW, I personally think that it’s not crazy to have the version number duplicated in the module, setup script, changelog, Sphinx conf.py file and so on; other people like Ronny don’t even want to have the version number in one file, but make their build process use the VCS tag. I think this PEP addresses a useful middle ground.)
Static egg info Is that the distutils 2.5+ generated metadata? You may want to read PEP 376 and update the terminology to “dist-info metadata” <0.2 wink>.
For example, a package's metadata can be made available via a simple HTTP GET operation on a URL within the package's presence on the Cheeseshop. First, insert usual remark about “package” here; second, I think discussing PyPI is out of scope here. The rationale that “the metadata will be available for introspection even when the code is not installed“ is already strong enough.
.. [1] Distutils2 documentation (http://distutils2.notmyidea.org/) Alexis, is this still the good link to use?
Regards
On 25/03/2011 02:52, Éric Araujo wrote:
.. [1] Distutils2 documentation (http://distutils2.notmyidea.org/) Alexis, is this still the good link to use?
Yes, at least for now. Waiting for docs.python.org ;) -- Alexis — http://notmyidea.org
On March 24, 2011, Éric Araujo wrote:
Bob learns about the Cheeseshop [2]_, and adds some simple packaging using classic distutils so that he can upload *The Bob Package* to the Cheeseshop. I know that the referenced PEP 345 call these things “software packages”, but let’s try to use consistent terminology. See threads starting at http://mail.python.org/pipermail/distutils-sig/2011-March/017438.html and http://mail.python.org/pipermail/distutils-sig/2011-March/017450.html .
Éric, can you summarize the discussion that took place on these threads? As far as I can tell, no consensus was reached for a new terminology and so the old definition still prevails: http://docs.python.org/dev/distutils/introduction#concepts-terminology In that case, a "package" in PEP 396 would refer to: a module that contains other modules; typically contained in a directory in the filesystem and distinguished from other directories by the presence of a file __init__.py. I fell like the usage proposed for *The Bob Package* is pretty good, except for the choice of "upload". Of course, you don't upload the package, you upload "distributions" that contain that package. -- Yannick Gingras http://ygingras.net
On Mar 27, 2011, at 03:36 PM, Yannick Gingras wrote:
On March 24, 2011, Éric Araujo wrote:
Bob learns about the Cheeseshop [2]_, and adds some simple packaging using classic distutils so that he can upload *The Bob Package* to the Cheeseshop. I know that the referenced PEP 345 call these things “software packages”, but let’s try to use consistent terminology. See threads starting at http://mail.python.org/pipermail/distutils-sig/2011-March/017438.html and http://mail.python.org/pipermail/distutils-sig/2011-March/017450.html .
Éric, can you summarize the discussion that took place on these threads? As far as I can tell, no consensus was reached for a new terminology and so the old definition still prevails:
http://docs.python.org/dev/distutils/introduction#concepts-terminology
As I mentioned in my follow up to Éric, if you really want to encourage adoption of specific terms, you're probably going to need to write a PEP that clearly defines them. Referencing a mailing list thread ain't gonna cut it.
In that case, a "package" in PEP 396 would refer to:
a module that contains other modules; typically contained in a directory in the filesystem and distinguished from other directories by the presence of a file __init__.py.
I fell like the usage proposed for *The Bob Package* is pretty good, except for the choice of "upload". Of course, you don't upload the package, you upload "distributions" that contain that package.
See my previous follow up. -Barry
Hi Éric, Thanks for the feedback, and my apologies for the delay in responding. On Mar 25, 2011, at 03:52 AM, Éric Araujo wrote:
`distutils2` [1]_) may be adapted to use the conventions defined here. Nit: I never rely on docutils/sphinx default role (using a bare `text` without explicit :role:), cause I never remember what it is, and the produced text may not be what you thought it would.
EIBTI :). Thanks.
Alice is writing a new module, called ``alice.py``, which she wants to share with other Python developers. ``alice.py`` is a simple module and lives in one file. You should call the module alice and the file alice.py to eliminate weirdness. (Ditto for other examples throughout the PEP.)
Excellent point.
Bob learns about the Cheeseshop [2]_, and adds some simple packaging using classic distutils so that he can upload *The Bob Package* to the Cheeseshop. I know that the referenced PEP 345 call these things “software packages”, but let’s try to use consistent terminology. See threads starting at http://mail.python.org/pipermail/distutils-sig/2011-March/017438.html and http://mail.python.org/pipermail/distutils-sig/2011-March/017450.html .
I remember that discussion, but I don't actually remember if there was agreement on terminology. ;) I'm sympathetic to Jim's Elaboration On PJE's Glossary. That would make a worthy PEP for someone else to write <wink>. In this case I'm changing it to *The Bob Bundle* since that's sufficiently meaningless as to not be distracting.
Carole maintains several namespace packages, each of which are independently developed and distributed. I am not sure we should advertise setuptools namespace packages, given that standardization is under way (PEP 382). On one hand it would be childish not to acknowledge that setuptools is widely used, on the other hand in this particular time and place I think we should wait for official namespace packages to be implemented and talk about those. That said, even if the mechanism changes, the packaging-related parts won’t, so the story is useful. Make that +0 after all.
Right. This is just a use case and it doesn't mention setuptools specifically, even though it does mention setup.py. Everybody knows what the latter is, and I can't think of any better way to phrase this, so I guess I'll leave it.
at *sdist* tarball build time. Do non-UNIX people understand “tarball”? You could remove it or replace it with “archive”.
Good point. I've rewritten this to read: "...extract the module version number when she builds the *sdist* archive."
David maintains a package in the standard library, and also produces standalone versions for other versions of Python. Thoughtful hat tip :)
Kind of worked out that way! :)
Often, version numbers can be retrieved from a module programmatically, by importing the module and inspecting an attribute. Classic Python distutils ``setup()`` functions [3]_ describe a ``version`` argument where the package's version number can be specified. See above for package vs. distribution terminology.
s/package's version number/release's version number/
This makes me think: It is obvious to us that Python packages are a type of Python modules, but the PEP could mention that near the beginning, to make clear that your PEP is relevant to any kind of module, whatever its physical incarnation.
Hmmm. OT1H I can see your point, but OTOH, I can't really find a good place to squeeze that definition in, and I'm not certain defining this is a goal of the PEP. For example, I don't really like adding that to the Abstract, or as a separate section between Abstract and User Stories. I kind of think that it should be fairly self-evident for any experienced Pythonista.
of an ``__version__`` module attribute by independent module s/an/a/
Heh, yeah I'm old skool so I still pronounce it "under under". Saying "dunder" just reminds me too much of The Office to take seriously. :) (Sadly, I just missed April Fools, or I would have suggested a PEP to add a __mifflin__ attribute to all objects. What joy that would bring to Python conversations.)
Another example of version information is the sqlite3 [5]_ library the sqlite3 module
This informational PEP codifies established practice, and recommends standard ways of describing module version numbers, along with some use cases for when -- and when *not* -- to include them. Its adoption is purely voluntary, but other tools in the Python universe may support the standards defined herein. You say “other tools“ without having referred to tools before, I find it confusing (I’m not a native speaker, however). The text could mention here that official tools will have opt-in support for the PEP:
Its adoption is purely voluntary; the packaging tools in the standard library will provide optional support for the standards defined herein (see section XX), and other tools in the Python universe may comply too.
I rewrote this just slightly: This informational PEP codifies established practice, and recommends standard ways of describing module version numbers, along with some use cases for when -- and when *not* -- to include them. Its adoption by module authors is purely voluntary; packaging tools in the standard library will provide optional support for the standards defined herein, and other tools in the Python universe may comply as well.
#. On a case-by-case basis, standard library modules which are also distributed as standalone packages for other Python versions MAY Problematic “packages” again. What about this: “which are also released in standalone form for other Python versions”?
Looks good, thanks.
#. For modules which are also packages, the top level module namespace SHOULD include the ``__version__`` attribute. Just a remark: I don’t remember ever reading the term “top-level module namespace”. It’s not hard to understand, but it might be helpful to some readers if you add “(i.e. the :file:`{somepackage}/__init__.py` file)”. (The brackets will cause the enclosed text to be marked up as replaceable text, just a nicety.)
How about just removing "top-level"? #. For modules which are also packages, the module namespace SHOULD include the ``__version__`` attribute. (Aside: using :file:`file.py` produces a warning when the PEP html is generated: pep-0396.txt:31: (ERROR/3) Unknown interpreted text role "file".)
#. For modules which live inside a namespace package, the sub-package name SHOULD include the ``__version__`` attribute. I think this works with both setuptools and PEP 382 namespace packages, which is nice (see above questioning).
The namespace module itself SHOULD NOT include its own ``__version__`` attribute. I guess this makes sense for setuptools namespace packages, but from my understanding of PEP 382, it is possible to have a Python package that is a namespace package and has submodules. (I hope Martin will correct me if needed.) This thing (“portion” in PEP 382 lingo) should be allowed to declare a version IMO.
Agreed, if that is true. I kind of hope it's *not* true though! Anyway, this is a SHOULD NOT not MUST NOT so I think it's safe.
#. The ``__version__`` attribute's value SHOULD be a simple string. What’s a non-simple string? This may be only me, but here I think you tried to be simple and had the opposite effect. I’d just use the simple “a string” or the precise “a string (str object in 3.x)”.
s/simple//
#. The ``version`` attribute in a classic distutils ``setup.py`` file, or the ``Version`` metadata field in a PEP 345 [7]_ SHOULD be derived from the ``__version__`` field, or vice versa. “In a PEP 345” what? :) file, I guess.
Oops, IIUC there really isn't a PEP 345 "thing" so I've rewritten it like this: #. The ``version`` attribute in a classic distutils ``setup.py`` file, or the PEP 345 [7]_ ``Version`` metadata field SHOULD be derived from the ``__version__`` field, or vice versa.
I think this part should either take a position, that is choose one way instead of vaguely telling about two ways, or be removed, given that the section Deriving has the same info.
I'm not sure we can make that recommendation yet though. I'd prefer to derive everything from the __version__, but I'm not sure there's agreement on that. Leaving it this way for now allows for some experimentation.
They also need to be specified in either the classic distutils ``setup()`` function, as the ``version`` attribute in a ``setup.py``, or in the distutils2 ``setup.cfg`` file's ``version`` keyword, I’d say the setup.py has a version argument and the setup.cfg has a version key.
they need to get into the PEP 345 package metadata, preferably at *sdist* package build-time. s/package metadata/metadata/; s/*sdist* package/*sdist*/
Module version numbers can appear in at least two places, and sometimes more. For example, in accordance with this PEP, they are available programmatically on the module's ``__version__`` attribute. In a classic distutils ``setup.py`` file, the ``setup()`` function takes a ``version`` argument, while the distutils2 ``setup.cfg`` file has a ``version`` key. The version number must also get into the PEP 345 metadata, preferably when the *sdist* archive is built. It's desirable for module authors to only have to specify the version number once, and have all the other uses derive from this single definition.
In the PEP author's experience however, this can fail in some cases, such as when the module uses automatic Python 3 conversion via the ``2to3`` program. Just to make this 100% explicit, you could add “because the setup.py script is executed by Python 3 before the elle module has been converted”.
I added this, though I'm not sure if flows as well.
In that case, it's not much more difficult to write a little code to parse the ``__version__`` from the file rather than The function could be simplified (use re.search, hard-code the re), but that’s very minor.
Indeed.
Because the distutils2 style ``setup.cfg`` is declarative, we can't run any code to extract the ``__version__`` attribute, either via import or via parsing. This PEP suggests a special key be allowed for the ``version`` field in a ``setup.cfg`` file to indicate "get the version from this file". With my distutils2 hat on, I recommend a KISS approach similar to what’s done for the long description: just define another key in the setup.cfg specification:
[metadata] version-from-file: elle.py
It's an open issue, but we definitely want built-in support from distutils2/packaging. This section was one of the main reasons why I posted here first, because I really wanted to get feedback on how best to support this in a setup.cfg file. I've changed the example to your text above, since it does seem cleaner. Though if we get more universal adoption of the PEP, I suspect version-from-file will be much more popular than version, so we might want to address keeping the common case simple.
An alternative is to only define the version number in setup.cfg and use the ``pkgutil`` module [8]_ to make it available programmatically. E.g. in ``elle.py``::
from distutils2._backport import pkgutil __version__ = pkgutil.get_distribution('elle').metadata['version'] One of the main complaint against setuptools is that having to change your application code because of the packaging tool used was not a good idea. Having to use require instead of import or resource_whatever instead of open (or get_data, the most sadly underused function in the stdlib) because you use setuptools instead of distutils was a bad thing.
As stated in the PEP, having a __version__ attribute in the module is common, so my opinion is that making the packaging tool use that info is the Right Thing™, and having the dependency in the reverse sense is wrong. I don’t see a problem with having harmless duplication in the *installed* system, once in elle.__version__ and once in the pkgutil metadata database.
I'm including this section because at Pycon, some people did express an interest in deriving the version number in this direction. I wanted to capture what that might look like. Since this is an informational PEP, I think it makes sense to include alternative approaches, but I tend to agree with you that it will be much more common to define module.__version__ and derive the metadata from that.
(FWIW, I personally think that it’s not crazy to have the version number duplicated in the module, setup script, changelog, Sphinx conf.py file and so on; other people like Ronny don’t even want to have the version number in one file, but make their build process use the VCS tag. I think this PEP addresses a useful middle ground.)
Cool.
Static egg info Is that the distutils 2.5+ generated metadata? You may want to read PEP 376 and update the terminology to “dist-info metadata” <0.2 wink>.
I meant it in more general terms, that any metadata using the derived version number is better off being derived at build time rather than install time. PEP 376 doesn't really talk much about the process by which the metadata files are created, so I'm not sure referencing it is appropriate. Hmm, let me think about that section. (Side note: PEP 376 could probably benefit from a glossary. Its abstract starts off by using the term "project distributions" but doesn't provide any definition of what "project" means or what "distributions" are. As I mentioned before, if you want folks to adopt a specific terminology, I think you're going to need a separate informational PEP that explicitly defines that terminology.) Hmm, okay, I took a crack at rewriting this section: PEP 376 metadata ================ PEP 376 [9]_ defines a standard for static metadata, but doesn't describe the process by which this metadata gets created. It is highly desirable for the derived version information to be placed into the PEP 376 ``.dist-info`` metadata at build-time rather than install-time. This way, the metadata will be available for introspection even when the code is not installed.
For example, a package's metadata can be made available via a simple HTTP GET operation on a URL within the package's presence on the Cheeseshop. First, insert usual remark about “package” here; second, I think discussing PyPI is out of scope here. The rationale that “the metadata will be available for introspection even when the code is not installed“ is already strong enough.
.. [1] Distutils2 documentation (http://distutils2.notmyidea.org/) Alexis, is this still the good link to use?
Again, thanks for the feedback. I'm going to do another pass through the PEP, then check it in, and post it to python-dev. Cheers, -Barry
At 10:31 AM 4/5/2011 -0400, Barry Warsaw wrote:
On Mar 25, 2011, at 03:52 AM, Ãric Araujo wrote:
I am not sure we should advertise setuptools namespace packages, given that standardization is under way (PEP 382). On one hand it would be childish not to acknowledge that setuptools is widely used, on the other hand in this particular time and place I think we should wait for official namespace packages to be implemented and talk about those.
Just as an FYI, "official" namespace packages have existed since Python 2.3; they are implemented using pkgutil.extend_path() -- added, IIRC, back when Guido and Barry were both working at Zope Corp. ;-) Setuptools and PEP 382 are simply enhanced implementations of the concept.
#. For modules which live inside a namespace package, the sub-package name SHOULD include the ``__version__`` attribute. I think this works with both setuptools and PEP 382 namespace packages, which is nice (see above questioning).
The namespace module itself SHOULD NOT include its own ``__version__`` attribute. I guess this makes sense for setuptools namespace packages, but from my understanding of PEP 382, it is possible to have a Python package that is a namespace package and has submodules. (I hope Martin will correct me if needed.) This thing (âportionâ in PEP 382 lingo) should be allowed to declare a version IMO.
Agreed, if that is true. I kind of hope it's *not* true though! Anyway, this is a SHOULD NOT not MUST NOT so I think it's safe.
In principle, if you simply *must* have a non-empty __init__ module in a namespace package, and you really need to have a __version__ of that, then I suppose its __version__ should match the version of the project that supplies it. But yeah, I think it should still be considered a poor practice to put stuff in a namespace's __init__, even if/when PEP 382 makes it practical to implement non-empty __init__'s.
Hi, Glad to read my review helped :)
I know that the referenced PEP 345 call these things “software packages”, but let’s try to use consistent terminology. See threads starting at
http://mail.python.org/pipermail/distutils-sig/2011-March/017438.html and http://mail.python.org/pipermail/distutils-sig/2011-March/017450.html . I remember that discussion, but I don't actually remember if there was agreement on terminology. ;) I'm sympathetic to Jim's Elaboration On PJE's Glossary. That would make a worthy PEP for someone else to write <wink>.
Ah, right, I probably have extrapolated the distutils2 consensus. I’m not sure I should be the one to write this PEP, I already have enough of a nitpicker reputation. Maybe if a distutils-sig veteran accepts to be a co-writer.
In this case I'm changing it to *The Bob Bundle* since that's sufficiently meaningless as to not be distracting.
I also think that “bundle” is a nice term to name what the docs currently calls a distribution.
Carole maintains several namespace packages, each of which are independently developed and distributed. I am not sure we should advertise setuptools namespace packages, given that standardization is under way (PEP 382). [...] Right. This is just a use case and it doesn't mention setuptools specifically, even though it does mention setup.py. Everybody knows what the latter is, and I can't think of any better way to phrase this, so I guess I'll leave it.
As PJE helpfully corrected, namespaces packages are not tied to setuptools, even though in practice they mostly are. The current PEP text is therefore fine.
of an ``__version__`` module attribute by independent module s/an/a/ Heh, yeah I'm old skool so I still pronounce it "under under". Saying "dunder" just reminds me too much of The Office to take seriously. :)
I write about Python much more than I talk about it, so I pronounce it “version” (or more exactly, I say “init” when I talk about “__init__”, or “underscore-underscore-init-underscore-underscore” when I need total explicitness). I never read or heard “dunder”.
Another example of version information is the sqlite3 [5]_ library the sqlite3 module
You overlooked that one.
#. For modules which are also packages, the top level module namespace SHOULD include the ``__version__`` attribute. Just a remark: I don’t remember ever reading the term “top-level module namespace”. It’s not hard to understand, but it might be helpful to some readers if you add “(i.e. the :file:`{somepackage}/__init__.py` file)”. (The brackets will cause the enclosed text to be marked up as replaceable text, just a nicety.) How about just removing "top-level"?
#. For modules which are also packages, the module namespace SHOULD include the ``__version__`` attribute.
I’m still not sure “module namespace” will be clear to everyone.
(Aside: using :file:`file.py` produces a warning when the PEP html is generated:
Fooled again: it’s a Sphinx-specific role, not a docutils one. Forget my advice and use ````.
#. The ``version`` attribute in a classic distutils ``setup.py`` file, or the ``Version`` metadata field in a PEP 345 [7]_ SHOULD be derived from the ``__version__`` field, or vice versa. “In a PEP 345” what? :) file, I guess. Oops, IIUC there really isn't a PEP 345 "thing" so I've rewritten it like this:
There is actually a METADATA file, but your rewrite is good without mentioning that.
Because the distutils2 style ``setup.cfg`` is declarative, we can't run any code to extract the ``__version__`` attribute, either via import or via parsing. This PEP suggests a special key be allowed for the ``version`` field in a ``setup.cfg`` file to indicate "get the version from this file". With my distutils2 hat on, I recommend a KISS approach similar to what’s done for the long description: just define another key in the setup.cfg specification:
[metadata] version-from-file: elle.py It's an open issue, but we definitely want built-in support from distutils2/packaging. This section was one of the main reasons why I posted here first, because I really wanted to get feedback on how best to support this in a setup.cfg file. I've changed the example to your text above, since it does seem cleaner. Though if we get more universal adoption of the PEP, I suspect version-from-file will be much more popular than version, so we might want to address keeping the common case simple.
Tarek already ruled last summer that field names in setup.cfg have to have their PEP 345 name. I proposed to merge author name and email into the author field, and to have the description field always refer to a file: author and author_email are still separate, and a new description_from_file fields has been added. That’s why I think a new field has to be defined. version-from should be a short enough name. I also expect most people to use copy-paste or the interactive setup.cfg creation helper, so field name length should not be that big of an issue. Now on to defuse FUD on python-dev. Regards
On Apr 09, 2011, at 06:23 PM, Éric Araujo wrote:
Glad to read my review helped :)
Indeed, thanks.
I also think that “bundle” is a nice term to name what the docs currently calls a distribution.
At the very least, *bundle* isn't completely overloaded 10x over in Pythonland yet. :)
Another example of version information is the sqlite3 [5]_ library the sqlite3 module
You overlooked that one.
Got it.
#. For modules which are also packages, the top level module >>> namespace SHOULD include the ``__version__`` attribute. Just a remark: I don’t remember ever reading the term “top-level >> module namespace”. It’s not hard to understand, but it might be helpful to some readers if you add “(i.e. the :file:`{somepackage}/__init__.py` file)”. (The brackets will cause the enclosed text to be marked up >> as replaceable text, just a nicety.) How about just removing "top-level"?
#. For modules which are also packages, the module namespace > SHOULD include the ``__version__`` attribute.
I’m still not sure “module namespace” will be clear to everyone.
Really? We know what a module is, and we know what a namespace is, so given the context, I think it should be clear.
Tarek already ruled last summer that field names in setup.cfg have to have their PEP 345 name. I proposed to merge author name and email into the author field, and to have the description field always refer to a file: author and author_email are still separate, and a new description_from_file fields has been added. That’s why I think a new field has to be defined. version-from should be a short enough name. I also expect most people to use copy-paste or the interactive setup.cfg creation helper, so field name length should not be that big of an issue.
Perhaps. In lieu of a better idea it's fine for now. -Barry
Hi, Just two things I thought about while perusing my archives yesterday.
#. For modules which are also packages, the module namespace > SHOULD include the ``__version__`` attribute.
I’m still not sure “module namespace” will be clear to everyone.
Really? We know what a module is, and we know what a namespace is, so given the context, I think it should be clear.
FYI, I noticed that PEP 382 (namespace packages) says “the namespace package itself” to refer to the corp/__init__.py file of the corp.somelib package. In the Python tutorial, we have things like “the __init__.py code”. So it looks like there’s no agreed term to refer to this module. A note about the setup.cfg field used to get the version from a file: It will definitely need to use another name than “version”: Tarek wants the setup.cfg field to be a direct translation from PEP 345 (modulo case insensitivity), so the description-file is another field, and version-file should certainly be one too. (I hope it’s short enough to comply with your wish of keeping the common case simple.) Regards
Hi Éric, On Jun 07, 2011, at 05:30 PM, Éric Araujo wrote:
Just two things I thought about while perusing my archives yesterday.
#. For modules which are also packages, the module namespace > SHOULD include the ``__version__`` attribute.
I’m still not sure “module namespace” will be clear to everyone.
Really? We know what a module is, and we know what a namespace is, so given the context, I think it should be clear.
FYI, I noticed that PEP 382 (namespace packages) says “the namespace package itself” to refer to the corp/__init__.py file of the corp.somelib package. In the Python tutorial, we have things like “the __init__.py code”. So it looks like there’s no agreed term to refer to this module.
So, what *should* we call this thing? Note that in the PEP, I'm specifically talking about the namespace, not the file. Maybe "module's namespace" would be clearer?
A note about the setup.cfg field used to get the version from a file: It will definitely need to use another name than “version”: Tarek wants the setup.cfg field to be a direct translation from PEP 345 (modulo case insensitivity), so the description-file is another field, and version-file should certainly be one too. (I hope it’s short enough to comply with your wish of keeping the common case simple.)
The PEP currently uses `version-from-file` which seems okay to me. Would that work? -Barry
Barry Warsaw <barry@python.org> writes:
Hi Éric,
On Jun 07, 2011, at 05:30 PM, Éric Araujo wrote:
Just two things I thought about while perusing my archives yesterday.
#. For modules which are also packages, the module namespace SHOULD include the ``__version__`` attribute.
I’m still not sure “module namespace” will be clear to everyone. […]
Agreed. Damn English and its ample opportunities for ambiguity.
So, what *should* we call this thing? Note that in the PEP, I'm specifically talking about the namespace, not the file. Maybe "module's namespace" would be clearer?
+1. I think the grammar could be even clearer: For modules which are also packages, the ``__version__`` attribute SHOULD be in the module's namespace. -- \ “The opposite of a correct statement is a false statement. But | `\ the opposite of a profound truth may well be another profound | _o__) truth.” —Niels Bohr | Ben Finney
On Tue, Jun 7, 2011 at 11:48 PM, Ben Finney <ben+python@benfinney.id.au> wrote:
For modules which are also packages, the ``__version__`` attribute SHOULD be in the module's namespace.
This suggests to me that there's no need to describe it as a special case. A importable directory contains an __init__.py; it's represented as a module at runtime, just like any other. -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> "Give me the luxuries of life and I will willingly do without the necessities." --Frank Lloyd Wright
Given Ben's and Fred's feedback, what do you think about this list in the Specification's section: #. In general, modules in the standard library SHOULD NOT have version numbers. They implicitly carry the version number of the Python release they are included in. #. On a case-by-case basis, standard library modules which are also released in standalone form for other Python versions MAY include a module version number when included in the standard library, and SHOULD include a version number when packaged separately. #. When a module (or package) includes a version number, the version SHOULD be available in the ``__version__`` attribute. #. For modules which live inside a namespace package, the sub-package name SHOULD include the ``__version__`` attribute. The namespace module itself SHOULD NOT include its own ``__version__`` attribute. #. The ``__version__`` attribute's value SHOULD be a string. #. Module version numbers SHOULD conform to the normalized version format specified in PEP 386 [6]_. #. Module version numbers SHOULD NOT contain version control system supplied revision numbers, or any other semantically different version numbers (e.g. underlying library version number). #. The ``version`` attribute in a classic distutils ``setup.py`` file, or the PEP 345 [7]_ ``Version`` metadata field SHOULD be derived from the ``__version__`` field, or vice versa. -Barry
Barry Warsaw <barry@python.org> writes:
#. The ``__version__`` attribute's value SHOULD be a string.
I may be fighting against the tide here; but this screams to me that the PEP should not be talking at all about “version number” (except to point out that they're strings, not numbers). Instead, the term should be “version string” throughout. Much damage is done to understanding version strings by calling them “version numbers”, with all the baggage about parsing and sequencing etc. that entails. We don't have to make the same mistake in this PEP. -- \ “He may look like an idiot and talk like an idiot but don't let | `\ that fool you. He really is an idiot.” —Groucho Marx | _o__) | Ben Finney
On Jun 09, 2011, at 10:42 AM, Ben Finney wrote:
Barry Warsaw <barry@python.org> writes:
#. The ``__version__`` attribute's value SHOULD be a string.
I may be fighting against the tide here; but this screams to me that the PEP should not be talking at all about “version number” (except to point out that they're strings, not numbers). Instead, the term should be “version string” throughout.
As I was doing the last edit, I did think about that. The suggestion is not without merit, but I also think "version number" is a commonly accepted term for what this thing is. I mean, we've used that term for ages to describe things like 2.6.7, which clearly isn't a number. -Barry
Barry Warsaw <barry@python.org> writes:
#. When a module (or package) includes a version number, the version SHOULD be available in the ``__version__`` attribute.
#. For modules which live inside a namespace package, the sub-package name SHOULD include the ``__version__`` attribute. The namespace module itself SHOULD NOT include its own ``__version__`` attribute.
I still find a little ambiguity in “the ``__version__`` attribute”, but it's much improved, thanks. I think those paragraphs are good. -- \ “It is clear that thought is not free if the profession of | `\ certain opinions makes it impossible to earn a living.” | _o__) —Bertrand Russell, _Free Thought and Official Propaganda_, 1928 | Ben Finney
On Wed, Jun 8, 2011 at 6:14 PM, Barry Warsaw <barry@python.org> wrote:
#. For modules which live inside a namespace package, the sub-package name SHOULD include the ``__version__`` attribute. The namespace module itself SHOULD NOT include its own ``__version__`` attribute.
I've no idea what you're saying here. What's a sub-package? If you're referring to a package like zope.testing, I'd just call that a package; there's nothing special about that. I'd expect the __version__, if it exists, to be present in the file zope/testing/__init__.py. An namespace package, like zope or zc, should not have a __version__. Ben Finney wrote:
I may be fighting against the tide here; but this screams to me that the PEP should not be talking at all about “version number” (except to point out that they're strings, not numbers). Instead, the term should be “version string” throughout.
I'd rather we just say 'version' instead of 'version number' or 'version string'. Natural use of natural language is... natural. A separate sentence can state simply that versions are expressed as strings. -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> "Give me the luxuries of life and I will willingly do without the necessities." --Frank Lloyd Wright
Fred Drake <fdrake@acm.org> writes:
On Wed, Jun 8, 2011 at 6:14 PM, Barry Warsaw <barry@python.org> wrote:
#. For modules which live inside a namespace package, the sub-package name SHOULD include the ``__version__`` attribute. The namespace module itself SHOULD NOT include its own ``__version__`` attribute.
I've no idea what you're saying here. What's a sub-package?
Moreover, how can a “sub-package name” include an attribute? I agree that needs to be clarified.
If you're referring to a package like zope.testing, I'd just call that a package; there's nothing special about that. I'd expect the __version__, if it exists, to be present in the file zope/testing/__init__.py.
Yes, but how to specify that? The ‘__init__.py’ file is a module. What's that, then; a package module?
Ben Finney wrote:
I may be fighting against the tide here; but this screams to me that the PEP should not be talking at all about “version number” (except to point out that they're strings, not numbers). Instead, the term should be “version string” throughout.
I'd rather we just say 'version' instead of 'version number' or 'version string'. Natural use of natural language is... natural. A separate sentence can state simply that versions are expressed as strings.
−1. A version is a state of the code base at a point in its development; what we're talking about here are strings which act as identifiers for versions of the code. I would argue for “version identifier”, but that has virtually no actual use :-) -- \ “I was sleeping the other night, alone, thanks to the | `\ exterminator.” —Emo Philips | _o__) | Ben Finney
I wrote:
If you're referring to a package like zope.testing, I'd just call that a package; there's nothing special about that. I'd expect the __version__, if it exists, to be present in the file zope/testing/__init__.py.
Ben Finney responded
Yes, but how to specify that? The ‘__init__.py’ file is a module. What's that, then; a package module?
The package zope.testing includes the module zope.testing (implemented in zope/testing/__init__.py), as well as other modules (zope.testing.cleanup for example). The zope.testing module SHOULD contain any appropriate __version__ attribute. The only real special cases are "namespace" packages like zc, zope, and many others. Since those are *not* tied to a single distribution, they SHOULD NOT have __version__ attributes. (I think we agree on this, but language is tedious, since there are many casual uses of the term 'package' here, and 'namespace packages' aren't as commonly known outside particular segments of the community.) -Fred -- Fred L. Drake, Jr. <fdrake at acm.org> "Give me the luxuries of life and I will willingly do without the necessities." --Frank Lloyd Wright
On Jun 09, 2011, at 12:31 AM, Fred Drake wrote:
(I think we agree on this, but language is tedious, since there are many casual uses of the term 'package' here, and 'namespace packages' aren't as commonly known outside particular segments of the community.)
I think "namespace package" is a pretty commonly accepted term in the Python community. See PEP 382. -Barry
On Jun 08, 2011, at 10:47 PM, Fred Drake wrote:
On Wed, Jun 8, 2011 at 6:14 PM, Barry Warsaw <barry@python.org> wrote:
#. For modules which live inside a namespace package, the sub-package name SHOULD include the ``__version__`` attribute. The namespace module itself SHOULD NOT include its own ``__version__`` attribute.
I've no idea what you're saying here. What's a sub-package?
It's a package that lives within another package.
If you're referring to a package like zope.testing, I'd just call that a package; there's nothing special about that. I'd expect the __version__, if it exists, to be present in the file zope/testing/__init__.py.
That's where I'd expect __version__ too, and it's what the PEP tries to say. Unfortunately, I think it's ambiguous to change "sub-package" to "package" here; it just isn't clear. We're hampered by a lack of consistent terminology in the Python world about these things. I'm willing to add some definitions to the PEP to help make things clearer, or to rewrite something, but we first need to agree on what to call these things. :)
An namespace package, like zope or zc, should not have a __version__.
Agreed. Is this any clearer? #. For modules which live inside a namespace package, the module SHOULD include the ``__version__`` attribute. The namespace package itself SHOULD NOT include its own ``__version__`` attribute.
Ben Finney wrote:
I may be fighting against the tide here; but this screams to me that the PEP should not be talking at all about “version number” (except to point out that they're strings, not numbers). Instead, the term should be “version string” throughout.
I'd rather we just say 'version' instead of 'version number' or 'version string'. Natural use of natural language is... natural. A separate sentence can state simply that versions are expressed as strings.
#. The ``__version__`` attribute's value SHOULD be a string. I still don't have a problem with using "version number" to express what these things are. We have oodles of existing practice on this. -Barry
Hi,
The PEP currently uses `version-from-file` which seems okay to me. Would that work?
Yes, the PEP uses that field since I said I thought it could not reuse the version field; my email was meant to change “I think it should be another field” to “it must definitely be another field”. version-from-file is a good name if a regex is applied to extract a version from the first lines of a file; if the whole contents of the file are the version number (sorry Ben, I cannot call it something else :), it should be version-file to mirror description-file. Regards
On Jun 09, 2011, at 01:29 PM, Éric Araujo wrote:
Yes, the PEP uses that field since I said I thought it could not reuse the version field; my email was meant to change “I think it should be another field” to “it must definitely be another field”.
version-from-file is a good name if a regex is applied to extract a version from the first lines of a file; if the whole contents of the file are the version number (sorry Ben, I cannot call it something else :), it should be version-file to mirror description-file.
Hi Éric, I hadn't thought about a file that only contains the version number, but that makes perfect sense. Here's what I propose for the PEP. Distutils2 ---------- Because the distutils2 style ``setup.cfg`` is declarative, we can't run any code to extract the ``__version__`` attribute, either via import or via parsing. In consultation with the distutils-sig [9]_, two options are proposed. Both entail containing the version number in a file, and declaring that file in the ``setup.cfg``. When the entire contents of the file contains the version number, the ``version-file`` key will be used:: [metadata] version-file: version.txt When the version number is contained within a larger file, e.g. of Python code, such that the file must be parsed to extract the version, the key ``version-from-file`` will be used:: [metadata] version-from-file: elle.py A parsing method similar to that described above will be performed on the file named after the colon. The exact recipe for doing this will be discussed in the appropriate distutils2 development forum. Cheers, -Barry
participants (7)
-
Alexis Métaireau
-
Barry Warsaw
-
Ben Finney
-
Fred Drake
-
P.J. Eby
-
Yannick Gingras
-
Éric Araujo