Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b88a496

Browse files
author
Tarek Ziadé
committed
Merged revisions 76702,76704 via svnmerge from
svn+ssh://[email protected]/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 ........
1 parent 0b9293f commit b88a496

5 files changed

Lines changed: 150 additions & 18 deletions

File tree

Doc/distutils/examples.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,48 @@ by using the `docutils` parser::
285285
warning: check: Title underline too short. (line 2)
286286
warning: check: Could not finish the parsing.
287287

288+
Reading the metadata
289+
=====================
290+
291+
The :func:`distutils.core.setup` function provides a command-line interface
292+
that allows you to query the metadata fields of a project through the
293+
`setup.py` script of a given project::
294+
295+
$ python setup.py --name
296+
distribute
297+
298+
This call reads the `name` metadata by running the
299+
:func:`distutils.core.setup` function. Although, when a source or binary
300+
distribution is created with Distutils, the metadata fields are written
301+
in a static file called :file:`PKG-INFO`. When a Distutils-based project is
302+
installed in Python, the :file:`PKG-INFO` file is copied alongside the modules
303+
and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`,
304+
where `NAME` is the name of the project, `VERSION` its version as defined
305+
in the Metadata, and `pyX.X` the major and minor version of Python like
306+
`2.7` or `3.2`.
307+
308+
You can read back this static file, by using the
309+
:class:`distutils.dist.DistributionMetadata` class and its
310+
:func:`read_pkg_file` method::
311+
312+
>>> from distutils.dist import DistributionMetadata
313+
>>> metadata = DistributionMetadata()
314+
>>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info'))
315+
>>> metadata.name
316+
'distribute'
317+
>>> metadata.version
318+
'0.6.8'
319+
>>> metadata.description
320+
'Easily download, build, install, upgrade, and uninstall Python packages'
321+
322+
Notice that the class can also be instanciated with a metadata file path to
323+
loads its values::
324+
325+
>>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info'
326+
>>> DistributionMetadata(pkg_info_path).name
327+
'distribute'
328+
329+
288330
.. % \section{Multiple extension modules}
289331
.. % \label{multiple-ext}
290332

Doc/whatsnew/2.7.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,10 @@ changes, or look through the Subversion logs for all the details.
539539
process, but instead simply not install the failing extension.
540540
(Contributed by Georg Brandl; :issue:`5583`.)
541541

542+
Issue #7457: added a read_pkg_file method to.distutils.dist.DistributionMetadata
543+
see file:///MacDev/svn.python.org/python-trunk/Doc/build/html/distutils/examples.html#reading-the-metadata
544+
(:issue:`7457`, added by Tarek).
545+
542546
* The :class:`Fraction` class now accepts two rational numbers
543547
as arguments to its constructor.
544548
(Implemented by Mark Dickinson; :issue:`5812`.)

Lib/distutils/dist.py

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
__revision__ = "$Id$"
88

99
import sys, os, re
10+
from email import message_from_file
1011

1112
try:
1213
import warnings
@@ -1014,25 +1015,80 @@ class DistributionMetadata:
10141015
"provides", "requires", "obsoletes",
10151016
)
10161017

1017-
def __init__ (self):
1018-
self.name = None
1019-
self.version = None
1020-
self.author = None
1021-
self.author_email = None
1018+
def __init__(self, path=None):
1019+
if path is not None:
1020+
self.read_pkg_file(open(path))
1021+
else:
1022+
self.name = None
1023+
self.version = None
1024+
self.author = None
1025+
self.author_email = None
1026+
self.maintainer = None
1027+
self.maintainer_email = None
1028+
self.url = None
1029+
self.license = None
1030+
self.description = None
1031+
self.long_description = None
1032+
self.keywords = None
1033+
self.platforms = None
1034+
self.classifiers = None
1035+
self.download_url = None
1036+
# PEP 314
1037+
self.provides = None
1038+
self.requires = None
1039+
self.obsoletes = None
1040+
1041+
def read_pkg_file(self, file):
1042+
"""Reads the metadata values from a file object."""
1043+
msg = message_from_file(file)
1044+
1045+
def _read_field(name):
1046+
value = msg[name]
1047+
if value == 'UNKNOWN':
1048+
return None
1049+
return value
1050+
1051+
def _read_list(name):
1052+
values = msg.get_all(name, None)
1053+
if values == []:
1054+
return None
1055+
return values
1056+
1057+
metadata_version = msg['metadata-version']
1058+
self.name = _read_field('name')
1059+
self.version = _read_field('version')
1060+
self.description = _read_field('summary')
1061+
# we are filling author only.
1062+
self.author = _read_field('author')
10221063
self.maintainer = None
1064+
self.author_email = _read_field('author-email')
10231065
self.maintainer_email = None
1024-
self.url = None
1025-
self.license = None
1026-
self.description = None
1027-
self.long_description = None
1028-
self.keywords = None
1029-
self.platforms = None
1030-
self.classifiers = None
1031-
self.download_url = None
1032-
# PEP 314
1033-
self.provides = None
1034-
self.requires = None
1035-
self.obsoletes = None
1066+
self.url = _read_field('home-page')
1067+
self.license = _read_field('license')
1068+
1069+
if 'download-url' in msg:
1070+
self.download_url = _read_field('download-url')
1071+
else:
1072+
self.download_url = None
1073+
1074+
self.long_description = _read_field('description')
1075+
self.description = _read_field('summary')
1076+
1077+
if 'keywords' in msg:
1078+
self.keywords = _read_field('keywords').split(',')
1079+
1080+
self.platforms = _read_list('platform')
1081+
self.classifiers = _read_list('classifier')
1082+
1083+
# PEP 314 - these fields only exist in 1.1
1084+
if metadata_version == '1.1':
1085+
self.requires = _read_list('requires')
1086+
self.provides = _read_list('provides')
1087+
self.obsoletes = _read_list('obsoletes')
1088+
else:
1089+
self.requires = None
1090+
self.provides = None
1091+
self.obsoletes = None
10361092

10371093
def write_pkg_info(self, base_dir):
10381094
"""Write the PKG-INFO file into the release tree.

Lib/distutils/tests/test_dist.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import warnings
88
import textwrap
99

10-
from distutils.dist import Distribution, fix_help_options
10+
from distutils.dist import Distribution, fix_help_options, DistributionMetadata
1111
from distutils.cmd import Command
1212
import distutils.dist
1313

@@ -369,6 +369,33 @@ def test_long_description(self):
369369
meta = meta.replace('\n' + 8 * ' ', '\n')
370370
self.assertTrue(long_desc in meta)
371371

372+
def test_read_metadata(self):
373+
attrs = {"name": "package",
374+
"version": "1.0",
375+
"long_description": "desc",
376+
"description": "xxx",
377+
"download_url": "http://example.com",
378+
"keywords": ['one', 'two'],
379+
"requires": ['foo']}
380+
381+
dist = Distribution(attrs)
382+
metadata = dist.metadata
383+
384+
# write it then reloads it
385+
PKG_INFO = io.StringIO()
386+
metadata.write_pkg_file(PKG_INFO)
387+
PKG_INFO.seek(0)
388+
metadata.read_pkg_file(PKG_INFO)
389+
390+
self.assertEquals(metadata.name, "package")
391+
self.assertEquals(metadata.version, "1.0")
392+
self.assertEquals(metadata.description, "xxx")
393+
self.assertEquals(metadata.download_url, 'http://example.com')
394+
self.assertEquals(metadata.keywords, ['one', 'two'])
395+
self.assertEquals(metadata.platforms, ['UNKNOWN'])
396+
self.assertEquals(metadata.obsoletes, None)
397+
self.assertEquals(metadata.requires, ['foo'])
398+
372399
def test_suite():
373400
suite = unittest.TestSuite()
374401
suite.addTest(unittest.makeSuite(DistributionTestCase))

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ C-API
154154
Library
155155
-------
156156

157+
- Issue #7457: added a read_pkg_file method to
158+
distutils.dist.DistributionMetadata.
159+
157160
- logging: Added optional `secure` parameter to SMTPHandler, to enable use of
158161
TLS with authentication credentials.
159162

0 commit comments

Comments
 (0)