1.. _distutils_examples:
2
3******************
4Distutils Examples
5******************
6
7.. include:: ./_setuptools_disclaimer.rst
8
9This chapter provides a number of basic examples to help get started with
10distutils.  Additional information about using distutils can be found in the
11Distutils Cookbook.
12
13
14.. seealso::
15
16   `Distutils Cookbook <https://wiki.python.org/moin/Distutils/Cookbook>`_
17      Collection of recipes showing how to achieve more control over distutils.
18
19
20.. _pure-mod:
21
22Pure Python distribution (by module)
23====================================
24
25If you're just distributing a couple of modules, especially if they don't live
26in a particular package, you can specify them individually using the
27``py_modules`` option in the setup script.
28
29In the simplest case, you'll have two files to worry about: a setup script and
30the single module you're distributing, :file:`foo.py` in this example::
31
32   <root>/
33           setup.py
34           foo.py
35
36(In all diagrams in this section, *<root>* will refer to the distribution root
37directory.)  A minimal setup script to describe this situation would be::
38
39   from distutils.core import setup
40   setup(name='foo',
41         version='1.0',
42         py_modules=['foo'],
43         )
44
45Note that the name of the distribution is specified independently with the
46``name`` option, and there's no rule that says it has to be the same as
47the name of the sole module in the distribution (although that's probably a good
48convention to follow).  However, the distribution name is used to generate
49filenames, so you should stick to letters, digits, underscores, and hyphens.
50
51Since ``py_modules`` is a list, you can of course specify multiple
52modules, eg. if you're distributing modules :mod:`foo` and :mod:`bar`, your
53setup might look like this::
54
55   <root>/
56           setup.py
57           foo.py
58           bar.py
59
60and the setup script might be  ::
61
62   from distutils.core import setup
63   setup(name='foobar',
64         version='1.0',
65         py_modules=['foo', 'bar'],
66         )
67
68You can put module source files into another directory, but if you have enough
69modules to do that, it's probably easier to specify modules by package rather
70than listing them individually.
71
72
73.. _pure-pkg:
74
75Pure Python distribution (by package)
76=====================================
77
78If you have more than a couple of modules to distribute, especially if they are
79in multiple packages, it's probably easier to specify whole packages rather than
80individual modules.  This works even if your modules are not in a package; you
81can just tell the Distutils to process modules from the root package, and that
82works the same as any other package (except that you don't have to have an
83:file:`__init__.py` file).
84
85The setup script from the last example could also be written as  ::
86
87   from distutils.core import setup
88   setup(name='foobar',
89         version='1.0',
90         packages=[''],
91         )
92
93(The empty string stands for the root package.)
94
95If those two files are moved into a subdirectory, but remain in the root
96package, e.g.::
97
98   <root>/
99           setup.py
100           src/      foo.py
101                     bar.py
102
103then you would still specify the root package, but you have to tell the
104Distutils where source files in the root package live::
105
106   from distutils.core import setup
107   setup(name='foobar',
108         version='1.0',
109         package_dir={'': 'src'},
110         packages=[''],
111         )
112
113More typically, though, you will want to distribute multiple modules in the same
114package (or in sub-packages).  For example, if the :mod:`foo`  and :mod:`bar`
115modules belong in package :mod:`foobar`, one way to layout your source tree is
116::
117
118   <root>/
119           setup.py
120           foobar/
121                    __init__.py
122                    foo.py
123                    bar.py
124
125This is in fact the default layout expected by the Distutils, and the one that
126requires the least work to describe in your setup script::
127
128   from distutils.core import setup
129   setup(name='foobar',
130         version='1.0',
131         packages=['foobar'],
132         )
133
134If you want to put modules in directories not named for their package, then you
135need to use the ``package_dir`` option again.  For example, if the
136:file:`src` directory holds modules in the :mod:`foobar` package::
137
138   <root>/
139           setup.py
140           src/
141                    __init__.py
142                    foo.py
143                    bar.py
144
145an appropriate setup script would be  ::
146
147   from distutils.core import setup
148   setup(name='foobar',
149         version='1.0',
150         package_dir={'foobar': 'src'},
151         packages=['foobar'],
152         )
153
154Or, you might put modules from your main package right in the distribution
155root::
156
157   <root>/
158           setup.py
159           __init__.py
160           foo.py
161           bar.py
162
163in which case your setup script would be  ::
164
165   from distutils.core import setup
166   setup(name='foobar',
167         version='1.0',
168         package_dir={'foobar': ''},
169         packages=['foobar'],
170         )
171
172(The empty string also stands for the current directory.)
173
174If you have sub-packages, they must be explicitly listed in ``packages``,
175but any entries in ``package_dir`` automatically extend to sub-packages.
176(In other words, the Distutils does *not* scan your source tree, trying to
177figure out which directories correspond to Python packages by looking for
178:file:`__init__.py` files.)  Thus, if the default layout grows a sub-package::
179
180   <root>/
181           setup.py
182           foobar/
183                    __init__.py
184                    foo.py
185                    bar.py
186                    subfoo/
187                              __init__.py
188                              blah.py
189
190then the corresponding setup script would be  ::
191
192   from distutils.core import setup
193   setup(name='foobar',
194         version='1.0',
195         packages=['foobar', 'foobar.subfoo'],
196         )
197
198
199.. _single-ext:
200
201Single extension module
202=======================
203
204Extension modules are specified using the ``ext_modules`` option.
205``package_dir`` has no effect on where extension source files are found;
206it only affects the source for pure Python modules.  The simplest  case, a
207single extension module in a single C source file, is::
208
209   <root>/
210           setup.py
211           foo.c
212
213If the :mod:`foo` extension belongs in the root package, the setup script for
214this could be  ::
215
216   from distutils.core import setup
217   from distutils.extension import Extension
218   setup(name='foobar',
219         version='1.0',
220         ext_modules=[Extension('foo', ['foo.c'])],
221         )
222
223If the extension actually belongs in a package, say :mod:`foopkg`, then
224
225With exactly the same source tree layout, this extension can be put in the
226:mod:`foopkg` package simply by changing the name of the extension::
227
228   from distutils.core import setup
229   from distutils.extension import Extension
230   setup(name='foobar',
231         version='1.0',
232         ext_modules=[Extension('foopkg.foo', ['foo.c'])],
233         )
234
235Checking a package
236==================
237
238The ``check`` command allows you to verify if your package meta-data
239meet the minimum requirements to build a distribution.
240
241To run it, just call it using your :file:`setup.py` script. If something is
242missing, ``check`` will display a warning.
243
244Let's take an example with a simple script::
245
246    from distutils.core import setup
247
248    setup(name='foobar')
249
250Running the ``check`` command will display some warnings:
251
252.. code-block:: shell-session
253
254    $ python setup.py check
255    running check
256    warning: check: missing required meta-data: version, url
257    warning: check: missing meta-data: either (author and author_email) or
258             (maintainer and maintainer_email) must be supplied
259
260
261If you use the reStructuredText syntax in the ``long_description`` field and
262`docutils`_  is installed you can check if the syntax is fine with the
263``check`` command, using the ``restructuredtext`` option.
264
265For example, if the :file:`setup.py` script is changed like this::
266
267    from distutils.core import setup
268
269    desc = """\
270    My description
271    ==============
272
273    This is the description of the ``foobar`` package.
274    """
275
276    setup(name='foobar', version='1', author='tarek',
277        author_email='tarek@ziade.org',
278        url='http://example.com', long_description=desc)
279
280Where the long description is broken, ``check`` will be able to detect it
281by using the :mod:`docutils` parser:
282
283.. code-block:: shell-session
284
285    $ python setup.py check --restructuredtext
286    running check
287    warning: check: Title underline too short. (line 2)
288    warning: check: Could not finish the parsing.
289
290Reading the metadata
291=====================
292
293The :func:`distutils.core.setup` function provides a command-line interface
294that allows you to query the metadata fields of a project through the
295``setup.py`` script of a given project:
296
297.. code-block:: shell-session
298
299    $ python setup.py --name
300    distribute
301
302This call reads the ``name`` metadata by running the
303:func:`distutils.core.setup`  function. Although, when a source or binary
304distribution is created with Distutils, the metadata fields are written
305in a static file called :file:`PKG-INFO`. When a Distutils-based project is
306installed in Python, the :file:`PKG-INFO` file is copied alongside the modules
307and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`,
308where ``NAME`` is the name of the project, ``VERSION`` its version as defined
309in the Metadata, and ``pyX.X`` the major and minor version of Python like
310``2.7`` or ``3.2``.
311
312You can read back this static file, by using the
313:class:`distutils.dist.DistributionMetadata` class and its
314:func:`read_pkg_file` method::
315
316    >>> from distutils.dist import DistributionMetadata
317    >>> metadata = DistributionMetadata()
318    >>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info'))
319    >>> metadata.name
320    'distribute'
321    >>> metadata.version
322    '0.6.8'
323    >>> metadata.description
324    'Easily download, build, install, upgrade, and uninstall Python packages'
325
326Notice that the class can also be instantiated with a metadata file path to
327loads its values::
328
329    >>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info'
330    >>> DistributionMetadata(pkg_info_path).name
331    'distribute'
332
333
334.. % \section{Multiple extension modules}
335.. % \label{multiple-ext}
336
337.. % \section{Putting it all together}
338
339
340.. _docutils: http://docutils.sourceforge.net
341