/usr/lib/python2.7/dist-packages/duecredit/versions.py is in python-duecredit 0.6.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | # emacs: -*- mode: python; py-indent-offset: 4; tab-width: 4; indent-tabs-mode: nil -*-
# ex: set sts=4 ts=4 sw=4 noet:
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
# See COPYING file distributed along with the duecredit package for the
# copyright and license terms.
#
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
"""Module to help maintain a registry of versions for external modules etc
"""
import sys
from os import linesep
from six import string_types
from distutils.version import StrictVersion, LooseVersion
# To depict an unknown version, which can't be compared by mistake etc
class UnknownVersion:
"""For internal use
"""
def __str__(self):
return "UNKNOWN"
def __cmp__(self, other):
if other is self:
return 0
raise TypeError("UNKNOWN version is not comparable")
class ExternalVersions(object):
"""Helper to figure out/use versions of the external modules.
It maintains a dictionary of `distuil.version.StrictVersion`s to make
comparisons easy. If version string doesn't conform the StrictVersion
LooseVersion will be used. If version can't be deduced for the module,
'None' is assigned
"""
UNKNOWN = UnknownVersion()
def __init__(self):
self._versions = {}
@classmethod
def _deduce_version(klass, module):
version = None
for attr in ('__version__', 'version'):
if hasattr(module, attr):
version = getattr(module, attr)
break
if isinstance(version, tuple) or isinstance(version, list):
# Generate string representation
version = ".".join(str(x) for x in version)
if version:
try:
return StrictVersion(version)
except ValueError:
# let's then go with Loose one
return LooseVersion(version)
else:
return klass.UNKNOWN
def __getitem__(self, module):
# when ran straight in its source code -- fails to discover nipy's version.. TODO
#if module == 'nipy':
# import pdb; pdb.set_trace()
if not isinstance(module, string_types):
modname = module.__name__
else:
modname = module
module = None
if modname not in self._versions:
if module is None:
if modname not in sys.modules:
try:
module = __import__(modname)
except ImportError:
return None
else:
module = sys.modules[modname]
self._versions[modname] = self._deduce_version(module)
return self._versions.get(modname, self.UNKNOWN)
def keys(self):
"""Return names of the known modules"""
return self._versions.keys()
def __contains__(self, item):
return item in self._versions
@property
def versions(self):
"""Return dictionary (copy) of versions"""
return self._versions.copy()
def dumps(self, indent=False, preamble="Versions:"):
"""Return listing of versions as a string
Parameters
----------
indent: bool or str, optional
If set would instruct on how to indent entries (if just True, ' '
is used). Otherwise returned in a single line
preamble: str, optional
What preamble to the listing to use
"""
if indent and (indent is True):
indent = ' '
items = ["%s=%s" % (k, self._versions[k]) for k in sorted(self._versions)]
out = "%s" % preamble
if indent:
out += (linesep + indent).join([''] + items) + linesep
else:
out += " " + ' '.join(items)
return out
external_versions = ExternalVersions()
|