Try guessing versions of pkgs not listed by pip
* 'pip.get_installed_distributions' doesn't include some packages such as 'pip', 'setuptools' etc. so the installed versions for these is not available. This change tries to guess the installed version by importing the module and checking if the version is defined in '__version__' variable. * Another related change is that the 'required' and 'installed' versions will be shown for all intermediate packages. When 'required' is not specified, it will show 'None' and when 'installed' is not available, it will show '?'. This is to keep the output consistent with the confusing deps output. * Fix indentation in output. Kind of fixes #46.
This commit is contained in:
parent
9949bf66db
commit
a44baabaa5
|
@ -5,6 +5,7 @@ from collections import defaultdict, OrderedDict
|
|||
import argparse
|
||||
from operator import attrgetter
|
||||
import json
|
||||
from importlib import import_module
|
||||
|
||||
import pip
|
||||
import pkg_resources
|
||||
|
@ -98,6 +99,23 @@ def reverse_tree(tree):
|
|||
return rtree
|
||||
|
||||
|
||||
def guess_version(pkg_key, default='?'):
|
||||
"""Guess the version of a pkg when pip doesn't provide it
|
||||
|
||||
:param str pkg_key: key of the package
|
||||
:param str default: default version to return if unable to find
|
||||
:returns: version
|
||||
:rtype: string
|
||||
|
||||
"""
|
||||
try:
|
||||
m = import_module(pkg_key)
|
||||
except ImportError:
|
||||
return default
|
||||
else:
|
||||
return getattr(m, '__version__', default)
|
||||
|
||||
|
||||
class Package(object):
|
||||
"""Abstract class for wrappers around objects that pip returns.
|
||||
|
||||
|
@ -209,9 +227,9 @@ class ReqPackage(Package):
|
|||
|
||||
@property
|
||||
def installed_version(self):
|
||||
# if the dist is None as in some cases, we don't know the
|
||||
# installed version
|
||||
return self.dist.version if self.dist else '?'
|
||||
if not self.dist:
|
||||
return guess_version(self.key)
|
||||
return self.dist.version
|
||||
|
||||
def render_as_root(self, frozen):
|
||||
if not frozen:
|
||||
|
@ -223,15 +241,10 @@ class ReqPackage(Package):
|
|||
|
||||
def render_as_branch(self, frozen):
|
||||
if not frozen:
|
||||
vers = []
|
||||
if self.version_spec:
|
||||
vers.append(('required', self.version_spec))
|
||||
if self.dist:
|
||||
vers.append(('installed', self.installed_version))
|
||||
if not vers:
|
||||
return self.key
|
||||
ver_str = ', '.join(['{0}: {1}'.format(k, v) for k, v in vers])
|
||||
return '{0} [{1}]'.format(self.project_name, ver_str)
|
||||
return (
|
||||
'{0} [required: {1}, installed: {2}]'
|
||||
).format(self.project_name, self.version_spec,
|
||||
self.installed_version)
|
||||
else:
|
||||
return self.render_as_root(frozen)
|
||||
|
||||
|
@ -276,7 +289,7 @@ def render_tree(tree, list_all=True, show_only=None, frozen=False):
|
|||
chain = [node.project_name]
|
||||
node_str = node.render(parent, frozen)
|
||||
if parent:
|
||||
prefix = ' '*indent + ('-' if use_bullets else ' ') + ' '
|
||||
prefix = ' '*indent + ('- ' if use_bullets else '')
|
||||
node_str = prefix + node_str
|
||||
result = [node_str]
|
||||
children = [aux(c, node, indent=indent+2,
|
||||
|
@ -422,13 +435,7 @@ def main():
|
|||
pkg = p.render_as_root(False)
|
||||
print('* %s' % pkg, file=sys.stderr)
|
||||
for req in reqs:
|
||||
if not req.dist:
|
||||
req_str = (
|
||||
'{0} [required: {1}, '
|
||||
'installed: <unknown>]'
|
||||
).format(req.project_name, req.version_spec)
|
||||
else:
|
||||
req_str = req.render_as_branch(p, False)
|
||||
req_str = req.render_as_branch(False)
|
||||
print(' - %s' % req_str, file=sys.stderr)
|
||||
print('-'*72, file=sys.stderr)
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ def test_ReqPackage_render_as_branch():
|
|||
assert mks1.project_name == 'markupsafe'
|
||||
assert mks1.installed_version == '0.18'
|
||||
assert mks1.version_spec is None
|
||||
assert mks1.render_as_branch(False) == 'markupsafe [installed: 0.18]'
|
||||
assert mks1.render_as_branch(False) == 'markupsafe [required: None, installed: 0.18]'
|
||||
assert mks1.render_as_branch(True) == 'MarkupSafe==0.18'
|
||||
mks2 = find_req('markupsafe', 'mako')
|
||||
assert mks2.project_name == 'MarkupSafe'
|
||||
|
@ -126,7 +126,7 @@ def test_render_tree_freeze():
|
|||
line = line.replace('origin/HEAD', 'master')
|
||||
lines.add(line)
|
||||
assert 'Flask-Script==0.6.6' in lines
|
||||
assert ' SQLAlchemy==0.9.1' in lines
|
||||
assert ' SQLAlchemy==0.9.1' in lines
|
||||
# TODO! Fix the following failing test
|
||||
# assert '-e git+https://github.com/naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy-master' in lines
|
||||
assert 'itsdangerous==0.23' not in lines
|
||||
|
@ -147,9 +147,9 @@ def test_render_tree_cyclic_dependency():
|
|||
tree_str = render_tree(tree, list_all=True)
|
||||
lines = set(tree_str.split('\n'))
|
||||
assert 'CircularDependencyA==0.0.0' in lines
|
||||
assert ' - CircularDependencyB [installed: 0.0.0]' in lines
|
||||
assert ' - CircularDependencyB [required: None, installed: 0.0.0]' in lines
|
||||
assert 'CircularDependencyB==0.0.0' in lines
|
||||
assert ' - CircularDependencyA [installed: 0.0.0]' in lines
|
||||
assert ' - CircularDependencyA [required: None, installed: 0.0.0]' in lines
|
||||
|
||||
|
||||
def test_render_tree_freeze_cyclic_dependency():
|
||||
|
@ -157,9 +157,9 @@ def test_render_tree_freeze_cyclic_dependency():
|
|||
tree_str = render_tree(tree, list_all=True, frozen=True)
|
||||
lines = set(tree_str.split('\n'))
|
||||
assert 'CircularDependencyA==0.0.0' in lines
|
||||
assert ' CircularDependencyB==0.0.0' in lines
|
||||
assert ' CircularDependencyB==0.0.0' in lines
|
||||
assert 'CircularDependencyB==0.0.0' in lines
|
||||
assert ' CircularDependencyA==0.0.0' in lines
|
||||
assert ' CircularDependencyA==0.0.0' in lines
|
||||
|
||||
|
||||
def test_conflicting_deps():
|
||||
|
|
Loading…
Reference in New Issue