Kaydet (Commit) a939ecd9 authored tarafından Tarek Ziadé's avatar Tarek Ziadé

Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata…

Issue #7457: added a read_pkg_file method to distutils.dist.DistributionMetadata so we can read back PKG-INFO files
üst 8f254e7f
...@@ -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
import rfc822
try: try:
import warnings import warnings
...@@ -1006,6 +1007,20 @@ Common commands: (see '--help-commands' for more) ...@@ -1006,6 +1007,20 @@ Common commands: (see '--help-commands' for more)
# to self.metadata.get_XXX. The actual code is in the # to self.metadata.get_XXX. The actual code is in the
# DistributionMetadata class, below. # DistributionMetadata class, below.
class _MetadataMessage(rfc822.Message):
def read_field(self, name):
value = self[name]
if value == 'UNKNOWN':
return None
return value
def getheaders(self, name, default):
values = rfc822.Message.getheaders(self, name)
if values == []:
return None
return values
class DistributionMetadata: class DistributionMetadata:
"""Dummy class to hold the distribution meta-data: name, version, """Dummy class to hold the distribution meta-data: name, version,
author, and so forth. author, and so forth.
...@@ -1021,25 +1036,67 @@ class DistributionMetadata: ...@@ -1021,25 +1036,67 @@ class DistributionMetadata:
"provides", "requires", "obsoletes", "provides", "requires", "obsoletes",
) )
def __init__ (self): def __init__(self, path=None):
self.name = None if path is not None:
self.version = None self.read_pkg_file(open(path))
self.author = None else:
self.author_email = None self.name = None
self.version = None
self.author = None
self.author_email = None
self.maintainer = None
self.maintainer_email = None
self.url = None
self.license = None
self.description = None
self.long_description = None
self.keywords = None
self.platforms = None
self.classifiers = None
self.download_url = None
# PEP 314
self.provides = None
self.requires = None
self.obsoletes = None
def read_pkg_file(self, file):
"""Reads the metadata values from a file object."""
msg = _MetadataMessage(file)
metadata_version = msg['metadata-version']
self.name = msg.read_field('name')
self.version = msg.read_field('version')
self.description = msg.read_field('summary')
# we are filling author only.
self.author = msg.read_field('author')
self.maintainer = None self.maintainer = None
self.author_email = msg.read_field('author-email')
self.maintainer_email = None self.maintainer_email = None
self.url = None self.url = msg.read_field('home-page')
self.license = None self.license = msg.read_field('license')
self.description = None
self.long_description = None if 'download-url' in msg:
self.keywords = None self.download_url = msg.read_field('download-url')
self.platforms = None else:
self.classifiers = None self.download_url = None
self.download_url = None
# PEP 314 self.long_description = msg.read_field('description')
self.provides = None self.description = msg.read_field('summary')
self.requires = None
self.obsoletes = None if 'keywords' in msg:
self.keywords = msg.read_field('keywords').split(',')
self.platforms = msg.getheaders('platform', None)
self.classifiers = msg.getheaders('classifier', None)
# PEP 314 - these fields only exist in 1.1
if metadata_version == '1.1':
self.requires = msg.getheaders('requires', None)
self.provides = msg.getheaders('provides', None)
self.obsoletes = msg.getheaders('obsoletes', None)
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.
......
...@@ -8,10 +8,9 @@ import unittest ...@@ -8,10 +8,9 @@ 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
from test.test_support import TESTFN, captured_stdout from test.test_support import TESTFN, captured_stdout
from distutils.tests import support from distutils.tests import support
...@@ -239,6 +238,7 @@ class DistributionTestCase(support.TempdirManager, ...@@ -239,6 +238,7 @@ class DistributionTestCase(support.TempdirManager,
# make sure --no-user-cfg disables the user cfg file # make sure --no-user-cfg disables the user cfg file
self.assertEquals(len(all_files)-1, len(files)) self.assertEquals(len(all_files)-1, len(files))
class MetadataTestCase(support.TempdirManager, support.EnvironGuard, class MetadataTestCase(support.TempdirManager, support.EnvironGuard,
unittest.TestCase): unittest.TestCase):
...@@ -397,6 +397,33 @@ class MetadataTestCase(support.TempdirManager, support.EnvironGuard, ...@@ -397,6 +397,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 = StringIO.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))
......
...@@ -15,6 +15,8 @@ Core and Builtins ...@@ -15,6 +15,8 @@ Core and Builtins
Library Library
------- -------
- Issue #7457: added a read_pkg_file method to
distutils.dist.DistributionMetadata.
What's New in Python 2.7 alpha 1 What's New in Python 2.7 alpha 1
================================ ================================
......
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