What keyword arguments does setuptools.setup() accept?

Question:

What is the full list of keyword arguments that the setuptools.setup() function accepts? (Please include a description of what each argument means, if possible.)

I have looked all over the web and I can’t believe this isn’t documented.

I found these documents:

But even when I combine these, they are missing other arguments such as

  • scripts
  • packages
  • provides
  • obsoletes

…and I don’t know how many more arguments are missing.

What is the full list of keyword arguments that the setuptools.setup() function accepts?

Asked By: cowlinator

||

Answers:

Update (January 2024):

The Setup Tools maintainers have largely fixed the documentation gap that existed in late 2019 and a year or two thereafter.

The official documentation should be the preferred reference for this information going forward, although this post is still accurate (in January 2024) as both documents are based on the same sources.


Original Answer:

setuptools.setup() calls distutils.core.setup() and passes it’s own **kwargs as the only parameter, so any keywords that distutils accepts will also be accepted by setuptools. If we go look at distutils

    setup_keywords = ('distclass', 'script_name', 'script_args', 
                      'options', 'name', 'version', 'author', 
                      'author_email', 'maintainer', 'maintainer_email', 
                      'url', 'license', 'description', 
                      'long_description', 'keywords', 'platforms', 
                      'classifiers', 'download_url', 'requires', 
                      'provides', 'obsoletes',
                  )

Most of these are documented here but some are not included in the table: packages, package_dir, package_data, scripts, obsoletes, provides, py_modules and data_files.

Some of these are also missing from the setup_keywords tuple. And if you grep for setup_keywords it doesn’t look like that it’s actually referenced anywhere…. But that’s a story for another day. Anyway, here is the (hopefully complete) list for Python 3.10.


distutils.core.setup() keyword arguments

(Required: name, version, and at least one of author or maintainer)

author:

package author’s name (required if maintainer is not provided)

author_email:

email address of the package author

classifiers:

a list of classifiers (see: https://pypi.org/classifiers/)

data_files:

The data_files option can be used to specify additional files needed by the module distribution: configuration files, message catalogs, data files, anything which doesn’t fit in the previous categories.

data_files specifies a sequence of (directory, files) pairs in the following way:

setup(...,
     data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
                 ('config', ['cfg/data.cfg'])],
    )

Each (directory, files) pair in the sequence specifies the installation directory and the files to install there. Each file name in files is interpreted relative to the setup.py script.

description:

short, summary description of the package

download_url:

location where the package may be downloaded

keywords:

a list of keywords (Also takes a string. If comma separated, it is split into a list)

license:

license for the package (Use only if the license is not one listed in the "trove classifiers". See: Classifiers)

long_description:

longer description of the package, used by PyPI to build the project page

maintainer:

package maintainer’s name (required if author is not provided)

maintainer_email:

email address of the package maintainer

name:

name of the package (required by distutils)

obsoletes:

A package can declare that it obsoletes other packages using the obsoletes keyword argument. The value for this is similar to that of the requires keyword: a list of strings giving module or package specifiers. Each specifier consists of a module or package name optionally followed by one or more version qualifiers. Version qualifiers are given in parentheses after the module or package name

package_data:

Package data can be added to packages using the package_data keyword argument to the setup() function. The value must be a mapping from package name to a list of relative path names that should be copied into the package. The paths are interpreted as relative to the directory containing the package (information from the package_dir mapping is used if appropriate); that is, the files are expected to be part of the package in the source directories.

package_dir:

If you use a different convention to lay out your source directory, that’s no problem: you just have to supply the package_dir option to tell the Distutils about your convention. For example, say you keep all Python source under lib, so that modules in the “root package” (i.e., not in any package at all) are in lib, modules in the foo package are in lib/foo, and so forth. Then you would put

package_dir = {'': 'lib'}

in your setup script. The keys to this dictionary are package names, and an empty package name stands for the root package. The values are directory names relative to your distribution root. In this case, when you say packages = ['foo'], you are promising that the file lib/foo/__init__.py exists.

Another possible convention is to put the foo package right in lib, the foo.bar package in lib/bar, etc. This would be written in the setup script as

package_dir = {'foo': 'lib'}

A package: dir entry in the package_dir dictionary implicitly applies to all packages below package, so the foo.bar case is automatically handled here. In this example, having packages = ['foo', 'foo.bar'] tells the Distutils to look for lib/__init__.py and lib/bar/__init__.py. (Keep in mind that although package_dir applies recursively, you must explicitly list all packages in packages: the Distutils will not recursively scan your source tree looking for any directory with an __init__.py file.)

packages:

Package data can be added to packages using the package_data keyword argument to the setup() function. The value must be a mapping from package name to a list of relative path names that should be copied into the package. The paths are interpreted as relative to the directory containing the package (information from the package_dir mapping is used if appropriate); that is, the files are expected to be part of the package in the source directories. They may contain glob patterns as well.

platforms:

a list of platforms (Also takes a string. If comma separated, it is split into a list)

provides:

Now that we can specify dependencies, we also need to be able to specify what we provide that other distributions can require. This is done using the provides keyword argument to setup().

py_modules:

For a small module distribution, you might prefer to list all modules rather than listing packages—especially the case of a single module that goes in the “root package” (i.e., no package at all).

py_modules = ['foo.py']

here is a slightly more involved example:

py_modules = ['mod1', 'pkg.mod2']

This describes two modules, one of them in the “root” package, the other in the pkg package. Again, the default package/directory layout implies that these two modules can be found in mod1.py and pkg/mod2.py, and that pkg/__init__.py exists as well. And again, you can override the package/directory correspondence using the package_dir option.

scripts:

Scripts are files containing Python source code, intended to be started from the command line. Scripts don’t require Distutils to do anything very complicated. The only clever feature is that if the first line of the script starts with #! and contains the word “python”, the Distutils will adjust the first line to refer to the current interpreter location. By default, it is replaced with the current interpreter location. The --executable (or -e) option will allow the interpreter path to be explicitly overridden.

The scripts option simply is a list of files to be handled in this way. From the PyXML setup script:

    setup(...,
          scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']
          )

url:

home page for the package

version:

version of this release (required by distutils)


setuptools.setup() keyword arguments

There are even more arguments that setuptools.setup() will accept, beyond those which are used by distutils.

Although it’s called "New and Changed Setup Keywords" (which to me suggests a version changelog), the intro text says these are "keyword arguments to setup() [that are] added or changed by setuptools" so I believe the link actually provides a complete list. I will add it here for completeness.

(Since setuptools.setup() calls distutils.core.setup(), the same parameters are Required: name, version, and at least one of author or maintainer)

convert_2to3_doctests:

List of doctest source files that need to be converted with 2to3. See Supporting both Python 2 and Python 3 with Setuptools for more details.

dependency_links:

A list of strings naming URLs to be searched when satisfying dependencies. These links will be used if needed to install packages specified by setup_requires or tests_require. They will also be written into the egg’s metadata for use by tools like EasyInstall to use when installing an .egg file.

eager_resources:

A list of strings naming resources that should be extracted together, if any of them is needed, or if any C extensions included in the project are imported. This argument is only useful if the project will be installed as a zipfile, and there is a need to have all of the listed resources be extracted to the filesystem as a unit. Resources listed here should be ‘/’-separated paths, relative to the source root, so to list a resource foo.png in package bar.baz, you would include the string bar/baz/foo.png in this argument.
If you only need to obtain resources one at a time, or you don’t have any C extensions that access other files in the project (such as data files or shared libraries), you probably do NOT need this argument and shouldn’t mess with it. For more details on how this argument works, see the section below on Automatic Resource Extraction.

entry_points:

A dictionary mapping entry point group names to strings or lists of strings defining the entry points. Entry points are used to support dynamic discovery of services or plugins provided by a project. See Dynamic Discovery of Services and Plugins for details and examples of the format of this argument. In addition, this keyword is used to support Automatic Script Creation.

exclude_package_data:

A dictionary mapping package names to lists of glob patterns that should be excluded from your package directories. You can use this to trim back any excess files included by include_package_data. For a complete description and examples, see the section below on Including Data Files.

extras_require:

A dictionary mapping names of “extras” (optional features of your project) to strings or lists of strings specifying what other distributions must be installed to support those features. See the section below on Declaring Dependencies for details and examples of the format of this argument.

NOTE: For the extras_require dictionarhy, in versions prior to 54.1.0 if dashes were used in keys, the were converted to underscores. Later versions allow dashes and warn users if they use an alias containing dashes that should use underscores (eg. author-email instead of author_email), and in such cases the conversion is still performed. In the future this conversion will no longer be done automatically.

include_package_data:

If set to True, this tells setuptools to automatically include any data files it finds inside your package directories that are specified by your MANIFEST.in file. For more information, see the section below on Including Data Files.

install_requires:

A string or list of strings specifying what other distributions need to be installed when this one is. See the section below on Declaring Dependencies for details and examples of the format of this argument.

namespace_packages:

A list of strings naming the project’s “namespace packages”. A namespace package is a package that may be split across multiple project distributions. For example, Zope 3’s zope package is a namespace package, because subpackages like zope.interface and zope.publisher may be distributed separately. The egg runtime system can automatically merge such subpackages into a single parent package at runtime, as long as you declare them in each project that contains any subpackages of the namespace package, and as long as the namespace package’s __init__.py does not contain any code other than a namespace declaration. See the section below on Namespace Packages for more information.

package_data:

A dictionary mapping package names to lists of glob patterns. For a complete description and examples, see the section below on Including Data Files. You do not need to use this option if you are using include_package_data, unless you need to add e.g. files that are generated by your setup script and build process. (And are therefore not in source control or are files that you don’t want to include in your source distribution.)

project_urls:

An arbitrary map of URL names to hyperlinks, allowing more extensible documentation of where various resources can be found than the simple url and download_url options provide.

python_requires:

A string corresponding to a version specifier (as defined in PEP 440) for the Python version, used to specify the Requires-Python defined in PEP 345.

setup_requires:

A string or list of strings specifying what other distributions need to be present in order for the setup script to run. setuptools will attempt to obtain these (even going so far as to download them using EasyInstall) before processing the rest of the setup script or commands. This argument is needed if you are using distutils extensions as part of your build process; for example, extensions that process setup() arguments and turn them into EGG-INFO metadata files.
(Note: projects listed in setup_requires will NOT be automatically installed on the system where the setup script is being run. They are simply downloaded to the ./.eggs directory if they’re not locally available already. If you want them to be installed, as well as being available when the setup script is run, you should add them to install_requires and setup_requires.)

test_loader:

If you would like to use a different way of finding tests to run than what setuptools normally uses, you can specify a module name and class name in this argument. The named class must be instantiable with no arguments, and its instances must support the loadTestsFromNames() method as defined in the Python unittest module’s TestLoader class. Setuptools will pass only one test “name” in the names argument: the value supplied for the test_suite argument. The loader you specify may interpret this string in any way it likes, as there are no restrictions on what may be contained in a test_suite string.
The module name and class name must be separated by a :. The default value of this argument is setuptools.command.test:ScanningLoader. If you want to use the default unittest behavior, you can specify unittest:TestLoader as your test_loader argument instead. This will prevent automatic scanning of submodules and subpackages.
The module and class you specify here may be contained in another package, as long as you use the tests_require option to ensure that the package containing the loader class is available when the test command is run.

test_suite:

A string naming a unittest.TestCase subclass (or a package or module containing one or more of them, or a method of such a subclass), or naming a function that can be called with no arguments and returns a unittest.TestSuite. If the named suite is a module, and the module has an additional_tests() function, it is called and the results are added to the tests to be run. If the named suite is a package, any submodules and subpackages are recursively added to the overall test suite.
Specifying this argument enables use of the test command to run the specified test suite, e.g. via setup.py test. See the section on the test command below for more details.

tests_require:

If your project’s tests need one or more additional packages besides those needed to install it, you can use this option to specify them. It should be a string or list of strings specifying what other distributions need to be present for the package’s tests to run. When you run the test command, setuptools will attempt to obtain these (even going so far as to download them using EasyInstall). Note that these required projects will not be installed on the system where the tests are run, but only downloaded to the project’s setup directory if they’re not already installed locally.

use_2to3:

Convert the source code from Python 2 to Python 3 with 2to3 during the build process. See Supporting both Python 2 and Python 3 with Setuptools for more details.

use_2to3_exclude_fixers:

By default, the conversion uses all fixers in the lib2to3.fixers package. To use additional fixers, the parameter use_2to3_fixers can be set to a list of names of packages containing fixers. To exclude fixers, the parameter use_2to3_exclude_fixers can be set to fixer names to be skipped.

use_2to3_fixers:

A list of modules to search for additional fixers to be used during the 2to3 conversion. See Supporting both Python 2 and Python 3 with Setuptools for more details.

zip_safe:

A boolean (True or False) flag specifying whether the project can be safely installed and run from a zip file. If this argument is not supplied, the bdist_egg command will have to analyze all of your project’s contents for possible problems each time it builds an egg.


Extensions

Building an extension (rather than a pure Python module) is more complicated, since it essentially requires you to specify the necessary parameters and arguments to successfully build the extension from C source files. This is done through the ext_modules keyword, which is nothing but a list of Extension instances (importable from distutils.core). The keyword arguments accepted by the Extension class constructor are the input vector for specifying the build steps to compile the extension.

Since this question is about setuptools.setup() specifically, I will only include the definition of ext_modules, but the documentation for the Extension class provides full details. For completeness, this is the list of accepted keywords for the Extension constructor:

    extension_keywords = ('name', 'sources', 'include_dirs',
                          'define_macros', 'undef_macros',
                          'library_dirs', 'libraries', 
                          'runtime_library_dirs', 'extra_objects', 
                          'extra_compile_args', 'extra_link_args',
                          'swig_opts', 'export_symbols', 'depends', 
                          'language')

ext_modules:

A list of Extension instances, each of which describes a single extension module. Suppose your distribution includes a single extension, called foo and implemented by foo.c. If no additional instructions to the compiler/linker are needed, describing this extension is quite simple:

   from distutils.core import setup, Extension
   setup(name='foo',
         version='1.0',
         ext_modules=[Extension('foo', ['foo.c'])],
         )


Misc.

Finally, there are even more kwargs which can be found implemented in setuptools.dist and elsewhere, but for some reason were never added to any of the main setuptools/distutils documentation:

features (deprecated):

a dictionary mapping option names to setuptools.Feature objects. Features are a portion of the distribution that can be included or excluded based on user options, inter-feature dependencies, and availability on the current system. Excluded features are omitted from all setup commands, including source and binary distributions, so you can create multiple distributions from the same source tree.

long_description_content_type (Per Making a PyPI-friendly README):

set to an accepted Content-Type-style value for your README file’s markup, such as text/plain, text/x-rst (for reStructuredText), or text/markdown.

provides_extras (Per PEP566, listed as "Provides-Extra"):

A string containing the name of an optional feature. Must be a valid Python identifier. May be used to make a dependency conditional on whether the optional feature has been requested.

Answered By: Z4-tier