What is setup.py?

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 setup.py:

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?

A basic 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 and 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 to PyPi:
  $ twine upload dist/*

Also consider using test.pypi.org for testing before uploading to the real index.

Some tips:

  • Ensure your package name is unique on PyPi to avoid conflicts.
  • Consider using twine for 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 setup.py Commands

Q: How to install a Python package using setup.py?
A: Use install to install the package.

python setup.py install

Q: How to create a source distribution of the package?
A: Use sdist to create a source distribution.

python setup.py sdist

Q: Can you provide a basic example of setup.py?
A:

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 setup.py?
A: Use install_requires to list dependencies.

setup(
    ...
    install_requires=['numpy', 'pandas'],
    ...
)

Q: How to install a package in development mode?
A: Use 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?
A: Use bdist_wheel to create a .whl file.

python setup.py bdist_wheel

Q: How to create a distribution with egg info?
A: Use egg_info to produce egg metadata.

python setup.py egg_info

Q: How to build the package?
A: Use build to compile and prepare the package.

python setup.py build

Q: How to uninstall a package installed with setup.py?
A: setup.py doesn’t provide an uninstall command. Use pip to uninstall.

pip uninstall package_name

Q: How to build C extension modules?
A: Use build_ext to compile and build extension modules.

python setup.py build_ext

Setup.py Keywords

  1. name: Specifies the name of the package.
  2. version: Defines the version number of the package.
  3. description: A short, one-line description of the package.
  4. long_description: Provides a detailed description of the package.
  5. long_description_content_type: Specifies the content type for the long description (e.g., text/markdown).
  6. author_email: Indicates the email address of the package author.
  7. maintainer: Names the current maintainer if different from the author.
  8. maintainer_email: Specifies the email address of the current maintainer.
  9. url: Provides the URL for the package homepage.
  10. download_url: Indicates the URL to download the package.
  11. packages: Lists the packages that setuptools will manipulate.
  12. py_modules: Lists the modules that setuptools will manipulate.
  13. scripts: Specifies the standalone script files to be built and installed.
  14. ext_package: Specifies the base package name for the extensions provided by this package.
  15. ext_modules: Provides a list of Python extensions to be built.
  16. classifiers: Describes the categories for the package.
  17. distclass: Specifies a subclass of Distribution to use.
  18. script_name: Names the setup.py script, defaulting to sys.argv[0].
  19. script_args: Defines the arguments to supply to the setup script.
  20. options: Provides the default options for the setup script.
  21. license: Specifies the license of the package.
  22. license_file: (Deprecated) Use license_files instead.
  23. license_files: Lists glob patterns for license-related files to be included.
  24. keywords: Provides descriptive meta-data using a list of strings or a comma-separated string.
  25. platforms: Specifies the platforms using a list of strings or a comma-separated string.
  26. cmdclass: Maps command names to Command subclasses.
  27. data_files: (Deprecated) Specifies the data files to install.
  28. package_dir: Maps package names to directory paths.
  29. requires: (Deprecated) Superseded by install_requires.
  30. obsoletes: Describes packages that this package renders obsolete.
  31. provides: Describes package- and virtual package names contained within this package.
  32. include_package_data: Tells setuptools to automatically include any data files it finds inside your package directories.
  33. exclude_package_data: Maps package names to lists of glob patterns to be excluded from your package directories.
  34. package_data: Maps package names to lists of glob patterns.
  35. zip_safe: A boolean flag specifying whether the project can be safely installed and run from a zip file.
  36. install_requires: Specifies what other distributions need to be installed when this one is.
  37. entry_points: Maps entry point group names to strings or lists of strings defining the entry points.
  38. python_requires: Specifies a version specifier for the Python version.
  39. setup_requires: (Discouraged) Specifies what other distributions need to be present for the setup script to run.
  40. dependency_links: (Deprecated) Lists strings naming URLs to be searched when satisfying dependencies.
  41. namespace_packages: (Deprecated) Lists strings naming the project’s “namespace packages”.
  42. test_suite: (Deprecated) Names a unittest.TestCase subclass or a package or module containing one or more of them.
  43. tests_require: (Deprecated) Specifies what other distributions need to be present for the package’s tests to run.
  44. test_loader: (Deprecated) Specifies a module name and class name to find tests to run.
  45. eager_resources: Lists strings naming resources that should be extracted together, if any of them is needed.
  46. project_urls: Maps URL names to hyperlinks.

You can find all the keywords in the documentation.