1========================== 2``setuptools`` Quickstart 3========================== 4 5Installation 6============ 7 8To install the latest version of setuptools, use:: 9 10 pip install --upgrade setuptools 11 12 13Python packaging at a glance 14============================ 15The landscape of Python packaging is shifting and ``Setuptools`` has evolved to 16only provide backend support, no longer being the de-facto packaging tool in 17the market. Every python package must provide a ``pyproject.toml`` and specify 18the backend (build system) it wants to use. The distribution can then 19be generated with whatever tool that provides a ``build sdist``-like 20functionality. While this may appear cumbersome, given the added pieces, 21it in fact tremendously enhances the portability of your package. The 22change is driven under :pep:`PEP 517 <517#build-requirements>`. To learn more about Python packaging in general, 23navigate to the :ref:`bottom <packaging-resources>` of this page. 24 25 26Basic Use 27========= 28For basic use of setuptools, you will need a ``pyproject.toml`` with the 29exact following info, which declares you want to use ``setuptools`` to 30package your project: 31 32.. code-block:: toml 33 34 [build-system] 35 requires = ["setuptools"] 36 build-backend = "setuptools.build_meta" 37 38Then, you will need to specify your package information such as metadata, 39contents, dependencies, etc. 40 41Setuptools currently supports configurations from either ``setup.cfg``, 42``setup.py`` or ``pyproject.toml`` [#experimental]_ files, however, configuring new 43projects via ``setup.py`` is discouraged [#setup.py]_. 44 45The following example demonstrates a minimum configuration: 46 47.. tab:: setup.cfg 48 49 .. code-block:: ini 50 51 [metadata] 52 name = mypackage 53 version = 0.0.1 54 55 [options] 56 packages = mypackage 57 install_requires = 58 requests 59 importlib-metadata; python_version < "3.8" 60 61 See :doc:`/userguide/declarative_config` for more information. 62 63.. tab:: setup.py [#setup.py]_ 64 65 .. code-block:: python 66 67 from setuptools import setup 68 69 setup( 70 name='mypackage', 71 version='0.0.1', 72 packages=['mypackage'], 73 install_requires=[ 74 'requests', 75 'importlib-metadata; python_version == "3.8"', 76 ], 77 ) 78 79 See :doc:`/references/keywords` for more information. 80 81.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 82 83 .. code-block:: toml 84 85 [project] 86 name = "mypackage" 87 version = "0.0.1" 88 dependencies = [ 89 "requests", 90 'importlib-metadata; python_version<"3.8"', 91 ] 92 93 See :doc:`/userguide/pyproject_config` for more information. 94 95This is what your project would look like:: 96 97 ~/mypackage/ 98 pyproject.toml 99 setup.cfg # or setup.py 100 mypackage/__init__.py 101 102Then, you need a builder, such as :std:doc:`PyPA build <pypa-build:index>` 103which you can obtain via ``pip install build``. After downloading it, invoke 104the builder:: 105 106 python -m build 107 108You now have your distribution ready (e.g. a ``tar.gz`` file and a ``.whl`` 109file in the ``dist`` directory), which you can upload to PyPI! 110 111Of course, before you release your project to PyPI, you'll want to add a bit 112more information to your setup script to help people find or learn about your 113project. And maybe your project will have grown by then to include a few 114dependencies, and perhaps some data files and scripts. In the next few sections, 115we will walk through the additional but essential information you need 116to specify to properly package your project. 117 118 119Automatic package discovery 120=========================== 121For simple projects, it's usually easy enough to manually add packages to 122the ``packages`` keyword in ``setup.cfg``. However, for very large projects, 123it can be a big burden to keep the package list updated. 124Therefore, ``setuptoops`` provides a convenient way to automatically list all 125the packages in your project directory: 126 127.. tab:: setup.cfg 128 129 .. code-block:: ini 130 131 [options] 132 packages = find: # OR `find_namespaces:` if you want to use namespaces 133 134 [options.packages.find] (always `find` even if `find_namespaces:` was used before) 135 # This section is optional 136 # Each entry in this section is optional, and if not specified, the default values are: 137 # `where=.`, `include=*` and `exclude=` (empty). 138 include=mypackage* 139 exclude=mypackage.tests* 140 141.. tab:: setup.py [#setup.py]_ 142 143 .. code-block:: python 144 145 from setuptools import find_packages # or find_namespace_packages 146 147 setup( 148 # ... 149 packages=find_packages( 150 where='.', 151 include=['mypackage*'], # ["*"] by default 152 exclude=['mypackage.tests'], # empty by default 153 ), 154 # ... 155 ) 156 157.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 158 159 .. code-block:: toml 160 161 # ... 162 [tool.setuptools.packages] 163 find = {} # Scan the project directory with the default parameters 164 165 # OR 166 [tool.setuptools.packages.find] 167 where = ["src"] # ["."] by default 168 include = ["mypackage*"] # ["*"] by default 169 exclude = ["mypackage.tests*"] # empty by default 170 namespaces = false # true by default 171 172When you pass the above information, alongside other necessary information, 173``setuptools`` walks through the directory specified in ``where`` (omitted 174here as the package resides in the current directory) and filters the packages 175it can find following the ``include`` (defaults to none), then removes 176those that match the ``exclude`` and returns a list of Python packages. The above 177setup also allows you to adopt a ``src/`` layout. For more details and advanced 178use, go to :ref:`package_discovery`. 179 180.. tip:: 181 Starting with version 61.0.0, setuptools' automatic discovery capabilities 182 have been improved to detect popular project layouts (such as the 183 :ref:`flat-layout` and :ref:`src-layout`) without requiring any 184 special configuration. Check out our :ref:`reference docs <package_discovery>` 185 for more information, but please keep in mind that this functionality is 186 still considered **experimental** and might change (or even be removed) in 187 future releases. 188 189 190Entry points and automatic script creation 191=========================================== 192Setuptools supports automatic creation of scripts upon installation, that runs 193code within your package if you specify them as :doc:`entry points 194<PyPUG:specifications/entry-points>`. 195This is what allows you to run commands like ``pip install`` instead of having 196to type ``python -m pip install``. 197The following configuration examples show how to accomplish this: 198 199.. tab:: setup.cfg 200 201 .. code-block:: ini 202 203 [options.entry_points] 204 console_scripts = 205 cli-name = mypkg.mymodule:some_func 206 207.. tab:: setup.py [#setup.py]_ 208 209 .. code-block:: python 210 211 setup( 212 # ... 213 entry_points={ 214 'console_scripts': [ 215 'cli-name = mypkg.mymodule:some_func', 216 ] 217 } 218 ) 219 220.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 221 222 .. code-block:: toml 223 224 [project.scripts] 225 cli-name = mypkg.mymodule:some_func 226 227When this project is installed, a ``cli-name`` executable will be created. 228``cli-name`` will invoke the function ``some_func`` in the 229``mypkg/mymodule.py`` file when called by the user. 230Note that you can also use the ``entry-points`` mechanism to advertise 231components between installed packages and implement plugin systems. 232For detailed usage, go to :doc:`entry_point`. 233 234 235Dependency management 236===================== 237Packages built with ``setuptools`` can specify dependencies to be automatically 238installed when the package itself is installed. 239The example below show how to configure this kind of dependencies: 240 241.. tab:: setup.cfg 242 243 .. code-block:: ini 244 245 [options] 246 install_requires = 247 docutils 248 requests <= 0.4 249 250.. tab:: setup.py [#setup.py]_ 251 252 .. code-block:: python 253 254 setup( 255 # ... 256 install_requires=["docutils", "requests <= 0.4"], 257 # ... 258 ) 259 260.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 261 262 .. code-block:: toml 263 264 [project] 265 # ... 266 dependencies = [ 267 "docutils", 268 "requires <= 0.4", 269 ] 270 # ... 271 272Each dependency is represented by a string that can optionally contain version requirements 273(e.g. one of the operators <, >, <=, >=, == or !=, followed by a version identifier), 274and/or conditional environment markers, e.g. ``sys_platform == "win32"`` 275(see :doc:`PyPUG:specifications/version-specifiers` for more information). 276 277When your project is installed, all of the dependencies not already installed 278will be located (via PyPI), downloaded, built (if necessary), and installed. 279This, of course, is a simplified scenario. You can also specify groups of 280extra dependencies that are not strictly required by your package to work, but 281that will provide additional functionalities. 282For more advanced use, see :doc:`dependency_management`. 283 284 285.. _Including Data Files: 286 287Including Data Files 288==================== 289The distutils have traditionally allowed installation of "data files", which 290are placed in a platform-specific location. Setuptools offers three ways to 291specify data files to be included in your packages. For the simplest use, you 292can simply use the ``include_package_data`` keyword: 293 294.. tab:: setup.cfg 295 296 .. code-block:: ini 297 298 [options] 299 include_package_data = True 300 301.. tab:: setup.py [#setup.py]_ 302 303 .. code-block:: python 304 305 setup( 306 # ... 307 include_package_data=True, 308 # ... 309 ) 310 311.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 312 313 .. code-block:: toml 314 315 [tool.setuptools] 316 include-package-data = true 317 # This is already the default behaviour if your are using 318 # pyproject.toml to configure your build. 319 # You can deactivate that with `include-package-data = false` 320 321This tells setuptools to install any data files it finds in your packages. 322The data files must be specified via the distutils' |MANIFEST.in|_ file 323or automatically added by a :ref:`Revision Control System plugin 324<Adding Support for Revision Control Systems>`. 325For more details, see :doc:`datafiles`. 326 327 328Development mode 329================ 330 331``setuptools`` allows you to install a package without copying any files 332to your interpreter directory (e.g. the ``site-packages`` directory). 333This allows you to modify your source code and have the changes take 334effect without you having to rebuild and reinstall. 335Here's how to do it:: 336 337 pip install --editable . 338 339This creates a link file in your interpreter site package directory which 340associate with your source code. For more information, see :doc:`development_mode`. 341 342.. tip:: 343 344 Prior to :ref:`pip v21.1 <pip:v21-1>`, a ``setup.py`` script was 345 required to be compatible with development mode. With late 346 versions of pip, ``setup.cfg``-only projects may be installed in this mode. 347 348 If you are experimenting with :doc:`configuration using <pyproject_config>`, 349 or have version of ``pip`` older than v21.1, you might need to keep a 350 ``setup.py`` file in file in your repository if you want to use editable 351 installs (for the time being). 352 353 A simple script will suffice, for example: 354 355 .. code-block:: python 356 357 from setuptools import setup 358 359 setup() 360 361 You can still keep all the configuration in :doc:`setup.cfg </userguide/declarative_config>` 362 (or :doc:`pyproject.toml </userguide/pyproject_config>`). 363 364 365Uploading your package to PyPI 366============================== 367After generating the distribution files, the next step would be to upload your 368distribution so others can use it. This functionality is provided by 369:pypi:`twine` and is documented in the :doc:`Python packaging tutorial 370<PyPUG:tutorials/packaging-projects>`. 371 372 373Transitioning from ``setup.py`` to ``setup.cfg`` 374================================================ 375To avoid executing arbitrary scripts and boilerplate code, we are transitioning 376into a full-fledged ``setup.cfg`` to declare your package information instead 377of running ``setup()``. This inevitably brings challenges due to a different 378syntax. :doc:`Here </userguide/declarative_config>` we provide a quick guide to 379understanding how ``setup.cfg`` is parsed by ``setuptools`` to ease the pain of 380transition. 381 382.. _packaging-resources: 383 384Resources on Python packaging 385============================= 386Packaging in Python can be hard and is constantly evolving. 387`Python Packaging User Guide <https://packaging.python.org>`_ has tutorials and 388up-to-date references that can help you when it is time to distribute your work. 389 390 391.. |MANIFEST.in| replace:: ``MANIFEST.in`` 392.. _MANIFEST.in: https://packaging.python.org/en/latest/guides/using-manifest-in/ 393 394 395---- 396 397.. rubric:: Notes 398 399.. [#setup.py] 400 The ``setup.py`` file should be used only when custom scripting during the 401 build is necessary. 402 Examples are kept in this document to help people interested in maintaining or 403 contributing to existing packages that use ``setup.py``. 404 Note that you can still keep most of configuration declarative in 405 :doc:`setup.cfg <declarative_config>` or :doc:`pyproject.toml 406 <pyproject_config>` and use ``setup.py`` only for the parts not 407 supported in those files (e.g. C extensions). 408 409.. [#experimental] 410 While the ``[build-system]`` table should always be specified in the 411 ``pyproject.toml`` file, support for adding package metadata and build configuration 412 options via the ``[project]`` and ``[tool.setuptools]`` tables is still 413 experimental and might change (or be completely removed) in future releases. 414 See :doc:`/userguide/pyproject_config`. 415