| 
									
										
										
										
											2018-10-12 09:51:05 +02:00
										 |  |  | .. _distutils_examples:
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ********
 | 
					
						
							|  |  |  | Examples
 | 
					
						
							|  |  |  | ********
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This chapter provides a number of basic examples to help get started with
 | 
					
						
							|  |  |  | distutils.  Additional information about using distutils can be found in the
 | 
					
						
							|  |  |  | Distutils Cookbook.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. seealso::
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-29 08:36:35 +01:00
										 |  |  |    `Distutils Cookbook <https://wiki.python.org/moin/Distutils/Cookbook>`_
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  |       Collection of recipes showing how to achieve more control over distutils.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. _pure-mod:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Pure Python distribution (by module)
 | 
					
						
							|  |  |  | ====================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you're just distributing a couple of modules, especially if they don't live
 | 
					
						
							|  |  |  | in a particular package, you can specify them individually using the
 | 
					
						
							| 
									
										
										
										
											2014-09-21 00:35:08 +02:00
										 |  |  | ``py_modules`` option in the setup script.
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | In the simplest case, you'll have two files to worry about: a setup script and
 | 
					
						
							|  |  |  | the single module you're distributing, :file:`foo.py` in this example::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    <root>/
 | 
					
						
							|  |  |  |            setup.py
 | 
					
						
							|  |  |  |            foo.py
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (In all diagrams in this section, *<root>* will refer to the distribution root
 | 
					
						
							|  |  |  | directory.)  A minimal setup script to describe this situation would be::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    setup(name='foo',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          py_modules=['foo'],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Note that the name of the distribution is specified independently with the
 | 
					
						
							| 
									
										
										
										
											2014-09-21 00:35:08 +02:00
										 |  |  | ``name`` option, and there's no rule that says it has to be the same as
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | the name of the sole module in the distribution (although that's probably a good
 | 
					
						
							|  |  |  | convention to follow).  However, the distribution name is used to generate
 | 
					
						
							|  |  |  | filenames, so you should stick to letters, digits, underscores, and hyphens.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-21 00:35:08 +02:00
										 |  |  | Since ``py_modules`` is a list, you can of course specify multiple
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | modules, eg. if you're distributing modules :mod:`foo` and :mod:`bar`, your
 | 
					
						
							|  |  |  | setup might look like this::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    <root>/
 | 
					
						
							|  |  |  |            setup.py
 | 
					
						
							|  |  |  |            foo.py
 | 
					
						
							|  |  |  |            bar.py
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | and the setup script might be  ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    setup(name='foobar',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          py_modules=['foo', 'bar'],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You can put module source files into another directory, but if you have enough
 | 
					
						
							|  |  |  | modules to do that, it's probably easier to specify modules by package rather
 | 
					
						
							|  |  |  | than listing them individually.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. _pure-pkg:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Pure Python distribution (by package)
 | 
					
						
							|  |  |  | =====================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you have more than a couple of modules to distribute, especially if they are
 | 
					
						
							|  |  |  | in multiple packages, it's probably easier to specify whole packages rather than
 | 
					
						
							|  |  |  | individual modules.  This works even if your modules are not in a package; you
 | 
					
						
							|  |  |  | can just tell the Distutils to process modules from the root package, and that
 | 
					
						
							|  |  |  | works the same as any other package (except that you don't have to have an
 | 
					
						
							|  |  |  | :file:`__init__.py` file).
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The setup script from the last example could also be written as  ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    setup(name='foobar',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          packages=[''],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (The empty string stands for the root package.)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If those two files are moved into a subdirectory, but remain in the root
 | 
					
						
							|  |  |  | package, e.g.::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    <root>/
 | 
					
						
							|  |  |  |            setup.py
 | 
					
						
							|  |  |  |            src/      foo.py
 | 
					
						
							|  |  |  |                      bar.py
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | then you would still specify the root package, but you have to tell the
 | 
					
						
							|  |  |  | Distutils where source files in the root package live::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    setup(name='foobar',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          package_dir={'': 'src'},
 | 
					
						
							|  |  |  |          packages=[''],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | More typically, though, you will want to distribute multiple modules in the same
 | 
					
						
							|  |  |  | package (or in sub-packages).  For example, if the :mod:`foo`  and :mod:`bar`
 | 
					
						
							|  |  |  | modules belong in package :mod:`foobar`, one way to layout your source tree is
 | 
					
						
							|  |  |  | ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    <root>/
 | 
					
						
							|  |  |  |            setup.py
 | 
					
						
							|  |  |  |            foobar/
 | 
					
						
							|  |  |  |                     __init__.py
 | 
					
						
							|  |  |  |                     foo.py
 | 
					
						
							|  |  |  |                     bar.py
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is in fact the default layout expected by the Distutils, and the one that
 | 
					
						
							|  |  |  | requires the least work to describe in your setup script::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    setup(name='foobar',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          packages=['foobar'],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you want to put modules in directories not named for their package, then you
 | 
					
						
							| 
									
										
										
										
											2014-09-21 00:35:08 +02:00
										 |  |  | need to use the ``package_dir`` option again.  For example, if the
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | :file:`src` directory holds modules in the :mod:`foobar` package::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    <root>/
 | 
					
						
							|  |  |  |            setup.py
 | 
					
						
							|  |  |  |            src/
 | 
					
						
							|  |  |  |                     __init__.py
 | 
					
						
							|  |  |  |                     foo.py
 | 
					
						
							|  |  |  |                     bar.py
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | an appropriate setup script would be  ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    setup(name='foobar',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          package_dir={'foobar': 'src'},
 | 
					
						
							|  |  |  |          packages=['foobar'],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Or, you might put modules from your main package right in the distribution
 | 
					
						
							|  |  |  | root::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    <root>/
 | 
					
						
							|  |  |  |            setup.py
 | 
					
						
							|  |  |  |            __init__.py
 | 
					
						
							|  |  |  |            foo.py
 | 
					
						
							|  |  |  |            bar.py
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | in which case your setup script would be  ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    setup(name='foobar',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          package_dir={'foobar': ''},
 | 
					
						
							|  |  |  |          packages=['foobar'],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (The empty string also stands for the current directory.)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-21 00:35:08 +02:00
										 |  |  | If you have sub-packages, they must be explicitly listed in ``packages``,
 | 
					
						
							|  |  |  | but any entries in ``package_dir`` automatically extend to sub-packages.
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | (In other words, the Distutils does *not* scan your source tree, trying to
 | 
					
						
							|  |  |  | figure out which directories correspond to Python packages by looking for
 | 
					
						
							|  |  |  | :file:`__init__.py` files.)  Thus, if the default layout grows a sub-package::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    <root>/
 | 
					
						
							|  |  |  |            setup.py
 | 
					
						
							|  |  |  |            foobar/
 | 
					
						
							|  |  |  |                     __init__.py
 | 
					
						
							|  |  |  |                     foo.py
 | 
					
						
							|  |  |  |                     bar.py
 | 
					
						
							|  |  |  |                     subfoo/
 | 
					
						
							|  |  |  |                               __init__.py
 | 
					
						
							|  |  |  |                               blah.py
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | then the corresponding setup script would be  ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    setup(name='foobar',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          packages=['foobar', 'foobar.subfoo'],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. _single-ext:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Single extension module
 | 
					
						
							|  |  |  | =======================
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-21 00:35:08 +02:00
										 |  |  | Extension modules are specified using the ``ext_modules`` option.
 | 
					
						
							|  |  |  | ``package_dir`` has no effect on where extension source files are found;
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | it only affects the source for pure Python modules.  The simplest  case, a
 | 
					
						
							|  |  |  | single extension module in a single C source file, is::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    <root>/
 | 
					
						
							|  |  |  |            setup.py
 | 
					
						
							|  |  |  |            foo.c
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the :mod:`foo` extension belongs in the root package, the setup script for
 | 
					
						
							|  |  |  | this could be  ::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    from distutils.extension import Extension
 | 
					
						
							|  |  |  |    setup(name='foobar',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          ext_modules=[Extension('foo', ['foo.c'])],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the extension actually belongs in a package, say :mod:`foopkg`, then
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | With exactly the same source tree layout, this extension can be put in the
 | 
					
						
							|  |  |  | :mod:`foopkg` package simply by changing the name of the extension::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    from distutils.core import setup
 | 
					
						
							|  |  |  |    from distutils.extension import Extension
 | 
					
						
							|  |  |  |    setup(name='foobar',
 | 
					
						
							|  |  |  |          version='1.0',
 | 
					
						
							|  |  |  |          ext_modules=[Extension('foopkg.foo', ['foo.c'])],
 | 
					
						
							|  |  |  |          )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-31 09:10:51 +00:00
										 |  |  | Checking a package
 | 
					
						
							|  |  |  | ==================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The ``check`` command allows you to verify if your package meta-data
 | 
					
						
							|  |  |  | meet the minimum requirements to build a distribution.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To run it, just call it using your :file:`setup.py` script. If something is
 | 
					
						
							|  |  |  | missing, ``check`` will display a warning.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Let's take an example with a simple script::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from distutils.core import setup
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setup(name='foobar')
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-26 11:18:21 +02:00
										 |  |  | Running the ``check`` command will display some warnings:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. code-block:: shell-session
 | 
					
						
							| 
									
										
										
										
											2010-07-31 09:10:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $ python setup.py check
 | 
					
						
							|  |  |  |     running check
 | 
					
						
							|  |  |  |     warning: check: missing required meta-data: version, url
 | 
					
						
							|  |  |  |     warning: check: missing meta-data: either (author and author_email) or
 | 
					
						
							|  |  |  |              (maintainer and maintainer_email) must be supplied
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-15 13:29:33 +00:00
										 |  |  | If you use the reStructuredText syntax in the ``long_description`` field and
 | 
					
						
							|  |  |  | `docutils`_  is installed you can check if the syntax is fine with the
 | 
					
						
							|  |  |  | ``check`` command, using the ``restructuredtext`` option.
 | 
					
						
							| 
									
										
										
										
											2010-07-31 09:10:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | For example, if the :file:`setup.py` script is changed like this::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     from distutils.core import setup
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     desc = """\
 | 
					
						
							|  |  |  |     My description
 | 
					
						
							| 
									
										
										
										
											2014-10-30 22:50:46 +01:00
										 |  |  |     ==============
 | 
					
						
							| 
									
										
										
										
											2010-07-31 09:10:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     This is the description of the ``foobar`` package.
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     setup(name='foobar', version='1', author='tarek',
 | 
					
						
							|  |  |  |         author_email='tarek@ziade.org',
 | 
					
						
							|  |  |  |         url='http://example.com', long_description=desc)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Where the long description is broken, ``check`` will be able to detect it
 | 
					
						
							| 
									
										
										
										
											2016-07-26 11:18:21 +02:00
										 |  |  | by using the :mod:`docutils` parser:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. code-block:: shell-session
 | 
					
						
							| 
									
										
										
										
											2010-07-31 09:10:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-22 21:27:10 +02:00
										 |  |  |     $ python setup.py check --restructuredtext
 | 
					
						
							| 
									
										
										
										
											2010-07-31 09:10:51 +00:00
										 |  |  |     running check
 | 
					
						
							|  |  |  |     warning: check: Title underline too short. (line 2)
 | 
					
						
							|  |  |  |     warning: check: Could not finish the parsing.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-10 18:15:03 -05:00
										 |  |  | Reading the metadata
 | 
					
						
							|  |  |  | =====================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The :func:`distutils.core.setup` function provides a command-line interface
 | 
					
						
							|  |  |  | that allows you to query the metadata fields of a project through the
 | 
					
						
							| 
									
										
										
										
											2016-07-26 11:18:21 +02:00
										 |  |  | ``setup.py`` script of a given project:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. code-block:: shell-session
 | 
					
						
							| 
									
										
										
										
											2013-11-10 18:15:03 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $ python setup.py --name
 | 
					
						
							|  |  |  |     distribute
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-30 22:26:26 +01:00
										 |  |  | This call reads the ``name`` metadata by running the
 | 
					
						
							| 
									
										
										
										
											2013-11-10 18:15:03 -05:00
										 |  |  | :func:`distutils.core.setup`  function. Although, when a source or binary
 | 
					
						
							|  |  |  | distribution is created with Distutils, the metadata fields are written
 | 
					
						
							|  |  |  | in a static file called :file:`PKG-INFO`. When a Distutils-based project is
 | 
					
						
							|  |  |  | installed in Python, the :file:`PKG-INFO` file is copied alongside the modules
 | 
					
						
							|  |  |  | and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`,
 | 
					
						
							| 
									
										
										
										
											2014-10-30 22:26:26 +01:00
										 |  |  | where ``NAME`` is the name of the project, ``VERSION`` its version as defined
 | 
					
						
							|  |  |  | in the Metadata, and ``pyX.X`` the major and minor version of Python like
 | 
					
						
							|  |  |  | ``2.7`` or ``3.2``.
 | 
					
						
							| 
									
										
										
										
											2013-11-10 18:15:03 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | You can read back this static file, by using the
 | 
					
						
							|  |  |  | :class:`distutils.dist.DistributionMetadata` class and its
 | 
					
						
							|  |  |  | :func:`read_pkg_file` method::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> from distutils.dist import DistributionMetadata
 | 
					
						
							|  |  |  |     >>> metadata = DistributionMetadata()
 | 
					
						
							|  |  |  |     >>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info'))
 | 
					
						
							|  |  |  |     >>> metadata.name
 | 
					
						
							|  |  |  |     'distribute'
 | 
					
						
							|  |  |  |     >>> metadata.version
 | 
					
						
							|  |  |  |     '0.6.8'
 | 
					
						
							|  |  |  |     >>> metadata.description
 | 
					
						
							|  |  |  |     'Easily download, build, install, upgrade, and uninstall Python packages'
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-04 16:41:06 -08:00
										 |  |  | Notice that the class can also be instantiated with a metadata file path to
 | 
					
						
							| 
									
										
										
										
											2013-11-10 18:15:03 -05:00
										 |  |  | loads its values::
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info'
 | 
					
						
							|  |  |  |     >>> DistributionMetadata(pkg_info_path).name
 | 
					
						
							|  |  |  |     'distribute'
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-15 14:28:22 +00:00
										 |  |  | .. % \section{Multiple extension modules}
 | 
					
						
							|  |  |  | .. % \label{multiple-ext}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. % \section{Putting it all together}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-15 13:29:33 +00:00
										 |  |  | .. _docutils: http://docutils.sourceforge.net
 |