blob: 5be1078a6480a60e530a36d57fd5a9f8e61745df [file] [log] [blame]
Dan Willemsenadad21e2022-03-25 17:22:05 -07001==========================
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`.