summaryrefslogtreecommitdiff
path: root/docs/source
diff options
context:
space:
mode:
authorArc Riley <arcriley@gmail.com>2011-03-13 00:12:23 -0500
committerArc Riley <arcriley@gmail.com>2011-03-13 00:12:23 -0500
commitefa667603bc41168dc547563fffef464b728adfa (patch)
tree6b3f76ba3d107c984335253b3d42d9ab65cb7748 /docs/source
parentf3f78c2aca495aed87bc416e5f20134b9d0fc351 (diff)
parente2d2d3d18380338920819d2bd0524f6629b1874b (diff)
downloaddisutils2-efa667603bc41168dc547563fffef464b728adfa.tar.gz
Branch merge to trunk
Diffstat (limited to 'docs/source')
-rw-r--r--docs/source/contributing.rst27
-rw-r--r--docs/source/distutils/apiref.rst40
-rw-r--r--docs/source/distutils/examples.rst8
-rw-r--r--docs/source/distutils/sourcedist.rst7
-rw-r--r--docs/source/index.rst3
-rw-r--r--docs/source/install/index.rst39
-rw-r--r--docs/source/library/distutils2.index.xmlrpc.rst2
-rw-r--r--docs/source/library/distutils2.metadata.rst24
-rw-r--r--docs/source/library/distutils2.rst1
-rw-r--r--docs/source/library/distutils2.tests.pypi_server.rst3
-rw-r--r--docs/source/library/pkgutil.rst218
-rw-r--r--docs/source/setupcfg.rst428
12 files changed, 688 insertions, 112 deletions
diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst
new file mode 100644
index 0000000..989d1a0
--- /dev/null
+++ b/docs/source/contributing.rst
@@ -0,0 +1,27 @@
+==========================
+Contributing to Distutils2
+==========================
+
+----------------
+Reporting Issues
+----------------
+
+When using, testing or developping distutils2, you may encounter issues. Please report to the following sections to know how these issues should be reported.
+
+Please keep in mind that this guide is intended to ease the triage and fixing processes by giving the maximum information to the developers. It should not be viewed as mandatory, only advisory ;).
+
+
+- Go to http://bugs.python.org/ (you'll need a Python Bugs account), then "Issues" > "Create ticket".
+- **Title**: write in a short summary of the issue. You may prefix the issue title with “component:”, where component can be something like installer, sdist, setup.cfg, etc., or add it at the end of your title if the normal flow of the sentence allows it. This will ease up later searches.
+- **Components**: choose "Distutils2"
+- **Version**: choose "3rd party"
+- **Body**: explain how to reproduce the bug: What you want to do, what code you write, what happens, what should happen, how to fix it (if you have an idea).
+ * You should always test with the tip of the main repository, not releases.
+ * Mention the versions of Python you tested with. d2 supports 2.4 to 2.7.
+ * If relevant, mention the version of your operating system (for example with issues related to C extensions).
+ * When referencing commits, be careful to use the universal changeset identifiers (12 characters, for instance c3cf81fc64db), not the local sequential numbers (for example 925) that are not shared among clones.
+ * Try to be as concise as possible, but not too much.
+ * If useful, paste tracebacks.
+ * If useful, attach setup.cfg or other files (binary files like archives are not very convenient, better to stick to text).
+
+Issues related to PyPI are reported via email to the **catalog-sig@python.org** mailing list, not within bugs.python.org.
diff --git a/docs/source/distutils/apiref.rst b/docs/source/distutils/apiref.rst
index 02e4158..b01ba95 100644
--- a/docs/source/distutils/apiref.rst
+++ b/docs/source/distutils/apiref.rst
@@ -104,6 +104,26 @@ setup script). Indirectly provides the :class:`distutils2.dist.Distribution` and
| *package_dir* | A mapping of package to | a dictionary |
| | directory names | |
+--------------------+--------------------------------+-------------------------------------------------------------+
+ | *extra_path* | Information about an | a string, 1-tuple or 2-tuple |
+ | | intervening directory the | |
+ | | install directory and the | |
+ | | actual installation directory. | |
+ | | | |
+ | | If the value is a string is is | |
+ | | treated as a comma-separated | |
+ | | tuple. | |
+ | | | |
+ | | If the value is a 2-tuple, | |
+ | | the first element is the | |
+ | | ``.pth`` file and the second | |
+ | | is the name of the intervening | |
+ | | directory. | |
+ | | | |
+ | | If the value is a 1-tuple that | |
+ | | element is both the name of | |
+ | | the ``.pth`` file and the | |
+ | | intervening directory. | |
+ +--------------------+--------------------------------+-------------------------------------------------------------+
@@ -888,7 +908,7 @@ tarballs or zipfiles.
.. function:: make_zipfile(base_name, base_dir[, verbose=0, dry_run=0])
Create a zip file from all files in and under *base_dir*. The output zip file
- will be named *base_dir* + :file:`.zip`. Uses either the :mod:`zipfile` Python
+ will be named *base_name* + :file:`.zip`. Uses either the :mod:`zipfile` Python
module (if available) or the InfoZIP :file:`zip` utility (if installed and
found on the default search path). If neither tool is available, raises
:exc:`DistutilsExecError`. Returns the name of the output zip file.
@@ -1055,6 +1075,15 @@ This module contains some utility functions for operating on individual files.
Create a file called *filename* and write *contents* (a sequence of strings
without line terminators) to it.
+:mod:`distutils2.metadata` --- Metadata handling
+================================================================
+
+.. module:: distutils2.metadata
+
+.. FIXME CPython/stdlib docs don't use autoclass, write doc manually here
+
+.. autoclass:: distutils2.metadata.Metadata
+ :members:
:mod:`distutils2.util` --- Miscellaneous other utility functions
================================================================
@@ -1157,15 +1186,6 @@ other utility module.
an underscore. No { } or ( ) style quoting is available.
-.. function:: grok_environment_error(exc[, prefix='error: '])
-
- Generate a useful error message from an :exc:`EnvironmentError`
- (:exc:`IOError` or :exc:`OSError`) exception object. Does what it can to deal
- with exception objects that don't have a filename (which happens when the
- error is due to a two-file operation, such as :func:`rename` or
- :func:`link`). Returns the error message as a string prefixed with *prefix*.
-
-
.. function:: split_quoted(s)
Split a string up according to Unix shell-like rules for quotes and
diff --git a/docs/source/distutils/examples.rst b/docs/source/distutils/examples.rst
index fb89dc9..796ecbb 100644
--- a/docs/source/distutils/examples.rst
+++ b/docs/source/distutils/examples.rst
@@ -298,11 +298,11 @@ in the Metadata, and ``pyX.X`` the major and minor version of Python like
``2.7`` or ``3.2``.
You can read back this static file, by using the
-:class:`distutils2.dist.DistributionMetadata` class and its
+:class:`distutils2.dist.Metadata` class and its
:func:`read_pkg_file` method::
- >>> from distutils2.dist import DistributionMetadata
- >>> metadata = DistributionMetadata()
+ >>> from distutils2.metadata import Metadata
+ >>> metadata = Metadata()
>>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info'))
>>> metadata.name
'distribute'
@@ -315,7 +315,7 @@ Notice that the class can also be instantiated with a metadata file path to
loads its values::
>>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info'
- >>> DistributionMetadata(pkg_info_path).name
+ >>> Metadata(pkg_info_path).name
'distribute'
diff --git a/docs/source/distutils/sourcedist.rst b/docs/source/distutils/sourcedist.rst
index 1aa722b..7ed9637 100644
--- a/docs/source/distutils/sourcedist.rst
+++ b/docs/source/distutils/sourcedist.rst
@@ -86,8 +86,7 @@ source distribution:
distributions, but in the future there will be a standard for testing Python
module distributions)
-* :file:`README.txt` (or :file:`README`), :file:`setup.py` (or whatever you
- called your setup script), and :file:`setup.cfg`
+* The configuration file :file:`setup.cfg`
* all files that matches the ``package_data`` metadata.
See :ref:`distutils-installing-package-data`.
@@ -95,6 +94,10 @@ source distribution:
* all files that matches the ``data_files`` metadata.
See :ref:`distutils-additional-files`.
+.. Warning::
+ In Distutils2, setup.py and README (or README.txt) files are not more
+ included in source distribution by default
+
Sometimes this is enough, but usually you will want to specify additional files
to distribute. The typical way to do this is to write a *manifest template*,
called :file:`MANIFEST.in` by default. The manifest template is just a list of
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 91db2bd..8a3d63c 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -29,7 +29,7 @@ a library used to package, distribute, build and install Python projects.
.. __: http://bitbucket.org/tarek/distutils2/wiki/GSoC_2010_teams
If you’re looking for information on how to contribute, head to
-:doc:`devresources`.
+:doc:`devresources`, and be sure to have a look at :doc:`contributing`.
Documentation
@@ -76,6 +76,7 @@ The documentation is split in four sections, as in the standard Python docs:
distutils/index
library/distutils2
library/pkgutil
+ contributing
Indices and tables
diff --git a/docs/source/install/index.rst b/docs/source/install/index.rst
index 15627ee..4a6f755 100644
--- a/docs/source/install/index.rst
+++ b/docs/source/install/index.rst
@@ -927,15 +927,34 @@ section :ref:`inst-config-files`.)
GNU C / Cygwin / MinGW
^^^^^^^^^^^^^^^^^^^^^^
-These instructions only apply if you're using a version of Python prior to
-2.4.1 with a MinGW prior to 3.0.0 (with binutils-2.13.90-20030111-1).
-
This section describes the necessary steps to use Distutils with the GNU C/C++
compilers in their Cygwin and MinGW distributions. [#]_ For a Python interpreter
that was built with Cygwin, everything should work without any of these
following steps.
-These compilers require some special libraries. This task is more complex than
+Not all extensions can be built with MinGW or Cygwin, but many can. Extensions
+most likely to not work are those that use C++ or depend on Microsoft Visual C
+extensions.
+
+To let Distutils compile your extension with Cygwin you have to type::
+
+ python setup.py build --compiler=cygwin
+
+and for Cygwin in no-cygwin mode [#]_ or for MinGW type::
+
+ python setup.py build --compiler=mingw32
+
+If you want to use any of these options/compilers as default, you should
+consider writing it in your personal or system-wide configuration file for
+Distutils (see section :ref:`inst-config-files`.)
+
+Older Versions of Python and MinGW
+""""""""""""""""""""""""""""""""""
+The following instructions only apply if you're using a version of Python
+inferior to 2.4.1 with a MinGW inferior to 3.0.0 (with
+binutils-2.13.90-20030111-1).
+
+These compilers require some special libraries. This task is more complex than
for Borland's C++, because there is no program to convert the library. First
you have to create a list of symbols which the Python DLL exports. (You can find
a good program for this task at
@@ -965,18 +984,6 @@ If your extension uses other libraries (zlib,...) you might have to convert
them too. The converted files have to reside in the same directories as the
normal libraries do.
-To let Distutils compile your extension with Cygwin you now have to type ::
-
- python setup.py build --compiler cygwin
-
-and for Cygwin in no-cygwin mode [#]_ or for MinGW type::
-
- python setup.py build --compiler mingw32
-
-If you want to use any of these options/compilers as default, you should
-consider to write it in your personal or system-wide configuration file for
-Distutils (see section :ref:`inst-config-files`.)
-
.. seealso::
diff --git a/docs/source/library/distutils2.index.xmlrpc.rst b/docs/source/library/distutils2.index.xmlrpc.rst
index e1439d5..8f96727 100644
--- a/docs/source/library/distutils2.index.xmlrpc.rst
+++ b/docs/source/library/distutils2.index.xmlrpc.rst
@@ -90,7 +90,7 @@ It's really simple to do so::
<ReleaseInfo FooBar 1.1>
Assuming we already have a :class:`distutils2.index.ReleaseInfo` object defined,
-it's possible to pass it ot the xmlrpc client to retrieve and complete it's
+it's possible to pass it ot the xmlrpc client to retrieve and complete its
metadata::
>>> foobar11 = ReleaseInfo("FooBar", "1.1")
diff --git a/docs/source/library/distutils2.metadata.rst b/docs/source/library/distutils2.metadata.rst
index 9f4f693..6fe24c6 100644
--- a/docs/source/library/distutils2.metadata.rst
+++ b/docs/source/library/distutils2.metadata.rst
@@ -2,7 +2,9 @@
Metadata
========
-Distutils2 provides a :class:`DistributionMetadata` class that can read and
+.. module:: distutils2.metadata
+
+Distutils2 provides a :class:`~distutils2.metadata.Metadata` class that can read and
write metadata files. This class is compatible with all metadata versions:
* 1.0: :PEP:`241`
@@ -17,11 +19,11 @@ markers, and displays warnings when versions that are supposed to be
Reading metadata
================
-The :class:`DistributionMetadata` class can be instantiated with the path of
+The :class:`~distutils2.metadata.Metadata` class can be instantiated with the path of
the metadata file, and provides a dict-like interface to the values::
- >>> from distutils2.metadata import DistributionMetadata
- >>> metadata = DistributionMetadata('PKG-INFO')
+ >>> from distutils2.metadata import Metadata
+ >>> metadata = Metadata('PKG-INFO')
>>> metadata.keys()[:5]
('Metadata-Version', 'Name', 'Version', 'Platform', 'Supported-Platform')
>>> metadata['Name']
@@ -33,13 +35,13 @@ the metadata file, and provides a dict-like interface to the values::
The fields that supports environment markers can be automatically ignored if
the object is instantiated using the ``platform_dependent`` option.
-:class:`DistributionMetadata` will interpret in the case the markers and will
+:class:`~distutils2.metadata.Metadata` will interpret in the case the markers and will
automatically remove the fields that are not compliant with the running
environment. Here's an example under Mac OS X. The win32 dependency
we saw earlier is ignored::
- >>> from distutils2.metadata import DistributionMetadata
- >>> metadata = DistributionMetadata('PKG-INFO', platform_dependent=True)
+ >>> from distutils2.metadata import Metadata
+ >>> metadata = Metadata('PKG-INFO', platform_dependent=True)
>>> metadata['Requires-Dist']
['bar']
@@ -51,9 +53,9 @@ expects.
Here's an example, simulating a win32 environment::
- >>> from distutils2.metadata import DistributionMetadata
+ >>> from distutils2.metadata import Metadata
>>> context = {'sys.platform': 'win32'}
- >>> metadata = DistributionMetadata('PKG-INFO', platform_dependent=True,
+ >>> metadata = Metadata('PKG-INFO', platform_dependent=True,
... execution_context=context)
...
>>> metadata['Requires-Dist'] = ["pywin32; sys.platform == 'win32'",
@@ -81,8 +83,8 @@ Conflict checking and best version
Some fields in :PEP:`345` have to follow a version scheme in their versions
predicate. When the scheme is violated, a warning is emitted::
- >>> from distutils2.metadata import DistributionMetadata
- >>> metadata = DistributionMetadata()
+ >>> from distutils2.metadata import Metadata
+ >>> metadata = Metadata()
>>> metadata['Requires-Dist'] = ['Funky (Groovie)']
"Funky (Groovie)" is not a valid predicate
>>> metadata['Requires-Dist'] = ['Funky (1.2)']
diff --git a/docs/source/library/distutils2.rst b/docs/source/library/distutils2.rst
index 9d2e53c..202c79b 100644
--- a/docs/source/library/distutils2.rst
+++ b/docs/source/library/distutils2.rst
@@ -24,6 +24,7 @@ guides to install a project or package your own code, head to `See also`__.
distutils2.version
distutils2.metadata
distutils2.depgraph
+ distutils2.install
distutils2.index
distutils2.tests.pypi_server
diff --git a/docs/source/library/distutils2.tests.pypi_server.rst b/docs/source/library/distutils2.tests.pypi_server.rst
index 6ad3936..c290f06 100644
--- a/docs/source/library/distutils2.tests.pypi_server.rst
+++ b/docs/source/library/distutils2.tests.pypi_server.rst
@@ -77,6 +77,7 @@ For this, you need to add a `server` parameter to your method, like this::
@use_pypi_server()
def test_somthing(self, server):
# your tests goes here
+ ...
The decorator will instantiate the server for you, and run and stop it just
before and after your method call. You also can pass the server initializer,
@@ -85,4 +86,4 @@ just like this::
class SampleTestCase(TestCase):
@use_pypi_server("test_case_name")
def test_something(self, server):
- # something
+ ...
diff --git a/docs/source/library/pkgutil.rst b/docs/source/library/pkgutil.rst
index d529508..43a9a2a 100644
--- a/docs/source/library/pkgutil.rst
+++ b/docs/source/library/pkgutil.rst
@@ -4,77 +4,204 @@
.. module:: pkgutil
:synopsis: Utilities to support packages.
-.. TODO Follow the reST conventions used in the stdlib
-
-This module provides functions to manipulate packages, as well as
-the necessary functions to provide support for the "Importer Protocol" as
-described in :PEP:`302` and for working with the database of installed Python
-distributions which is specified in :PEP:`376`. In addition to the functions
-required in :PEP:`376`, back support for older ``.egg`` and ``.egg-info``
-distributions is provided as well. These distributions are represented by the
-class :class:`~distutils2._backport.pkgutil.EggInfoDistribution` and most
-functions provide an extra argument ``use_egg_info`` which indicates if
-they should consider these old styled distributions. This document details
-first the functions and classes available and then presents several use cases.
+This module provides utilities to manipulate packages: support for the
+Importer protocol defined in :PEP:`302` and implementation of the API
+described in :PEP:`376` to work with the database of installed Python
+distributions.
+Import system utilities
+-----------------------
.. function:: extend_path(path, name)
- Extend the search path for the modules which comprise a package. Intended use is
- to place the following code in a package's :file:`__init__.py`::
+ Extend the search path for the modules which comprise a package. Intended
+ use is to place the following code in a package's :file:`__init__.py`::
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
- This will add to the package's ``__path__`` all subdirectories of directories on
- ``sys.path`` named after the package. This is useful if one wants to distribute
- different parts of a single logical package as multiple directories.
+ This will add to the package's ``__path__`` all subdirectories of directories
+ on :data:`sys.path` named after the package. This is useful if one wants to
+ distribute different parts of a single logical package as multiple
+ directories.
- It also looks for :file:`\*.pkg` files beginning where ``*`` matches the *name*
- argument. This feature is similar to :file:`\*.pth` files (see the :mod:`site`
- module for more information), except that it doesn't special-case lines starting
- with ``import``. A :file:`\*.pkg` file is trusted at face value: apart from
- checking for duplicates, all entries found in a :file:`\*.pkg` file are added to
- the path, regardless of whether they exist on the filesystem. (This is a
- feature.)
+ It also looks for :file:`\*.pkg` files beginning where ``*`` matches the
+ *name* argument. This feature is similar to :file:`\*.pth` files (see the
+ :mod:`site` module for more information), except that it doesn't special-case
+ lines starting with ``import``. A :file:`\*.pkg` file is trusted at face
+ value: apart from checking for duplicates, all entries found in a
+ :file:`\*.pkg` file are added to the path, regardless of whether they exist
+ on the filesystem. (This is a feature.)
If the input path is not a list (as is the case for frozen packages) it is
returned unchanged. The input path is not modified; an extended copy is
returned. Items are only appended to the copy at the end.
- It is assumed that ``sys.path`` is a sequence. Items of ``sys.path`` that are
- not strings referring to existing directories are ignored. Unicode items on
- ``sys.path`` that cause errors when used as filenames may cause this function
- to raise an exception (in line with :func:`os.path.isdir` behavior).
+ It is assumed that :data:`sys.path` is a sequence. Items of :data:`sys.path`
+ that are not strings referring to existing directories are ignored. Unicode
+ items on :data:`sys.path` that cause errors when used as filenames may cause
+ this function to raise an exception (in line with :func:`os.path.isdir`
+ behavior).
+
+
+.. class:: ImpImporter(dirname=None)
+
+ :pep:`302` Importer that wraps Python's "classic" import algorithm.
+
+ If *dirname* is a string, a :pep:`302` importer is created that searches that
+ directory. If *dirname* is ``None``, a :pep:`302` importer is created that
+ searches the current :data:`sys.path`, plus any modules that are frozen or
+ built-in.
+
+ Note that :class:`ImpImporter` does not currently support being used by
+ placement on :data:`sys.meta_path`.
+
+
+.. class:: ImpLoader(fullname, file, filename, etc)
+
+ :pep:`302` Loader that wraps Python's "classic" import algorithm.
+
+
+.. function:: find_loader(fullname)
+
+ Find a :pep:`302` "loader" object for *fullname*.
+
+ If *fullname* contains dots, path must be the containing package's
+ ``__path__``. Returns ``None`` if the module cannot be found or imported.
+ This function uses :func:`iter_importers`, and is thus subject to the same
+ limitations regarding platform-specific special import locations such as the
+ Windows registry.
+
+
+.. function:: get_importer(path_item)
+
+ Retrieve a :pep:`302` importer for the given *path_item*.
+
+ The returned importer is cached in :data:`sys.path_importer_cache` if it was
+ newly created by a path hook.
+
+ If there is no importer, a wrapper around the basic import machinery is
+ returned. This wrapper is never inserted into the importer cache (None is
+ inserted instead).
+
+ The cache (or part of it) can be cleared manually if a rescan of
+ :data:`sys.path_hooks` is necessary.
+
+
+.. function:: get_loader(module_or_name)
+
+ Get a :pep:`302` "loader" object for *module_or_name*.
+
+ If the module or package is accessible via the normal import mechanism, a
+ wrapper around the relevant part of that machinery is returned. Returns
+ ``None`` if the module cannot be found or imported. If the named module is
+ not already imported, its containing package (if any) is imported, in order
+ to establish the package ``__path__``.
+
+ This function uses :func:`iter_importers`, and is thus subject to the same
+ limitations regarding platform-specific special import locations such as the
+ Windows registry.
+
+
+.. function:: iter_importers(fullname='')
+
+ Yield :pep:`302` importers for the given module name.
+
+ If fullname contains a '.', the importers will be for the package containing
+ fullname, otherwise they will be importers for :data:`sys.meta_path`,
+ :data:`sys.path`, and Python's "classic" import machinery, in that order. If
+ the named module is in a package, that package is imported as a side effect
+ of invoking this function.
+
+ Non-:pep:`302` mechanisms (e.g. the Windows registry) used by the standard
+ import machinery to find files in alternative locations are partially
+ supported, but are searched *after* :data:`sys.path`. Normally, these
+ locations are searched *before* :data:`sys.path`, preventing :data:`sys.path`
+ entries from shadowing them.
+
+ For this to cause a visible difference in behaviour, there must be a module
+ or package name that is accessible via both :data:`sys.path` and one of the
+ non-:pep:`302` file system mechanisms. In this case, the emulation will find
+ the former version, while the builtin import mechanism will find the latter.
+
+ Items of the following types can be affected by this discrepancy:
+ ``imp.C_EXTENSION``, ``imp.PY_SOURCE``, ``imp.PY_COMPILED``,
+ ``imp.PKG_DIRECTORY``.
+
+
+.. function:: iter_modules(path=None, prefix='')
+
+ Yields ``(module_loader, name, ispkg)`` for all submodules on *path*, or, if
+ path is ``None``, all top-level modules on :data:`sys.path`.
+
+ *path* should be either ``None`` or a list of paths to look for modules in.
+
+ *prefix* is a string to output on the front of every module name on output.
+
+
+.. function:: walk_packages(path=None, prefix='', onerror=None)
+
+ Yields ``(module_loader, name, ispkg)`` for all modules recursively on
+ *path*, or, if path is ``None``, all accessible modules.
+
+ *path* should be either ``None`` or a list of paths to look for modules in.
+
+ *prefix* is a string to output on the front of every module name on output.
+
+ Note that this function must import all *packages* (*not* all modules!) on
+ the given *path*, in order to access the ``__path__`` attribute to find
+ submodules.
+
+ *onerror* is a function which gets called with one argument (the name of the
+ package which was being imported) if any exception occurs while trying to
+ import a package. If no *onerror* function is supplied, :exc:`ImportError`\s
+ are caught and ignored, while all other exceptions are propagated,
+ terminating the search.
+
+ Examples::
+
+ # list all modules python can access
+ walk_packages()
+
+ # list all submodules of ctypes
+ walk_packages(ctypes.__path__, ctypes.__name__ + '.')
+
.. function:: get_data(package, resource)
Get a resource from a package.
- This is a wrapper for the :pep:`302` loader :func:`get_data` API. The package
- argument should be the name of a package, in standard module format
- (foo.bar). The resource argument should be in the form of a relative
- filename, using ``/`` as the path separator. The parent directory name
+ This is a wrapper for the :pep:`302` loader :func:`get_data` API. The
+ *package* argument should be the name of a package, in standard module format
+ (``foo.bar``). The *resource* argument should be in the form of a relative
+ filename, using ``/`` as the path separator. The parent directory name
``..`` is not allowed, and nor is a rooted name (starting with a ``/``).
- The function returns a binary string that is the contents of the
- specified resource.
+ The function returns a binary string that is the contents of the specified
+ resource.
For packages located in the filesystem, which have already been imported,
this is the rough equivalent of::
- d = os.path.dirname(sys.modules[package].__file__)
- data = open(os.path.join(d, resource), 'rb').read()
+ d = os.path.dirname(sys.modules[package].__file__)
+ data = open(os.path.join(d, resource), 'rb').read()
If the package cannot be located or loaded, or it uses a :pep:`302` loader
- which does not support :func:`get_data`, then None is returned.
+ which does not support :func:`get_data`, then ``None`` is returned.
+
+Installed distributions database
+--------------------------------
-API Reference
-=============
+Installed Python distributions are represented by instances of
+:class:`~distutils2._backport.pkgutil.Distribution`, or its subclass
+:class:`~distutils2._backport.pkgutil.EggInfoDistribution` for legacy ``.egg``
+and ``.egg-info`` formats). Most functions also provide an extra argument
+``use_egg_info`` to take legacy distributions into account.
-.. automodule:: distutils2._backport.pkgutil
- :members:
+.. TODO write docs here, don't rely on automodule
+ classes: Distribution and descendents
+ functions: provides, obsoletes, replaces, etc.
Caching
+++++++
@@ -86,11 +213,10 @@ it using :func:`~distutils2._backport.pkgutil.enable_cache`,
:func:`~distutils2._backport.pkgutil.clear_cache`.
+Examples
+--------
-Example Usage
-=============
-
-Print All Information About a Distribution
+Print all information about a distribution
++++++++++++++++++++++++++++++++++++++++++
Given a path to a ``.dist-info`` distribution, we shall print out all
@@ -182,7 +308,7 @@ we get the following output:
=====
* It was installed as a dependency
-Find Out Obsoleted Distributions
+Find out obsoleted distributions
++++++++++++++++++++++++++++++++
Now, we take tackle a different problem, we are interested in finding out
diff --git a/docs/source/setupcfg.rst b/docs/source/setupcfg.rst
index 0cbf4f2..abe25c6 100644
--- a/docs/source/setupcfg.rst
+++ b/docs/source/setupcfg.rst
@@ -7,24 +7,35 @@ Distutils2 to replace the :file:`setup.py` file.
Each section contains a description of its options.
-- Options that are marked *\*multi* can have multiple values, one value
- per line.
+- Options that are marked *\*multi* can have multiple values, one value per
+ line.
- Options that are marked *\*optional* can be omited.
-- Options that are marked *\*environ* can use environement markes, as described
- in PEP 345.
+- Options that are marked *\*environ* can use environment markers, as described
+ in :PEP:`345`.
+
The sections are:
-- global
-- metadata
-- files
-- command sections
+global
+ Global options for Distutils2.
+
+metadata
+ The metadata section contains the metadata for the project as described in
+ :PEP:`345`.
+
+files
+ Declaration of package files included in the project.
+
+`command` sections
+ Redefinition of user options for Distutils2 commands.
global
======
-Contains global options for Distutils2. This section is shared with Distutils1.
+Contains global options for Distutils2. This section is shared with Distutils1
+(legacy version distributed in python 2.X standard library).
+
- **commands**: Defined Distutils2 command. A command is defined by its fully
qualified name.
@@ -38,13 +49,13 @@ Contains global options for Distutils2. This section is shared with Distutils1.
*\*optional* *\*multi*
- **compilers**: Defined Distutils2 compiler. A compiler is defined by its fully
- qualified name.
+ qualified name.
Example::
[global]
compiler =
- package.compilers.CustomCCompiler
+ package.compiler.CustomCCompiler
*\*optional* *\*multi*
@@ -52,21 +63,29 @@ Contains global options for Distutils2. This section is shared with Distutils1.
:file:`setup.cfg` file is read. The callable receives the configuration
in form of a mapping and can make some changes to it. *\*optional*
+ Example::
+
+ [global]
+ setup_hook =
+ distutils2.tests.test_config.hook
+
metadata
========
The metadata section contains the metadata for the project as described in
-PEP 345.
+:PEP:`345`.
+.. Note::
+ Field names are case-insensitive.
Fields:
- **name**: Name of the project.
-- **version**: Version of the project. Must comply with PEP 386.
+- **version**: Version of the project. Must comply with :PEP:`386`.
- **platform**: Platform specification describing an operating system supported
by the distribution which is not listed in the "Operating System" Trove
- classifiers. *\*multi* *\*optional*
+ classifiers (:PEP:`301`). *\*multi* *\*optional*
- **supported-platform**: Binary distributions containing a PKG-INFO file will
use the Supported-Platform field in their metadata to specify the OS and
CPU for which the binary distribution was compiled. The semantics of
@@ -113,14 +132,18 @@ Example::
name = pypi2rpm
version = 0.1
author = Tarek Ziade
- author_email = tarek@ziade.org
+ author-email = tarek@ziade.org
summary = Script that transforms a sdist archive into a rpm archive
description-file = README
- home_page = http://bitbucket.org/tarek/pypi2rpm
+ home-page = http://bitbucket.org/tarek/pypi2rpm
+ project-url: RSS feed, https://bitbucket.org/tarek/pypi2rpm/rss
classifier = Development Status :: 3 - Alpha
License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1)
+.. Note::
+ Some metadata fields seen in :PEP:`345` are automatically generated
+ (for instance Metadata-Version value).
files
@@ -128,6 +151,8 @@ files
This section describes the files included in the project.
+- **packages_root**: the root directory containing all packages. If not provided
+ Distutils2 will use the current directory. *\*optional*
- **packages**: a list of packages the project includes *\*optional* *\*multi*
- **modules**: a list of packages the project includes *\*optional* *\*multi*
- **scripts**: a list of scripts the project includes *\*optional* *\*multi*
@@ -136,6 +161,7 @@ This section describes the files included in the project.
Example::
[files]
+ packages_root = src
packages =
pypi2rpm
pypi2rpm.command
@@ -145,17 +171,379 @@ Example::
extra_files =
setup.py
+ README
+
+.. Note::
+ In Distutils2, setup.cfg will be implicitly included.
+
+Resources
+=========
+
+This section describes the files used by the project which must not be installed in the same place that python modules or libraries, they are called **resources**. They are for example documentation files, script files, databases, etc...
+
+For declaring resources, you must use this notation ::
+
+ source = destination
+
+Data-files are declared in the **resources** field in the **file** section, for example::
+
+ [files]
+ resources =
+ source1 = destination1
+ source2 = destination2
+
+The **source** part of the declaration are relative paths of resources files (using unix path separator **/**). For example, if you've this source tree::
+
+ foo/
+ doc/
+ doc.man
+ scripts/
+ foo.sh
+
+Your setup.cfg will look like::
+
+ [files]
+ resources =
+ doc/doc.man = destination_doc
+ scripts/foo.sh = destination_scripts
+
+The final paths where files will be placed are composed by : **source** + **destination**. In the previous example, **doc/doc.man** will be placed in **destination_doc/doc/doc.man** and **scripts/foo.sh** will be placed in **destination_scripts/scripts/foo.sh**. (If you want more control on the final path, take a look at base_prefix_).
+
+The **destination** part of resources declaration are paths with categories. Indeed, it's generally a bad idea to give absolute path as it will be cross incompatible. So, you must use resources categories in your **destination** declaration. Categories will be replaced by their real path at the installation time. Using categories is all benefit, your declaration will be simpler, cross platform and it will allow packager to place resources files where they want without breaking your code.
+
+Categories can be specified by using this syntax::
+
+ {category}
+
+Default categories are::
+
+* config
+* appdata
+* appdata.arch
+* appdata.persistent
+* appdata.disposable
+* help
+* icon
+* scripts
+* doc
+* info
+* man
+
+A special category also exists **{distribution.name}** that will be replaced by the name of the distribution, but as most of the defaults categories use them, so it's not necessary to add **{distribution.name}** into your destination.
+
+If you use categories in your declarations, and you are encouraged to do, final path will be::
+
+ source + destination_expanded
+
+.. _example_final_path:
+
+For example, if you have this setup.cfg::
+
+ [metadata]
+ name = foo
+
+ [files]
+ resources =
+ doc/doc.man = {doc}
+
+And if **{doc}** is replaced by **{datadir}/doc/{distribution.name}**, final path will be::
+
+ {datadir}/doc/foo/doc/doc.man
+
+Where {datafir} category will be platform-dependent.
+
+
+More control on source part
+---------------------------
+
+Glob syntax
+___________
+
+When you declare source file, you can use a glob-like syntax to match multiples file, for example::
+
+ scripts/* = {script}
+
+Will match all the files in the scripts directory and placed them in the script category.
+
+Glob tokens are:
+
+ * * : match all files.
+ * ? : match any character.
+ * ** : match any level of tree recursion (even 0).
+ * {} : will match any part separated by comma (example : {sh,bat}).
+
+TODO ::
+
+ Add an example
+
+Order of declaration
+____________________
+
+The order of declaration is important if one file match multiple rules. The last rules matched by file is used, this is useful if you have this source tree::
+
+ foo/
+ doc/
+ index.rst
+ setup.rst
+ documentation.txt
+ doc.tex
+ README
+
+And you want all the files in the doc directory to be placed in {doc} category, but README must be placed in {help} category, instead of listing all the files one by one, you can declare them in this way::
+
+ [files]
+ resources =
+ doc/* = {doc}
+ doc/README = {help}
+
+Exclude
+_______
+
+You can exclude some files of resources declaration by giving no destination, it can be useful if you have a non-resources file in the same directory of resources files::
+
+ foo/
+ doc/
+ RELEASES
+ doc.tex
+ documentation.txt
+ docu.rst
+
+Your **file** section will be::
+
+ [files]
+ resources =
+ doc/* = {doc}
+ doc/RELEASES =
+
+More control on destination part
+--------------------------------
+
+.. _base_prefix:
+
+Define a base-prefix
+____________________
+
+When you define your resources, you can have more control of how the final path is compute.
+
+By default, the final path is::
+
+ destination + source
+
+This can generate long paths, for example (example_final_path_)::
+
+ {datadir}/doc/foo/doc/doc.man
+
+When you declare your source, you can use a separator to split the source in **prefix** **suffix**. The supported separator are :
+
+ * Whitespace
+
+So, for example, if you have this source::
+
+ docs/ doc.man
+
+The **prefix** is "docs/" and the **suffix** is "doc.html".
+
+.. note::
+
+ Separator can be placed after a path separator or replace it. So theses two sources are equivalent::
+
+ docs/ doc.man
+ docs doc.man
+
+.. note::
+
+ Glob syntax is working the same way with standard source and splitted source. So theses rules::
+
+ docs/*
+ docs/ *
+ docs *
+
+ Will match all the files in the docs directory.
+
+When you use splitted source, the final path is compute in this way::
+
+ destination + prefix
+
+So for example, if you have this setup.cfg::
+
+ [metadata]
+ name = foo
+
+ [files]
+ resources =
+ doc/ doc.man = {doc}
+
+And if **{doc}** is replaced by **{datadir}/doc/{distribution.name}**, final path will be::
+
+ {datadir}/doc/foo/doc.man
+
+
+Overwrite paths for categories
+------------------------------
+
+.. warning::
+
+ This part is intended for system administrator or packager.
+
+The real paths of categories are registered in the *sysconfig.cfg* file installed in your python installation. The format of this file is INI-like. The content of the file is organized into several sections :
+
+ * globals : Standard categories's paths.
+ * posix_prefix : Standard paths for categories and installation paths for posix system.
+ * other one...
+
+Standard categories's paths are platform independent, they generally refers to other categories, which are platform dependent. Sysconfig module will choose these category from sections matching os.name. For example::
+ doc = {datadir}/doc/{distribution.name}
-command sections
-================
+It refers to datadir category, which can be different between platforms. In posix system, it may be::
-Each command can have its options described in :file:`setup.cfg`
+ datadir = /usr/share
+
+So the final path will be::
+ doc = /usr/share/doc/{distribution.name}
+
+The platform dependent categories are :
+
+ * confdir
+ * datadir
+ * libdir
+ * base
+
+Define extra-categories
+-----------------------
+
+Examples
+--------
+
+.. note::
+
+ These examples are incremental but works unitarily.
+
+Resources in root dir
+_____________________
+
+Source tree::
+
+ babar-1.0/
+ README
+ babar.sh
+ launch.sh
+ babar.py
+
+Setup.cfg::
+
+ [files]
+ resources =
+ README = {doc}
+ *.sh = {scripts}
+
+So babar.sh and launch.sh will be placed in {scripts} directory.
+
+Now let's move all the scripts into a scripts directory.
+
+Resources in sub-directory
+__________________________
+
+Source tree::
+
+ babar-1.1/
+ README
+ scripts/
+ babar.sh
+ launch.sh
+ LAUNCH
+ babar.py
+
+Setup.cfg::
+
+ [files]
+ resources =
+ README = {doc}
+ scripts/ LAUNCH = {doc}
+ scripts/ *.sh = {scripts}
+
+It's important to use the separator after scripts/ to install all the bash scripts into {scripts} instead of {scripts}/scripts.
+
+Now let's add some docs.
+
+Resources in multiple sub-directories
+_____________________________________
+
+Source tree::
+
+ babar-1.2/
+ README
+ scripts/
+ babar.sh
+ launch.sh
+ LAUNCH
+ docs/
+ api
+ man
+ babar.py
+
+Setup.cfg::
+
+ [files]
+ resources =
+ README = {doc}
+ scripts/ LAUNCH = {doc}
+ scripts/ *.sh = {scripts}
+ doc/ * = {doc}
+ doc/ man = {man}
+
+You want to place all the file in the docs script into {doc} category, instead of man, which must be placed into {man} category, we will use the order of declaration of globs to choose the destination, the last glob that match the file is used.
+
+Now let's add some scripts for windows users.
+
+Complete example
+________________
+
+Source tree::
+
+ babar-1.3/
+ README
+ doc/
+ api
+ man
+ scripts/
+ babar.sh
+ launch.sh
+ babar.bat
+ launch.bat
+ LAUNCH
+
+Setup.cfg::
+
+ [files]
+ resources =
+ README = {doc}
+ scripts/ LAUNCH = {doc}
+ scripts/ *.{sh,bat} = {scripts}
+ doc/ * = {doc}
+ doc/ man = {man}
+
+We use brace expansion syntax to place all the bash and batch scripts into {scripts} category.
+
+.. Warning::
+ In Distutils2, setup.py and README (or README.txt) files are not more
+ included in source distribution by default
+
+`command` sections
+==================
+
+Each Distutils2 command can have its own user options defined in :file:`setup.cfg`
Example::
[sdist]
- manifest_makers = package.module.Maker
+ manifest-builders = package.module.Maker
+
+
+To override the build class in order to generate Python3 code from your Python2 base::
+
+ [build_py]
+ use-2to3 = True