pkginfo-0.9.1/0000775000175000017500000000000012041302166013057 5ustar tseavertseaverpkginfo-0.9.1/setup.cfg0000664000175000017500000000007312041302166014700 0ustar tseavertseaver[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 pkginfo-0.9.1/PKG-INFO0000664000175000017500000001372212041302166014161 0ustar tseavertseaverMetadata-Version: 1.0 Name: pkginfo Version: 0.9.1 Summary: Query metadatdata from sdists / bdists / installed packages. Home-page: http://pypi.python.org/pypi/pkginfo/ Author: Tres Seaver, Agendaless Consulting Author-email: tseaver@agendaless.com License: Python Description: ``pkginfo`` README ================== This package provides an API for querying the distutils metadata written in the ``PKG-INFO`` file inside a source distriubtion (an ``sdist``), or into the ``EGG-INFO`` directory of an installed distribution. Please see the `pkginfo docs `_ for detailed documentation. ``pkginfo`` Changelog ===================== 0.9.1 (2012-10-22) ------------------ - Fix test failure under Python >= 2.7, which is enforcing 'metadata_version == 1.1' because we have classifiers. 0.9 (2012-04-25) ---------------- - Fix introspection of installed namespace packages. They may be installed as eggs or via dist-installed 'egg-info' files. https://bugs.launchpad.net/pkginfo/+bug/934311 - Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode. https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3 0.8 (2011-03-12) ---------------- - Work around Python 2.7's breakage of StringIO. Fixes https://bugs.launchpad.net/pkginfo/+bug/733827 - Fixed bug in introspection of installed packages missing the ``__package__`` attribute. 0.7 (2010-11-04) ---------------- - Preserve newlines in the ``description`` field. Thanks to Sridhar Ratnakumar for the patch. - 100% test coverage. 0.6 (2010-06-01) ---------------- - Replaced use of ``StringIO.StringIO`` with ``io.StringIO``, where available (Python >= 2.6). - Replaced use of ``rfc822`` stdlib module with ``email.parser``, when available (Python >= 2.5). Ensured that distributions "unfold" wrapped continuation lines, stripping any leading / trailing whitespace, no matter which module was used for parsing. - Removed bogus testing dependency on ``zope.testing``. - Added tests that the "environment markers" spelled out in the approved PEP 345 are captured. - Added ``Project-URL`` for ``1.2`` PKG-INFO metdata (defined in the accepted version of PEP 345). 0.5 (2009-09-11) ---------------- - Marked package as non-zip-safe. - Fixed Trove metadata misspelling. - Restored compatibility with Python 2.4. - Noted that the introspection of installed packages / modules works only in Python 2.6 or later. - Added ``Index`` class as an abstraction over a collection of distributions. - Added ``download_url_prefix`` argument to ``pkginfo`` script. If passed, the script will use the prefix to synthesize a ``download_url`` for distributions which do not supply that value directly. 0.4.1 (2009-05-07) ------------------ - Fixed bugs in handling of installed packages which lack ``__file__`` or ``PKG-INFO``. 0.4 (2009-05-07) ---------------- - Extended the console script to allow output as CSV or INI. Also, added arguments to specify the metadata version and other parsing / output policies. - Added support for the different metadata versions specified in PEPs 241, 314, and 345. Distributions now parse and expose only the attributes corresponding to their metadata version, which defaults to the version parsed from the ``PKG-INFO`` file. The programmer can override that version when creating the distribution object. 0.3 (2009-05-07) ---------------- - Added support for introspection of "development eggs" (checkouts with ``PKG-INFO``, perhaps created via ``setup.py develop``). - Added a console script, ``pkginfo``, which takes one or more paths on the command line and writes out the associated information. Thanks to ``runeh`` for the patch! - Added ``get_metadata`` helper function, which dispatches a given path or module across the available distribution types, and returns a distribution object. Thanks to ``runeh`` for the patch! - Made distribution objects support iteration over the metadata fields. Thanks to ``runeh`` for the patch! - Made Distribution and subclasses new-style classes. Thanks to ``runeh`` for the patch! 0.2 (2009-04-14) ---------------- - Added support for introspection of ``bdist_egg`` binary distributions. 0.1.1 (2009-04-10) ------------------ - Fixed packaging errors. 0.1 (2009-04-10) ---------------- - Initial release. Keywords: distribution sdist installed metadata Platform: Unix Platform: Windows Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Python Software Foundation License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2.5 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Software Distribution pkginfo-0.9.1/setup.py0000644000175000017500000000261312041301714014567 0ustar tseavertseaverimport os try: from setuptools import setup except ImportError: from distutils.core import setup extras = {} else: extras = { 'test_suite': 'pkginfo.tests', 'zip_safe': False, } here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, 'README.txt')).read() CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() setup( name='pkginfo', version='0.9.1', description='Query metadatdata from sdists / bdists / installed packages.', platforms=['Unix', 'Windows'], long_description='\n\n'.join([README, CHANGES]), keywords='distribution sdist installed metadata', url='http://pypi.python.org/pypi/pkginfo/', author='Tres Seaver, Agendaless Consulting', author_email='tseaver@agendaless.com', license='Python', classifiers=[ 'Intended Audience :: Developers', 'License :: OSI Approved :: Python Software Foundation License', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: System :: Software Distribution', ], entry_points={ 'console_scripts': [ ['pkginfo = pkginfo.commandline:main'] ] }, packages=['pkginfo', 'pkginfo.tests'], **extras ) pkginfo-0.9.1/.bzrignore0000644000175000017500000000013211724745273015074 0ustar tseavertseaver*.egg-info ./docs/.build/html ./docs/.build/doctrees ./build ./dist .coverage __pycache__ pkginfo-0.9.1/pkginfo.egg-info/0000775000175000017500000000000012041302166016206 5ustar tseavertseaverpkginfo-0.9.1/pkginfo.egg-info/top_level.txt0000664000175000017500000000001012041302166020727 0ustar tseavertseaverpkginfo pkginfo-0.9.1/pkginfo.egg-info/SOURCES.txt0000664000175000017500000000257712041302166020105 0ustar tseavertseaver.bzrignore CHANGES.txt README.txt TODO.txt setup.py docs/Makefile docs/conf.py docs/distributions.rst docs/index.rst docs/indexes.rst docs/metadata.rst docs/examples/mypackage-0.1-py2.6.egg docs/examples/mypackage-0.1.tar.bz2 docs/examples/mypackage-0.1.tar.gz docs/examples/mypackage-0.1.zip docs/examples/nopkginfo-0.1.egg docs/examples/nopkginfo-0.1.zip pkginfo/__init__.py pkginfo/bdist.py pkginfo/commandline.py pkginfo/develop.py pkginfo/distribution.py pkginfo/index.py pkginfo/installed.py pkginfo/sdist.py pkginfo/utils.py pkginfo.egg-info/PKG-INFO pkginfo.egg-info/SOURCES.txt pkginfo.egg-info/dependency_links.txt pkginfo.egg-info/entry_points.txt pkginfo.egg-info/not-zip-safe pkginfo.egg-info/top_level.txt pkginfo/tests/__init__.py pkginfo/tests/test_bdist.py pkginfo/tests/test_develop.py pkginfo/tests/test_distribution.py pkginfo/tests/test_index.py pkginfo/tests/test_installed.py pkginfo/tests/test_sdist.py pkginfo/tests/test_utils.py pkginfo/tests/funny/__init__.py pkginfo/tests/funny/funny.egg-info pkginfo/tests/manky/NOT-A-PACKAGE.txt pkginfo/tests/manky/namespaced/__init__.py pkginfo/tests/manky/namespaced.manky-0.1.egg-info/PKG-INFO pkginfo/tests/manky/namespaced/manky/__init__.py pkginfo/tests/silly/PKG-INFO pkginfo/tests/wonky/NOT-A-PACKAGE.txt pkginfo/tests/wonky/EGG-INFO/PKG-INFO pkginfo/tests/wonky/namespaced/__init__.py pkginfo/tests/wonky/namespaced/wonky/__init__.pypkginfo-0.9.1/pkginfo.egg-info/PKG-INFO0000664000175000017500000001372212041302166017310 0ustar tseavertseaverMetadata-Version: 1.0 Name: pkginfo Version: 0.9.1 Summary: Query metadatdata from sdists / bdists / installed packages. Home-page: http://pypi.python.org/pypi/pkginfo/ Author: Tres Seaver, Agendaless Consulting Author-email: tseaver@agendaless.com License: Python Description: ``pkginfo`` README ================== This package provides an API for querying the distutils metadata written in the ``PKG-INFO`` file inside a source distriubtion (an ``sdist``), or into the ``EGG-INFO`` directory of an installed distribution. Please see the `pkginfo docs `_ for detailed documentation. ``pkginfo`` Changelog ===================== 0.9.1 (2012-10-22) ------------------ - Fix test failure under Python >= 2.7, which is enforcing 'metadata_version == 1.1' because we have classifiers. 0.9 (2012-04-25) ---------------- - Fix introspection of installed namespace packages. They may be installed as eggs or via dist-installed 'egg-info' files. https://bugs.launchpad.net/pkginfo/+bug/934311 - Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode. https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3 0.8 (2011-03-12) ---------------- - Work around Python 2.7's breakage of StringIO. Fixes https://bugs.launchpad.net/pkginfo/+bug/733827 - Fixed bug in introspection of installed packages missing the ``__package__`` attribute. 0.7 (2010-11-04) ---------------- - Preserve newlines in the ``description`` field. Thanks to Sridhar Ratnakumar for the patch. - 100% test coverage. 0.6 (2010-06-01) ---------------- - Replaced use of ``StringIO.StringIO`` with ``io.StringIO``, where available (Python >= 2.6). - Replaced use of ``rfc822`` stdlib module with ``email.parser``, when available (Python >= 2.5). Ensured that distributions "unfold" wrapped continuation lines, stripping any leading / trailing whitespace, no matter which module was used for parsing. - Removed bogus testing dependency on ``zope.testing``. - Added tests that the "environment markers" spelled out in the approved PEP 345 are captured. - Added ``Project-URL`` for ``1.2`` PKG-INFO metdata (defined in the accepted version of PEP 345). 0.5 (2009-09-11) ---------------- - Marked package as non-zip-safe. - Fixed Trove metadata misspelling. - Restored compatibility with Python 2.4. - Noted that the introspection of installed packages / modules works only in Python 2.6 or later. - Added ``Index`` class as an abstraction over a collection of distributions. - Added ``download_url_prefix`` argument to ``pkginfo`` script. If passed, the script will use the prefix to synthesize a ``download_url`` for distributions which do not supply that value directly. 0.4.1 (2009-05-07) ------------------ - Fixed bugs in handling of installed packages which lack ``__file__`` or ``PKG-INFO``. 0.4 (2009-05-07) ---------------- - Extended the console script to allow output as CSV or INI. Also, added arguments to specify the metadata version and other parsing / output policies. - Added support for the different metadata versions specified in PEPs 241, 314, and 345. Distributions now parse and expose only the attributes corresponding to their metadata version, which defaults to the version parsed from the ``PKG-INFO`` file. The programmer can override that version when creating the distribution object. 0.3 (2009-05-07) ---------------- - Added support for introspection of "development eggs" (checkouts with ``PKG-INFO``, perhaps created via ``setup.py develop``). - Added a console script, ``pkginfo``, which takes one or more paths on the command line and writes out the associated information. Thanks to ``runeh`` for the patch! - Added ``get_metadata`` helper function, which dispatches a given path or module across the available distribution types, and returns a distribution object. Thanks to ``runeh`` for the patch! - Made distribution objects support iteration over the metadata fields. Thanks to ``runeh`` for the patch! - Made Distribution and subclasses new-style classes. Thanks to ``runeh`` for the patch! 0.2 (2009-04-14) ---------------- - Added support for introspection of ``bdist_egg`` binary distributions. 0.1.1 (2009-04-10) ------------------ - Fixed packaging errors. 0.1 (2009-04-10) ---------------- - Initial release. Keywords: distribution sdist installed metadata Platform: Unix Platform: Windows Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Python Software Foundation License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2.5 Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: System :: Software Distribution pkginfo-0.9.1/pkginfo.egg-info/dependency_links.txt0000664000175000017500000000000112041302166022254 0ustar tseavertseaver pkginfo-0.9.1/pkginfo.egg-info/not-zip-safe0000664000175000017500000000000112041300263020430 0ustar tseavertseaver pkginfo-0.9.1/pkginfo.egg-info/entry_points.txt0000664000175000017500000000006612041302166021506 0ustar tseavertseaver[console_scripts] pkginfo = pkginfo.commandline:main pkginfo-0.9.1/README.txt0000644000175000017500000000053011536720731014563 0ustar tseavertseaver``pkginfo`` README ================== This package provides an API for querying the distutils metadata written in the ``PKG-INFO`` file inside a source distriubtion (an ``sdist``), or into the ``EGG-INFO`` directory of an installed distribution. Please see the `pkginfo docs `_ for detailed documentation. pkginfo-0.9.1/TODO.txt0000644000175000017500000000054611357450726014407 0ustar tseavertseaverTODOs ===== - [X] Catch up to latest changes in PEP345: * Project-URL header * "environment markers" - [_] Add APIs to ``Distribution`` which expose the semantics of the requirement versions and environment markers. - [_] Allow the ``pkginfo`` script to process URLs. - [_] Allow the ``pkginfo`` script to process requirements specs. pkginfo-0.9.1/pkginfo/0000775000175000017500000000000012041302166014514 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/bdist.py0000644000175000017500000000213611357450726016212 0ustar tseavertseaverimport os import zipfile from pkginfo.distribution import Distribution class BDist(Distribution): def __init__(self, filename, metadata_version=None): self.filename = filename self.metadata_version = metadata_version self.extractMetadata() def read(self): fqn = os.path.abspath( os.path.normpath(self.filename)) if not os.path.exists(fqn): raise ValueError('No such file: %s' % fqn) if fqn.endswith('.egg'): archive = zipfile.ZipFile(fqn) names = archive.namelist() def read_file(name): return archive.read(name) else: raise ValueError('Not a known archive format: %s' % fqn) tuples = [x.split('/') for x in names if 'PKG-INFO' in x] schwarz = sorted([(len(x), x) for x in tuples]) for path in [x[1] for x in schwarz]: candidate = '/'.join(path) data = read_file(candidate) if 'Metadata-Version' in data: return data raise ValueError('No PKG-INFO in archive: %s' % fqn) pkginfo-0.9.1/pkginfo/index.py0000644000175000017500000000101511357450726016207 0ustar tseavertseaverfrom pkginfo.distribution import Distribution class Index(dict): def __setitem__(self, key, value): if not isinstance(value, Distribution): raise ValueError('Not a distribution: %r.' % value) if key != '%s-%s' % (value.name, value.version): raise ValueError('Key must match -.') super(Index, self).__setitem__(key, value) def add(self, distribution): key = '%s-%s' % (distribution.name, distribution.version) self[key] = distribution pkginfo-0.9.1/pkginfo/__init__.py0000644000175000017500000000040111357450726016635 0ustar tseavertseaverfrom pkginfo.bdist import BDist from pkginfo.develop import Develop from pkginfo.distribution import Distribution from pkginfo.index import Index from pkginfo.installed import Installed from pkginfo.sdist import SDist from pkginfo.utils import get_metadata pkginfo-0.9.1/pkginfo/installed.py0000644000175000017500000000355711724740050017062 0ustar tseavertseaverimport glob import os import sys import warnings from pkginfo.distribution import Distribution class Installed(Distribution): def __init__(self, package, metadata_version=None): if isinstance(package, basestring): self.package_name = package try: __import__(package) except ImportError: package = None else: package = sys.modules[package] else: self.package_name = package.__name__ self.package = package self.metadata_version = metadata_version self.extractMetadata() def read(self): opj = os.path.join if self.package is not None: package = self.package.__package__ if package is None: package = self.package.__name__ pattern = '%s*.egg-info' % package file = getattr(self.package, '__file__', None) if file is not None: candidates = [] def _add_candidate(where): candidates.extend(glob.glob(where)) for entry in sys.path: if file.startswith(entry): _add_candidate(opj(entry, 'EGG-INFO')) # egg? _add_candidate(opj(entry, pattern)) # dist-installed? dir, name = os.path.split(self.package.__file__) _add_candidate(opj(dir, pattern)) _add_candidate(opj(dir, '..', pattern)) for candidate in candidates: if os.path.isdir(candidate): path = opj(candidate, 'PKG-INFO') else: path = candidate if os.path.exists(path): return open(path).read() warnings.warn('No PKG-INFO found for package: %s' % self.package_name) pkginfo-0.9.1/pkginfo/distribution.py0000644000175000017500000001044511724723316017622 0ustar tseavertseavertry: from email.parser import Parser except ImportError: #pragma NO COVER # Python < 2.5 import rfc822 def parse(fp): return rfc822.Message(fp) def get(msg, header): return _collapse_leading_ws(header, msg.getheader(header)) def get_all(msg, header): return [_collapse_leading_ws(header, x) for x in msg.getheaders(header)] else: # Python >= 2.5 def parse(fp): return Parser().parse(fp) def get(msg, header): return _collapse_leading_ws(header, msg.get(header)) def get_all(msg, header): return [_collapse_leading_ws(header, x) for x in msg.get_all(header)] def _collapse_leading_ws(header, txt): """ ``Description`` header must preserve newlines; all others need not """ if header.lower() == 'description': # preserve newlines return '\n'.join([x[8:] if x.startswith(' ' * 8) else x for x in txt.strip().splitlines()]) else: return ' '.join([x.strip() for x in txt.splitlines()]) try: from io import BytesIO as StringIO except ImportError: #pragma NO COVER # Python < 2.6 from StringIO import StringIO HEADER_ATTRS_1_0 = ( # PEP 241 ('Metadata-Version', 'metadata_version', False), ('Name', 'name', False), ('Version', 'version', False), ('Platform', 'platforms', True), ('Supported-Platform', 'supported_platforms', True), ('Summary', 'summary', False), ('Description', 'description', False), ('Keywords', 'keywords', False), ('Home-Page', 'home_page', False), ('Author', 'author', False), ('Author-email', 'author_email', False), ('License', 'license', False), ) HEADER_ATTRS_1_1 = HEADER_ATTRS_1_0 + ( # PEP 314 ('Classifier', 'classifiers', True), ('Download-URL', 'download_url', False), ('Requires', 'requires', True), ('Provides', 'provides', True), ('Obsoletes', 'obsoletes', True), ) HEADER_ATTRS_1_2 = HEADER_ATTRS_1_1 + ( # PEP 345 ('Maintainer', 'maintainer', False), ('Maintainer-email', 'maintainer_email', False), ('Requires-Python', 'requires_python', False), ('Requires-External', 'requires_external', True), ('Requires-Dist', 'requires_dist', True), ('Provides-Dist', 'provides_dist', True), ('Obsoletes-Dist', 'obsoletes_dist', True), ('Project-URL', 'project_urls', True), ) HEADER_ATTRS = { '1.0': HEADER_ATTRS_1_0, '1.1': HEADER_ATTRS_1_1, '1.2': HEADER_ATTRS_1_2, } class Distribution(object): metadata_version = None # version 1.0 name = None version = None platforms = () supported_platforms = () summary = None description = None keywords = None home_page = None download_url = None author = None author_email = None license = None # version 1.1 classifiers = () requires = () provides = () obsoletes = () # version 1.2 maintainer = None maintainer_email = None requires_python = None requires_external = () requires_dist = () provides_dist = () obsoletes_dist = () project_urls = () def extractMetadata(self): data = self.read() self.parse(data) def read(self): raise NotImplementedError def _getHeaderAttrs(self): return HEADER_ATTRS.get(self.metadata_version, []) def parse(self, data): if isinstance(data, unicode): data = str(data) # caller has to give us encodable text. fp = StringIO(data) msg = parse(fp) if 'Metadata-Version' in msg and self.metadata_version is None: value = get(msg, 'Metadata-Version') metadata_version = self.metadata_version = value for header_name, attr_name, multiple in self._getHeaderAttrs(): if attr_name == 'metadata_version': continue if header_name in msg: if multiple: values = get_all(msg, header_name) setattr(self, attr_name, values) else: value = get(msg, header_name) if value != 'UNKNOWN': setattr(self, attr_name, value) def __iter__(self): for header_name, attr_name, multiple in self._getHeaderAttrs(): yield attr_name iterkeys = __iter__ pkginfo-0.9.1/pkginfo/tests/0000775000175000017500000000000012041302166015656 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/__init__.py0000644000175000017500000000310611743301031017763 0ustar tseavertseaver# requirements def additional_tests(): import doctest import unittest return unittest.TestSuite(( doctest.DocFileSuite('../../docs/index.rst', module_relative=True), doctest.DocFileSuite('../../docs/distributions.rst', module_relative=True), doctest.DocFileSuite('../../docs/metadata.rst', module_relative=True), doctest.DocFileSuite('../../docs/indexes.rst', module_relative=True), )) def _checkSample(testcase, installed): try: import pkg_resources except ImportError: # no setuptools :( pass else: version = pkg_resources.require('pkginfo')[0].version testcase.assertEqual(installed.version, version) testcase.assertEqual(installed.name, 'pkginfo') testcase.assertEqual(installed.keywords, 'distribution sdist installed metadata' ) testcase.assertEqual(list(installed.supported_platforms), []) def _checkClassifiers(testcase, installed): testcase.assertEqual(list(installed.classifiers), [ 'Intended Audience :: Developers', 'License :: OSI Approved :: Python Software Foundation License', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: System :: Software Distribution', ]) pkginfo-0.9.1/pkginfo/tests/silly/0000775000175000017500000000000012041302166017012 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/silly/PKG-INFO0000644000175000017500000000005711464573074020127 0ustar tseavertseaverMetadata-Version: 1.0 Name: silly Version: 0.1 pkginfo-0.9.1/pkginfo/tests/test_index.py0000644000175000017500000000505011536726336020415 0ustar tseavertseaverimport unittest class IndexTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.index import Index return Index def _makeOne(self): return self._getTargetClass()() def test_empty(self): index = self._makeOne() self.assertEqual(len(index), 0) self.assertEqual(len(index.keys()), 0) self.assertEqual(len(index.values()), 0) self.assertEqual(len(index.items()), 0) def _makeDummy(self): from pkginfo.distribution import Distribution class DummyDistribution(Distribution): name = 'dummy' version = '1.0' return DummyDistribution() def test___getitem___miss(self): index = self._makeOne() self.assertRaises(KeyError, index.__getitem__, 'nonesuch') def test___setitem___value_not_dist(self): class NotDistribution: name = 'dummy' version = '1.0' dummy = NotDistribution() index = self._makeOne() self.assertRaises(ValueError, index.__setitem__, 'dummy-1.0', dummy) def test___setitem___bad_key(self): index = self._makeOne() dummy = self._makeDummy() self.assertRaises(ValueError, index.__setitem__, 'nonesuch', dummy) def test___setitem___valid_key(self): index = self._makeOne() dummy = self._makeDummy() index['dummy-1.0'] = dummy self.failUnless(index['dummy-1.0'] is dummy) self.assertEqual(len(index), 1) self.assertEqual(len(index.keys()), 1) self.assertEqual(index.keys()[0], 'dummy-1.0') self.assertEqual(len(index.values()), 1) self.assertEqual(index.values()[0], dummy) self.assertEqual(len(index.items()), 1) self.assertEqual(index.items()[0], ('dummy-1.0', dummy)) def test_add_not_dist(self): index = self._makeOne() class NotDistribution: name = 'dummy' version = '1.0' dummy = NotDistribution() self.assertRaises(ValueError, index.add, dummy) def test_add_valid_dist(self): index = self._makeOne() dummy = self._makeDummy() index.add(dummy) self.failUnless(index['dummy-1.0'] is dummy) self.assertEqual(len(index), 1) self.assertEqual(len(index.keys()), 1) self.assertEqual(index.keys()[0], 'dummy-1.0') self.assertEqual(len(index.values()), 1) self.assertEqual(index.values()[0], dummy) self.assertEqual(len(index.items()), 1) self.assertEqual(index.items()[0], ('dummy-1.0', dummy)) pkginfo-0.9.1/pkginfo/tests/test_installed.py0000644000175000017500000001371312041301462021247 0ustar tseavertseaverimport unittest import sys if sys.version_info >= (2, 6): # no PKG-INFO installed in earlier Pythons class InstalledTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.installed import Installed return Installed def _makeOne(self, filename=None, metadata_version=None): if metadata_version is not None: return self._getTargetClass()(filename, metadata_version) return self._getTargetClass()(filename) def test_ctor_w_package_no___file__(self): import sys import warnings old_filters = warnings.filters[:] warnings.filterwarnings('ignore') try: installed = self._makeOne(sys) self.assertEqual(installed.package, sys) self.assertEqual(installed.package_name, 'sys') self.assertEqual(installed.metadata_version, None) finally: warnings.filters[:] = old_filters def test_ctor_w_package(self): import pkginfo from pkginfo.tests import _checkSample EXPECTED = sys.version_info >= (2, 7) and '1.1' or '1.0' installed = self._makeOne(pkginfo) self.assertEqual(installed.package, pkginfo) self.assertEqual(installed.package_name, 'pkginfo') self.assertEqual(installed.metadata_version, EXPECTED) _checkSample(self, installed) def test_ctor_w_no___package___falls_back_to___name__(self): import wsgiref installed = self._makeOne(wsgiref) self.assertEqual(installed.package, wsgiref) self.assertEqual(installed.package_name, 'wsgiref') self.assertEqual(installed.metadata_version, '1.0') def test_ctor_w_package_no_PKG_INFO(self): import types import warnings old_filters = warnings.filters[:] warnings.filterwarnings('ignore') try: installed = self._makeOne(types) self.assertEqual(installed.package, types) self.assertEqual(installed.package_name, 'types') self.assertEqual(installed.metadata_version, None) finally: warnings.filters[:] = old_filters def test_ctor_w_package_and_metadata_version(self): import pkginfo from pkginfo.tests import _checkSample installed = self._makeOne(pkginfo, metadata_version='1.2') self.assertEqual(installed.metadata_version, '1.2') self.assertEqual(installed.package.__name__, 'pkginfo') _checkSample(self, installed) def test_ctor_w_name(self): import pkginfo from pkginfo.tests import _checkSample EXPECTED = sys.version_info >= (2, 7) and '1.1' or '1.0' installed = self._makeOne('pkginfo') self.assertEqual(installed.metadata_version, EXPECTED) self.assertEqual(installed.package, pkginfo) self.assertEqual(installed.package_name, 'pkginfo') _checkSample(self, installed) def test_ctor_w_name_and_metadata_version(self): import pkginfo from pkginfo.tests import _checkSample installed = self._makeOne('pkginfo', metadata_version='1.2') self.assertEqual(installed.metadata_version, '1.2') self.assertEqual(installed.package, pkginfo) self.assertEqual(installed.package_name, 'pkginfo') _checkSample(self, installed) def test_ctor_w_invalid_name(self): import warnings old_filters = warnings.filters[:] warnings.filterwarnings('ignore') try: installed = self._makeOne('nonesuch') self.assertEqual(installed.package, None) self.assertEqual(installed.package_name, 'nonesuch') self.assertEqual(installed.metadata_version, None) finally: warnings.filters[:] = old_filters def test_ctor_w_egg_info_as_file(self): import pkginfo.tests.funny installed = self._makeOne('pkginfo.tests.funny') self.assertEqual(installed.metadata_version, '1.0') self.assertEqual(installed.package, pkginfo.tests.funny) self.assertEqual(installed.package_name, 'pkginfo.tests.funny') def test_namespaced_pkg_installed_via_setuptools(self): import os import sys where, _ = os.path.split(__file__) wonky = os.path.join(where, 'wonky') oldpath = sys.path[:] try: sys.path.append(wonky) import namespaced.wonky installed = self._makeOne('namespaced.wonky') self.assertEqual(installed.metadata_version, '1.0') self.assertEqual(installed.package, namespaced.wonky) self.assertEqual(installed.package_name, 'namespaced.wonky') finally: sys.path[:] = oldpath sys.modules.pop('namespaced.wonky', None) sys.modules.pop('namespaced', None) def test_namespaced_pkg_installed_via_pth(self): # E.g., installed by a Linux distro import os import sys where, _ = os.path.split(__file__) manky = os.path.join(where, 'manky') oldpath = sys.path[:] try: sys.path.append(manky) import namespaced.manky installed = self._makeOne('namespaced.manky') self.assertEqual(installed.metadata_version, '1.0') self.assertEqual(installed.package, namespaced.manky) self.assertEqual(installed.package_name, 'namespaced.manky') finally: sys.path[:] = oldpath sys.modules.pop('namespaced.manky', None) sys.modules.pop('namespaced', None) pkginfo-0.9.1/pkginfo/tests/funny/0000775000175000017500000000000012041302166017015 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/funny/__init__.py0000644000175000017500000000010411464571503021132 0ustar tseavertseaver# sample installed package w/ .egg-info file. __package__ = 'funny' pkginfo-0.9.1/pkginfo/tests/funny/funny.egg-info0000644000175000017500000000005711464570605021606 0ustar tseavertseaverMetadata-Version: 1.0 Name: funny Version: 0.1 pkginfo-0.9.1/pkginfo/tests/test_distribution.py0000644000175000017500000003627411724723775022044 0ustar tseavertseaverimport unittest class DistributionTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.distribution import Distribution return Distribution def _makeOne(self, metadata_version='1.0'): dist = self._getTargetClass()() if metadata_version is not None: dist.metadata_version = metadata_version return dist def test_ctor_defaults(self): sdist = self._makeOne(None) self.assertEqual(sdist.metadata_version, None) self.assertEqual(sdist.name, None) self.assertEqual(sdist.version, None) self.assertEqual(sdist.platforms, ()) self.assertEqual(sdist.supported_platforms, ()) self.assertEqual(sdist.summary, None) self.assertEqual(sdist.description, None) self.assertEqual(sdist.keywords, None) self.assertEqual(sdist.home_page, None) self.assertEqual(sdist.download_url, None) self.assertEqual(sdist.author, None) self.assertEqual(sdist.author_email, None) self.assertEqual(sdist.license, None) self.assertEqual(sdist.classifiers, ()) self.assertEqual(sdist.requires, ()) self.assertEqual(sdist.provides, ()) self.assertEqual(sdist.obsoletes, ()) self.assertEqual(sdist.maintainer, None) self.assertEqual(sdist.maintainer_email, None) self.assertEqual(sdist.requires_python, None) self.assertEqual(sdist.requires_external, ()) self.assertEqual(sdist.requires_dist, ()) self.assertEqual(sdist.provides_dist, ()) self.assertEqual(sdist.obsoletes_dist, ()) self.assertEqual(sdist.project_urls, ()) def test_extractMetadata_raises_NotImplementedError(self): # 'extractMetadata' calls 'read', which subclasses must override. dist = self._makeOne(None) self.assertRaises(NotImplementedError, dist.extractMetadata) def test_read_raises_NotImplementedError(self): # Subclasses must override 'read'. dist = self._makeOne(None) self.assertRaises(NotImplementedError, dist.read) def test_parse_Metadata_Version_1_0(self): from pkginfo.distribution import HEADER_ATTRS_1_0 dist = self._makeOne(None) dist.parse('Metadata-Version: 1.0') self.assertEqual(dist.metadata_version, '1.0') self.assertEqual(list(dist), [x[1] for x in HEADER_ATTRS_1_0]) def test_parse_Metadata_Version_unknown(self): dist = self._makeOne(None) dist.parse('Metadata-Version: 1.3') self.assertEqual(dist.metadata_version, '1.3') self.assertEqual(list(dist), []) def test_parse_Metadata_Version_override(self): dist = self._makeOne('1.2') dist.parse('Metadata-Version: 1.0') self.assertEqual(dist.metadata_version, '1.2') def test_parse_Name(self): dist = self._makeOne() dist.parse('Name: foobar') self.assertEqual(dist.name, 'foobar') def test_parse_Version(self): dist = self._makeOne() dist.parse('Version: 2.1.3b5') self.assertEqual(dist.version, '2.1.3b5') def test_parse_Platform_single(self): dist = self._makeOne() dist.parse('Platform: Plan9') self.assertEqual(list(dist.platforms), ['Plan9']) def test_parse_Platform_multiple(self): dist = self._makeOne() dist.parse('Platform: Plan9\nPlatform: AIX') self.assertEqual(list(dist.platforms), ['Plan9', 'AIX']) def test_parse_Supported_Platform_single(self): dist = self._makeOne() dist.parse('Supported-Platform: Plan9') self.assertEqual(list(dist.supported_platforms), ['Plan9']) def test_parse_Supported_Platform_multiple(self): dist = self._makeOne() dist.parse('Supported-Platform: i386-win32\n' 'Supported-Platform: RedHat 7.2') self.assertEqual(list(dist.supported_platforms), ['i386-win32', 'RedHat 7.2']) def test_parse_Summary(self): dist = self._makeOne() dist.parse('Summary: Package for foo') self.assertEqual(dist.summary, 'Package for foo') def test_parse_Description(self): dist = self._makeOne() dist.parse('Description: This package enables integration with ' 'foo servers.') self.assertEqual(dist.description, 'This package enables integration with ' 'foo servers.') def test_parse_Description_multiline(self): dist = self._makeOne() dist.parse('Description: This package enables integration with\n' ' foo servers.') self.assertEqual(dist.description, 'This package enables integration with\n' 'foo servers.') def test_parse_Keywords(self): dist = self._makeOne() dist.parse('Keywords: bar foo qux') self.assertEqual(dist.keywords, 'bar foo qux') def test_parse_Home_page(self): dist = self._makeOne() dist.parse('Home-page: http://example.com/package') self.assertEqual(dist.home_page, 'http://example.com/package') def test_parse_Author(self): dist = self._makeOne() dist.parse('Author: J. Phredd Bloggs') self.assertEqual(dist.author, 'J. Phredd Bloggs') def test_parse_Author_Email(self): dist = self._makeOne() dist.parse('Author-email: phreddy@example.com') self.assertEqual(dist.author_email, 'phreddy@example.com') def test_parse_License(self): dist = self._makeOne() dist.parse('License: Poetic') self.assertEqual(dist.license, 'Poetic') # Metadata version 1.1, defined in PEP 314. def test_parse_Classifier_single(self): dist = self._makeOne('1.1') dist.parse('Classifier: Some :: Silly Thing') self.assertEqual(list(dist.classifiers), ['Some :: Silly Thing']) def test_parse_Classifier_multiple(self): dist = self._makeOne('1.1') dist.parse('Classifier: Some :: Silly Thing\n' 'Classifier: Or :: Other') self.assertEqual(list(dist.classifiers), ['Some :: Silly Thing', 'Or :: Other']) def test_parse_Download_URL(self): dist = self._makeOne('1.1') dist.parse('Download-URL: ' 'http://example.com/package/mypackage-0.1.zip') self.assertEqual(dist.download_url, 'http://example.com/package/mypackage-0.1.zip') def test_parse_Requires_single_wo_version(self): dist = self._makeOne('1.1') dist.parse('Requires: SpanishInquisition') self.assertEqual(list(dist.requires), ['SpanishInquisition']) def test_parse_Requires_single_w_version(self): dist = self._makeOne('1.1') dist.parse('Requires: SpanishInquisition (>=1.3)') self.assertEqual(list(dist.requires), ['SpanishInquisition (>=1.3)']) def test_parse_Requires_multiple(self): dist = self._makeOne('1.1') dist.parse('Requires: SpanishInquisition\n' 'Requires: SillyWalks (1.4)\n' 'Requires: kniggits (>=2.3,<3.0)') self.assertEqual(list(dist.requires), ['SpanishInquisition', 'SillyWalks (1.4)', 'kniggits (>=2.3,<3.0)', ]) def test_parse_Provides_single_wo_version(self): dist = self._makeOne('1.1') dist.parse('Provides: SillyWalks') self.assertEqual(list(dist.provides), ['SillyWalks']) def test_parse_Provides_single_w_version(self): dist = self._makeOne('1.1') dist.parse('Provides: SillyWalks (1.4)') self.assertEqual(list(dist.provides), ['SillyWalks (1.4)']) def test_parse_Provides_multiple(self): dist = self._makeOne('1.1') dist.parse('Provides: SillyWalks\n' 'Provides: DeadlyJoke (3.1.4)') self.assertEqual(list(dist.provides), ['SillyWalks', 'DeadlyJoke (3.1.4)', ]) def test_parse_Obsoletes_single_no_version(self): dist = self._makeOne('1.1') dist.parse('Obsoletes: SillyWalks') self.assertEqual(list(dist.obsoletes), ['SillyWalks']) def test_parse_Obsoletes_single_w_version(self): dist = self._makeOne('1.1') dist.parse('Obsoletes: SillyWalks (<=1.3)') self.assertEqual(list(dist.obsoletes), ['SillyWalks (<=1.3)']) def test_parse_Obsoletes_multiple(self): dist = self._makeOne('1.1') dist.parse('Obsoletes: kniggits\n' 'Obsoletes: SillyWalks (<=2.0)') self.assertEqual(list(dist.obsoletes), ['kniggits', 'SillyWalks (<=2.0)', ]) # Metadata version 1.2, defined in PEP 345. def test_parse_Maintainer(self): dist = self._makeOne(metadata_version='1.2') dist.parse('Maintainer: J. Phredd Bloggs') self.assertEqual(dist.maintainer, 'J. Phredd Bloggs') def test_parse_Maintainer_Email(self): dist = self._makeOne(metadata_version='1.2') dist.parse('Maintainer-email: phreddy@example.com') self.assertEqual(dist.maintainer_email, 'phreddy@example.com') def test_parse_Requires_Python_single_spec(self): dist = self._makeOne('1.2') dist.parse('Requires-Python: >2.4') self.assertEqual(dist.requires_python, '>2.4') def test_parse_Requires_External_single_wo_version(self): dist = self._makeOne('1.2') dist.parse('Requires-External: libfoo') self.assertEqual(list(dist.requires_external), ['libfoo']) def test_parse_Requires_External_single_w_version(self): dist = self._makeOne('1.2') dist.parse('Requires-External: libfoo (>=1.3)') self.assertEqual(list(dist.requires_external), ['libfoo (>=1.3)']) def test_parse_Requires_External_multiple(self): dist = self._makeOne('1.2') dist.parse('Requires-External: libfoo\n' 'Requires-External: libbar (1.4)\n' 'Requires-External: libbaz (>=2.3,<3.0)') self.assertEqual(list(dist.requires_external), ['libfoo', 'libbar (1.4)', 'libbaz (>=2.3,<3.0)', ]) def test_parse_Requires_Dist_single_wo_version(self): dist = self._makeOne('1.2') dist.parse('Requires-Dist: SpanishInquisition') self.assertEqual(list(dist.requires_dist), ['SpanishInquisition']) def test_parse_Requires_Dist_single_w_version(self): dist = self._makeOne('1.2') dist.parse('Requires-Dist: SpanishInquisition (>=1.3)') self.assertEqual(list(dist.requires_dist), ['SpanishInquisition (>=1.3)']) def test_parse_Requires_Dist_single_w_env_marker(self): dist = self._makeOne('1.2') dist.parse("Requires-Dist: SpanishInquisition; " "python_version == '1.4'") self.assertEqual(list(dist.requires_dist), ["SpanishInquisition; python_version == '1.4'"]) def test_parse_Requires_Dist_multiple(self): dist = self._makeOne('1.2') dist.parse("Requires-Dist: SpanishInquisition\n" "Requires-Dist: SillyWalks; python_version == '1.4'\n" "Requires-Dist: kniggits (>=2.3,<3.0)") self.assertEqual(list(dist.requires_dist), ["SpanishInquisition", "SillyWalks; python_version == '1.4'", "kniggits (>=2.3,<3.0)", ]) def test_parse_Provides_Dist_single_wo_version(self): dist = self._makeOne('1.2') dist.parse('Provides-Dist: SillyWalks') self.assertEqual(list(dist.provides_dist), ['SillyWalks']) def test_parse_Provides_Dist_single_w_version(self): dist = self._makeOne('1.2') dist.parse('Provides-Dist: SillyWalks (1.4)') self.assertEqual(list(dist.provides_dist), ['SillyWalks (1.4)']) def test_parse_Provides_Dist_single_w_env_marker(self): dist = self._makeOne('1.2') dist.parse("Provides-Dist: SillyWalks; sys.platform == 'os2'") self.assertEqual(list(dist.provides_dist), ["SillyWalks; sys.platform == 'os2'"]) def test_parse_Provides_Dist_multiple(self): dist = self._makeOne('1.2') dist.parse("Provides-Dist: SillyWalks\n" "Provides-Dist: SpanishInquisition; sys.platform == 'os2'\n" "Provides-Dist: DeadlyJoke (3.1.4)") self.assertEqual(list(dist.provides_dist), ["SillyWalks", "SpanishInquisition; sys.platform == 'os2'", "DeadlyJoke (3.1.4)", ]) def test_parse_Obsoletes_Dist_single_no_version(self): dist = self._makeOne('1.2') dist.parse('Obsoletes-Dist: SillyWalks') self.assertEqual(list(dist.obsoletes_dist), ['SillyWalks']) def test_parse_Obsoletes_Dist_single_w_version(self): dist = self._makeOne('1.2') dist.parse('Obsoletes-Dist: SillyWalks (<=1.3)') self.assertEqual(list(dist.obsoletes_dist), ['SillyWalks (<=1.3)']) def test_parse_Obsoletes_Dist_single_w_env_marker(self): dist = self._makeOne('1.2') dist.parse("Obsoletes-Dist: SillyWalks; sys.platform == 'os2'") self.assertEqual(list(dist.obsoletes_dist), ["SillyWalks; sys.platform == 'os2'"]) def test_parse_Obsoletes_Dist_multiple(self): dist = self._makeOne('1.2') dist.parse("Obsoletes-Dist: kniggits\n" "Obsoletes-Dist: SillyWalks; sys.platform == 'os2'\n" "Obsoletes-Dist: DeadlyJoke (<=2.0)\n" ) self.assertEqual(list(dist.obsoletes_dist), ["kniggits", "SillyWalks; sys.platform == 'os2'", "DeadlyJoke (<=2.0)", ]) def test_parse_Project_URL_single_no_version(self): dist = self._makeOne('1.2') dist.parse('Project-URL: Bug tracker, http://bugs.example.com/grail') self.assertEqual(list(dist.project_urls), ['Bug tracker, http://bugs.example.com/grail']) def test_parse_Project_URL_multiple(self): dist = self._makeOne('1.2') dist.parse('Project-URL: Bug tracker, http://bugs.example.com/grail\n' 'Project-URL: Repository, http://svn.example.com/grail') self.assertEqual(list(dist.project_urls), ['Bug tracker, http://bugs.example.com/grail', 'Repository, http://svn.example.com/grail', ]) def test_parse_given_unicode(self): dist = self._makeOne() dist.parse(u'Metadata-Version: 1.0\nName: lp722928_c3') # no raise def test_parse_given_non_encodable_unicode(self): dist = self._makeOne() self.assertRaises(UnicodeEncodeError, dist.parse, u'Metadata-Version: 1.0\nName: lp722928_c3\n' u'Description: tr\u00E9s mal') pkginfo-0.9.1/pkginfo/tests/manky/0000775000175000017500000000000012041302166016775 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/manky/namespaced.manky-0.1.egg-info/0000775000175000017500000000000012041302166024201 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/manky/namespaced.manky-0.1.egg-info/PKG-INFO0000644000175000017500000000005511724736225025312 0ustar tseavertseaverMetadata-Version: 1.0 Name: namespaced.wonky pkginfo-0.9.1/pkginfo/tests/manky/NOT-A-PACKAGE.txt0000644000175000017500000000022011724734771021417 0ustar tseavertseaverTHIS IS NOT A PYTHON PACKAGE!!!! It is meant to be added to sys.path for testing introspection of namespace packages installed via setuptools. pkginfo-0.9.1/pkginfo/tests/manky/namespaced/0000775000175000017500000000000012041302166021075 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/manky/namespaced/__init__.py0000644000175000017500000000031011724735325023214 0ustar tseavertseaver# this is a namespace package try: import pkg_resources pkg_resources.declare_namespace(__name__) except ImportError: import pkgutil __path__ = pkgutil.extend_path(__path__, __name__) pkginfo-0.9.1/pkginfo/tests/manky/namespaced/manky/0000775000175000017500000000000012041302166022214 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/manky/namespaced/manky/__init__.py0000644000175000017500000000006311724735325024340 0ustar tseavertseaver# Dummy package inside the 'namespaced' namespace. pkginfo-0.9.1/pkginfo/tests/test_utils.py0000644000175000017500000001426712041301224020431 0ustar tseavertseaverimport unittest class Test_get_metadata(unittest.TestCase): def _callFUT(self, path, metadata_version=None): from pkginfo.utils import get_metadata if metadata_version is not None: return get_metadata(path, metadata_version) return get_metadata(path) def _checkMyPackage(self, dist, filename): self.assertEqual(dist.filename, filename) self.assertEqual(dist.name, 'mypackage') self.assertEqual(dist.version, '0.1') self.assertEqual(dist.keywords, None) self.assertEqual(list(dist.supported_platforms), []) def _checkClassifiers(self, dist): self.assertEqual(list(dist.classifiers), ['Development Status :: 4 - Beta', 'Environment :: Console (Text Based)', ]) def test_w_gztar(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d dist = self._callFUT(filename) self.assertEqual(dist.metadata_version, '1.0') self._checkMyPackage(dist, filename) def test_w_gztar_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d dist = self._callFUT(filename, metadata_version='1.1') self.assertEqual(dist.metadata_version, '1.1') self._checkMyPackage(dist, filename) self._checkClassifiers(dist) def test_w_bztar(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d dist = self._callFUT(filename) self.assertEqual(dist.metadata_version, '1.0') self._checkMyPackage(dist, filename) def test_w_bztar_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d dist = self._callFUT(filename, metadata_version='1.1') self.assertEqual(dist.metadata_version, '1.1') self._checkMyPackage(dist, filename) self._checkClassifiers(dist) def test_w_zip(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d dist = self._callFUT(filename) self.assertEqual(dist.metadata_version, '1.0') self._checkMyPackage(dist, filename) def test_w_zip_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d dist = self._callFUT(filename, metadata_version='1.1') self.assertEqual(dist.metadata_version, '1.1') self._checkMyPackage(dist, filename) self._checkClassifiers(dist) def test_w_egg(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d dist = self._callFUT(filename) self.assertEqual(dist.metadata_version, '1.0') self._checkMyPackage(dist, filename) def test_w_egg_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d dist = self._callFUT(filename, metadata_version='1.1') self.assertEqual(dist.metadata_version, '1.1') self._checkMyPackage(dist, filename) self._checkClassifiers(dist) def test_w_module(self): import sys if sys.version_info >= (2, 6): EXPECTED = sys.version_info >= (2, 7) and '1.1' or '1.0' import pkginfo from pkginfo.tests import _checkSample dist = self._callFUT(pkginfo) self.assertEqual(dist.metadata_version, EXPECTED) _checkSample(self, dist) def test_w_module_and_metadata_version(self): import sys if sys.version_info >= (2, 6): import pkginfo from pkginfo.tests import _checkSample from pkginfo.tests import _checkClassifiers dist = self._callFUT(pkginfo, metadata_version='1.2') self.assertEqual(dist.metadata_version, '1.2') _checkSample(self, dist) _checkClassifiers(self, dist) def test_w_package_name(self): import sys if sys.version_info >= (2, 6): EXPECTED = sys.version_info >= (2, 7) and '1.1' or '1.0' from pkginfo.tests import _checkSample dist = self._callFUT('pkginfo') self.assertEqual(dist.metadata_version, EXPECTED) _checkSample(self, dist) def test_w_package_name_and_metadata_version(self): import sys if sys.version_info >= (2, 6): from pkginfo.tests import _checkSample from pkginfo.tests import _checkClassifiers dist = self._callFUT('pkginfo', metadata_version='1.2') self.assertEqual(dist.metadata_version, '1.2') _checkSample(self, dist) _checkClassifiers(self, dist) def test_w_directory_no_EGG_INFO(self): import os import warnings dir, name = os.path.split(__file__) subdir = os.path.join(dir, 'funny') old_filters = warnings.filters[:] warnings.filterwarnings('ignore') try: dist = self._callFUT(subdir) self.assertEqual(dist.path, subdir) self.assertEqual(dist.name, None) self.assertEqual(dist.version, None) finally: warnings.filters[:] = old_filters def test_w_directory(self): import os dir, name = os.path.split(__file__) subdir = os.path.join(dir, 'silly') dist = self._callFUT(subdir) self.assertEqual(dist.metadata_version, '1.0') self.assertEqual(dist.name, 'silly') self.assertEqual(dist.version, '0.1') def test_w_directory_and_metadata_version(self): import os dir, name = os.path.split(__file__) subdir = os.path.join(dir, 'silly') dist = self._callFUT(subdir, metadata_version='1.2') self.assertEqual(dist.metadata_version, '1.2') self.assertEqual(dist.name, 'silly') self.assertEqual(dist.version, '0.1') pkginfo-0.9.1/pkginfo/tests/test_develop.py0000644000175000017500000000155611357450726020751 0ustar tseavertseaverimport unittest class DevelopTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.develop import Develop return Develop def _makeOne(self, dirname=None): return self._getTargetClass()(dirname) def test_ctor_w_path(self): from pkginfo.tests import _checkSample develop = self._makeOne('.') _checkSample(self, develop) def test_ctor_w_invalid_path(self): import warnings from pkginfo.tests import _checkSample old_filters = warnings.filters[:] warnings.filterwarnings('ignore') try: develop = self._makeOne('/nonesuch') self.assertEqual(develop.metadata_version, None) self.assertEqual(develop.name, None) self.assertEqual(develop.version, None) finally: warnings.filters[:] = old_filters pkginfo-0.9.1/pkginfo/tests/wonky/0000775000175000017500000000000012041302166017025 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/wonky/EGG-INFO/0000775000175000017500000000000012041302166020160 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/wonky/EGG-INFO/PKG-INFO0000644000175000017500000000005511724736166021275 0ustar tseavertseaverMetadata-Version: 1.0 Name: namespaced.wonky pkginfo-0.9.1/pkginfo/tests/wonky/NOT-A-PACKAGE.txt0000644000175000017500000000022011724732261021437 0ustar tseavertseaverTHIS IS NOT A PYTHON PACKAGE!!!! It is meant to be added to sys.path for testing introspection of namespace packages installed via setuptools. pkginfo-0.9.1/pkginfo/tests/wonky/namespaced/0000775000175000017500000000000012041302166021125 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/wonky/namespaced/__init__.py0000644000175000017500000000031011724732334023241 0ustar tseavertseaver# this is a namespace package try: import pkg_resources pkg_resources.declare_namespace(__name__) except ImportError: import pkgutil __path__ = pkgutil.extend_path(__path__, __name__) pkginfo-0.9.1/pkginfo/tests/wonky/namespaced/wonky/0000775000175000017500000000000012041302166022274 5ustar tseavertseaverpkginfo-0.9.1/pkginfo/tests/wonky/namespaced/wonky/__init__.py0000644000175000017500000000006311724732417024417 0ustar tseavertseaver# Dummy package inside the 'namespaced' namespace. pkginfo-0.9.1/pkginfo/tests/test_sdist.py0000644000175000017500000000652011464572165020436 0ustar tseavertseaverimport unittest class SDistTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.sdist import SDist return SDist def _makeOne(self, filename=None, metadata_version=None): if metadata_version is not None: return self._getTargetClass()(filename, metadata_version) return self._getTargetClass()(filename) def _checkSample(self, sdist, filename): self.assertEqual(sdist.filename, filename) self.assertEqual(sdist.name, 'mypackage') self.assertEqual(sdist.version, '0.1') self.assertEqual(sdist.keywords, None) self.assertEqual(list(sdist.supported_platforms), []) def _checkClassifiers(self, sdist): self.assertEqual(list(sdist.classifiers), ['Development Status :: 4 - Beta', 'Environment :: Console (Text Based)', ]) def test_ctor_w_invalid_filename(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nonesuch-0.1.tar.gz' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_wo_PKG_INFO(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nopkginfo-0.1.zip' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_w_gztar(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d sdist = self._makeOne(filename) self.assertEqual(sdist.metadata_version, '1.0') self._checkSample(sdist, filename) def test_ctor_w_gztar_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.gz' % d sdist = self._makeOne(filename, metadata_version='1.1') self._checkSample(sdist, filename) self.assertEqual(sdist.metadata_version, '1.1') self._checkClassifiers(sdist) def test_ctor_w_bztar(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d sdist = self._makeOne(filename) self.assertEqual(sdist.metadata_version, '1.0') self._checkSample(sdist, filename) def test_ctor_w_bztar_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.tar.bz2' % d sdist = self._makeOne(filename, metadata_version='1.1') self.assertEqual(sdist.metadata_version, '1.1') self._checkSample(sdist, filename) self._checkClassifiers(sdist) def test_ctor_w_zip(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d sdist = self._makeOne(filename) self.assertEqual(sdist.metadata_version, '1.0') self._checkSample(sdist, filename) def test_ctor_w_zip_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d sdist = self._makeOne(filename, metadata_version='1.1') self.assertEqual(sdist.metadata_version, '1.1') self._checkSample(sdist, filename) self._checkClassifiers(sdist) pkginfo-0.9.1/pkginfo/tests/test_bdist.py0000644000175000017500000000434711464567536020430 0ustar tseavertseaverimport unittest class BDistTests(unittest.TestCase): def _getTargetClass(self): from pkginfo.bdist import BDist return BDist def _makeOne(self, filename=None, metadata_version=None): if metadata_version is not None: return self._getTargetClass()(filename, metadata_version) return self._getTargetClass()(filename) def _checkSample(self, bdist, filename): self.assertEqual(bdist.filename, filename) self.assertEqual(bdist.name, 'mypackage') self.assertEqual(bdist.version, '0.1') self.assertEqual(bdist.keywords, None) def _checkClassifiers(self, bdist): self.assertEqual(list(bdist.classifiers), ['Development Status :: 4 - Beta', 'Environment :: Console (Text Based)', ]) self.assertEqual(list(bdist.supported_platforms), []) def test_ctor_w_bogus_filename(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nonesuch-0.1-py2.6.egg' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_w_non_egg(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1.zip' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_wo_PKG_INFO(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/nopkginfo-0.1.egg' % d self.assertRaises(ValueError, self._makeOne, filename) def test_ctor_w_egg(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d bdist = self._makeOne(filename) self.assertEqual(bdist.metadata_version, '1.0') self._checkSample(bdist, filename) def test_ctor_w_egg_and_metadata_version(self): import os d, _ = os.path.split(__file__) filename = '%s/../../docs/examples/mypackage-0.1-py2.6.egg' % d bdist = self._makeOne(filename, metadata_version='1.1') self.assertEqual(bdist.metadata_version, '1.1') self._checkSample(bdist, filename) self._checkClassifiers(bdist) pkginfo-0.9.1/pkginfo/utils.py0000644000175000017500000000302111464573124016234 0ustar tseavertseaverimport os from types import ModuleType from pkginfo.bdist import BDist from pkginfo.develop import Develop from pkginfo.distribution import Distribution from pkginfo.installed import Installed from pkginfo.sdist import SDist def get_metadata(path_or_module, metadata_version=None): """ Try to create a Distribution 'path_or_module'. o 'path_or_module' may be a module object. o If a string, 'path_or_module' may point to an sdist file, a bdist file, an installed package, or a working checkout (if it contains PKG-INFO). o Return None if 'path_or_module' can't be parsed. """ if isinstance(path_or_module, ModuleType): try: return Installed(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass try: __import__(path_or_module) except ImportError: pass else: try: return Installed(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass if os.path.isfile(path_or_module): try: return SDist(path_or_module, metadata_version) except (ValueError, IOError): pass try: return BDist(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass if os.path.isdir(path_or_module): try: return Develop(path_or_module, metadata_version) except (ValueError, IOError): #pragma NO COVER pass pkginfo-0.9.1/pkginfo/develop.py0000644000175000017500000000157111357450726016545 0ustar tseavertseaverimport glob import os import sys import warnings from pkginfo.distribution import Distribution class Develop(Distribution): def __init__(self, path, metadata_version=None): self.path = os.path.abspath( os.path.normpath( os.path.expanduser(path))) self.metadata_version = metadata_version self.extractMetadata() def read(self): candidates = [self.path] candidates.extend(glob.glob(os.path.join(self.path, '*.egg-info'))) candidates.extend(glob.glob(os.path.join(self.path, 'EGG-INFO'))) for candidate in candidates: if os.path.isdir(candidate): path = os.path.join(candidate, 'PKG-INFO') if os.path.exists(path): return open(path).read() warnings.warn('No PKG-INFO found for path: %s' % self.path) pkginfo-0.9.1/pkginfo/commandline.py0000644000175000017500000001462112041275443017365 0ustar tseavertseaver"""Print the metadata for one or more Python package distributions. Usage: %prog [options] path+ Each 'path' entry can be one of the following: o a source distribution: in this case, 'path' should point to an existing archive file (.tar.gz, .tar.bz2, or .zip) as generated by 'setup.py sdist'. o a binary distribution: in this case, 'path' should point to an existing archive file (.egg) o a "develop" checkout: in ths case, 'path' should point to a directory intialized via 'setup.py develop' (under setuptools). o an installed package: in this case, 'path' should be the importable name of the package. """ from ConfigParser import ConfigParser from csv import writer import optparse import os import sys from pkginfo import get_metadata from pkginfo.distribution import HEADER_ATTRS def _parse_options(): parser = optparse.OptionParser(usage=__doc__) parser.add_option("-m", "--metadata-version", default=None, help="Override metadata version") parser.add_option("-f", "--field", dest="fields", action="append", help="Specify an output field (repeatable)", ) parser.add_option("-d", "--download-url-prefix", dest="download_url_prefix", help="Download URL prefix", ) parser.add_option("--simple", dest="output", action="store_const", const='simple', default='simple', help="Output as simple key-value pairs", ) parser.add_option("-s", "--skip", dest="skip", action="store_true", default=True, help="Skip missing values in simple output", ) parser.add_option("-S", "--no-skip", dest="skip", action="store_false", help="Don't skip missing values in simple output", ) parser.add_option("--single", dest="output", action="store_const", const='single', help="Output delimited values", ) parser.add_option("--item-delim", dest="item_delim", action="store", default=';', help="Delimiter for fields in single-line output", ) parser.add_option("--sequence-delim", dest="sequence_delim", action="store", default=',', help="Delimiter for multi-valued fields", ) parser.add_option("--csv", dest="output", action="store_const", const='csv', help="Output as CSV", ) parser.add_option("--ini", dest="output", action="store_const", const='ini', help="Output as INI", ) options, args = parser.parse_args() if len(args)==0: parser.error("Pass one or more files or directories as arguments.") else: return options, args class Base(object): _fields = None def __init__(self, options): if options.fields: self._fields = options.fields def finish(self): pass class Simple(Base): def __init__(self, options): super(Simple, self).__init__(options) self._skip = options.skip def __call__(self, meta): for field in self._fields or list(meta): value = getattr(meta, field) if (not self._skip) or (value is not None and value!=()): print "%s: %s" % (field, value) class SingleLine(Base): _fields = None def __init__(self, options): super(SingleLine, self).__init__(options) self._item_delim = options.item_delim self._sequence_delim = options.sequence_delim def __call__(self, meta): if self._fields is None: self._fields = list(meta) values = [] for field in self._fields: value = getattr(meta, field) if isinstance(value, (tuple, list)): value = self._sequence_delim.join(value) else: value = str(value) values.append(value) print self._item_delim.join(values) class CSV(Base): _wrote_headers = False def __init__(self, options): super(CSV, self).__init__(options) self._writer = writer(sys.stdout) self._sequence_delim = options.sequence_delim def __call__(self, meta): if self._fields is None: self._fields = list(meta) # first dist wins fields = self._fields if not self._wrote_headers: # latch self._writer.writerow(fields) self._wrote_headers = True values = [] for field in fields: value = getattr(meta, field) if isinstance(value, (tuple, list)): value = self._sequence_delim.join(value) else: value = str(value) values.append(value) self._writer.writerow(values) class INI(Base): _fields = None def __init__(self, options): super(INI, self).__init__(options) self._parser = ConfigParser() def __call__(self, meta): name = meta.name version = meta.version section = '%s-%s' % (name, version) if self._parser.has_section(section): raise ValueError('Duplicate distribution: %s' % section) self._parser.add_section(section) for field in self._fields or list(meta): value = getattr(meta, field) if isinstance(value, (tuple, list)): value = '\n\t'.join(value) self._parser.set(section, field, value) def finish(self): self._parser.write(sys.stdout) _FORMATTERS = { 'simple': Simple, 'single': SingleLine, 'csv': CSV, 'ini': INI, } def main(): """Entry point for pkginfo tool """ options, paths = _parse_options() format = getattr(options, 'output', 'simple') formatter = _FORMATTERS[format](options) for path in paths: meta = get_metadata(path, options.metadata_version) if meta is None: continue if options.download_url_prefix: if meta.download_url is None: filename = os.path.basename(path) meta.download_url = '%s/%s' % (options.download_url_prefix, filename) formatter(meta) formatter.finish() pkginfo-0.9.1/pkginfo/sdist.py0000644000175000017500000000252411357450726016234 0ustar tseavertseaverimport os import tarfile import zipfile from pkginfo.distribution import Distribution class SDist(Distribution): def __init__(self, filename, metadata_version=None): self.filename = filename self.metadata_version = metadata_version self.extractMetadata() def read(self): fqn = os.path.abspath( os.path.normpath(self.filename)) if not os.path.exists(fqn): raise ValueError('No such file: %s' % fqn) if fqn.endswith('.zip'): archive = zipfile.ZipFile(fqn) names = archive.namelist() def read_file(name): return archive.read(name) elif fqn.endswith('gz') or fqn.endswith('bz2'): archive = tarfile.TarFile.open(fqn) names = archive.getnames() def read_file(name): return archive.extractfile(name).read() else: raise ValueError('Not a known archive format: %s' % fqn) tuples = [x.split('/') for x in names if 'PKG-INFO' in x] schwarz = sorted([(len(x), x) for x in tuples]) for path in [x[1] for x in schwarz]: candidate = '/'.join(path) data = read_file(candidate) if 'Metadata-Version' in data: return data raise ValueError('No PKG-INFO in archive: %s' % fqn) pkginfo-0.9.1/CHANGES.txt0000644000175000017500000000726712041301707014702 0ustar tseavertseaver``pkginfo`` Changelog ===================== 0.9.1 (2012-10-22) ------------------ - Fix test failure under Python >= 2.7, which is enforcing 'metadata_version == 1.1' because we have classifiers. 0.9 (2012-04-25) ---------------- - Fix introspection of installed namespace packages. They may be installed as eggs or via dist-installed 'egg-info' files. https://bugs.launchpad.net/pkginfo/+bug/934311 - Avoid a regression in 0.8 under Python 2.6 / 2.7 when parsing unicode. https://bugs.launchpad.net/pkginfo/+bug/733827/comments/3 0.8 (2011-03-12) ---------------- - Work around Python 2.7's breakage of StringIO. Fixes https://bugs.launchpad.net/pkginfo/+bug/733827 - Fixed bug in introspection of installed packages missing the ``__package__`` attribute. 0.7 (2010-11-04) ---------------- - Preserve newlines in the ``description`` field. Thanks to Sridhar Ratnakumar for the patch. - 100% test coverage. 0.6 (2010-06-01) ---------------- - Replaced use of ``StringIO.StringIO`` with ``io.StringIO``, where available (Python >= 2.6). - Replaced use of ``rfc822`` stdlib module with ``email.parser``, when available (Python >= 2.5). Ensured that distributions "unfold" wrapped continuation lines, stripping any leading / trailing whitespace, no matter which module was used for parsing. - Removed bogus testing dependency on ``zope.testing``. - Added tests that the "environment markers" spelled out in the approved PEP 345 are captured. - Added ``Project-URL`` for ``1.2`` PKG-INFO metdata (defined in the accepted version of PEP 345). 0.5 (2009-09-11) ---------------- - Marked package as non-zip-safe. - Fixed Trove metadata misspelling. - Restored compatibility with Python 2.4. - Noted that the introspection of installed packages / modules works only in Python 2.6 or later. - Added ``Index`` class as an abstraction over a collection of distributions. - Added ``download_url_prefix`` argument to ``pkginfo`` script. If passed, the script will use the prefix to synthesize a ``download_url`` for distributions which do not supply that value directly. 0.4.1 (2009-05-07) ------------------ - Fixed bugs in handling of installed packages which lack ``__file__`` or ``PKG-INFO``. 0.4 (2009-05-07) ---------------- - Extended the console script to allow output as CSV or INI. Also, added arguments to specify the metadata version and other parsing / output policies. - Added support for the different metadata versions specified in PEPs 241, 314, and 345. Distributions now parse and expose only the attributes corresponding to their metadata version, which defaults to the version parsed from the ``PKG-INFO`` file. The programmer can override that version when creating the distribution object. 0.3 (2009-05-07) ---------------- - Added support for introspection of "development eggs" (checkouts with ``PKG-INFO``, perhaps created via ``setup.py develop``). - Added a console script, ``pkginfo``, which takes one or more paths on the command line and writes out the associated information. Thanks to ``runeh`` for the patch! - Added ``get_metadata`` helper function, which dispatches a given path or module across the available distribution types, and returns a distribution object. Thanks to ``runeh`` for the patch! - Made distribution objects support iteration over the metadata fields. Thanks to ``runeh`` for the patch! - Made Distribution and subclasses new-style classes. Thanks to ``runeh`` for the patch! 0.2 (2009-04-14) ---------------- - Added support for introspection of ``bdist_egg`` binary distributions. 0.1.1 (2009-04-10) ------------------ - Fixed packaging errors. 0.1 (2009-04-10) ---------------- - Initial release. pkginfo-0.9.1/docs/0000775000175000017500000000000012041302166014007 5ustar tseavertseaverpkginfo-0.9.1/docs/distributions.rst0000644000175000017500000000653711357450726017473 0ustar tseavertseaverDistribution Types ================== The fundamental abstraction provided by this pacakge is the ``Distribution`` base class. Implementations exist for specific cases: source distributions, binary distributions, installed pakcages, and development checkouts. .. doctest:: >>> from pkginfo import Distribution >>> from pkginfo import SDist >>> assert issubclass(SDist, Distribution) >>> from pkginfo import BDist >>> assert issubclass(BDist, Distribution) >>> from pkginfo import Installed >>> assert issubclass(Installed, Distribution) >>> from pkginfo import Develop >>> assert issubclass(Develop, Distribution) Introspecting Source Distributions ---------------------------------- ``SDist`` objects are created from a filesystem path to the corresponding archive, which should have been created via the ``sdist`` command from distutils: .. doctest:: >>> mypackage = SDist('docs/examples/mypackage-0.1.tar.gz') After creation, the ``SDist`` instance will have attributes corrsponding the the fields defined in the PEP corresponding to the metadata version, lower-cased and transliterated into valid Python identifiers by mapping hyphens to underscores. E.g.: .. doctest:: >>> print mypackage.metadata_version 1.0 >>> print mypackage.name mypackage >>> print mypackage.version 0.1 Fields which are optional under the PEP, and which have no value set in their ``PKG-INFO``, will map to the value ``None``: .. doctest:: >>> print mypackage.keywords None Fields which are marked "multiple use" under the PEP map onto sequences; their names are pluralized to indicate the sequence. "Multiple use" fields with no occurences in the ``PKG-INFO`` file will map onto an empty sequence: .. doctest:: >>> print list(mypackage.supported_platforms) [] See `Metadata Versions `_ for an example with a non-empty, "multiple-use" field. Introspecting Binary Distributions ---------------------------------- ``BDist`` objects are created from the filename, which should have been generated via ``setup.py bdist_egg``. .. doctest:: >>> mypackage = BDist('docs/examples/mypackage-0.1-py2.6.egg') After that, they have the same metadata as other ``Distribution`` objects, Introspecting Installed Packages -------------------------------- ``Installed`` objects are created from either a module object or its dotted name. Note that this feature only works in Python 2.6 or later: earlier Python versions did not record ``PKG-INFO`` for installed packages. .. doctest:: >>> import sys >>> if sys.version_info >= (2,6): ... dotted = Installed('pkginfo') ... import pkginfo ... direct = Installed(pkginfo) After that, they have the same metadata as other ``Distribution`` objects, assuming that the package on which they were based has a discoverable '.egg-info' file / directory. To be discoverable, the '.egg-info' must either be located inside the package (e.g., created via ``setup.py develop`` under setuptools), or adjacent to the package (e.g., created via ``setup.py instlall``). Introspecting Development Checkouts ----------------------------------- ``Develop`` objects are created from a path to a checkout containing a ``PKG-iNFO`` file, e.g., created by running ``setup.py develop`` under setuptools. .. doctest:: >>> develop = Develop('.') After that, they have the same metadata as other ``Distribution`` objects. pkginfo-0.9.1/docs/Makefile0000644000175000017500000000447711357450726015500 0ustar tseavertseaver# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d .build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html web pickle htmlhelp latex changes linkcheck help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " changes to make an overview over all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" clean: -rm -rf .build/* html: mkdir -p .build/html .build/doctrees $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) .build/html @echo @echo "Build finished. The HTML pages are in .build/html." pickle: mkdir -p .build/pickle .build/doctrees $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) .build/pickle @echo @echo "Build finished; now you can process the pickle files." web: pickle json: mkdir -p .build/json .build/doctrees $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) .build/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: mkdir -p .build/htmlhelp .build/doctrees $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) .build/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in .build/htmlhelp." latex: mkdir -p .build/latex .build/doctrees $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) .build/latex @echo @echo "Build finished; the LaTeX files are in .build/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." changes: mkdir -p .build/changes .build/doctrees $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) .build/changes @echo @echo "The overview file is in .build/changes." linkcheck: mkdir -p .build/linkcheck .build/doctrees $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) .build/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in .build/linkcheck/output.txt." pkginfo-0.9.1/docs/metadata.rst0000644000175000017500000000232111457313144016325 0ustar tseavertseaverMetadata Versions ================= The allowed ``PKG-INFO`` fields and their semantics are defined in a series of PEPs, each of which updates the metadata version field. - Metadata version 1.0 is specified in `PEP 241`_. - Metadata version 1.1 is specified in `PEP 314`_. - Metadata version 1.2 is specified in `PEP 345`_ (still in draft). A given ``Distribution`` object parses / exposes the attributes which correspond to the metadata version specified in its ``PKG-INFO``. You can override the metadata version stored in a given distribution by passing the specific version (as a string) to its constructor. E.g., updating the metadata version here in order to expose the classifiers, which were not defined under version '1.0': .. doctest:: >>> from pkginfo import SDist >>> mypackage = SDist('docs/examples/mypackage-0.1.tar.gz', ... metadata_version='1.1') >>> print [str(x) for x in mypackage.classifiers] ['Development Status :: 4 - Beta', 'Environment :: Console (Text Based)'] .. _`PEP 241`: http://svn.python.org/projects/peps/trunk/pep-0241.txt .. _`PEP 314`: http://svn.python.org/projects/peps/trunk/pep-0314.txt .. _`PEP 345`: http://svn.python.org/projects/peps/trunk/pep-0345.txt pkginfo-0.9.1/docs/conf.py0000644000175000017500000001371611357450726015333 0ustar tseavertseaver# -*- coding: utf-8 -*- # # pkginfo documentation build configuration file, created by # sphinx-quickstart on Wed Apr 8 19:26:04 2009. # # This file is execfile()d with the current directory set to its containing dir. # # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If your extensions are in another directory, add it here. If the directory # is relative to the documentation root, use os.path.abspath to make it # absolute, like shown here. #sys.path.append(os.path.abspath('.')) # General configuration # --------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', ] doctest_path = [os.path.abspath('..')] # Add any paths that contain templates here, relative to this directory. templates_path = ['.templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # General information about the project. project = u'pkginfo' copyright = u'2009, Tres Seaver' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '0.5' # The full version, including alpha/beta/rc tags. release = '0.5' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. exclude_trees = ['.build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # Options for HTML output # ----------------------- # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. html_style = 'default.css' # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['.static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, the reST sources are included in the HTML build as _sources/. #html_copy_source = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'pkginfodoc' # Options for LaTeX output # ------------------------ # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ ('index', 'pkginfo.tex', ur'pkginfo Documentation', ur'Tres Seaver', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True pkginfo-0.9.1/docs/indexes.rst0000644000175000017500000000107411357450726016217 0ustar tseavertseaverDistribution Indexes ===================== An ``Index`` is conceptually a set of ``Distribution`` objects, with some additional behavior for managing the set as a whole. .. doctest:: >>> from pkginfo import Distribution >>> from pkginfo import Index >>> index = Index() >>> list(index) [] >>> d1 = Distribution() >>> d1.name = 'foo' >>> d1.version = '1.0' >>> index.add(d1) >>> list(index) ['foo-1.0'] >>> d2 = Distribution() >>> d2.name = 'foo' >>> d2.version = '1.1' >>> index.add(d2) >>> sorted(list(index)) ['foo-1.0', 'foo-1.1'] pkginfo-0.9.1/docs/index.rst0000644000175000017500000000017611357450726015671 0ustar tseavertseaverpkginfo documentation ===================== Contents: .. toctree:: :maxdepth: 2 distributions metadata indexes pkginfo-0.9.1/docs/examples/0000775000175000017500000000000012041302166015625 5ustar tseavertseaverpkginfo-0.9.1/docs/examples/mypackage-0.1-py2.6.egg0000644000175000017500000000165011357450726021441 0ustar tseavertseaverPKIN:2EGG-INFO/dependency_links.txtPKIN:sXn`EGG-INFO/SOURCES.txt rutu+(*N-)-KNK *r+ SRu3u=9M"Z\]K]I~A|NjYjHPKIN:2EGG-INFO/top_level.txtPKIN:$1@.>EGG-INFO/PKG-INFOUMK0@sC]jyhݰI&$by B= V``7AOHo[NcZ 7OgSg,M]%Z9sМuea`0 eh gJ?"a_ºcmG!ӵ{%e9Ü`44)2e0]y?f8jq2;} 0SPKIN:2EGG-INFO/zip-safePKIN:2EGG-INFO/dependency_links.txtPKIN:sXn`>EGG-INFO/SOURCES.txtPKIN:2EGG-INFO/top_level.txtPKIN:$1@.>EGG-INFO/PKG-INFOPKIN:2EGG-INFO/zip-safePKOCpkginfo-0.9.1/docs/examples/mypackage-0.1.tar.gz0000644000175000017500000000140511357450726021226 0ustar tseavertseaver]Imypackage-0.1.tarN0s]A"i E@Qؽ@&nHbv*iR z<+|C9E5JnVW{RVv)Ͳ,Ϸ]ϳmʹzkZPbjc4Q?vGC܈MsGoY*/,ǗiM=/|nS \E'zŔL&Д><4{ka I2%e0u'Ffb,))j2-*-u?O_?1.8Kkgi_{"UU`;sWuMm:d71x:C 7 p𿁰~W?Y{?<:H 'fN-CeQx><$:~.T$) ’mފn),g s8W8GifPe(ayG,eKIĔֲ!ij'#4Dž#Da@pO.Ě렘''[gF=q >}#;_^[so: MavAHaSO[J$UtvjlQŽ̞ƄjF5aAϒIԒ=ZaËR4wk޸_mugRRR TZ(pkginfo-0.9.1/docs/examples/mypackage-0.1.zip0000644000175000017500000000375411357450726020634 0ustar tseavertseaverPKB:8Jmypackage-0.1/README.txt˭,HLNLOUrutuE\\. 0eiE %%y yi z\PK:DV2;mypackage-0.1/setup.cfgNMOKˏ*ILO*IQUsRKRl0,/(,83?,PK:$1@.>mypackage-0.1/PKG-INFOUMK0@sC]jyhݰI&$by B= V``7AOHo[NcZ 7OgSg,M]%Z9sМuea`0 eh gJ?"a_ºcmG!ӵ{%e9Ü`44)2e0]y?f8jq2;} 0SPK:95mypackage-0.1/setup.pyUAk0 .`at/hoe *m[ Ϳwz{BSbd2X9ɟT;E=g҇ꮔ`s,\s '‚KɣuFK[DZt#F.78}ܢV4׽ن>:N)mypackage-0.1/mypackage.egg-info/PKG-INFOUMK0@sC]jyhݰI&$by B= V``7AOHo[NcZ 7OgSg,M]%Z9sМuea`0 eh gJ?"a_ºcmG!ӵ{%e9Ü`44)2e0]y?f8jq2;} 0SPKB:8Jmypackage-0.1/README.txtPK:DV2;nmypackage-0.1/setup.cfgPK:$1@.>mypackage-0.1/PKG-INFOPK:95mypackage-0.1/setup.pyPK:25mypackage-0.1/mypackage.egg-info/dependency_links.txtPK:JyD[,=mypackage-0.1/mypackage.egg-info/SOURCES.txtPK:2.mypackage-0.1/mypackage.egg-info/top_level.txtPK:$1@.>)1mypackage-0.1/mypackage.egg-info/PKG-INFOPKSpkginfo-0.9.1/docs/examples/nopkginfo-0.1.egg0000644000175000017500000000167311464567504020625 0ustar tseavertseaverPK ld= EGG-INFO/UT  L6Lux PK IN:2EGG-INFO/zip-safeUT IIux  PKIN:sXn`EGG-INFO/SOURCES.txtUT IIux  rutu+(*N-)-KNK *r+ SRu3u=9M"Z\]K]I~A|NjYjHPK IN:2EGG-INFO/top_level.txtUT IIux  PK IN:2EGG-INFO/dependency_links.txtUT IIux  PK ld= AEGG-INFO/UT Lux PK IN:2CEGG-INFO/zip-safeUTIux PKIN:sXn`EGG-INFO/SOURCES.txtUTIux PK IN:2=EGG-INFO/top_level.txtUTIux PK IN:2EGG-INFO/dependency_links.txtUTIux PKpkginfo-0.9.1/docs/examples/mypackage-0.1.tar.bz20000644000175000017500000000157111357450726021307 0ustar tseavertseaverBZh91AY&SY¯ǔ@ߊ` P @R2 4ji2a40@ #L04TQ@ RM4i@H@$eOiħOQ==G!??viwt]2l0^ .i]@Y-r)wJWV\\A0$`x弦 :YAy6k-;2 ؅ְ+:Gnŝm礊AV|&. H h1^1*0A1Aǥdw|}e)ϒL cq(q-2SCJvgooH +8+ĥHHD?2W/lİEtt3*dlX d`+ f H%~V Y"QTH:O#?\(((K ,`#HZZy=@P{V~ϰ[CJa1dp"@iً5Fi}vpJ;:|@fytT%ݱ?& 7a:jb.979[BI&;IppZ`;\e2b/>#o4{( -B> .~V`!,8yX `91+XY)rfiq'a2';uy