This module provides an implementation of PEP 376. It was originally intended to land in pkgutil, but with the inclusion of Packaging in the standard library, it was thought best to include it in a submodule of packaging, leaving pkgutil to deal with imports.
Installed Python distributions are represented by instances of Distribution, or EggInfoDistribution for legacy egg formats. Most functions also provide an extra argument use_egg_info to take legacy distributions into account.
Class representing an installed distribution. It is different from packaging.dist.Distribution which holds the list of files, the metadata and options during the run of a Packaging command.
Instantiate with the path to a .dist-info directory. Instances can be compared and sorted. Other available methods are:
Return a read-only file object for a file located at project-version.dist-info/path. path should be a '/'-separated path relative to the .dist-info directory or an absolute path; if it is an absolute path and doesn’t start with the path to the .dist-info directory, a PackagingError is raised.
If binary is True, the file is opened in binary mode.
Return an iterator over all files located in the .dist-info directory. If local is True, each returned path is transformed into a local absolute path, otherwise the raw value found in the RECORD file is returned.
Iterate over the files installed with the distribution and registered in the RECORD file and yield a tuple (path, md5, size) for each line. If local is True, the returned path is transformed into a local absolute path, otherwise the raw value is returned.
A local absolute path is an absolute path in which occurrences of '/' have been replaced by os.sep.
Check whether path was installed by this distribution (i.e. if the path is present in the RECORD file). path can be a local absolute path or a relative '/'-separated path. Returns a boolean.
Available attributes:
Instance of packaging.metadata.Metadata filled with the contents of the project-version.dist-info/METADATA file.
Shortcut for metadata['Name'].
Shortcut for metadata['Version'].
Boolean indicating whether this distribution was requested by the user of automatically installed as a dependency.
Class representing a legacy distribution. It is compatible with distutils’ and setuptools’ .egg-info and .egg files and directories.
Instantiate with the path to an egg file or directory. Instances can be compared and sorted. Other available methods are:
Available attributes:
Instance of packaging.metadata.Metadata filled with the contents of the project-version.egg-info/PKG-INFO or project-version.egg file.
Shortcut for metadata['Name'].
Shortcut for metadata['Version'].
Return an instance of Distribution or EggInfoDistribution for the first installed distribution matching name. Egg distributions are considered only if use_egg_info is true; if both a dist-info and an egg file are found, the dist-info prevails. The directories to be searched are given in paths, which defaults to sys.path. Return None if no matching distribution is found.
Return an iterator of Distribution instances for all installed distributions found in paths (defaults to sys.path). If use_egg_info is true, also return instances of EggInfoDistribution for legacy distributions found.
Return an iterator over all distributions using path, a local absolute path or a relative '/'-separated path.
Return an iterator over all distributions that declare they obsolete name. version is an optional argument to match only specific releases (see packaging.version). If use_egg_info is true, legacy egg distributions will be considered as well.
Return an iterator over all distributions that declare they provide name. version is an optional argument to match only specific releases (see packaging.version). If use_egg_info is true, legacy egg distributions will be considered as well.
Escape name and version into a filename-safe form and return the directory name built from them, for example safename-safeversion.dist-info. In name, runs of non-alphanumeric characters are replaced with one '_'; in version, spaces become dots, and runs of other non-alphanumeric characters (except dots) a replaced by one '-'.
For performance purposes, the list of distributions is being internally cached. Caching is enabled by default, but you can control it with these functions:
Clear the cache.
Disable the cache, without clearing it.
Enable the internal cache, without clearing it.
Given a path to a .dist-info distribution, we shall print out all information that can be obtained using functions provided in this module:
import sys
import packaging.database
path = input()
# first create the Distribution instance
try:
dist = packaging.database.Distribution(path)
except FileNotFoundError:
sys.exit('No such distribution')
print('Information about %r' % dist.name)
print()
print('Files')
print('=====')
for path, md5, size in dist.list_installed_files():
print('* Path: %s' % path)
print(' Hash %s, Size: %s bytes' % (md5, size))
print()
print('Metadata')
print('========')
for key, value in dist.metadata.items():
print('%20s: %s' % (key, value))
print()
print('Extra')
print('=====')
if dist.requested:
print('* It was installed by user request')
else:
print('* It was installed as a dependency')
If we save the script above as print_info.py, we can use it to extract information from a .dist-info directory. By typing in the console:
$ echo /tmp/choxie/choxie-2.0.0.9.dist-info | python3 print_info.py
we get the following output:
Information about 'choxie'
Files
=====
* Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/truffles.py
Hash 5e052db6a478d06bad9ae033e6bc08af, Size: 111 bytes
* Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py
Hash ac56bf496d8d1d26f866235b95f31030, Size: 214 bytes
* Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py
Hash 416aab08dfa846f473129e89a7625bbc, Size: 25 bytes
* Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/INSTALLER
Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes
* Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA
Hash 696a209967fef3c8b8f5a7bb10386385, Size: 225 bytes
* Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/REQUESTED
Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes
* Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/RECORD
Hash None, Size: None bytes
Metadata
========
Metadata-Version: 1.2
Name: choxie
Version: 2.0.0.9
Platform: []
Supported-Platform: UNKNOWN
Summary: Chocolate with a kick!
Description: UNKNOWN
Keywords: []
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
Maintainer: UNKNOWN
Maintainer-email: UNKNOWN
License: UNKNOWN
Classifier: []
Download-URL: UNKNOWN
Obsoletes-Dist: ['truffles (<=0.8,>=0.5)', 'truffles (<=0.9,>=0.6)']
Project-URL: []
Provides-Dist: ['truffles (1.0)']
Requires-Dist: ['towel-stuff (0.1)']
Requires-Python: UNKNOWN
Requires-External: []
Extra
=====
* It was installed as a dependency
Now, we take tackle a different problem, we are interested in finding out which distributions have been obsoleted. This can be easily done as follows:
import packaging.database
# iterate over all distributions in the system
for dist in packaging.database.get_distributions():
name, version = dist.name, dist.version
# find out which distributions obsolete this name/version combination
replacements = packaging.database.obsoletes_distribution(name, version)
if replacements:
print('%r %s is obsoleted by' % (name, version),
', '.join(repr(r.name) for r in replacements))
This is how the output might look like:
'strawberry' 0.6 is obsoleted by 'choxie'
'grammar' 1.0a4 is obsoleted by 'towel-stuff'