I was just pondering on this question when working with a Python package. Let’s dive right in! 👇
The Python file
setup.py is pivotal for Python package creation, distribution, and management, ensuring that packages are easily installable and shareable within the Python community. In other words, it’s a script that contains information about a Python package and instructions on how to install it.
Here’s a concise guide to understanding and utilizing
What is the Purpose of setup.py?
The purpose of
setup.py is three-fold:
- Installation: It helps install a Python package so that it can be imported and utilized in other projects.
- Dependency Management: Manages and installs dependencies required by the package.
- Distribution: Assists in distributing the package to repositories like PyPi, making it accessible to others.
How to Use setup.py?
For example, to install a package named
foo, you might perform the following steps:
$ git clone https://github.com/user/foo $ cd foo $ python setup.py install
For development purposes, without installing, use:
$ python setup.py develop
This creates symlinks in
site-packages instead of copying files, making it faster and reflecting changes without reinstallation.
How to Create setup.py?
setup.py script might look like this:
from setuptools import setup setup( name='foo', version='1.0', description='A useful module', author='Man Foo', author_email='[email protected]', packages=['foo'], install_requires=['wheel', 'bar', 'greek'], )
name: The package name.
version: The package version.
description: A short description of the package.
author_email: Author information.
packages: List of all Python packages to be included.
install_requires: A list of dependencies that will be installed alongside the package.
For more complex package structures, you might need to include additional parameters like
scripts to specify additional scripts to be installed.
How to Make setup.py More Useful?
To make your
setup.py more informative and useful, consider adding more metadata:
with open("README", 'r') as f: long_description = f.read() setup( ... license="MIT", long_description=long_description, url="http://www.foopackage.example/", ... )
license: The license under which the package is available.
long_description: A detailed description, often from the README.
url: The URL for the package’s homepage.
How to Distribute Your Package?
Once your package is ready, you might want to distribute it via PyPi in two steps:
- Build distributions locally:
$ python setup.py sdist bdist_wheel
- Upload using
$ twine upload dist/*
Also consider using
test.pypi.org for testing before uploading to the real index.
- Ensure your package name is unique on PyPi to avoid conflicts.
- Consider using
twinefor secure uploads to PyPi.
- Explore PEP 517 and setuptools documentation for advanced packaging features or to simplify your packaging setup:
Let’s end this quick guide on a short Q&A on some questions I had and that I found are asked often in forums:
Q&A on Various
Q: How to install a Python package using
install to install the package.
python setup.py install
Q: How to create a source distribution of the package?
sdist to create a source distribution.
python setup.py sdist
Q: Can you provide a basic example of
from setuptools import setup setup( name='example_package', version='0.1', description='An example package', author='Author Name', packages=['example_package'], )
Q: How to specify dependencies in
install_requires to list dependencies.
setup( ... install_requires=['numpy', 'pandas'], ... )
Q: How to install a package in development mode?
develop to install in a way that reflects code changes without reinstallation.
python setup.py develop
Q: How to create a wheel distribution of the package?
bdist_wheel to create a
python setup.py bdist_wheel
Q: How to create a distribution with egg info?
egg_info to produce egg metadata.
python setup.py egg_info
Q: How to build the package?
build to compile and prepare the package.
python setup.py build
Q: How to uninstall a package installed with
setup.py doesn’t provide an
uninstall command. Use
pip to uninstall.
pip uninstall package_name
Q: How to build C extension modules?
build_ext to compile and build extension modules.
python setup.py build_ext
name: Specifies the name of the package.
version: Defines the version number of the package.
description: A short, one-line description of the package.
long_description: Provides a detailed description of the package.
long_description_content_type: Specifies the content type for the long description (e.g., text/markdown).
author_email: Indicates the email address of the package author.
maintainer: Names the current maintainer if different from the author.
maintainer_email: Specifies the email address of the current maintainer.
url: Provides the URL for the package homepage.
download_url: Indicates the URL to download the package.
packages: Lists the packages that
py_modules: Lists the modules that
scripts: Specifies the standalone script files to be built and installed.
ext_package: Specifies the base package name for the extensions provided by this package.
ext_modules: Provides a list of Python extensions to be built.
classifiers: Describes the categories for the package.
distclass: Specifies a subclass of Distribution to use.
script_name: Names the
setup.pyscript, defaulting to
script_args: Defines the arguments to supply to the setup script.
options: Provides the default options for the setup script.
license: Specifies the license of the package.
license_file: (Deprecated) Use
license_files: Lists glob patterns for license-related files to be included.
keywords: Provides descriptive meta-data using a list of strings or a comma-separated string.
platforms: Specifies the platforms using a list of strings or a comma-separated string.
cmdclass: Maps command names to
data_files: (Deprecated) Specifies the data files to install.
package_dir: Maps package names to directory paths.
requires: (Deprecated) Superseded by
obsoletes: Describes packages that this package renders obsolete.
provides: Describes package- and virtual package names contained within this package.
setuptoolsto automatically include any data files it finds inside your package directories.
exclude_package_data: Maps package names to lists of glob patterns to be excluded from your package directories.
package_data: Maps package names to lists of glob patterns.
zip_safe: A boolean flag specifying whether the project can be safely installed and run from a zip file.
install_requires: Specifies what other distributions need to be installed when this one is.
entry_points: Maps entry point group names to strings or lists of strings defining the entry points.
python_requires: Specifies a version specifier for the Python version.
setup_requires: (Discouraged) Specifies what other distributions need to be present for the setup script to run.
dependency_links: (Deprecated) Lists strings naming URLs to be searched when satisfying dependencies.
namespace_packages: (Deprecated) Lists strings naming the project’s “namespace packages”.
test_suite: (Deprecated) Names a
unittest.TestCasesubclass or a package or module containing one or more of them.
tests_require: (Deprecated) Specifies what other distributions need to be present for the package’s tests to run.
test_loader: (Deprecated) Specifies a module name and class name to find tests to run.
eager_resources: Lists strings naming resources that should be extracted together, if any of them is needed.
project_urls: Maps URL names to hyperlinks.
You can find all the keywords in the documentation.
While working as a researcher in distributed systems, Dr. Christian Mayer found his love for teaching computer science students.
To help students reach higher levels of Python success, he founded the programming education website Finxter.com that has taught exponential skills to millions of coders worldwide. He’s the author of the best-selling programming books Python One-Liners (NoStarch 2020), The Art of Clean Code (NoStarch 2022), and The Book of Dash (NoStarch 2022). Chris also coauthored the Coffee Break Python series of self-published books. He’s a computer science enthusiast, freelancer, and owner of one of the top 10 largest Python blogs worldwide.
His passions are writing, reading, and coding. But his greatest passion is to serve aspiring coders through Finxter and help them to boost their skills. You can join his free email academy here.