renamed project to distribution

This commit is contained in:
Tarek Ziadé 2009-06-22 13:06:55 +00:00
parent 8f153bdac1
commit 45a852796f
1 changed files with 62 additions and 42 deletions

View File

@ -17,22 +17,33 @@ Abstract
This PEP proposes various enhancements for Distutils: This PEP proposes various enhancements for Distutils:
- A new format for the .egg-info structure. - A new format for the .egg-info structure.
- Some APIs to read the meta-data of a project - Some APIs to read the meta-data of a distribution
- A replacement PEP 262 - A replacement PEP 262
- An uninstall feature - An uninstall feature
Definitions Definitions
=========== ===========
A **project** is a distribution of one or several files, which can be Python A **distribution** is a collection of files, which can be Python modules,
modules, extensions or data. It is distributed using a `setup.py` script extensions or data. A distribution is managed by a special module called
with Distutils and/or Setuptools. The `setup.py` script indicates where each `setup.py` which contains a call to the `distutils.core.setup` function.
elements should be installed. The arguments passed to that function describe the distribution, like
its `name`, its `version`, and so on.
Disutils provides among other things **commands** that can be called
through the shell using the `setup.py` script. A `sdist` command is provided
for instance, to create a source distribution archive. An `install` command
is also provided, to perform an installation of the distribution in the Python
installation the script is invoked with::
$ python setup.py install
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:
- in Python's site-packages (Python modules, Python modules organized into packages, - in Python's site-packages (Python modules, Python modules organized into
Extensions, etc.) packages, Extensions, etc.)
- in Python's `include` directory. - in Python's `include` directory.
- in Python's `bin` or `Script` directory. - in Python's `bin` or `Script` directory.
- etc. - etc.
@ -40,15 +51,16 @@ Once installed, the elements are located in various places in the system, like:
Rationale Rationale
========= =========
There are two problems right now in the way projects are installed in Python: There are two problems right now in the way distributions are installed in
Python:
- There are too many ways to do it. - There are too many ways to do it.
- There is no API to get the metadata of installed projects. - There is no API to get the metadata of installed distributions.
How projects are installed How distributions are installed
-------------------------- -------------------------------
Right now, when a project is installed in Python, every elements its contains Right now, when a distribution is installed in Python, every elements its contains
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,
@ -60,14 +72,14 @@ various subcommands.
The `install_egg_info` subcommand is called during this process, in order to The `install_egg_info` subcommand is called during this process, in order to
create an `.egg-info` file in the `purelib` directory. create an `.egg-info` file in the `purelib` directory.
For example, if the `zlib` project (which contains one package) is installed, For example, if the `zlib` distribution (which contains one package) is
two elements will be installed in `site-packages`:: installed, two elements will be installed in `site-packages`::
- zlib - zlib
- zlib-2.5.2-py2.4.egg-info - zlib-2.5.2-py2.4.egg-info
Where `zlib` is a Python package, and `zlib-2.5.2-py2.4.egg-info` is Where `zlib` is a Python package, and `zlib-2.5.2-py2.4.egg-info` is
a file containing the project metadata as described in PEP 314 [#pep314]_. a file containing the distribution metadata as described in PEP 314 [#pep314]_.
This file corresponds to the file called `PKG-INFO`, built by This file corresponds to the file called `PKG-INFO`, built by
the `sdist` command. the `sdist` command.
@ -78,12 +90,12 @@ 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
contains in that case all the elements of the project that are supposed to contains in that case all the elements of the distribution that are supposed
be installed in `site-packages`, and is placed in the `site-packages` to be installed in `site-packages`, and is placed in the `site-packages`
directory. directory.
- `pip` creates an `.egg-info` directory inside the `site-packages` directory - `pip` creates an `.egg-info` directory inside the `site-packages` directory
and adds a `PKG-INFO` file inside it. Elements of the project are then and adds a `PKG-INFO` file inside it. Elements of the distribution are then
installed in various places like Distutils does. installed in various places like Distutils does.
They both add other files in the `EGG-INFO` or `.egg-info` directory, and They both add other files in the `EGG-INFO` or `.egg-info` directory, and
@ -93,17 +105,18 @@ Uninstall information
--------------------- ---------------------
Distutils doesn't provide any `uninstall` command. If you want to uninstall Distutils doesn't provide any `uninstall` command. If you want to uninstall
a project, you have to be a power user and remove the various elements that a distribution, you have to be a power user and remove the various elements
were installed. Then look over the `.pth` file to clean them if necessary. that were installed. Then look over the `.pth` file to clean them if necessary.
And the process differs, depending on the tools you have used to install the And the process differs, depending on the tools you have used to install the
project, and if the project's `setup.py` uses Distutils or Setuptools. distribution, and if the distribution's `setup.py` uses Distutils or
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 project by have removed everything, or that you didn't break another distribution by
removing a file that was shared among several projects. removing a file that was shared among several distributions.
But there's common behavior: when you install a project, 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
them. them.
@ -115,7 +128,7 @@ To address those issues, this PEP proposes a few changes:
- a new `.egg-info` structure using a directory, based on one form of - a new `.egg-info` structure using a directory, based on one form of
the `EggFormats` standard from `setuptools` [#eggformats]_. the `EggFormats` standard from `setuptools` [#eggformats]_.
- new APIs in `pkgutil` to be able to query the information of installed - new APIs in `pkgutil` to be able to query the information of installed
projects. distributions.
- a de-facto replacement for PEP 262 - a de-facto replacement for PEP 262
- an uninstall function in Distutils. - an uninstall function in Distutils.
@ -131,7 +144,7 @@ Notice that this change is based on the standard proposed by `EggFormats`.
Although, this standard proposes two ways to install files : Although, this standard proposes two ways to install files :
- a self-contained directory that can be zipped or left unzipped and that - a self-contained directory that can be zipped or left unzipped and that
contains the project files *and* the `.egg-info` directory. contains the distribution files *and* the `.egg-info` directory.
- a distinct `.egg-info` directory located in the site-packages directory. - a distinct `.egg-info` directory located in the site-packages directory.
@ -259,9 +272,9 @@ lower-case string matching `[a-z0-9_\-\.]`.
It will default to `distutils` if not provided. It will default to `distutils` if not provided.
When a project is installed, the INSTALLER file is generated in the When a distribution is installed, the INSTALLER file is generated in the
`.egg-info` directory with this value, to keep track of **who** installed the `.egg-info` directory with this value, to keep track of **who** installed the
project. The file is a single-line text file. distribution. The file is a single-line text file.
New APIs in pkgutil New APIs in pkgutil
=================== ===================
@ -269,7 +282,9 @@ New APIs in pkgutil
To use the `.egg-info` directory content, we need to add in the standard To use the `.egg-info` directory content, we need to add in the standard
library a set of APIs. The best place to put these APIs seems to be `pkgutil`. library a set of APIs. The best place to put these APIs seems to be `pkgutil`.
The API is organized in five classes: 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
[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
@ -280,8 +295,6 @@ The API is organized in five classes:
some `.egg.info` directory. some `.egg.info` directory.
- ``DistributionDirectories``: manages ``EggInfoDirectory`` instances. - ``DistributionDirectories``: manages ``EggInfoDirectory`` instances.
XXX mention PEP 273
Distribution class Distribution class
------------------ ------------------
@ -412,16 +425,16 @@ from ``dict``::
Iterates over all ``Distribution`` and ``ZippedDistribution`` contained Iterates over all ``Distribution`` and ``ZippedDistribution`` contained
in ``DistributionDirectory`` and ``ZippedDistributionDirectory`` instances. in ``DistributionDirectory`` and ``ZippedDistributionDirectory`` instances.
- ``get_distribution(project_name)`` -> ``Distribution`` (or - ``get_distribution(dist_name)`` -> ``Distribution`` (or
``ZippedDistribution``) or None. ``ZippedDistribution``) or None.
Returns a ``Distribution`` (or ``ZippedDistribution``) instance for the Returns a ``Distribution`` (or ``ZippedDistribution``) instance for the
given project name. If not found, returns None. given distribution name. If not found, returns None.
- ``get_file_users(path)`` -> Iterator of ``Distribution`` (or - ``get_file_users(path)`` -> Iterator of ``Distribution`` (or
``ZippedDistribution``) instances. ``ZippedDistribution``) instances.
Iterates over all projects to find out which project uses the file. Iterates over all distributions to find out which distributions use the file.
Returns ``Distribution`` (or ``ZippedDistribution``) instances. Returns ``Distribution`` (or ``ZippedDistribution``) instances.
.egg-info functions .egg-info functions
@ -450,7 +463,7 @@ The new functions added in the ``pkgutil`` are :
- ``get_file_users(path)`` -> iterator of ``Distribution`` (or - ``get_file_users(path)`` -> iterator of ``Distribution`` (or
``ZippedDistribution``) instances. ``ZippedDistribution``) instances.
Iterates over all projects to find out which project uses ``path``. Iterates over all distributions to find out which distributions uses ``path``.
``path`` can be a local absolute path or a relative '/'-separated path. ``path`` can be a local absolute path or a relative '/'-separated path.
All these functions use the same global instance of ``DistributionDirectories`` All these functions use the same global instance of ``DistributionDirectories``
@ -507,12 +520,13 @@ standard and will fullfill the requirements described in PEP 262, like the
Adding an Uninstall function Adding an Uninstall function
============================ ============================
Distutils already provides a very basic way to install a project, which is running Distutils already provides a very basic way to install a distribution, which
the `install` command over the `setup.py` script of the distribution. is running the `install` command over the `setup.py` script of the
distribution.
Distutils will provide a very basic ``uninstall`` function, that will be added Distutils will provide a very basic ``uninstall`` function, that will be added
in ``distutils.util`` and will take the name of the project to uninstall as in ``distutils.util`` and will take the name of the distribution to uninstall
its argument. ``uninstall`` will use the APIs desribed earlier and remove all as its argument. ``uninstall`` will use the APIs desribed earlier and remove all
unique files, as long as their hash didn't change. Then it will remove unique files, as long as their hash didn't change. Then it will remove
empty directories left behind. empty directories left behind.
@ -523,7 +537,7 @@ empty directories left behind.
['/opt/local/lib/python2.6/site-packages/zlib/file1', ['/opt/local/lib/python2.6/site-packages/zlib/file1',
'/opt/local/lib/python2.6/site-packages/zlib/file2'] '/opt/local/lib/python2.6/site-packages/zlib/file2']
If the project is not found, a ``DistutilsUninstallError`` will be raised. If the distribution is not found, a ``DistutilsUninstallError`` will be raised.
Filtering Filtering
--------- ---------
@ -556,7 +570,7 @@ Installer marker
As explained earlier in this PEP, the `install` command adds an `INSTALLER` As explained earlier in this PEP, the `install` command adds an `INSTALLER`
file in the `.egg-info` directory with the name of the installer. file in the `.egg-info` directory with the name of the installer.
To avoid removing projects that where installed by another packaging system, To avoid removing distributions that where installed by another packaging system,
the ``uninstall`` function takes an extra argument ``installer`` which default the ``uninstall`` function takes an extra argument ``installer`` which default
to ``distutils``. to ``distutils``.
@ -571,7 +585,7 @@ this argument. If not, it will raise a ``DistutilsUninstallError``::
>>> uninstall('zlib', installer='cool-pkg-manager') >>> uninstall('zlib', 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 project it has and make sure it's the only program that can remove a distribution it has
previously installed. This is useful when a third-party program that relies previously installed. This is useful when a third-party program that relies
on Distutils APIs does extra steps on the system at installation time, on Distutils APIs does extra steps on the system at installation time,
it has to undo at uninstallation time. it has to undo at uninstallation time.
@ -605,6 +619,12 @@ References
.. [#eggformats] .. [#eggformats]
http://peak.telecommunity.com/DevCenter/EggFormats http://peak.telecommunity.com/DevCenter/EggFormats
.. [#pep273]
http://www.python.org/dev/peps/pep-0273
.. [distutils]
http://docs.python.org/distutils
Aknowledgments Aknowledgments
============== ==============