using docutils in all examples + polished reST
This commit is contained in:
parent
98e6c43034
commit
c8bc9c1f23
161
pep-0376.txt
161
pep-0376.txt
|
@ -32,13 +32,13 @@ its `name`, its `version`, and so on.
|
||||||
|
|
||||||
Disutils provides among other things **commands** that can be called
|
Disutils provides among other things **commands** that can be called
|
||||||
through the shell using the `setup.py` script. A `sdist` command is provided
|
through the shell using the `setup.py` script. A `sdist` command is provided
|
||||||
for instance, to create a source distribution archive. An `install` command
|
for instance to create a source distribution archive. An `install` command
|
||||||
is also provided, to perform an installation of the distribution in the Python
|
is also provided to perform an installation of the distribution in the Python
|
||||||
installation the script is invoked with::
|
installation the script is invoked with::
|
||||||
|
|
||||||
$ python setup.py install
|
$ python setup.py install
|
||||||
|
|
||||||
See the Distutils [distutils]_ documentation for more information.
|
See the Distutils [#distutils]_ documentation for more information.
|
||||||
|
|
||||||
Once installed, the elements are located in various places in the system, like:
|
Once installed, the elements are located in various places in the system, like:
|
||||||
|
|
||||||
|
@ -64,8 +64,8 @@ Right now, when a distribution is installed in Python, every elements its contai
|
||||||
is installed in various directories.
|
is installed in various directories.
|
||||||
|
|
||||||
The pure Python code for instance is installed in the `purelib` directory,
|
The pure Python code for instance is installed in the `purelib` directory,
|
||||||
which is located in the Python installation in `lib\python2.6\site-packages`
|
which is located in the Python installation in ``lib\python2.6\site-packages``
|
||||||
for example under unix-like systems or Mac OS X, and in `Lib/site-packages`
|
for example under unix-like systems or Mac OS X, and in ``Lib/site-packages``
|
||||||
under Windows. This is done with the Distutils `install` command, which calls
|
under Windows. This is done with the Distutils `install` command, which calls
|
||||||
various subcommands.
|
various subcommands.
|
||||||
|
|
||||||
|
@ -74,20 +74,21 @@ create an `.egg-info` file in the `purelib` directory.
|
||||||
|
|
||||||
For example, for the `docutils` distribution, which contains one package an
|
For example, for the `docutils` distribution, which contains one package an
|
||||||
extra module and executable scripts, three elements will be installed in
|
extra module and executable scripts, three elements will be installed in
|
||||||
`site-packages`::
|
`site-packages`:
|
||||||
|
|
||||||
- docutils : the docutils pakage
|
- `docutils` : the ``docutils`` pakage
|
||||||
- roman.py : an extra module used by docutils
|
- `roman.py` : an extra module used by `docutils`
|
||||||
- docutils-0.5-py2.6.egg-info : a file containing the distribution metadata
|
- `docutils-0.5-py2.6.egg-info` : a file containing the distribution metadata
|
||||||
as described in PEP 314 [#pep314]_. This file corresponds to the file
|
as described in PEP 314 [#pep314]_. This file corresponds to the file
|
||||||
called `PKG-INFO`, built by the `sdist` command.
|
called `PKG-INFO`, built by the `sdist` command.
|
||||||
|
|
||||||
Some executable scripts such as `rst2html.py` will also be added in the `bin`
|
Some executable scripts such as `rst2html.py` will also be added in the `bin`
|
||||||
directory of the Python installation.
|
directory of the Python installation.
|
||||||
|
|
||||||
The problem is that many people use `easy_install` (setuptools [#setuptools]_)
|
The problem is that many people use `easy_install` (from the `setuptools`
|
||||||
or `pip` [#pip]_ to install their packages, and these third-party tools do not
|
project [#setuptools]_) or `pip` [#pip]_ to install their packages, and
|
||||||
install packages in the same way that Distutils does:
|
these third-party tools do not install packages in the same way that Distutils
|
||||||
|
does:
|
||||||
|
|
||||||
- `easy_install` creates an `EGG-INFO` directory inside an `.egg` directory,
|
- `easy_install` creates an `EGG-INFO` directory inside an `.egg` directory,
|
||||||
and adds a `PKG-INFO` file inside this directory. The `.egg` directory
|
and adds a `PKG-INFO` file inside this directory. The `.egg` directory
|
||||||
|
@ -115,7 +116,7 @@ Setuptools.
|
||||||
|
|
||||||
Under some circumstances, you might not be able to know for sure that you
|
Under some circumstances, you might not be able to know for sure that you
|
||||||
have removed everything, or that you didn't break another distribution by
|
have removed everything, or that you didn't break another distribution by
|
||||||
removing a file that was shared among several distributions.
|
removing a file that is shared among several distributions.
|
||||||
|
|
||||||
But there's common behavior: when you install a distribution, files are copied
|
But there's common behavior: when you install a distribution, files are copied
|
||||||
in your system. And there's a way to keep track of theses files, so to remove
|
in your system. And there's a way to keep track of theses files, so to remove
|
||||||
|
@ -161,7 +162,7 @@ file, the change will have no deep consequences.
|
||||||
For example, if the `docutils` package is installed, the elements that
|
For example, if the `docutils` package is installed, the elements that
|
||||||
will be installed in `site-packages` will become::
|
will be installed in `site-packages` will become::
|
||||||
|
|
||||||
- docutils
|
- docutils/
|
||||||
- roman.py
|
- roman.py
|
||||||
- docutils-0.5-py2.6.egg-info/
|
- docutils-0.5-py2.6.egg-info/
|
||||||
PKG-INFO
|
PKG-INFO
|
||||||
|
@ -215,7 +216,7 @@ the `excel` dialect, which uses these options to read the file:
|
||||||
|
|
||||||
- field delimiter : `,`
|
- field delimiter : `,`
|
||||||
- quoting char : `"`.
|
- quoting char : `"`.
|
||||||
- line terminator : ``os.linesep`` (so `\r\n` or `\r`)
|
- line terminator : ``os.linesep`` (so ``\r\n`` or ``\r``)
|
||||||
|
|
||||||
Each record is composed of three elements.
|
Each record is composed of three elements.
|
||||||
|
|
||||||
|
@ -242,33 +243,34 @@ so the field separator will be ",". Any "," characters found within a field
|
||||||
will be escaped automatically by ``csv``.
|
will be escaped automatically by ``csv``.
|
||||||
|
|
||||||
When the file is read, the `U` option will be used so the universal newline
|
When the file is read, the `U` option will be used so the universal newline
|
||||||
support (see PEP 278 [pep278]_) will be activated, avoiding any trouble
|
support (see PEP 278 [#pep278]_) will be activated, avoiding any trouble
|
||||||
reading a file produced on a platform that uses a different new line
|
reading a file produced on a platform that uses a different new line
|
||||||
terminator.
|
terminator.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Back to our `zlib` example, we will have::
|
Back to our `docutils` example, we will have::
|
||||||
|
|
||||||
- zlib
|
- docutils/
|
||||||
- zlib-2.5.2.egg-info/
|
- roman.py
|
||||||
|
- docutils-0.5-py2.6.egg-info/
|
||||||
PKG-INFO
|
PKG-INFO
|
||||||
RECORD
|
RECORD
|
||||||
|
|
||||||
And the RECORD file will contain::
|
And the RECORD file will contain (extract)::
|
||||||
|
|
||||||
zlib/include/zconf.h,b690274f621402dda63bf11ba5373bf2,9544
|
docutils/__init__.py,b690274f621402dda63bf11ba5373bf2,9544
|
||||||
zlib/include/zlib.h,9c4b84aff68aa55f2e9bf70481b94333,66188
|
docutils/core.py,9c4b84aff68aa55f2e9bf70481b94333,66188
|
||||||
zlib/lib/libz.a,e6d43fb94292411909404b07d0692d46,91128
|
roman.py,a4b84aff68aa55f2e9bf70481b943D3,234
|
||||||
zlib/share/man/man3/zlib.3,785dc03452f0508ff0678fba2457e0ba,4486
|
/usr/local/bin/rst2html.py,a4b84aff68aa55f2e9bf70481b943D3,234
|
||||||
zlib-2.5.2.egg-info/PKG-INFO,6fe57de576d749536082d8e205b77748,195
|
docutils-0.5-py2.6.egg-info/PKG-INFO,6fe57de576d749536082d8e205b77748,195
|
||||||
zlib-2.5.2.egg-info/RECORD
|
docutils-0.5-py2.6.egg-info/RECORD
|
||||||
|
|
||||||
Notice that:
|
Notice that:
|
||||||
|
|
||||||
- the `RECORD` file can't contain a hash of itself and is just mentioned here
|
- the `RECORD` file can't contain a hash of itself and is just mentioned here
|
||||||
- `zlib` and `zlib-2.5.2.egg-info` are located in `site-packages` so the file
|
- `docutils` and `docutils-0.5-py2.6.egg-info` are located in `site-packages` so the file
|
||||||
paths are relative to it.
|
paths are relative to it.
|
||||||
|
|
||||||
Adding an INSTALLER file in the .egg-info directory
|
Adding an INSTALLER file in the .egg-info directory
|
||||||
|
@ -294,7 +296,7 @@ library a set of APIs. The best place to put these APIs seems to be `pkgutil`.
|
||||||
|
|
||||||
The API is organized in five classes that work with directories and Zip files
|
The API is organized in five classes that work with directories and Zip files
|
||||||
(so its works with files included in Zip files, see PEP 273 for more details
|
(so its works with files included in Zip files, see PEP 273 for more details
|
||||||
[pep273]_.
|
[#pep273]_.
|
||||||
|
|
||||||
- ``Distribution``: manages an `.egg-info` directory.
|
- ``Distribution``: manages an `.egg-info` directory.
|
||||||
- ``ZippedDistribution``: manages an `.egg-info` directory contained in a zip
|
- ``ZippedDistribution``: manages an `.egg-info` directory contained in a zip
|
||||||
|
@ -312,6 +314,10 @@ A new class called ``Distribution`` is created with a the path of the
|
||||||
`.egg-info` directory provided to the contructor. It reads the metadata
|
`.egg-info` directory provided to the contructor. It reads the metadata
|
||||||
contained in `PKG-INFO` when it is instanciated.
|
contained in `PKG-INFO` when it is instanciated.
|
||||||
|
|
||||||
|
``Distribution(path)`` -> instance
|
||||||
|
|
||||||
|
Creates a ``Distribution`` instance for the given ``path``.
|
||||||
|
|
||||||
``Distribution`` provides the following attributes:
|
``Distribution`` provides the following attributes:
|
||||||
|
|
||||||
- ``name``: The name of the distribution.
|
- ``name``: The name of the distribution.
|
||||||
|
@ -362,6 +368,12 @@ ZippedDistribution class
|
||||||
A ``ZippedDistribution`` class is provided. It overrides the ``Distribution``
|
A ``ZippedDistribution`` class is provided. It overrides the ``Distribution``
|
||||||
class so its methods work with an `.egg.info` directory located in a zip file.
|
class so its methods work with an `.egg.info` directory located in a zip file.
|
||||||
|
|
||||||
|
``ZippedDistribution(zipfile, path)`` -> instance
|
||||||
|
|
||||||
|
Creates a ``ZippedDistribution`` instance for the given relative ``path``
|
||||||
|
located in the ``zipfile`` file.
|
||||||
|
|
||||||
|
Other public methods and attributes are similar to ``Distribution``.
|
||||||
|
|
||||||
DistributionDirectory class
|
DistributionDirectory class
|
||||||
---------------------------
|
---------------------------
|
||||||
|
@ -373,17 +385,17 @@ corresponding to a directory. For each `.egg-info` directory founded in
|
||||||
The class is a ``set`` of ``Distribution`` instances. ``DistributionDirectory``
|
The class is a ``set`` of ``Distribution`` instances. ``DistributionDirectory``
|
||||||
provides a ``path`` attribute corresponding to the path is was created with.
|
provides a ``path`` attribute corresponding to the path is was created with.
|
||||||
|
|
||||||
It also provides two methods besides the ones from ``set``:
|
``DistributionDirectory(path)`` -> instance
|
||||||
|
|
||||||
|
Creates a ``DistributionDirectory`` instance for the given ``path``.
|
||||||
|
|
||||||
|
It also provides one extra method besides the ones from ``set``:
|
||||||
|
|
||||||
- ``get_file_users(path)`` -> Iterator of ``Distribution``.
|
- ``get_file_users(path)`` -> Iterator of ``Distribution``.
|
||||||
|
|
||||||
Returns all ``Distribution`` which uses ``path``, by calling
|
Returns all ``Distribution`` which uses ``path``, by calling
|
||||||
``Distribution.uses(path)`` on all ``Distribution`` instances.
|
``Distribution.uses(path)`` on all ``Distribution`` instances.
|
||||||
|
|
||||||
- ``owner(path)`` -> ``Distribution`` instance or None
|
|
||||||
|
|
||||||
If ``path`` is used by only one ``Distribution`` instance, returns it.
|
|
||||||
Otherwise returns None.
|
|
||||||
|
|
||||||
ZippedDistributionDirectory class
|
ZippedDistributionDirectory class
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
@ -391,30 +403,42 @@ ZippedDistributionDirectory class
|
||||||
A ``ZippedDistributionDirectory`` is provided. It overrides the
|
A ``ZippedDistributionDirectory`` is provided. It overrides the
|
||||||
``DistributionDirectory`` class so its methods work with a Zip file.
|
``DistributionDirectory`` class so its methods work with a Zip file.
|
||||||
|
|
||||||
|
``ZippedDistributionDirectory(path)`` -> instance
|
||||||
|
|
||||||
|
Creates a ``ZippedDistributionDirectory`` instance for the given ``path``.
|
||||||
|
|
||||||
|
Other public methods and attributes are similar to ``DistributionDirectory``.
|
||||||
|
|
||||||
|
|
||||||
DistributionDirectories class
|
DistributionDirectories class
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
A new class called ``DistributionDirectories`` is created. It's a collection of
|
A new class called ``DistributionDirectories`` is created. It's a collection of
|
||||||
``DistributionDirectory`` and ``ZippedDistributionDirectory`` instances.
|
``DistributionDirectory`` and ``ZippedDistributionDirectory`` instances.
|
||||||
The constructor takes one optional argument ``use_cache`` set to ``True`` by
|
|
||||||
default. When ``True``, ``DistributionDirectories`` will use a global cache
|
|
||||||
to reduce the numbers of I/O accesses and speed up the lookups.
|
|
||||||
|
|
||||||
The cache is a global mapping containing ``DistributionDirectory`` and
|
``DistributionDirectories(paths=None, use_cache=True)`` -> instance
|
||||||
``ZippedDistributionDirectory`` instances. When an ``DistributionDirectories``
|
|
||||||
object is created, it will use the cache to add an entry for each path it
|
|
||||||
visits, or reuse existing entries. The cache usage can be disabled at any time
|
|
||||||
with the ``use_cache`` attribute.
|
|
||||||
|
|
||||||
The cache can also be emptied with the global ``purge_cache`` function.
|
If ``paths`` is not not, it's a sequence of paths the constructor loads
|
||||||
|
in the instance.
|
||||||
|
|
||||||
|
The constructor also takes an optional ``use_cache`` argument.
|
||||||
|
When it's ``True``, ``DistributionDirectories`` will use a global
|
||||||
|
cache to reduce the numbers of I/O accesses and speed up the lookups.
|
||||||
|
|
||||||
|
The cache is a global mapping containing ``DistributionDirectory`` and
|
||||||
|
``ZippedDistributionDirectory`` instances. When a
|
||||||
|
``DistributionDirectories`` object is created, it will use the cache to
|
||||||
|
add an entry for each path it visits, or reuse existing entries. The
|
||||||
|
cache usage can be disabled at any time with the ``use_cache`` attribute.
|
||||||
|
|
||||||
|
The cache can also be emptied with the global ``purge_cache`` function.
|
||||||
|
|
||||||
The class is a ``dict`` where the values are ``DistributionDirectory``
|
The class is a ``dict`` where the values are ``DistributionDirectory``
|
||||||
and ``ZippedDistributionDirectory`` instances and the keys are their path
|
and ``ZippedDistributionDirectory`` instances and the keys are their path
|
||||||
attributes.
|
attributes.
|
||||||
|
|
||||||
``DistributionDirectories`` also provides the following methods besides the ones
|
``DistributionDirectories`` also provides the following methods besides the ones
|
||||||
from ``dict``::
|
from ``dict``:
|
||||||
|
|
||||||
- ``load(*paths)``
|
- ``load(*paths)``
|
||||||
|
|
||||||
|
@ -478,26 +502,29 @@ to use the cache. Notice that the cache is never emptied explicitely.
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Let's use some of the new APIs with our `zlib` example::
|
Let's use some of the new APIs with our `docutils` example::
|
||||||
|
|
||||||
>>> from pkgutil import get_distribution, get_file_users
|
>>> from pkgutil import get_distribution, get_file_users
|
||||||
>>> dist = get_distribution('zlib')
|
>>> dist = get_distribution('docutils')
|
||||||
>>> dist.name
|
>>> dist.name
|
||||||
'zlib'
|
'docutils'
|
||||||
>>> dist.metadata.version
|
>>> dist.metadata.version
|
||||||
'2.5.2'
|
'0.5'
|
||||||
|
|
||||||
>>> for path, hash, size in dist.get_installed_files()::
|
>>> for path, hash, size in dist.get_installed_files()::
|
||||||
... print '%s %s %d' % (path, hash, size)
|
... print '%s %s %d' % (path, hash, size)
|
||||||
...
|
...
|
||||||
zlib/include/zconf.h b690274f621402dda63bf11ba5373bf2 9544
|
docutils/__init__.py b690274f621402dda63bf11ba5373bf2 9544
|
||||||
zlib/include/zlib.h 9c4b84aff68aa55f2e9bf70481b94333 66188
|
docutils/core.py 9c4b84aff68aa55f2e9bf70481b94333 66188
|
||||||
zlib/lib/libz.a e6d43fb94292411909404b07d0692d46 91128
|
roman.py a4b84aff68aa55f2e9bf70481b943D3 234
|
||||||
zlib/share/man/man3/zlib.3 785dc03452f0508ff0678fba2457e0ba 4486
|
/usr/local/bin/rst2html.py a4b84aff68aa55f2e9bf70481b943D3 234
|
||||||
zlib-2.5.2.egg-info/PKG-INFO 6fe57de576d749536082d8e205b77748 195
|
docutils-0.5-py2.6.egg-info/PKG-INFO 6fe57de576d749536082d8e205b77748 195
|
||||||
zlib-2.5.2.egg-info/RECORD None None
|
docutils-0.5-py2.6.egg-info/RECORD None None
|
||||||
|
|
||||||
>>> dist.uses('zlib/include/zlib.h')
|
>>> dist.uses('docutils/core.py')
|
||||||
|
True
|
||||||
|
|
||||||
|
>>> dist.uses('/usr/local/bin/rst2html.py')
|
||||||
True
|
True
|
||||||
|
|
||||||
>>> dist.get_egginfo_file('PKG-INFO')
|
>>> dist.get_egginfo_file('PKG-INFO')
|
||||||
|
@ -539,9 +566,10 @@ empty directories left behind.
|
||||||
``uninstall`` will return a list of uninstalled files::
|
``uninstall`` will return a list of uninstalled files::
|
||||||
|
|
||||||
>>> from distutils.util import uninstall
|
>>> from distutils.util import uninstall
|
||||||
>>> uninstall('zlib')
|
>>> uninstall('docutils')
|
||||||
['/opt/local/lib/python2.6/site-packages/zlib/file1',
|
['/opt/local/lib/python2.6/site-packages/docutils/core.py',
|
||||||
'/opt/local/lib/python2.6/site-packages/zlib/file2']
|
...
|
||||||
|
'/opt/local/lib/python2.6/site-packages/docutils/__init__.py']
|
||||||
|
|
||||||
If the distribution is not found, a ``DistutilsUninstallError`` will be raised.
|
If the distribution is not found, a ``DistutilsUninstallError`` will be raised.
|
||||||
|
|
||||||
|
@ -559,13 +587,13 @@ Examples::
|
||||||
... logging.info('Removing %s' % path)
|
... logging.info('Removing %s' % path)
|
||||||
... return True
|
... return True
|
||||||
...
|
...
|
||||||
>>> uninstall('zlib', _remove_and_log)
|
>>> uninstall('docutils', _remove_and_log)
|
||||||
|
|
||||||
>>> def _dry_run(path):
|
>>> def _dry_run(path):
|
||||||
... logging.info('Removing %s (dry run)' % path)
|
... logging.info('Removing %s (dry run)' % path)
|
||||||
... return False
|
... return False
|
||||||
...
|
...
|
||||||
>>> uninstall('zlib', _dry_run)
|
>>> uninstall('docutils', _dry_run)
|
||||||
|
|
||||||
Of course, a third-party tool can use ``pkgutil`` APIs to implement
|
Of course, a third-party tool can use ``pkgutil`` APIs to implement
|
||||||
its own uninstall feature.
|
its own uninstall feature.
|
||||||
|
@ -583,12 +611,12 @@ to ``distutils``.
|
||||||
When called, ``uninstall`` will control that the ``INSTALLER`` file matches
|
When called, ``uninstall`` will control that the ``INSTALLER`` file matches
|
||||||
this argument. If not, it will raise a ``DistutilsUninstallError``::
|
this argument. If not, it will raise a ``DistutilsUninstallError``::
|
||||||
|
|
||||||
>>> uninstall('zlib')
|
>>> uninstall('docutils')
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
DistutilsUninstallError: zlib was installed by 'cool-pkg-manager'
|
DistutilsUninstallError: docutils was installed by 'cool-pkg-manager'
|
||||||
|
|
||||||
>>> uninstall('zlib', installer='cool-pkg-manager')
|
>>> uninstall('docutils', installer='cool-pkg-manager')
|
||||||
|
|
||||||
This allows a third-party application to use the ``uninstall`` function
|
This allows a third-party application to use the ``uninstall`` function
|
||||||
and make sure it's the only program that can remove a distribution it has
|
and make sure it's the only program that can remove a distribution it has
|
||||||
|
@ -607,9 +635,13 @@ provided so people can benefit from these new features.
|
||||||
|
|
||||||
The plan is to integrate them for Python 2.7 and Python 3.2
|
The plan is to integrate them for Python 2.7 and Python 3.2
|
||||||
|
|
||||||
|
|
||||||
References
|
References
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
.. [#distutils]
|
||||||
|
http://docs.python.org/distutils
|
||||||
|
|
||||||
.. [#pep262]
|
.. [#pep262]
|
||||||
http://www.python.org/dev/peps/pep-0262
|
http://www.python.org/dev/peps/pep-0262
|
||||||
|
|
||||||
|
@ -628,13 +660,10 @@ References
|
||||||
.. [#pep273]
|
.. [#pep273]
|
||||||
http://www.python.org/dev/peps/pep-0273
|
http://www.python.org/dev/peps/pep-0273
|
||||||
|
|
||||||
.. [#pep2738]
|
.. [#pep278]
|
||||||
http://www.python.org/dev/peps/pep-0278
|
http://www.python.org/dev/peps/pep-0278
|
||||||
|
|
||||||
|
|
||||||
.. [distutils]
|
|
||||||
http://docs.python.org/distutils
|
|
||||||
|
|
||||||
Aknowledgments
|
Aknowledgments
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue