How to use "setup.cfg" instead of setup.py with Python 2.7

installation, python, python-2.7

Solution

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:

(env) gondolin/zender% ./setup.py --help-commands
Standard commands:
  build             build everything needed to install
  build_py          "build" pure Python modules (copy to build directory)
  .....
  install_data      install data files
  sdist             create a source distribution (tarball, zip file, etc.)

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:

(env) gondolin/zender% ./setup.py --help sdist
Common commands: (see '--help-commands' for more)
....
Options for 'sdist' command:
  --formats         formats for source distribution (comma-separated list)
  --keep-temp (-k)  keep the distribution tree around after creating archive
                    file(s)
  --dist-dir (-d)   directory to put the source distribution archive(s) in
                    [default: dist]
  --help-formats    list available distribution formats

You can control what happens when a user runs ./setup.py sdist in your project by adding a setup.cfg file like the following.

[sdist]
keep-temp = 1
dist-dir = dist/source

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 the `distutils.dist.Distribution` class that pulls metadata from setup.cfg and provide it as the `distclass=` keyword parameter to `setup`.

The missing piece to the puzzle is that the standard `Distribution` class does not provide a way to pass the `path` parameter to the `distutils.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 the `setup` function. Instead, it is used to parse the metadata embedded in a distributed package.

Problem

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.

Original source