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) should 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