`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