It seemed to me, that instead of the whole plethora of named keyword-arguments for
the distutils.core.setup
function, one can use a setup.cfg
file in the same directory
as the setup.py
file and all these keywords will be read from the setup.cfg file.
I thought i could simply create a setup.cfg
with Python 2.7, but a minimal testing
version just does not work. I did test it with setup.py --name
, which
just returns: UNKNOWN
.
And as usual with python-packaging the documentation is confusing as hell, as it is never clear, which version they relate to or at least how old the documentation is.
My two setup files:
setup.py:
from distutils.core import setup
setup()
setup.cfg:
[metadata]
name = foo
version = 0.1
I looked into the distutils package and found that (besides being fugly as hell)
it seems to use the mail.message_from_file
factory to read the setup.cfg
.
As i am quite ok with a setup.py
-only approach i would not bother much longer
with such nonsense, but i am still curious how to do it right, if it is possible at all.
Neither the official packaging doc nor the Packaging-Authority seems to be a big help here.
Almost every time i feel compelled to look into python's 2.x stdlib i am wondering if they try to showcase how not to program. On the other hand the C-Code seems quite beautiful.
Note that, as of December 2016 and setuptools version 30.3.0, it is possible to put package metadata in setup.cfg, per idle sign's answer.
The problem is that the setup.cfg file does not do what you want. It does not provide parameters to the
setup
function. It is used to supply parameters to the commands that setup.py makes available. You can list the supported commands with setup.py --help-commands. You should see something like:This is the list of sections that you can put in a setup.cfg file. You can list the options that a command supports using setup.py --help command. For example, the sdist command supports the following options:
You can control what happens when a user runs ./setup.py sdist in your project by adding a setup.cfg file like the following.
So... setup.cfg simply configures the behavior of the various setup commands for your project. The
setup
function really needs to have the metadata supplied to it as keyword parameters. You could write your own version of thedistutils.dist.Distribution
class that pulls metadata from setup.cfg and provide it as thedistclass=
keyword parameter tosetup
.The missing piece to the puzzle is that the standard
Distribution
class does not provide a way to pass thepath
parameter to thedistutils.dist.DistributionMetadata
initializer which does pretty much what you want - it reads the package information using the email parsing stuff that you mentioned. What you found is the code that is used to process a PEP-314/PEP-345 metadata file. This is not used by thesetup
function. Instead, it is used to parse the metadata embedded in a distributed package.Disclaimer: The following remarks are true for python 2.7 with the stdlib
distutils
package. They may be misleading or false for other versions.Independently to D. Shawleys very elaborate and sophisticated answer i came to pretty the same conclusions and decided to do a trivial solution for declarative metadatas.
So for the sake of everyone, who got stuck with the same question and does not want to loose to much time on such trivialities here is a short summary for
setup.cfg
issues:setup()
use ofsetup.cfg
does not allow to declare name, version, license and similar meta-data for all provided commands, in a general waysetup()
to define those meta-datassetup.cfg
are named after commands and change the behaviour of thesetup()
function see D.Shawleys answerSo with these findings in mind i implemented a Q&D™ solution which allows a
setup.cfg
-section like:and a setup.py with:
Basically i took the distutils2-solution as orientation and avoided the need to do an additional import, with the additional path-hassle in the
setup.py
script, by usingexecfile
.There is an exemplary gist for the interested available.
I'm glad to say that since setuptools 30.3.0 (8 Dec 2016) declarative configuration in setup.cfg is available.
Documentation.