Commit b88a4960 authored by Tarek Ziadé's avatar Tarek Ziadé

Merged revisions 76702,76704 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r76702 | tarek.ziade | 2009-12-08 09:56:49 +0100 (Tue, 08 Dec 2009) | 1 line

  Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata so we can read back PKG-INFO files
........
  r76704 | tarek.ziade | 2009-12-08 10:39:51 +0100 (Tue, 08 Dec 2009) | 1 line

  removed the usage of rfc822 in favor of email.message.Message
........
parent 0b9293f2
...@@ -285,6 +285,48 @@ by using the `docutils` parser:: ...@@ -285,6 +285,48 @@ by using the `docutils` parser::
warning: check: Title underline too short. (line 2) warning: check: Title underline too short. (line 2)
warning: check: Could not finish the parsing. warning: check: Could not finish the parsing.
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
`setup.py` script of a given project::
$ python setup.py --name
distribute
This call reads the `name` metadata by running the
: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`,
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`.
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'
Notice that the class can also be instanciated 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
'distribute'
.. % \section{Multiple extension modules} .. % \section{Multiple extension modules}
.. % \label{multiple-ext} .. % \label{multiple-ext}
......
...@@ -539,6 +539,10 @@ changes, or look through the Subversion logs for all the details. ...@@ -539,6 +539,10 @@ changes, or look through the Subversion logs for all the details.
process, but instead simply not install the failing extension. process, but instead simply not install the failing extension.
(Contributed by Georg Brandl; :issue:`5583`.) (Contributed by Georg Brandl; :issue:`5583`.)
Issue #7457: added a read_pkg_file method to.distutils.dist.DistributionMetadata
see file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata
(:issue:`7457`, added by Tarek).
* The :class:`Fraction` class now accepts two rational numbers * The :class:`Fraction` class now accepts two rational numbers
as arguments to its constructor. as arguments to its constructor.
(Implemented by Mark Dickinson; :issue:`5812`.) (Implemented by Mark Dickinson; :issue:`5812`.)
......
...@@ -7,6 +7,7 @@ being built/installed/distributed. ...@@ -7,6 +7,7 @@ being built/installed/distributed.
__revision__ = "$Id$" __revision__ = "$Id$"
import sys, os, re import sys, os, re
from email import message_from_file
try: try:
import warnings import warnings
...@@ -1014,7 +1015,10 @@ class DistributionMetadata: ...@@ -1014,7 +1015,10 @@ class DistributionMetadata:
"provides", "requires", "obsoletes", "provides", "requires", "obsoletes",
) )
def __init__ (self): def __init__(self, path=None):
if path is not None:
self.read_pkg_file(open(path))
else:
self.name = None self.name = None
self.version = None self.version = None
self.author = None self.author = None
...@@ -1034,6 +1038,58 @@ class DistributionMetadata: ...@@ -1034,6 +1038,58 @@ class DistributionMetadata:
self.requires = None self.requires = None
self.obsoletes = None self.obsoletes = None
def read_pkg_file(self, file):
"""Reads the metadata values from a file object."""
msg = message_from_file(file)
def _read_field(name):
value = msg[name]
if value == 'UNKNOWN':
return None
return value
def _read_list(name):
values = msg.get_all(name, None)
if values == []:
return None
return values
metadata_version = msg['metadata-version']
self.name = _read_field('name')
self.version = _read_field('version')
self.description = _read_field('summary')
# we are filling author only.
self.author = _read_field('author')
self.maintainer = None
self.author_email = _read_field('author-email')
self.maintainer_email = None
self.url = _read_field('home-page')
self.license = _read_field('license')
if 'download-url' in msg:
self.download_url = _read_field('download-url')
else:
self.download_url = None
self.long_description = _read_field('description')
self.description = _read_field('summary')
if 'keywords' in msg:
self.keywords = _read_field('keywords').split(',')
self.platforms = _read_list('platform')
self.classifiers = _read_list('classifier')
# PEP 314 - these fields only exist in 1.1
if metadata_version == '1.1':
self.requires = _read_list('requires')
self.provides = _read_list('provides')
self.obsoletes = _read_list('obsoletes')
else:
self.requires = None
self.provides = None
self.obsoletes = None
def write_pkg_info(self, base_dir): def write_pkg_info(self, base_dir):
"""Write the PKG-INFO file into the release tree. """Write the PKG-INFO file into the release tree.
""" """
......
...@@ -7,7 +7,7 @@ import unittest ...@@ -7,7 +7,7 @@ import unittest
import warnings import warnings
import textwrap import textwrap
from distutils.dist import Distribution, fix_help_options from distutils.dist import Distribution, fix_help_options, DistributionMetadata
from distutils.cmd import Command from distutils.cmd import Command
import distutils.dist import distutils.dist
...@@ -369,6 +369,33 @@ class MetadataTestCase(support.TempdirManager, support.EnvironGuard, ...@@ -369,6 +369,33 @@ class MetadataTestCase(support.TempdirManager, support.EnvironGuard,
meta = meta.replace('\n' + 8 * ' ', '\n') meta = meta.replace('\n' + 8 * ' ', '\n')
self.assertTrue(long_desc in meta) self.assertTrue(long_desc in meta)
def test_read_metadata(self):
attrs = {"name": "package",
"version": "1.0",
"long_description": "desc",
"description": "xxx",
"download_url": "http://example.com",
"keywords": ['one', 'two'],
"requires": ['foo']}
dist = Distribution(attrs)
metadata = dist.metadata
# write it then reloads it
PKG_INFO = io.StringIO()
metadata.write_pkg_file(PKG_INFO)
PKG_INFO.seek(0)
metadata.read_pkg_file(PKG_INFO)
self.assertEquals(metadata.name, "package")
self.assertEquals(metadata.version, "1.0")
self.assertEquals(metadata.description, "xxx")
self.assertEquals(metadata.download_url, 'http://example.com')
self.assertEquals(metadata.keywords, ['one', 'two'])
self.assertEquals(metadata.platforms, ['UNKNOWN'])
self.assertEquals(metadata.obsoletes, None)
self.assertEquals(metadata.requires, ['foo'])
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(DistributionTestCase)) suite.addTest(unittest.makeSuite(DistributionTestCase))
......
...@@ -154,6 +154,9 @@ C-API ...@@ -154,6 +154,9 @@ C-API
Library Library
------- -------
- Issue #7457: added a read_pkg_file method to
distutils.dist.DistributionMetadata.
- logging: Added optional `secure` parameter to SMTPHandler, to enable use of - logging: Added optional `secure` parameter to SMTPHandler, to enable use of
TLS with authentication credentials. TLS with authentication credentials.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment