Why did I have to figure this out all by myself? Why is setuputil's docs so garbage???
Key | Description |
---|---|
name | A string specifying the name of the package. |
version | A string specifying the version number of the package. |
url | A string specifying the URL for the package homepage. |
download_url | A string specifying the URL to download the package. |
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. |
author | A string specifying the author of the package. |
author_email | A string specifying the email address of the package author. |
maintainer | A string specifying the name of the current maintainer, if different from the author. Note that if the maintainer is provided, setuptools will use it as the author in PKG-INFO . |
maintainer_email | A string specifying the email address of the current maintainer, if different from the author. |
classifiers | A list of strings describing the categories for the package. |
license | A string specifying the license of the package. |
license_file is deprecated. Use license_files instead. |
|
license_files | A list of glob patterns for license related files that should be included. If neither license_file nor license_files is specified, this option defaults to LICEN[CS]E* , COPYING* , NOTICE* , and AUTHORS* . |
description | A string describing the package in a single line. |
long_description | A string providing a longer description of the package. |
long_description_content_type | A string specifying the content type is used for the long_description (e.g. text/markdown ) |
keywords | A list of strings or a comma-separated string providing descriptive meta-data. See: PEP-314 |
platforms | A list of strings or comma-separated string. |
pip . |
|
❌ Deprecated: Superseded by install_requires and should not be used anymore. |
|
pip |
Key | Description |
---|---|
zip_safe | A boolean 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. |
❌ Deprecated: Using setup_requires is discouraged in favor of PEP-518 |
|
install_requires | A string or list of strings specifying what other distributions need to be installed when this one is. See the section on Declaring Dependencies for details. |
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 on Declaring Dependencies for details. |
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. |
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 Advertising Behaviour for details and examples of the format of this argument. |
❌ Deprecated: Used in converting python 2 to python 3 | |
❌ Deprecated: Used in converting python 2 to python 3 | |
❌ Deprecated: Used in converting python 2 to python 3 | |
❌ Deprecated: Used in converting python 2 to python 3 | |
scripts | A list of strings specifying the standalone script files to be built and installed. |
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 Automatic Resource Extraction. |
❌ Deprecated: not supported anymore by pip. | |
❌ Deprecated: the test command is deprecated. | |
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 on Including Data Files |
packages | A list of strings specifying the packages that setuptools will manipulate. |
package_dir | A dictionary providing a mapping of package to directory names. |
package_data | A dictionary mapping package names to lists of glob patterns. For a complete description and examples, see the section 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.) |
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 on Including Data Files |
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 on Namespace Package for more information. |
py_modules | A list of strings specifying the modules that setuptools will manipulate. |
❌ Deprecated: It does not work with wheels, so it should be avoided. |
This is where a package declares its core dependencies, without which it won't
be able to run. setuptools
support automatically download and install
these dependencies when the package is installed. Although there is more
finesse to it, let's start with a simple example.
[options]
; ...
install_requires =
docutils
BazSpam ==1.1
setup(
# ...
install_requires = [
'docutils',
'BazSpam ==1.1'
]
)
When your project is installed (e.g. using pip), all of the dependencies not already installed will be located (via PyPI), downloaded, built (if necessary), and installed. Any scripts in your project will be installed with wrappers that verify the availability of the specified dependencies at runtime.
Console scripts are one use of the more general concept of entry points. Entry points more generally allow a packager to advertise behavior for discovery by other libraries and applications. This feature enables "plug-in"-like functionality, where one library solicits entry points and any number of other libraries provide those entry points.
A good example of this plug-in behavior can be seen in
pytest plugins,
where pytest is a test framework that allows other libraries to extend
or modify its functionality through the pytest11
entry point.
The console scripts work similarly, where libraries advertise their commands
and tools like pip
create wrapper scripts that invoke those commands.
For a project wishing to solicit entry points, Setuptools recommends the
importlib.metadata
module (part of stdlib since Python 3.8) or its backport,
importlib_metadata
For example, to find the console script entry points from the example above:
from importlib import metadata
eps = metadata.entry_points()['console_scripts']
eps
is now a list of EntryPoint
objects, one of which corresponds
to the hello-world = timmins:hello_world
defined above. Each EntryPoint
contains the name
, group
, and value
. It also supplies a .load()
method to import and load that entry point (module or object).
[options.entry_points]
my.plugins =
hello-world = timmins:hello_world
Then, a different project wishing to load my.plugins
plugins could run
the following routine to load (and invoke) such plugins:
from importlib import metadata
eps = metadata.entry_points()['my.plugins']
for ep in eps:
plugin = ep.load()
plugin()
The project soliciting the entry points needs not to have any dependency or prior knowledge about the libraries implementing the entry points, and downstream users are able to compose functionality by pulling together libraries implementing the entry points.
If you are using tools that expect your resources to be "real" files, or your
project includes non-extension native libraries or other files that your C
extensions expect to be able to access, you may need to list those files in
the eager_resources
argument to setup()
, so that the files will be
extracted together, whenever a C extension in the project is imported.
This is especially important if your project includes shared libraries other
than distutils-built C extensions, and those shared libraries use file
extensions other than .dll
, .so
, or .dylib
, which are the
extensions that setuptools 0.6a8 and higher automatically detects as shared
libraries and adds to the native_libs.txt
file for you. Any shared
libraries whose names do not end with one of those extensions should be listed
as eager_resources
, because they need to be present in the filesystem when
he C extensions that link to them are used.
The pkg_resources
runtime for compressed packages will automatically
extract all C extensions and eager_resources
at the same time, whenever
any C extension or eager resource is requested via the resource_filename()
API (C extensions are imported using resource_filename()
internally).
This ensures that C extensions will see all of the "real" files that they
expect to see.
Note also that you can list directory resource names in eager_resources
as
well, in which case the directory's contents (including subdirectories) will be
extracted whenever any C extension or eager resource is requested.
Please note that if you're not sure whether you need to use this argument, you
don't! It's really intended to support projects with lots of non-Python
dependencies and as a last resort for crufty projects that can't otherwise
handle being compressed. If your package is pure Python, Python plus data
files, or Python plus C, you really don't need this. You've got to be using
either C or an external program that needs "real" files in your project before
there's any possibility of eager_resources
being relevant to your project.
The distutils have traditionally allowed installation of "data files", which
are placed in a platform-specific location. Setuptools offers three ways to
specify data files to be included in your packages. For the simpliest use, you
can simply use the include_package_data
keyword:
[options]
include_package_data = True
This tells setuptools to install any data files it finds in your packages.
The data files must be specified via the distutils' MANIFEST.in
file.
For more details, see :doc:datafiles
setuptools
provides the find_namespace:
(find_namespace_packages
)
which behaves similarly to find:
but works with namespace package. Before
diving in, it is important to have a good understanding of what namespace
packages are. Here is a quick recap:
Suppose you have two packages named as follows:
/Users/Desktop/timmins/foo/__init__.py
/Library/timmins/bar/__init__.py
If both Desktop
and Library
are on your PYTHONPATH
, then a
namespace package called timmins
will be created automatically for you when
you invoke the import mechanism, allowing you to accomplish the following
import timmins.foo
import timmins.bar
as if there is only one timmins
on your system. The two packages can then
be distributed separately and installed individually without affecting the
other one. Suppose you are packaging the foo
part:
foo/
src/
timmins/foo/__init__.py
setup.cfg # or setup.py
and you want the foo
to be automatically included, find:
won't work
because timmins doesn't contain __init__.py
directly, instead, you have
to use find_namespace:
:
[options]
package_dir =
=src
packages = find_namespace:
[options.packages.find]
where = src
When you install the zipped distribution, timmins.foo
would become
available to your interpreter.
You can think of find_namespace:
as identical to find:
except it
would count a directory as a package even if it doesn't contain __init__.py
file directly. As a result, this creates an interesting side effect. If you
organize your package like this:
foo/
timmins/
foo/__init__.py
setup.cfg # or setup.py
tests/
test_foo/__init__.py
a naive find_namespace:
would include tests as part of your package to
be installed. A simple way to fix it is to adopt the aforementioned
src
layout.
List of classifiers: https://pypi.org/pypi?%3Aaction=list_classifiers