[python] What is setup.py?

Can anyone please explain what setup.py is and how it can be configured or used?

This question is related to python python-3.x setup.py pypi python-packaging

The answer is


It helps to install a python package foo on your machine (can also be in virtualenv) so that you can import the package foo from other projects and also from [I]Python prompts.

It does the similar job of pip, easy_install etc.,


Using setup.py

Let's start with some definitions:

Package - A folder/directory that contains __init__.py file.
Module - A valid python file with .py extension.
Distribution - How one package relates to other packages and modules.

Let's say you want to install a package named foo. Then you do,

$ git clone https://github.com/user/foo  
$ cd foo
$ python setup.py install

Instead, if you don't want to actually install it but still would like to use it. Then do,

$ python setup.py develop  

This command will create symlinks to the source directory within site-packages instead of copying things. Because of this, it is quite fast (particularly for large packages).


Creating setup.py

If you have your package tree like,

foo
+-- foo
¦   +-- data_struct.py
¦   +-- __init__.py
¦   +-- internals.py
+-- README
+-- requirements.txt
+-- setup.py

Then, you do the following in your setup.py script so that it can be installed on some machine:

from setuptools import setup

setup(
   name='foo',
   version='1.0',
   description='A useful module',
   author='Man Foo',
   author_email='[email protected]',
   packages=['foo'],  #same as name
   install_requires=['bar', 'greek'], #external packages as dependencies
)

Instead, if your package tree is more complex like the one below:

foo
+-- foo
¦   +-- data_struct.py
¦   +-- __init__.py
¦   +-- internals.py
+-- README
+-- requirements.txt
+-- scripts
¦   +-- cool
¦   +-- skype
+-- setup.py

Then, your setup.py in this case would be like:

from setuptools import setup

setup(
   name='foo',
   version='1.0',
   description='A useful module',
   author='Man Foo',
   author_email='[email protected]',
   packages=['foo'],  #same as name
   install_requires=['bar', 'greek'], #external packages as dependencies
   scripts=[
            'scripts/cool',
            'scripts/skype',
           ]
)

Add more stuff to (setup.py) & make it decent:

from setuptools import setup

with open("README", 'r') as f:
    long_description = f.read()

setup(
   name='foo',
   version='1.0',
   description='A useful module',
   license="MIT",
   long_description=long_description,
   author='Man Foo',
   author_email='[email protected]',
   url="http://www.foopackage.com/",
   packages=['foo'],  #same as name
   install_requires=['bar', 'greek'], #external packages as dependencies
   scripts=[
            'scripts/cool',
            'scripts/skype',
           ]
)

The long_description is used in pypi.org as the README description of your package.


And finally, you're now ready to upload your package to PyPi.org so that others can install your package using pip install yourpackage.

First step is to claim your package name & space in pypi using:

$ python setup.py register

Once your package name is registered, nobody can claim or use it. After successful registration, you have to upload your package there (to the cloud) by,

$ python setup.py upload

Optionally, you can also sign your package with GPG by,

$ python setup.py --sign upload

Bonus Reading:


To make it simple, setup.py is run as "__main__" when you call the install functions the other answers mentioned. Inside setup.py, you should put everything needed to install your package.

Common setup.py functions

The following two sections discuss two things many setup.py modules have.

setuptools.setup

This function allows you to specify project attributes like the name of the project, the version.... Most importantly, this function allows you to install other functions if they're packaged properly. See this webpage for an example of setuptools.setup

These attributes of setuptools.setup enable installing these types of packages:

  • Packages that are imported to your project and listed in PyPI using setuptools.findpackages:

    packages=find_packages(exclude=["docs","tests", ".gitignore", "README.rst","DESCRIPTION.rst"])

  • Packages not in PyPI, but can be downloaded from a URL using dependency_links

    dependency_links=["http://peak.telecommunity.com/snapshots/",]

Custom functions

In an ideal world, setuptools.setup would handle everything for you. Unfortunately this isn't always the case. Sometimes you have to do specific things, like installing dependencies with the subprocess command, to get the system you're installing on in the right state for your package. Try to avoid this, these functions get confusing and often differ between OS and even distribution.


setup.py is Python's answer to a multi-platform installer and make file.

If you’re familiar with command line installations, then make && make install translates to python setup.py build && python setup.py install.

Some packages are pure Python, and are only byte compiled. Others may contain native code, which will require a native compiler (like gcc or cl) and a Python interfacing module (like swig or pyrex).


If you downloaded package that has "setup.py" in root folder, you can install it by running

python setup.py install

If you are developing a project and are wondering what this file is useful for, check Python documentation on writing the Setup Script


setup.py is a Python file like any other. It can take any name, except by convention it is named setup.py so that there is not a different procedure with each script.

Most frequently setup.py is used to install a Python module but server other purposes:

Modules:

Perhaps this is most famous usage of setup.py is in modules. Although they can be installed using pip, old Python versions did not include pip by default and they needed to be installed separately.

If you wanted to install a module but did not want to install pip, just about the only alternative was to install the module from setup.py file. This could be achieved via python setup.py install. This would install the Python module to the root dictionary (without pip, easy_install ect).

This method is often used when pip will fail. For example if the correct Python version of the desired package is not available via pipperhaps because it is no longer maintained, , downloading the source and running python setup.py install would perform the same thing, except in the case of compiled binaries are required, (but will disregard the Python version -unless an error is returned).

Another use of setup.py is to install a package from source. If a module is still under development the wheel files will not be available and the only way to install is to install from the source directly.

Building Python extensions:

When a module has been built it can be converted into module ready for distribution using a distutils setup script. Once built these can be installed using the command above.

A setup script is easy to build and once the file has been properly configured and can be compiled by running python setup.py build (see link for all commands).

Once again it is named setup.py for ease of use and by convention, but can take any name.

Cython:

Another famous use of setup.py files include compiled extensions. These require a setup script with user defined values. They allow fast (but once compiled are platform dependant) execution. Here is a simple example from the documentation:

from distutils.core import setup
from Cython.Build import cythonize

setup(
    name = 'Hello world app',
    ext_modules = cythonize("hello.pyx"),
)

This can be compiled via python setup.py build

Cx_Freeze:

Another module requiring a setup script is cx_Freeze. This converts Python script to executables. This allows many commands such as descriptions, names, icons, packages to include, exclude ect and once run will produce a distributable application. An example from the documentation:

import sys
from cx_Freeze import setup, Executable
build_exe_options = {"packages": ["os"], "excludes": ["tkinter"]} 

base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(  name = "guifoo",
        version = "0.1",
        description = "My GUI application!",
        options = {"build_exe": build_exe_options},
        executables = [Executable("guifoo.py", base=base)])

This can be compiled via python setup.py build.

So what is a setup.py file?

Quite simply it is a script that builds or configures something in the Python environment.

A package when distributed should contain only one setup script but it is not uncommon to combine several together into a single setup script. Notice this often involves distutils but not always (as I showed in my last example). The thing to remember it just configures Python package/script in some way.

It takes the name so the same command can always be used when building or installing.


When you download a package with setup.py open your Terminal (Mac,Linux) or Command Prompt (Windows). Using cd and helping you with Tab button set the path right to the folder where you have downloaded the file and where there is setup.py :

iMac:~ user $ cd path/pakagefolderwithsetupfile/

Press enter, you should see something like this:

iMac:pakagefolderwithsetupfile user$

Then type after this python setup.py install :

iMac:pakagefolderwithsetupfile user$ python setup.py install

Press enter. Done!


setup.py can be used in two scenarios , First, you want to install a Python package. Second, you want to create your own Python package. Usually standard Python package has couple of important files like setup.py, setup.cfg and Manifest.in. When you are creating the Python package, these three files will determine the (content in PKG-INFO under egg-info folder) name, version, description, other required installations (usually in .txt file) and few other parameters. setup.cfg is read by setup.py while package is created (could be tar.gz ). Manifest.in is where you can define what should be included in your package. Anyways you can do bunch of stuff using setup.py like

python setup.py build
python setup.py install
python setup.py sdist <distname> upload [-r urltorepo]  (to upload package to pypi or local repo)

There are bunch of other commands which could be used with setup.py . for help

python setup.py --help-commands

To install a Python package you've downloaded, you extract the archive and run the setup.py script inside:

python setup.py install

To me, this has always felt odd. It would be more natural to point a package manager at the download, as one would do in Ruby and Nodejs, eg. gem install rails-4.1.1.gem

A package manager is more comfortable too, because it's familiar and reliable. On the other hand, each setup.py is novel, because it's specific to the package. It demands faith in convention "I trust this setup.py takes the same commands as others I have used in the past". That's a regrettable tax on mental willpower.

I'm not saying the setup.py workflow is less secure than a package manager (I understand Pip just runs the setup.py inside), but certainly I feel it's awkard and jarring. There's a harmony to commands all being to the same package manager application. You might even grow fond it.


setup.py is a Python script that is usually shipped with libraries or programs, written in that language. It's purpose is the correct installation of the software.

Many packages use the distutils framework in conjuction with setup.py.

http://docs.python.org/distutils/


Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to python-3.x

Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation Replace specific text with a redacted version using Python Upgrade to python 3.8 using conda "Permission Denied" trying to run Python on Windows 10 Python: 'ModuleNotFoundError' when trying to import module from imported package What is the meaning of "Failed building wheel for X" in pip install? How to downgrade python from 3.7 to 3.6 I can't install pyaudio on Windows? How to solve "error: Microsoft Visual C++ 14.0 is required."? Iterating over arrays in Python 3 How to upgrade Python version to 3.7?

Examples related to setup.py

How do I install Python packages in Google's Colab? Why is python setup.py saying invalid command 'bdist_wheel' on Travis CI? No module named setuptools Python 3: ImportError "No Module named Setuptools" error: Unable to find vcvarsall.bat python setup.py uninstall What is setup.py?

Examples related to pypi

'pip install' fails for every package ("Could not find a version that satisfies the requirement") Why is python setup.py saying invalid command 'bdist_wheel' on Travis CI? Installing python module within code pypi UserWarning: Unknown distribution option: 'install_requires' Find all packages installed with easy_install/pip? Installing specific package versions with pip Why use pip over easy_install? python setup.py uninstall What is setup.py?

Examples related to python-packaging

How to import other Python files? What is setup.py? What is __init__.py for?