summaryrefslogtreecommitdiff
path: root/pkg_resources.py
diff options
context:
space:
mode:
Diffstat (limited to 'pkg_resources.py')
-rw-r--r--pkg_resources.py61
1 files changed, 57 insertions, 4 deletions
diff --git a/pkg_resources.py b/pkg_resources.py
index a61c0efe..350a50ef 100644
--- a/pkg_resources.py
+++ b/pkg_resources.py
@@ -15,6 +15,7 @@ method.
import sys, os, zipimport, time, re, imp, types
from urlparse import urlparse, urlunparse
+from email.parser import Parser
try:
frozenset
@@ -1746,7 +1747,7 @@ def find_on_path(importer, path_item, only=False):
# scan for .egg and .egg-info in directory
for entry in os.listdir(path_item):
lower = entry.lower()
- if lower.endswith('.egg-info'):
+ if lower.endswith('.egg-info') or lower.endswith('.dist-info'):
fullpath = os.path.join(path_item, entry)
if os.path.isdir(fullpath):
# egg-info directory, allow getting metadata
@@ -2119,6 +2120,8 @@ def _remove_md5_fragment(location):
class Distribution(object):
"""Wrap an actual or potential sys.path entry w/metadata"""
+ PKG_INFO = 'PKG-INFO'
+
def __init__(self,
location=None, metadata=None, project_name=None, version=None,
py_version=PY_MAJOR, platform=None, precedence = EGG_DIST
@@ -2136,12 +2139,14 @@ class Distribution(object):
def from_location(cls,location,basename,metadata=None,**kw):
project_name, version, py_version, platform = [None]*4
basename, ext = os.path.splitext(basename)
- if ext.lower() in (".egg",".egg-info"):
+ if ext.lower() in _distributionImpl:
+ # .dist-info gets much metadata differently
match = EGG_NAME(basename)
if match:
project_name, version, py_version, platform = match.group(
'name','ver','pyver','plat'
)
+ cls = _distributionImpl[ext.lower()]
return cls(
location, metadata, project_name=project_name, version=version,
py_version=py_version, platform=platform, **kw
@@ -2204,13 +2209,13 @@ class Distribution(object):
try:
return self._version
except AttributeError:
- for line in self._get_metadata('PKG-INFO'):
+ for line in self._get_metadata(self.PKG_INFO):
if line.lower().startswith('version:'):
self._version = safe_version(line.split(':',1)[1].strip())
return self._version
else:
raise ValueError(
- "Missing 'Version:' header and/or PKG-INFO file", self
+ "Missing 'Version:' header and/or %s file" % self.PKG_INFO, self
)
version = property(version)
@@ -2441,6 +2446,54 @@ class Distribution(object):
extras = property(extras)
+class DistInfoDistribution(Distribution):
+ """Wrap an actual or potential sys.path entry w/metadata, .dist-info style"""
+ PKG_INFO = 'METADATA'
+
+ @property
+ def _parsed_pkg_info(self):
+ """Parse and cache metadata"""
+ try:
+ return self._pkg_info
+ except AttributeError:
+ self._pkg_info = Parser().parsestr(self.get_metadata(self.PKG_INFO))
+ return self._pkg_info
+
+ @property
+ def _dep_map(self):
+ try:
+ return self.__dep_map
+ except AttributeError:
+ dm = self.__dep_map = {None: []}
+ # Including condition expressions
+ # XXX parse condition expressions, extras
+ reqs = self._parsed_pkg_info.get_all('Requires-Dist')
+# extras = self._parsed_pkg_info.get_all('Provides-Extra') or []
+# for extra,reqs in split_sections(self._get_metadata(name)):
+# if extra: extra = safe_extra(extra)
+ dm.setdefault(None,[]).extend(parse_requirements(reqs))
+ return dm
+
+ def requires(self,extras=()):
+ """List of Requirements needed for this distro if `extras` are used"""
+ dm = self._dep_map
+ deps = []
+ deps.extend(dm.get(None,()))
+ for ext in extras:
+ try:
+ deps.extend(dm[safe_extra(ext)])
+ except KeyError:
+ raise UnknownExtra(
+ "%s has no such extra feature %r" % (self, ext)
+ )
+ return deps
+
+
+_distributionImpl = {'.egg': Distribution,
+ '.egg-info': Distribution,
+ '.dist-info': DistInfoDistribution }
+
+
def issue_warning(*args,**kw):
level = 1
g = globals()