mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-20 05:28:04 +00:00
Merge pull request #907 from tahoe-lafs/3518.pypy-versions-None
Get rid of version_checks Fixes: ticket:3518
This commit is contained in:
commit
8e6773c690
1
newsfragments/3518.removed
Normal file
1
newsfragments/3518.removed
Normal file
@ -0,0 +1 @@
|
||||
Announcements delivered through the introducer system are no longer automatically annotated with copious information about the Tahoe-LAFS software version nor the versions of its dependencies.
|
@ -512,7 +512,6 @@ def create_introducer_clients(config, main_tub, _introducer_factory=None):
|
||||
config.nickname,
|
||||
str(allmydata.__full_version__),
|
||||
str(_Client.OLDEST_SUPPORTED_VERSION),
|
||||
list(node.get_app_versions()),
|
||||
partial(_sequencer, config),
|
||||
introducer_cache_filepath,
|
||||
)
|
||||
|
@ -24,7 +24,7 @@ class IntroducerClient(service.Service, Referenceable):
|
||||
|
||||
def __init__(self, tub, introducer_furl,
|
||||
nickname, my_version, oldest_supported,
|
||||
app_versions, sequencer, cache_filepath):
|
||||
sequencer, cache_filepath):
|
||||
self._tub = tub
|
||||
self.introducer_furl = introducer_furl
|
||||
|
||||
@ -32,13 +32,12 @@ class IntroducerClient(service.Service, Referenceable):
|
||||
self._nickname = nickname
|
||||
self._my_version = my_version
|
||||
self._oldest_supported = oldest_supported
|
||||
self._app_versions = app_versions
|
||||
self._sequencer = sequencer
|
||||
self._cache_filepath = cache_filepath
|
||||
|
||||
self._my_subscriber_info = { "version": 0,
|
||||
"nickname": self._nickname,
|
||||
"app-versions": self._app_versions,
|
||||
"app-versions": [],
|
||||
"my-version": self._my_version,
|
||||
"oldest-supported": self._oldest_supported,
|
||||
}
|
||||
@ -190,7 +189,7 @@ class IntroducerClient(service.Service, Referenceable):
|
||||
# "seqnum" and "nonce" will be populated with new values in
|
||||
# publish(), each time we make a change
|
||||
"nickname": self._nickname,
|
||||
"app-versions": self._app_versions,
|
||||
"app-versions": [],
|
||||
"my-version": self._my_version,
|
||||
"oldest-supported": self._oldest_supported,
|
||||
|
||||
|
@ -28,9 +28,10 @@ import configparser
|
||||
from twisted.python import log as twlog
|
||||
from twisted.application import service
|
||||
from twisted.python.failure import Failure
|
||||
from foolscap.api import Tub, app_versions
|
||||
from foolscap.api import Tub
|
||||
|
||||
import foolscap.logging.log
|
||||
from allmydata.version_checks import get_package_versions, get_package_versions_string
|
||||
|
||||
from allmydata.util import log
|
||||
from allmydata.util import fileutil, iputil
|
||||
from allmydata.util.assertutil import _assert
|
||||
@ -38,6 +39,10 @@ from allmydata.util.fileutil import abspath_expanduser_unicode
|
||||
from allmydata.util.encodingutil import get_filesystem_encoding, quote_output
|
||||
from allmydata.util import configutil
|
||||
|
||||
from . import (
|
||||
__full_version__,
|
||||
)
|
||||
|
||||
def _common_valid_config():
|
||||
return configutil.ValidConfiguration({
|
||||
"connections": (
|
||||
@ -78,11 +83,6 @@ def _common_valid_config():
|
||||
),
|
||||
})
|
||||
|
||||
# Add our application versions to the data that Foolscap's LogPublisher
|
||||
# reports. Foolscap requires native strings.
|
||||
for thing, things_version in list(get_package_versions().items()):
|
||||
app_versions.add_version(ensure_str(thing), ensure_str(things_version))
|
||||
|
||||
# group 1 will be addr (dotted quad string), group 3 if any will be portnum (string)
|
||||
ADDR_RE = re.compile("^([1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*)(:([1-9][0-9]*))?$")
|
||||
|
||||
@ -228,13 +228,6 @@ def config_from_string(basedir, portnumfile, config_str, _valid_config=None):
|
||||
return _Config(parser, portnumfile, basedir, fname)
|
||||
|
||||
|
||||
def get_app_versions():
|
||||
"""
|
||||
:returns: dict of versions important to Foolscap
|
||||
"""
|
||||
return dict(app_versions.versions)
|
||||
|
||||
|
||||
def _error_about_old_config_files(basedir, generated_files):
|
||||
"""
|
||||
If any old configuration files are detected, raise
|
||||
@ -759,7 +752,7 @@ class Node(service.MultiService):
|
||||
if self.control_tub is not None:
|
||||
self.control_tub.setServiceParent(self)
|
||||
|
||||
self.log("Node constructed. " + get_package_versions_string())
|
||||
self.log("Node constructed. " + __full_version__)
|
||||
iputil.increase_rlimits()
|
||||
|
||||
def _is_tub_listening(self):
|
||||
|
@ -7,7 +7,6 @@ import six
|
||||
from twisted.python import usage
|
||||
from twisted.internet import defer, task, threads
|
||||
|
||||
from allmydata.version_checks import get_package_versions_string
|
||||
from allmydata.scripts.common import get_default_nodedir
|
||||
from allmydata.scripts import debug, create_node, cli, \
|
||||
stats_gatherer, admin, tahoe_daemonize, tahoe_start, \
|
||||
@ -19,6 +18,10 @@ from allmydata.util.eliotutil import (
|
||||
eliot_logging_service,
|
||||
)
|
||||
|
||||
from .. import (
|
||||
__full_version__,
|
||||
)
|
||||
|
||||
_default_nodedir = get_default_nodedir()
|
||||
|
||||
NODEDIR_HELP = ("Specify which Tahoe node directory should be used. The "
|
||||
@ -77,12 +80,10 @@ class Options(usage.Options):
|
||||
]
|
||||
|
||||
def opt_version(self):
|
||||
print(get_package_versions_string(debug=True), file=self.stdout)
|
||||
print(__full_version__, file=self.stdout)
|
||||
self.no_command_needed = True
|
||||
|
||||
def opt_version_and_path(self):
|
||||
print(get_package_versions_string(show_paths=True, debug=True), file=self.stdout)
|
||||
self.no_command_needed = True
|
||||
opt_version_and_path = opt_version
|
||||
|
||||
opt_eliot_destination = opt_eliot_destination
|
||||
opt_help_eliot_destinations = opt_help_eliot_destinations
|
||||
|
@ -1266,7 +1266,7 @@ class Options(ReallyEqualMixin, unittest.TestCase):
|
||||
# "tahoe --version" dumps text to stdout and exits
|
||||
stdout = StringIO()
|
||||
self.failUnlessRaises(SystemExit, self.parse, ["--version"], stdout)
|
||||
self.failUnlessIn(allmydata.__appname__ + ":", stdout.getvalue())
|
||||
self.failUnlessIn(allmydata.__full_version__, stdout.getvalue())
|
||||
# but "tahoe SUBCOMMAND --version" should be rejected
|
||||
self.failUnlessRaises(usage.UsageError, self.parse,
|
||||
["start", "--version"])
|
||||
|
@ -110,7 +110,6 @@ class MemoryIntroducerClient(object):
|
||||
nickname = attr.ib()
|
||||
my_version = attr.ib()
|
||||
oldest_supported = attr.ib()
|
||||
app_versions = attr.ib()
|
||||
sequencer = attr.ib()
|
||||
cache_filepath = attr.ib()
|
||||
|
||||
|
@ -41,9 +41,6 @@ import allmydata.util.log
|
||||
|
||||
from allmydata.node import OldConfigError, UnescapedHashError, create_node_dir
|
||||
from allmydata.frontends.auth import NeedRootcapLookupScheme
|
||||
from allmydata.version_checks import (
|
||||
get_package_versions_string,
|
||||
)
|
||||
from allmydata import client
|
||||
from allmydata.storage_client import (
|
||||
StorageClientConfig,
|
||||
@ -621,8 +618,6 @@ class Basic(testutil.ReallyEqualMixin, unittest.TestCase):
|
||||
self.failIfEqual(str(allmydata.__version__), "unknown")
|
||||
self.failUnless("." in str(allmydata.__full_version__),
|
||||
"non-numeric version in '%s'" % allmydata.__version__)
|
||||
all_versions = get_package_versions_string()
|
||||
self.failUnless(allmydata.__appname__ in all_versions)
|
||||
# also test stats
|
||||
stats = c.get_stats()
|
||||
self.failUnless("node.uptime" in stats)
|
||||
|
@ -155,7 +155,7 @@ class ServiceMixin(object):
|
||||
class Introducer(ServiceMixin, AsyncTestCase):
|
||||
def test_create(self):
|
||||
ic = IntroducerClient(None, "introducer.furl", u"my_nickname",
|
||||
"my_version", "oldest_version", {}, fakeseq,
|
||||
"my_version", "oldest_version", fakeseq,
|
||||
FilePath(self.mktemp()))
|
||||
self.failUnless(isinstance(ic, IntroducerClient))
|
||||
|
||||
@ -188,13 +188,13 @@ class Client(AsyncTestCase):
|
||||
def test_duplicate_receive_v2(self):
|
||||
ic1 = IntroducerClient(None,
|
||||
"introducer.furl", u"my_nickname",
|
||||
"ver23", "oldest_version", {}, fakeseq,
|
||||
"ver23", "oldest_version", fakeseq,
|
||||
FilePath(self.mktemp()))
|
||||
# we use a second client just to create a different-looking
|
||||
# announcement
|
||||
ic2 = IntroducerClient(None,
|
||||
"introducer.furl", u"my_nickname",
|
||||
"ver24","oldest_version",{}, fakeseq,
|
||||
"ver24","oldest_version",fakeseq,
|
||||
FilePath(self.mktemp()))
|
||||
announcements = []
|
||||
def _received(key_s, ann):
|
||||
@ -298,7 +298,7 @@ class Server(AsyncTestCase):
|
||||
i = IntroducerService()
|
||||
ic1 = IntroducerClient(None,
|
||||
"introducer.furl", u"my_nickname",
|
||||
"ver23", "oldest_version", {}, realseq,
|
||||
"ver23", "oldest_version", realseq,
|
||||
FilePath(self.mktemp()))
|
||||
furl1 = "pb://62ubehyunnyhzs7r6vdonnm2hpi52w6y@127.0.0.1:36106/gydnp"
|
||||
|
||||
@ -396,7 +396,7 @@ class Queue(SystemTestMixin, AsyncTestCase):
|
||||
tub2 = Tub()
|
||||
tub2.setServiceParent(self.parent)
|
||||
c = IntroducerClient(tub2, ifurl,
|
||||
u"nickname", "version", "oldest", {}, fakeseq,
|
||||
u"nickname", "version", "oldest", fakeseq,
|
||||
FilePath(self.mktemp()))
|
||||
furl1 = "pb://onug64tu@127.0.0.1:123/short" # base32("short")
|
||||
private_key, _ = ed25519.create_signing_keypair()
|
||||
@ -477,7 +477,7 @@ class SystemTest(SystemTestMixin, AsyncTestCase):
|
||||
c = IntroducerClient(tub, self.introducer_furl,
|
||||
NICKNAME % str(i),
|
||||
"version", "oldest",
|
||||
{"component": "component-v1"}, fakeseq,
|
||||
fakeseq,
|
||||
FilePath(self.mktemp()))
|
||||
received_announcements[c] = {}
|
||||
def got(key_s_or_tubid, ann, announcements):
|
||||
@ -737,9 +737,8 @@ class ClientInfo(AsyncTestCase):
|
||||
def test_client_v2(self):
|
||||
introducer = IntroducerService()
|
||||
tub = introducer_furl = None
|
||||
app_versions = {"whizzy": "fizzy"}
|
||||
client_v2 = IntroducerClient(tub, introducer_furl, NICKNAME % u"v2",
|
||||
"my_version", "oldest", app_versions,
|
||||
"my_version", "oldest",
|
||||
fakeseq, FilePath(self.mktemp()))
|
||||
#furl1 = "pb://62ubehyunnyhzs7r6vdonnm2hpi52w6y@127.0.0.1:0/swissnum"
|
||||
#ann_s = make_ann_t(client_v2, furl1, None, 10)
|
||||
@ -751,7 +750,6 @@ class ClientInfo(AsyncTestCase):
|
||||
self.failUnlessEqual(len(subs), 1)
|
||||
s0 = subs[0]
|
||||
self.failUnlessEqual(s0.service_name, "storage")
|
||||
self.failUnlessEqual(s0.app_versions, app_versions)
|
||||
self.failUnlessEqual(s0.nickname, NICKNAME % u"v2")
|
||||
self.failUnlessEqual(s0.version, "my_version")
|
||||
|
||||
@ -760,9 +758,8 @@ class Announcements(AsyncTestCase):
|
||||
def test_client_v2_signed(self):
|
||||
introducer = IntroducerService()
|
||||
tub = introducer_furl = None
|
||||
app_versions = {"whizzy": "fizzy"}
|
||||
client_v2 = IntroducerClient(tub, introducer_furl, u"nick-v2",
|
||||
"my_version", "oldest", app_versions,
|
||||
"my_version", "oldest",
|
||||
fakeseq, FilePath(self.mktemp()))
|
||||
furl1 = "pb://62ubehyunnyhzs7r6vdonnm2hpi52w6y@127.0.0.1:0/swissnum"
|
||||
|
||||
@ -776,7 +773,6 @@ class Announcements(AsyncTestCase):
|
||||
self.failUnlessEqual(len(a), 1)
|
||||
self.assertThat(a[0].canary, Is(canary0))
|
||||
self.failUnlessEqual(a[0].index, ("storage", public_key_str))
|
||||
self.failUnlessEqual(a[0].announcement["app-versions"], app_versions)
|
||||
self.failUnlessEqual(a[0].nickname, u"nick-v2")
|
||||
self.failUnlessEqual(a[0].service_name, "storage")
|
||||
self.failUnlessEqual(a[0].version, "my_version")
|
||||
@ -854,7 +850,7 @@ class Announcements(AsyncTestCase):
|
||||
# test loading
|
||||
yield flushEventualQueue()
|
||||
ic2 = IntroducerClient(None, "introducer.furl", u"my_nickname",
|
||||
"my_version", "oldest_version", {}, fakeseq,
|
||||
"my_version", "oldest_version", fakeseq,
|
||||
ic._cache_filepath)
|
||||
announcements = {}
|
||||
def got(key_s, ann):
|
||||
@ -954,7 +950,7 @@ class NonV1Server(SystemTestMixin, AsyncTestCase):
|
||||
tub.setServiceParent(self.parent)
|
||||
listenOnUnused(tub)
|
||||
c = IntroducerClient(tub, self.introducer_furl,
|
||||
u"nickname-client", "version", "oldest", {},
|
||||
u"nickname-client", "version", "oldest",
|
||||
fakeseq, FilePath(self.mktemp()))
|
||||
announcements = {}
|
||||
def got(key_s, ann):
|
||||
@ -1027,7 +1023,6 @@ class Signatures(SyncTestCase):
|
||||
u"fake_nick",
|
||||
"0.0.0",
|
||||
"1.2.3",
|
||||
{},
|
||||
(0, u"i am a nonce"),
|
||||
"invalid",
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from future.utils import PY2, native_str
|
||||
from future.utils import PY2
|
||||
if PY2:
|
||||
from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
|
||||
|
||||
@ -46,7 +46,6 @@ from allmydata.node import (
|
||||
_tub_portlocation,
|
||||
formatTimeTahoeStyle,
|
||||
UnescapedHashError,
|
||||
get_app_versions,
|
||||
)
|
||||
from allmydata.introducer.server import create_introducer
|
||||
from allmydata import client
|
||||
@ -101,16 +100,6 @@ class TestCase(testutil.SignalMixin, unittest.TestCase):
|
||||
# conflict with another service to prove it.
|
||||
self._available_port = 22
|
||||
|
||||
def test_application_versions(self):
|
||||
"""
|
||||
Application versions should all have the same type, the native string.
|
||||
|
||||
This test is due to the Foolscap limitations, if Foolscap is fixed or
|
||||
removed it can be deleted.
|
||||
"""
|
||||
app_types = set(type(o) for o in get_app_versions())
|
||||
self.assertEqual(app_types, {native_str})
|
||||
|
||||
def _test_location(
|
||||
self,
|
||||
expected_addresses,
|
||||
|
@ -12,7 +12,6 @@ from twisted.internet import reactor
|
||||
from twisted.python import usage
|
||||
from twisted.internet.defer import (
|
||||
inlineCallbacks,
|
||||
returnValue,
|
||||
DeferredList,
|
||||
)
|
||||
from twisted.python.filepath import FilePath
|
||||
@ -20,12 +19,9 @@ from twisted.python.runtime import (
|
||||
platform,
|
||||
)
|
||||
from allmydata.util import fileutil, pollmixin
|
||||
from allmydata.util.encodingutil import unicode_to_argv, unicode_to_output, \
|
||||
get_filesystem_encoding
|
||||
from allmydata.util.encodingutil import unicode_to_argv, unicode_to_output
|
||||
from allmydata.test import common_util
|
||||
from allmydata.version_checks import normalized_version
|
||||
import allmydata
|
||||
from allmydata import __appname__
|
||||
from .common_util import parse_cli, run_cli
|
||||
from .cli_node_api import (
|
||||
CLINodeAPI,
|
||||
@ -58,17 +54,6 @@ rootdir = get_root_from_file(srcfile)
|
||||
|
||||
|
||||
class RunBinTahoeMixin(object):
|
||||
|
||||
@inlineCallbacks
|
||||
def find_import_location(self):
|
||||
res = yield self.run_bintahoe(["--version-and-path"])
|
||||
out, err, rc_or_sig = res
|
||||
self.assertEqual(rc_or_sig, 0, res)
|
||||
lines = out.splitlines()
|
||||
tahoe_pieces = lines[0].split()
|
||||
self.assertEqual(tahoe_pieces[0], "%s:" % (__appname__,), (tahoe_pieces, res))
|
||||
returnValue(tahoe_pieces[-1].strip("()"))
|
||||
|
||||
def run_bintahoe(self, args, stdin=None, python_options=[], env=None):
|
||||
command = sys.executable
|
||||
argv = python_options + ["-m", "allmydata.scripts.runner"] + args
|
||||
@ -86,64 +71,6 @@ class RunBinTahoeMixin(object):
|
||||
|
||||
|
||||
class BinTahoe(common_util.SignalMixin, unittest.TestCase, RunBinTahoeMixin):
|
||||
@inlineCallbacks
|
||||
def test_the_right_code(self):
|
||||
# running "tahoe" in a subprocess should find the same code that
|
||||
# holds this test file, else something is weird
|
||||
test_path = os.path.dirname(os.path.dirname(os.path.normcase(os.path.realpath(srcfile))))
|
||||
bintahoe_import_path = yield self.find_import_location()
|
||||
|
||||
same = (bintahoe_import_path == test_path)
|
||||
if not same:
|
||||
msg = ("My tests and my 'tahoe' executable are using different paths.\n"
|
||||
"tahoe: %r\n"
|
||||
"tests: %r\n"
|
||||
"( according to the test source filename %r)\n" %
|
||||
(bintahoe_import_path, test_path, srcfile))
|
||||
|
||||
if (not isinstance(rootdir, unicode) and
|
||||
rootdir.decode(get_filesystem_encoding(), 'replace') != rootdir):
|
||||
msg += ("However, this may be a false alarm because the import path\n"
|
||||
"is not representable in the filesystem encoding.")
|
||||
raise unittest.SkipTest(msg)
|
||||
else:
|
||||
msg += "Please run the tests in a virtualenv that includes both the Tahoe-LAFS library and the 'tahoe' executable."
|
||||
self.fail(msg)
|
||||
|
||||
def test_path(self):
|
||||
d = self.run_bintahoe(["--version-and-path"])
|
||||
def _cb(res):
|
||||
out, err, rc_or_sig = res
|
||||
self.failUnlessEqual(rc_or_sig, 0, str(res))
|
||||
|
||||
# Fail unless the __appname__ package is *this* version *and*
|
||||
# was loaded from *this* source directory.
|
||||
|
||||
required_verstr = str(allmydata.__version__)
|
||||
|
||||
self.failIfEqual(required_verstr, "unknown",
|
||||
"We don't know our version, because this distribution didn't come "
|
||||
"with a _version.py and 'setup.py update_version' hasn't been run.")
|
||||
|
||||
srcdir = os.path.dirname(os.path.dirname(os.path.normcase(os.path.realpath(srcfile))))
|
||||
info = repr((res, allmydata.__appname__, required_verstr, srcdir))
|
||||
|
||||
appverpath = out.split(')')[0]
|
||||
(appverfull, path) = appverpath.split('] (')
|
||||
(appver, comment) = appverfull.split(' [')
|
||||
(branch, full_version) = comment.split(': ')
|
||||
(app, ver) = appver.split(': ')
|
||||
|
||||
self.failUnlessEqual(app, allmydata.__appname__, info)
|
||||
norm_ver = normalized_version(ver)
|
||||
norm_required = normalized_version(required_verstr)
|
||||
self.failUnlessEqual(norm_ver, norm_required, info)
|
||||
self.failUnlessEqual(path, srcdir, info)
|
||||
self.failUnlessEqual(branch, allmydata.branch)
|
||||
self.failUnlessEqual(full_version, allmydata.full_version)
|
||||
d.addCallback(_cb)
|
||||
return d
|
||||
|
||||
def test_unicode_arguments_and_output(self):
|
||||
tricky = u"\u2621"
|
||||
try:
|
||||
@ -165,8 +92,8 @@ class BinTahoe(common_util.SignalMixin, unittest.TestCase, RunBinTahoeMixin):
|
||||
d = self.run_bintahoe(["--version"], python_options=["-t"])
|
||||
def _cb(res):
|
||||
out, err, rc_or_sig = res
|
||||
self.failUnlessEqual(rc_or_sig, 0, str(res))
|
||||
self.failUnless(out.startswith(allmydata.__appname__+':'), str(res))
|
||||
self.assertEqual(rc_or_sig, 0, str(res))
|
||||
self.assertTrue(out.startswith(allmydata.__appname__ + '/'), str(res))
|
||||
d.addCallback(_cb)
|
||||
return d
|
||||
|
||||
|
@ -1,275 +0,0 @@
|
||||
"""
|
||||
Tests for allmydata.util.verlib and allmydata.version_checks.
|
||||
|
||||
Ported to Python 3.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from future.utils import PY2
|
||||
if PY2:
|
||||
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
|
||||
|
||||
import sys
|
||||
import pkg_resources
|
||||
from operator import (
|
||||
setitem,
|
||||
)
|
||||
from twisted.trial import unittest
|
||||
|
||||
from allmydata.version_checks import (
|
||||
_cross_check as cross_check,
|
||||
_extract_openssl_version as extract_openssl_version,
|
||||
_get_package_versions_and_locations as get_package_versions_and_locations,
|
||||
)
|
||||
from allmydata.util.verlib import NormalizedVersion as V, \
|
||||
IrrationalVersionError, \
|
||||
suggest_normalized_version as suggest
|
||||
|
||||
|
||||
class MockSSL(object):
|
||||
SSLEAY_VERSION = 0
|
||||
SSLEAY_CFLAGS = 2
|
||||
|
||||
def __init__(self, version, compiled_without_heartbeats=False):
|
||||
self.opts = {
|
||||
self.SSLEAY_VERSION: version,
|
||||
self.SSLEAY_CFLAGS: compiled_without_heartbeats and 'compiler: gcc -DOPENSSL_NO_HEARTBEATS'
|
||||
or 'compiler: gcc',
|
||||
}
|
||||
|
||||
def SSLeay_version(self, which):
|
||||
return self.opts[which]
|
||||
|
||||
|
||||
class CheckRequirement(unittest.TestCase):
|
||||
def test_packages_from_pkg_resources(self):
|
||||
if hasattr(sys, 'frozen'):
|
||||
raise unittest.SkipTest("This test doesn't apply to frozen builds.")
|
||||
|
||||
class MockPackage(object):
|
||||
def __init__(self, project_name, version, location):
|
||||
self.project_name = project_name
|
||||
self.version = version
|
||||
self.location = location
|
||||
|
||||
def call_pkg_resources_require(*args):
|
||||
return [MockPackage("Foo", "1.0", "/path")]
|
||||
self.patch(pkg_resources, 'require', call_pkg_resources_require)
|
||||
|
||||
(packages, errors) = get_package_versions_and_locations()
|
||||
self.failUnlessIn(("foo", ("1.0", "/path", "according to pkg_resources")), packages)
|
||||
self.failIfEqual(errors, [])
|
||||
self.failUnlessEqual([e for e in errors if "was not found by pkg_resources" not in e], [])
|
||||
|
||||
def test_cross_check_unparseable_versions(self):
|
||||
# The bug in #1355 is triggered when a version string from either pkg_resources or import
|
||||
# is not parseable at all by normalized_version.
|
||||
|
||||
res = cross_check({"foo": ("unparseable", "")}, [("foo", ("1.0", "", None))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"foo": ("1.0", "")}, [("foo", ("unparseable", "", None))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"foo": ("unparseable", "")}, [("foo", ("unparseable", "", None))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
def test_cross_check(self):
|
||||
res = cross_check({}, [])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({}, [("tahoe-lafs", ("1.0", "", "blah"))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"foo": ("unparseable", "")}, [])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"argparse": ("unparseable", "")}, [])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({}, [("foo", ("unparseable", "", None))])
|
||||
self.failUnlessEqual(len(res), 1)
|
||||
self.assertTrue(("version 'unparseable'" in res[0]) or ("version u'unparseable'" in res[0]))
|
||||
self.failUnlessIn("was not found by pkg_resources", res[0])
|
||||
|
||||
res = cross_check({"distribute": ("1.0", "/somewhere")}, [("setuptools", ("2.0", "/somewhere", "distribute"))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"distribute": ("1.0", "/somewhere")}, [("setuptools", ("2.0", "/somewhere", None))])
|
||||
self.failUnlessEqual(len(res), 1)
|
||||
self.failUnlessIn("location mismatch", res[0])
|
||||
|
||||
res = cross_check({"distribute": ("1.0", "/somewhere")}, [("setuptools", ("2.0", "/somewhere_different", None))])
|
||||
self.failUnlessEqual(len(res), 1)
|
||||
self.failUnlessIn("location mismatch", res[0])
|
||||
|
||||
res = cross_check({"zope.interface": ("1.0", "")}, [("zope.interface", ("unknown", "", None))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"zope.interface": ("unknown", "")}, [("zope.interface", ("unknown", "", None))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"foo": ("1.0", "")}, [("foo", ("unknown", "", None))])
|
||||
self.failUnlessEqual(len(res), 1)
|
||||
self.failUnlessIn("could not find a version number", res[0])
|
||||
|
||||
res = cross_check({"foo": ("unknown", "")}, [("foo", ("unknown", "", None))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
# When pkg_resources and import both find a package, there is only a warning if both
|
||||
# the version and the path fail to match.
|
||||
|
||||
res = cross_check({"foo": ("1.0", "/somewhere")}, [("foo", ("2.0", "/somewhere", None))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"foo": ("1.0", "/somewhere")}, [("foo", ("1.0", "/somewhere_different", None))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"foo": ("1.0-r123", "/somewhere")}, [("foo", ("1.0.post123", "/somewhere_different", None))])
|
||||
self.failUnlessEqual(res, [])
|
||||
|
||||
res = cross_check({"foo": ("1.0", "/somewhere")}, [("foo", ("2.0", "/somewhere_different", None))])
|
||||
self.failUnlessEqual(len(res), 1)
|
||||
self.assertTrue(("but version '2.0'" in res[0]) or ("but version u'2.0'" in res[0]))
|
||||
|
||||
def test_extract_openssl_version(self):
|
||||
self.failUnlessEqual(extract_openssl_version(MockSSL("")),
|
||||
("", None, None))
|
||||
self.failUnlessEqual(extract_openssl_version(MockSSL("NotOpenSSL a.b.c foo")),
|
||||
("NotOpenSSL", None, "a.b.c foo"))
|
||||
self.failUnlessEqual(extract_openssl_version(MockSSL("OpenSSL a.b.c")),
|
||||
("a.b.c", None, None))
|
||||
self.failUnlessEqual(extract_openssl_version(MockSSL("OpenSSL 1.0.1e 11 Feb 2013")),
|
||||
("1.0.1e", None, "11 Feb 2013"))
|
||||
self.failUnlessEqual(extract_openssl_version(MockSSL("OpenSSL 1.0.1e 11 Feb 2013", compiled_without_heartbeats=True)),
|
||||
("1.0.1e", None, "11 Feb 2013, no heartbeats"))
|
||||
|
||||
|
||||
# based on https://bitbucket.org/tarek/distutilsversion/src/17df9a7d96ef/test_verlib.py
|
||||
|
||||
class VersionTestCase(unittest.TestCase):
|
||||
versions = ((V('1.0'), '1.0'),
|
||||
(V('1.1'), '1.1'),
|
||||
(V('1.2.3'), '1.2.3'),
|
||||
(V('1.2'), '1.2'),
|
||||
(V('1.2.3a4'), '1.2.3a4'),
|
||||
(V('1.2c4'), '1.2c4'),
|
||||
(V('1.2.3.4'), '1.2.3.4'),
|
||||
(V('1.2.3.4.0b3'), '1.2.3.4b3'),
|
||||
(V('1.2.0.0.0'), '1.2'),
|
||||
(V('1.0.dev345'), '1.0.dev345'),
|
||||
(V('1.0.post456.dev623'), '1.0.post456.dev623'))
|
||||
|
||||
def test_basic_versions(self):
|
||||
for v, s in self.versions:
|
||||
self.failUnlessEqual(str(v), s)
|
||||
|
||||
def test_from_parts(self):
|
||||
for v, s in self.versions:
|
||||
parts = v.parts
|
||||
v2 = V.from_parts(*parts)
|
||||
self.failUnlessEqual(v, v2)
|
||||
self.failUnlessEqual(str(v), str(v2))
|
||||
|
||||
def test_irrational_versions(self):
|
||||
irrational = ('1', '1.2a', '1.2.3b', '1.02', '1.2a03',
|
||||
'1.2a3.04', '1.2.dev.2', '1.2dev', '1.2.dev',
|
||||
'1.2.dev2.post2', '1.2.post2.dev3.post4')
|
||||
|
||||
for s in irrational:
|
||||
self.failUnlessRaises(IrrationalVersionError, V, s)
|
||||
|
||||
def test_comparison(self):
|
||||
self.failUnlessRaises(TypeError, lambda: V('1.2.0') == '1.2')
|
||||
|
||||
self.failUnlessEqual(V('1.2.0'), V('1.2'))
|
||||
self.failIfEqual(V('1.2.0'), V('1.2.3'))
|
||||
self.failUnless(V('1.2.0') < V('1.2.3'))
|
||||
self.failUnless(V('1.0') > V('1.0b2'))
|
||||
self.failUnless(V('1.0') > V('1.0c2') > V('1.0c1') > V('1.0b2') > V('1.0b1')
|
||||
> V('1.0a2') > V('1.0a1'))
|
||||
self.failUnless(V('1.0.0') > V('1.0.0c2') > V('1.0.0c1') > V('1.0.0b2') > V('1.0.0b1')
|
||||
> V('1.0.0a2') > V('1.0.0a1'))
|
||||
|
||||
self.failUnless(V('1.0') < V('1.0.post456.dev623'))
|
||||
self.failUnless(V('1.0.post456.dev623') < V('1.0.post456') < V('1.0.post1234'))
|
||||
|
||||
self.failUnless(V('1.0a1')
|
||||
< V('1.0a2.dev456')
|
||||
< V('1.0a2')
|
||||
< V('1.0a2.1.dev456') # e.g. need to do a quick post release on 1.0a2
|
||||
< V('1.0a2.1')
|
||||
< V('1.0b1.dev456')
|
||||
< V('1.0b2')
|
||||
< V('1.0c1')
|
||||
< V('1.0c2.dev456')
|
||||
< V('1.0c2')
|
||||
< V('1.0.dev7')
|
||||
< V('1.0.dev18')
|
||||
< V('1.0.dev456')
|
||||
< V('1.0.dev1234')
|
||||
< V('1.0')
|
||||
< V('1.0.post456.dev623') # development version of a post release
|
||||
< V('1.0.post456'))
|
||||
|
||||
def test_suggest_normalized_version(self):
|
||||
self.failUnlessEqual(suggest('1.0'), '1.0')
|
||||
self.failUnlessEqual(suggest('1.0-alpha1'), '1.0a1')
|
||||
self.failUnlessEqual(suggest('1.0c2'), '1.0c2')
|
||||
self.failUnlessEqual(suggest('walla walla washington'), None)
|
||||
self.failUnlessEqual(suggest('2.4c1'), '2.4c1')
|
||||
|
||||
# from setuptools
|
||||
self.failUnlessEqual(suggest('0.4a1.r10'), '0.4a1.post10')
|
||||
self.failUnlessEqual(suggest('0.7a1dev-r66608'), '0.7a1.dev66608')
|
||||
self.failUnlessEqual(suggest('0.6a9.dev-r41475'), '0.6a9.dev41475')
|
||||
self.failUnlessEqual(suggest('2.4preview1'), '2.4c1')
|
||||
self.failUnlessEqual(suggest('2.4pre1') , '2.4c1')
|
||||
self.failUnlessEqual(suggest('2.1-rc2'), '2.1c2')
|
||||
|
||||
# from pypi
|
||||
self.failUnlessEqual(suggest('0.1dev'), '0.1.dev0')
|
||||
self.failUnlessEqual(suggest('0.1.dev'), '0.1.dev0')
|
||||
|
||||
# we want to be able to parse Twisted
|
||||
# development versions are like post releases in Twisted
|
||||
self.failUnlessEqual(suggest('9.0.0+r2363'), '9.0.0.post2363')
|
||||
|
||||
# pre-releases are using markers like "pre1"
|
||||
self.failUnlessEqual(suggest('9.0.0pre1'), '9.0.0c1')
|
||||
|
||||
# we want to be able to parse Tcl-TK
|
||||
# they use "p1" "p2" for post releases
|
||||
self.failUnlessEqual(suggest('1.4p1'), '1.4.post1')
|
||||
|
||||
# from darcsver
|
||||
self.failUnlessEqual(suggest('1.8.1-r4956'), '1.8.1.post4956')
|
||||
|
||||
# zetuptoolz
|
||||
self.failUnlessEqual(suggest('0.6c16dev3'), '0.6c16.dev3')
|
||||
|
||||
|
||||
class T(unittest.TestCase):
|
||||
def test_report_import_error(self):
|
||||
"""
|
||||
get_package_versions_and_locations reports a dependency if a dependency
|
||||
cannot be imported.
|
||||
"""
|
||||
# Make sure we don't leave the system in a bad state.
|
||||
self.addCleanup(
|
||||
lambda foolscap=sys.modules["foolscap"]: setitem(
|
||||
sys.modules,
|
||||
"foolscap",
|
||||
foolscap,
|
||||
),
|
||||
)
|
||||
# Make it look like Foolscap isn't installed.
|
||||
sys.modules["foolscap"] = None
|
||||
vers_and_locs, errors = get_package_versions_and_locations()
|
||||
|
||||
foolscap_stuffs = [stuff for (pkg, stuff) in vers_and_locs if pkg == 'foolscap']
|
||||
self.failUnlessEqual(len(foolscap_stuffs), 1)
|
||||
self.failUnless([e for e in errors if "\'foolscap\' could not be imported" in e])
|
@ -127,7 +127,7 @@ class IntroducerWeb(unittest.TestCase):
|
||||
assert_soup_has_text(
|
||||
self,
|
||||
soup,
|
||||
u"%s: %s" % (allmydata.__appname__, allmydata.__version__),
|
||||
allmydata.__full_version__,
|
||||
)
|
||||
assert_soup_has_text(self, soup, u"no peers!")
|
||||
assert_soup_has_text(self, soup, u"subscribers!")
|
||||
|
@ -159,5 +159,4 @@ PORTED_TEST_MODULES = [
|
||||
"allmydata.test.test_upload",
|
||||
"allmydata.test.test_uri",
|
||||
"allmydata.test.test_util",
|
||||
"allmydata.test.test_version",
|
||||
]
|
||||
|
@ -1,334 +0,0 @@
|
||||
"""
|
||||
Produce reports about the versions of Python software in use by Tahoe-LAFS
|
||||
for debugging and auditing purposes.
|
||||
|
||||
Ported to Python 3.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from future.utils import PY2
|
||||
if PY2:
|
||||
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
|
||||
|
||||
__all__ = [
|
||||
"PackagingError",
|
||||
"get_package_versions",
|
||||
"get_package_versions_string",
|
||||
"normalized_version",
|
||||
]
|
||||
|
||||
import os, platform, re, sys, traceback, pkg_resources
|
||||
|
||||
import six
|
||||
|
||||
import distro
|
||||
|
||||
from . import (
|
||||
__appname__,
|
||||
full_version,
|
||||
branch,
|
||||
)
|
||||
from .util import (
|
||||
verlib,
|
||||
)
|
||||
|
||||
if getattr(sys, 'frozen', None):
|
||||
# "Frozen" python interpreters (i.e., standalone executables
|
||||
# generated by PyInstaller and other, similar utilities) run
|
||||
# independently of a traditional setuptools-based packaging
|
||||
# environment, and so pkg_resources.get_distribution() cannot be
|
||||
# used in such cases to gather a list of requirements at runtime
|
||||
# (and because a frozen application is one that has already been
|
||||
# "installed", an empty list suffices here).
|
||||
_INSTALL_REQUIRES = []
|
||||
else:
|
||||
_INSTALL_REQUIRES = list(
|
||||
str(req)
|
||||
for req
|
||||
in pkg_resources.get_distribution(__appname__).requires()
|
||||
)
|
||||
|
||||
class PackagingError(EnvironmentError):
|
||||
"""
|
||||
Raised when there is an error in packaging of Tahoe-LAFS or its
|
||||
dependencies which makes it impossible to proceed safely.
|
||||
"""
|
||||
|
||||
def get_package_versions():
|
||||
return dict([(k, v) for k, (v, l, c) in _vers_and_locs_list])
|
||||
|
||||
def get_package_versions_string(show_paths=False, debug=False):
|
||||
res = []
|
||||
for p, (v, loc, comment) in _vers_and_locs_list:
|
||||
info = str(p) + ": " + str(v)
|
||||
if comment:
|
||||
info = info + " [%s]" % str(comment)
|
||||
if show_paths:
|
||||
info = info + " (%s)" % str(loc)
|
||||
res.append(info)
|
||||
|
||||
output = "\n".join(res) + "\n"
|
||||
|
||||
if _cross_check_errors:
|
||||
output += _get_error_string(_cross_check_errors, debug=debug)
|
||||
|
||||
return output
|
||||
|
||||
_distributor_id_cmdline_re = re.compile("(?:Distributor ID:)\s*(.*)", re.I)
|
||||
_release_cmdline_re = re.compile("(?:Release:)\s*(.*)", re.I)
|
||||
|
||||
_distributor_id_file_re = re.compile("(?:DISTRIB_ID\s*=)\s*(.*)", re.I)
|
||||
_release_file_re = re.compile("(?:DISTRIB_RELEASE\s*=)\s*(.*)", re.I)
|
||||
|
||||
_distname = None
|
||||
_version = None
|
||||
|
||||
def normalized_version(verstr, what=None):
|
||||
try:
|
||||
suggested = verlib.suggest_normalized_version(verstr) or verstr
|
||||
return verlib.NormalizedVersion(suggested)
|
||||
except verlib.IrrationalVersionError:
|
||||
raise
|
||||
except Exception:
|
||||
cls, value, trace = sys.exc_info()
|
||||
new_exc = PackagingError("could not parse %s due to %s: %s"
|
||||
% (what or repr(verstr), cls.__name__, value))
|
||||
six.reraise(cls, new_exc, trace)
|
||||
|
||||
def _get_error_string(errors, debug=False):
|
||||
|
||||
msg = "\n%s\n" % ("\n".join(errors),)
|
||||
if debug:
|
||||
msg += (
|
||||
"\n"
|
||||
"For debugging purposes, the PYTHONPATH was\n"
|
||||
" %r\n"
|
||||
"install_requires was\n"
|
||||
" %r\n"
|
||||
"sys.path after importing pkg_resources was\n"
|
||||
" %s\n"
|
||||
% (
|
||||
os.environ.get('PYTHONPATH'),
|
||||
_INSTALL_REQUIRES,
|
||||
(os.pathsep+"\n ").join(sys.path),
|
||||
)
|
||||
)
|
||||
return msg
|
||||
|
||||
def _cross_check(pkg_resources_vers_and_locs, imported_vers_and_locs_list):
|
||||
"""This function returns a list of errors due to any failed cross-checks."""
|
||||
|
||||
from ._auto_deps import not_import_versionable
|
||||
|
||||
errors = []
|
||||
not_pkg_resourceable = ['python', 'platform', __appname__.lower(), 'openssl']
|
||||
|
||||
for name, (imp_ver, imp_loc, imp_comment) in imported_vers_and_locs_list:
|
||||
name = name.lower()
|
||||
if name not in not_pkg_resourceable:
|
||||
if name not in pkg_resources_vers_and_locs:
|
||||
if name == "setuptools" and "distribute" in pkg_resources_vers_and_locs:
|
||||
pr_ver, pr_loc = pkg_resources_vers_and_locs["distribute"]
|
||||
if not (os.path.normpath(os.path.realpath(pr_loc)) == os.path.normpath(os.path.realpath(imp_loc))
|
||||
and imp_comment == "distribute"):
|
||||
errors.append("Warning: dependency 'setuptools' found to be version %r of 'distribute' from %r "
|
||||
"by pkg_resources, but 'import setuptools' gave version %r [%s] from %r. "
|
||||
"A version mismatch is expected, but a location mismatch is not."
|
||||
% (pr_ver, pr_loc, imp_ver, imp_comment or 'probably *not* distribute', imp_loc))
|
||||
else:
|
||||
errors.append("Warning: dependency %r (version %r imported from %r) was not found by pkg_resources."
|
||||
% (name, imp_ver, imp_loc))
|
||||
continue
|
||||
|
||||
pr_ver, pr_loc = pkg_resources_vers_and_locs[name]
|
||||
if imp_ver is None and imp_loc is None:
|
||||
errors.append("Warning: dependency %r could not be imported. pkg_resources thought it should be possible "
|
||||
"to import version %r from %r.\nThe exception trace was %r."
|
||||
% (name, pr_ver, pr_loc, imp_comment))
|
||||
continue
|
||||
|
||||
# If the pkg_resources version is identical to the imported version, don't attempt
|
||||
# to normalize them, since it is unnecessary and may fail (ticket #2499).
|
||||
if imp_ver != 'unknown' and pr_ver == imp_ver:
|
||||
continue
|
||||
|
||||
try:
|
||||
pr_normver = normalized_version(pr_ver)
|
||||
except verlib.IrrationalVersionError:
|
||||
continue
|
||||
except Exception as e:
|
||||
errors.append("Warning: version number %r found for dependency %r by pkg_resources could not be parsed. "
|
||||
"The version found by import was %r from %r. "
|
||||
"pkg_resources thought it should be found at %r. "
|
||||
"The exception was %s: %s"
|
||||
% (pr_ver, name, imp_ver, imp_loc, pr_loc, e.__class__.__name__, e))
|
||||
else:
|
||||
if imp_ver == 'unknown':
|
||||
if name not in not_import_versionable:
|
||||
errors.append("Warning: unexpectedly could not find a version number for dependency %r imported from %r. "
|
||||
"pkg_resources thought it should be version %r at %r."
|
||||
% (name, imp_loc, pr_ver, pr_loc))
|
||||
else:
|
||||
try:
|
||||
imp_normver = normalized_version(imp_ver)
|
||||
except verlib.IrrationalVersionError:
|
||||
continue
|
||||
except Exception as e:
|
||||
errors.append("Warning: version number %r found for dependency %r (imported from %r) could not be parsed. "
|
||||
"pkg_resources thought it should be version %r at %r. "
|
||||
"The exception was %s: %s"
|
||||
% (imp_ver, name, imp_loc, pr_ver, pr_loc, e.__class__.__name__, e))
|
||||
else:
|
||||
if pr_ver == 'unknown' or (pr_normver != imp_normver):
|
||||
if not os.path.normpath(os.path.realpath(pr_loc)) == os.path.normpath(os.path.realpath(imp_loc)):
|
||||
errors.append("Warning: dependency %r found to have version number %r (normalized to %r, from %r) "
|
||||
"by pkg_resources, but version %r (normalized to %r, from %r) by import."
|
||||
% (name, pr_ver, str(pr_normver), pr_loc, imp_ver, str(imp_normver), imp_loc))
|
||||
|
||||
return errors
|
||||
|
||||
def _get_openssl_version():
|
||||
try:
|
||||
from OpenSSL import SSL
|
||||
return _extract_openssl_version(SSL)
|
||||
except Exception:
|
||||
return ("unknown", None, None)
|
||||
|
||||
def _extract_openssl_version(ssl_module):
|
||||
openssl_version = ssl_module.SSLeay_version(ssl_module.SSLEAY_VERSION)
|
||||
if openssl_version.startswith('OpenSSL '):
|
||||
openssl_version = openssl_version[8 :]
|
||||
|
||||
(version, _, comment) = openssl_version.partition(' ')
|
||||
|
||||
try:
|
||||
openssl_cflags = ssl_module.SSLeay_version(ssl_module.SSLEAY_CFLAGS)
|
||||
if '-DOPENSSL_NO_HEARTBEATS' in openssl_cflags.split(' '):
|
||||
comment += ", no heartbeats"
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return (version, None, comment if comment else None)
|
||||
|
||||
|
||||
def _get_platform():
|
||||
# Our version of platform.platform(), telling us both less and more than the
|
||||
# Python Standard Library's version does.
|
||||
# We omit details such as the Linux kernel version number, but we add a
|
||||
# more detailed and correct rendition of the Linux distribution and
|
||||
# distribution-version.
|
||||
if "linux" in platform.system().lower():
|
||||
return (
|
||||
platform.system() + "-" +
|
||||
"_".join(distro.linux_distribution()[:2]) + "-" +
|
||||
platform.machine() + "-" +
|
||||
"_".join([x for x in platform.architecture() if x])
|
||||
)
|
||||
else:
|
||||
return platform.platform()
|
||||
|
||||
def _get_package_versions_and_locations():
|
||||
import warnings
|
||||
from ._auto_deps import package_imports, global_deprecation_messages, deprecation_messages, \
|
||||
runtime_warning_messages, warning_imports, ignorable
|
||||
|
||||
def package_dir(srcfile):
|
||||
return os.path.dirname(os.path.dirname(os.path.normcase(os.path.realpath(srcfile))))
|
||||
|
||||
# pkg_resources.require returns the distribution that pkg_resources attempted to put
|
||||
# on sys.path, which can differ from the one that we actually import due to #1258,
|
||||
# or any other bug that causes sys.path to be set up incorrectly. Therefore we
|
||||
# must import the packages in order to check their versions and paths.
|
||||
|
||||
# This is to suppress all UserWarnings and various DeprecationWarnings and RuntimeWarnings
|
||||
# (listed in _auto_deps.py).
|
||||
|
||||
warnings.filterwarnings("ignore", category=UserWarning, append=True)
|
||||
|
||||
for msg in global_deprecation_messages + deprecation_messages:
|
||||
warnings.filterwarnings("ignore", category=DeprecationWarning, message=msg, append=True)
|
||||
for msg in runtime_warning_messages:
|
||||
warnings.filterwarnings("ignore", category=RuntimeWarning, message=msg, append=True)
|
||||
try:
|
||||
for modulename in warning_imports:
|
||||
try:
|
||||
__import__(modulename)
|
||||
except (ImportError, SyntaxError):
|
||||
pass
|
||||
finally:
|
||||
# Leave suppressions for UserWarnings and global_deprecation_messages active.
|
||||
for _ in runtime_warning_messages + deprecation_messages:
|
||||
warnings.filters.pop()
|
||||
|
||||
packages = []
|
||||
pkg_resources_vers_and_locs = dict()
|
||||
|
||||
if not hasattr(sys, 'frozen'):
|
||||
pkg_resources_vers_and_locs = {
|
||||
p.project_name.lower(): (str(p.version), p.location)
|
||||
for p
|
||||
in pkg_resources.require(_INSTALL_REQUIRES)
|
||||
}
|
||||
|
||||
def get_version(module):
|
||||
if hasattr(module, '__version__'):
|
||||
return str(getattr(module, '__version__'))
|
||||
elif hasattr(module, 'version'):
|
||||
ver = getattr(module, 'version')
|
||||
if isinstance(ver, tuple):
|
||||
return '.'.join(map(str, ver))
|
||||
else:
|
||||
return str(ver)
|
||||
else:
|
||||
return 'unknown'
|
||||
|
||||
for pkgname, modulename in [(__appname__, 'allmydata')] + package_imports:
|
||||
if modulename:
|
||||
try:
|
||||
__import__(modulename)
|
||||
module = sys.modules[modulename]
|
||||
except (ImportError, SyntaxError):
|
||||
etype, emsg, etrace = sys.exc_info()
|
||||
trace_info = (etype, str(emsg), ([None] + traceback.extract_tb(etrace))[-1])
|
||||
packages.append( (pkgname, (None, None, trace_info)) )
|
||||
else:
|
||||
comment = None
|
||||
if pkgname == __appname__:
|
||||
comment = "%s: %s" % (branch, full_version)
|
||||
elif pkgname == 'setuptools' and hasattr(module, '_distribute'):
|
||||
# distribute does not report its version in any module variables
|
||||
comment = 'distribute'
|
||||
ver = get_version(module)
|
||||
loc = package_dir(module.__file__)
|
||||
if ver == "unknown" and pkgname in pkg_resources_vers_and_locs:
|
||||
(pr_ver, pr_loc) = pkg_resources_vers_and_locs[pkgname]
|
||||
if loc == os.path.normcase(os.path.realpath(pr_loc)):
|
||||
ver = pr_ver
|
||||
packages.append( (pkgname, (ver, loc, comment)) )
|
||||
elif pkgname == 'python':
|
||||
packages.append( (pkgname, (platform.python_version(), sys.executable, None)) )
|
||||
elif pkgname == 'platform':
|
||||
packages.append( (pkgname, (_get_platform(), None, None)) )
|
||||
elif pkgname == 'OpenSSL':
|
||||
packages.append( (pkgname, _get_openssl_version()) )
|
||||
|
||||
cross_check_errors = []
|
||||
|
||||
if len(pkg_resources_vers_and_locs) > 0:
|
||||
imported_packages = set([p.lower() for (p, _) in packages])
|
||||
extra_packages = []
|
||||
|
||||
for pr_name, (pr_ver, pr_loc) in pkg_resources_vers_and_locs.items():
|
||||
if pr_name not in imported_packages and pr_name not in ignorable:
|
||||
extra_packages.append( (pr_name, (pr_ver, pr_loc, "according to pkg_resources")) )
|
||||
|
||||
cross_check_errors = _cross_check(pkg_resources_vers_and_locs, packages)
|
||||
packages += extra_packages
|
||||
|
||||
return packages, cross_check_errors
|
||||
|
||||
|
||||
_vers_and_locs_list, _cross_check_errors = _get_package_versions_and_locations()
|
@ -6,7 +6,6 @@ from twisted.python.filepath import FilePath
|
||||
from twisted.web import static
|
||||
import allmydata
|
||||
import json
|
||||
from allmydata.version_checks import get_package_versions_string
|
||||
from allmydata.util import idlib
|
||||
from allmydata.web.common import (
|
||||
render_time,
|
||||
@ -89,7 +88,7 @@ class IntroducerRootElement(Element):
|
||||
self.introducer_service = introducer_service
|
||||
self.node_data_dict = {
|
||||
"my_nodeid": idlib.nodeid_b2a(self.introducer_node.nodeid),
|
||||
"version": get_package_versions_string(),
|
||||
"version": allmydata.__full_version__,
|
||||
"import_path": str(allmydata).replace("/", "/ "), # XXX kludge for wrapping
|
||||
"rendered_at": render_time(time.time()),
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ from twisted.web.template import (
|
||||
)
|
||||
|
||||
import allmydata # to display import path
|
||||
from allmydata.version_checks import get_package_versions_string
|
||||
from allmydata.util import log
|
||||
from allmydata.interfaces import IFileNode
|
||||
from allmydata.web import (
|
||||
@ -566,7 +565,7 @@ class RootElement(Element):
|
||||
|
||||
@renderer
|
||||
def version(self, req, tag):
|
||||
return tag(get_package_versions_string())
|
||||
return tag(allmydata.__full_version__)
|
||||
|
||||
@renderer
|
||||
def import_path(self, req, tag):
|
||||
|
Loading…
Reference in New Issue
Block a user