1===================================== 2Dependencies Management in Setuptools 3===================================== 4 5There are three types of dependency styles offered by setuptools: 61) build system requirement, 2) required dependency and 3) optional 7dependency. 8 9.. Note:: 10 Packages that are added to dependency can be optionally specified with the 11 version by following `PEP 440 <https://www.python.org/dev/peps/pep-0440/>`_ 12 13 14Build system requirement 15======================== 16 17Package requirement 18------------------- 19After organizing all the scripts and files and getting ready for packaging, 20there needs to be a way to tell Python what programs it needs to actually 21do the packaging (in our case, ``setuptools`` of course). Usually, 22you also need the ``wheel`` package as well since it is recommended that you 23upload a ``.whl`` file to PyPI alongside your ``.tar.gz`` file. Unlike the 24other two types of dependency keyword, this one is specified in your 25``pyproject.toml`` file (if you have forgot what this is, go to 26:doc:`quickstart` or (WIP)): 27 28.. code-block:: ini 29 30 [build-system] 31 requires = ["setuptools"] 32 #... 33 34.. note:: 35 This used to be accomplished with the ``setup_requires`` keyword but is 36 now considered deprecated in favor of the PEP 517 style described above. 37 To peek into how this legacy keyword is used, consult our :doc:`guide on 38 deprecated practice (WIP) <../deprecated/index>` 39 40 41.. _Declaring Dependencies: 42 43Declaring required dependency 44============================= 45This is where a package declares its core dependencies, without which it won't 46be able to run. ``setuptools`` support automatically download and install 47these dependencies when the package is installed. Although there is more 48finesse to it, let's start with a simple example. 49 50.. tab:: setup.cfg 51 52 .. code-block:: ini 53 54 [options] 55 #... 56 install_requires = 57 docutils 58 BazSpam ==1.1 59 60.. tab:: setup.py 61 62 .. code-block:: python 63 64 setup( 65 ..., 66 install_requires=[ 67 'docutils', 68 'BazSpam ==1.1', 69 ], 70 ) 71 72.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 73 74 .. code-block:: toml 75 76 [project] 77 # ... 78 dependencies = [ 79 "docutils", 80 "BazSpam == 1.1", 81 ] 82 # ... 83 84 85When your project is installed (e.g. using pip), all of the dependencies not 86already installed will be located (via PyPI), downloaded, built (if necessary), 87and installed and 2) Any scripts in your project will be installed with wrappers 88that verify the availability of the specified dependencies at runtime. 89 90 91Platform specific dependencies 92------------------------------ 93Setuptools offer the capability to evaluate certain conditions before blindly 94installing everything listed in ``install_requires``. This is great for platform 95specific dependencies. For example, the ``enum`` package was added in Python 963.4, therefore, package that depends on it can elect to install it only when 97the Python version is older than 3.4. To accomplish this 98 99.. tab:: setup.cfg 100 101 .. code-block:: ini 102 103 [options] 104 #... 105 install_requires = 106 enum34;python_version<'3.4' 107 108.. tab:: setup.py 109 110 .. code-block:: python 111 112 setup( 113 ..., 114 install_requires=[ 115 "enum34;python_version<'3.4'", 116 ], 117 ) 118 119.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 120 121 .. code-block:: toml 122 123 [project] 124 # ... 125 dependencies = [ 126 "enum34; python_version<'3.4'", 127 ] 128 # ... 129 130Similarly, if you also wish to declare ``pywin32`` with a minimal version of 1.0 131and only install it if the user is using a Windows operating system: 132 133.. tab:: setup.cfg 134 135 .. code-block:: ini 136 137 [options] 138 #... 139 install_requires = 140 enum34;python_version<'3.4' 141 pywin32 >= 1.0;platform_system=='Windows' 142 143.. tab:: setup.py 144 145 .. code-block:: python 146 147 setup( 148 ..., 149 install_requires=[ 150 "enum34;python_version<'3.4'", 151 "pywin32 >= 1.0;platform_system=='Windows'", 152 ], 153 ) 154 155.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 156 157 .. code-block:: toml 158 159 [project] 160 # ... 161 dependencies = [ 162 "enum34; python_version<'3.4'", 163 "pywin32 >= 1.0; platform_system=='Windows'", 164 ] 165 # ... 166 167The environmental markers that may be used for testing platform types are 168detailed in `PEP 508 <https://www.python.org/dev/peps/pep-0508/>`_. 169 170 171Dependencies that aren't in PyPI 172-------------------------------- 173.. warning:: 174 Dependency links support has been dropped by pip starting with version 175 19.0 (released 2019-01-22). 176 177If your project depends on packages that don't exist on PyPI, you may still be 178able to depend on them, as long as they are available for download as: 179 180- an egg, in the standard distutils ``sdist`` format, 181- a single ``.py`` file, or 182- a VCS repository (Subversion, Mercurial, or Git). 183 184You just need to add some URLs to the ``dependency_links`` argument to 185``setup()``. 186 187The URLs must be either: 188 1891. direct download URLs, 1902. the URLs of web pages that contain direct download links, or 1913. the repository's URL 192 193In general, it's better to link to web pages, because it is usually less 194complex to update a web page than to release a new version of your project. 195You can also use a SourceForge ``showfiles.php`` link in the case where a 196package you depend on is distributed via SourceForge. 197 198If you depend on a package that's distributed as a single ``.py`` file, you 199must include an ``"#egg=project-version"`` suffix to the URL, to give a project 200name and version number. (Be sure to escape any dashes in the name or version 201by replacing them with underscores.) EasyInstall will recognize this suffix 202and automatically create a trivial ``setup.py`` to wrap the single ``.py`` file 203as an egg. 204 205In the case of a VCS checkout, you should also append ``#egg=project-version`` 206in order to identify for what package that checkout should be used. You can 207append ``@REV`` to the URL's path (before the fragment) to specify a revision. 208Additionally, you can also force the VCS being used by prepending the URL with 209a certain prefix. Currently available are: 210 211- ``svn+URL`` for Subversion, 212- ``git+URL`` for Git, and 213- ``hg+URL`` for Mercurial 214 215A more complete example would be: 216 217 ``vcs+proto://host/path@revision#egg=project-version`` 218 219Be careful with the version. It should match the one inside the project files. 220If you want to disregard the version, you have to omit it both in the 221``requires`` and in the URL's fragment. 222 223This will do a checkout (or a clone, in Git and Mercurial parlance) to a 224temporary folder and run ``setup.py bdist_egg``. 225 226The ``dependency_links`` option takes the form of a list of URL strings. For 227example, this will cause a search of the specified page for eggs or source 228distributions, if the package's dependencies aren't already installed: 229 230.. tab:: setup.cfg 231 232 .. code-block:: ini 233 234 [options] 235 #... 236 dependency_links = http://peak.telecommunity.com/snapshots/ 237 238.. tab:: setup.py 239 240 .. code-block:: python 241 242 setup( 243 ..., 244 dependency_links=[ 245 "http://peak.telecommunity.com/snapshots/", 246 ], 247 ) 248 249 250Optional dependencies 251===================== 252Setuptools allows you to declare dependencies that only get installed under 253specific circumstances. These dependencies are specified with ``extras_require`` 254keyword and are only installed if another package depends on it (either 255directly or indirectly) This makes it convenient to declare dependencies for 256ancillary functions such as "tests" and "docs". 257 258.. note:: 259 ``tests_require`` is now deprecated 260 261For example, Package-A offers optional PDF support and requires two other 262dependencies for it to work: 263 264.. tab:: setup.cfg 265 266 .. code-block:: ini 267 268 [metadata] 269 name = Package-A 270 271 [options.extras_require] 272 PDF = ReportLab>=1.2; RXP 273 274 275.. tab:: setup.py 276 277 .. code-block:: python 278 279 setup( 280 name="Project-A", 281 ..., 282 extras_require={ 283 "PDF": ["ReportLab>=1.2", "RXP"], 284 }, 285 ) 286 287.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 288 289 .. code-block:: toml 290 291 # ... 292 [project.optional-dependencies] 293 PDF = ["ReportLab>=1.2", "RXP"] 294 295The name ``PDF`` is an arbitrary identifier of such a list of dependencies, to 296which other components can refer and have them installed. 297 298A use case for this approach is that other package can use this "extra" for their 299own dependencies. For example, if "Project-B" needs "project A" with PDF support 300installed, it might declare the dependency like this: 301 302.. tab:: setup.cfg 303 304 .. code-block:: ini 305 306 [metadata] 307 name = Project-B 308 #... 309 310 [options] 311 #... 312 install_requires = 313 Project-A[PDF] 314 315.. tab:: setup.py 316 317 .. code-block:: python 318 319 setup( 320 name="Project-B", 321 install_requires=["Project-A[PDF]"], 322 ..., 323 ) 324 325.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 326 327 .. code-block:: toml 328 329 [project] 330 name = "Project-B" 331 # ... 332 dependencies = [ 333 "Project-A[PDF]" 334 ] 335 336This will cause ReportLab to be installed along with project A, if project B is 337installed -- even if project A was already installed. In this way, a project 338can encapsulate groups of optional "downstream dependencies" under a feature 339name, so that packages that depend on it don't have to know what the downstream 340dependencies are. If a later version of Project A builds in PDF support and 341no longer needs ReportLab, or if it ends up needing other dependencies besides 342ReportLab in order to provide PDF support, Project B's setup information does 343not need to change, but the right packages will still be installed if needed. 344 345.. note:: 346 Best practice: if a project ends up no longer needing any other packages to 347 support a feature, it should keep an empty requirements list for that feature 348 in its ``extras_require`` argument, so that packages depending on that feature 349 don't break (due to an invalid feature name). 350 351Historically ``setuptools`` also used to support extra dependencies in console 352scripts, for example: 353 354.. tab:: setup.cfg 355 356 .. code-block:: ini 357 358 [metadata] 359 name = Project A 360 #... 361 362 [options] 363 #... 364 entry_points= 365 [console_scripts] 366 rst2pdf = project_a.tools.pdfgen [PDF] 367 rst2html = project_a.tools.htmlgen 368 369.. tab:: setup.py 370 371 .. code-block:: python 372 373 setup( 374 name="Project-A", 375 ..., 376 entry_points={ 377 "console_scripts": [ 378 "rst2pdf = project_a.tools.pdfgen [PDF]", 379 "rst2html = project_a.tools.htmlgen", 380 ], 381 }, 382 ) 383 384This syntax indicates that the entry point (in this case a console script) 385is only valid when the PDF extra is installed. It is up to the installer 386to determine how to handle the situation where PDF was not indicated 387(e.g. omit the console script, provide a warning when attempting to load 388the entry point, assume the extras are present and let the implementation 389fail later). 390 391.. warning:: 392 ``pip`` and other tools might not support this use case for extra 393 dependencies, therefore this practice is considered **deprecated**. 394 See :doc:`PyPUG:specifications/entry-points`. 395 396 397Python requirement 398================== 399In some cases, you might need to specify the minimum required python version. 400This can be configured as shown in the example below. 401 402.. tab:: setup.cfg 403 404 .. code-block:: ini 405 406 [metadata] 407 name = Project-B 408 #... 409 410 [options] 411 #... 412 python_requires = >=3.6 413 414.. tab:: setup.py 415 416 .. code-block:: python 417 418 setup( 419 name="Project-B", 420 python_requires=">=3.6", 421 ..., 422 ) 423 424 425.. tab:: pyproject.toml (**EXPERIMENTAL**) [#experimental]_ 426 427 .. code-block:: toml 428 429 [project] 430 name = "Project-B" 431 requires-python = ">=3.6" 432 # ... 433 434---- 435 436.. rubric:: Notes 437 438.. [#experimental] 439 While the ``[build-system]`` table should always be specified in the 440 ``pyproject.toml`` file, support for adding package metadata and build configuration 441 options via the ``[project]`` and ``[tool.setuptools]`` tables is still 442 experimental and might change (or be completely removed) in future releases. 443 See :doc:`/userguide/pyproject_config`. 444