summarylogtreecommitdiffstats
path: root/setuptools_fix.patch
blob: f99e6bf30b04e0afb302783004045773de0ddd7b (plain)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
diff -Nuar -Naur allmydata-tahoe-1.10.0.post26-old/setuptools-0.6c16dev4.egg/pkg_resources.py allmydata-tahoe-1.10.0.post26-new/setuptools-0.6c16dev4.egg/pkg_resources.py
--- allmydata-tahoe-1.10.0.post26-old/setuptools-0.6c16dev4.egg/pkg_resources.py	2013-06-26 11:50:48.000000000 -0400
+++ allmydata-tahoe-1.10.0.post26-new/setuptools-0.6c16dev4.egg/pkg_resources.py	2015-06-10 18:22:49.197090458 -0400
@@ -527,14 +527,19 @@
         # If we have a __requires__ then we can already tell if this
         # dist is unsatisfactory, in which case we won't add it.
         if __requires__ is not None:
-            for thisreqstr in __requires__:
+            if isinstance(__requires__, basestring):
+                array_of__requires__ = [__requires__]
+            else:
+                array_of__requires__ = __requires__
+
+            for thisreqstr in array_of__requires__:
                 try:
                     for thisreq in parse_requirements(thisreqstr):
                         if thisreq.key == dist.key:
                             if dist not in thisreq:
                                 return
                 except ValueError, e:
-                    e.args = tuple(e.args + ({'thisreqstr': thisreqstr},))
+                    e.args = tuple(e.args + ({'thisreqstr': thisreqstr, '__requires__': __requires__},))
                     raise
 
         self.by_key[dist.key] = dist
diff -Nuar -Naur allmydata-tahoe-1.10.0.post26-old/src/allmydata/_auto_deps.py allmydata-tahoe-1.10.0.post26-new/src/allmydata/_auto_deps.py
--- allmydata-tahoe-1.10.0.post26-old/src/allmydata/_auto_deps.py	2013-06-26 11:50:48.000000000 -0400
+++ allmydata-tahoe-1.10.0.post26-new/src/allmydata/_auto_deps.py	2015-06-10 19:22:46.464853667 -0400
@@ -16,7 +16,7 @@
 
     # zope.interface >= 3.6.0 is required for Twisted >= 12.1.0.
     # zope.interface 3.6.3 and 3.6.4 are incompatible with Nevow (#1435).
-    "zope.interface == 3.6.0, == 3.6.1, == 3.6.2, >= 3.6.5",
+    "zope.interface >= 3.6.0, != 3.6.3, != 3.6.4",
 
     # * On Windows we need at least Twisted 9.0 to avoid an indirect
     #   dependency on pywin32.
@@ -48,15 +48,19 @@
     #   library, we need to update this declaration here.
     #
     "foolscap >= 0.6.3",
-    "pyOpenSSL",
+    "pyOpenSSL >= 0.13",
 
-    "Nevow >= 0.6.0",
+    "Nevow >= 0.9.33",
+
+    "service-identity",         # this is needed to suppress complaints about being unable to verify certs
+    "characteristic >= 14.0.0", # latest service-identity depends on this version
+    "pyasn1 >= 0.1.4",          # latest pyasn1-modules depends on this version
+    "pyasn1-modules",           # service-identity depends on this
 
     # Needed for SFTP. pyasn1 is needed by twisted.conch in Twisted >= 9.0.
     # pycrypto 2.2 doesn't work due to https://bugs.launchpad.net/pycrypto/+bug/620253
     # pycrypto 2.4 doesn't work due to https://bugs.launchpad.net/pycrypto/+bug/881130
-    "pycrypto == 2.1.0, == 2.3, >= 2.4.1",
-    "pyasn1 >= 0.0.8a",
+    "pycrypto >= 2.1.0, != 2.2, != 2.4",
 
     # http://www.voidspace.org.uk/python/mock/ , 0.8.0 provides "call"
     "mock >= 0.8.0",
@@ -85,6 +89,35 @@
     ('pycrypto',        'Crypto'),
     ('pyasn1',          'pyasn1'),
     ('mock',            'mock'),
+    ('service-identity', 'service_identity'),
+    ('characteristic',   'characteristic'),
+    ('pyasn1-modules',   'pyasn1_modules'),
+    ('cryptography',     'cryptography'),
+    ('cffi',             'cffi'),
+    ('six',              'six'),
+    ('enum34',           'enum'),
+    ('pycparser',        'pycparser'),
+]
+
+# Dependencies for which we don't know how to get a version number at run-time.
+not_import_versionable = [
+    'zope.interface',
+    'mock',
+    'pyasn1',
+    'pyasn1-modules',
+]
+
+# Dependencies reported by pkg_resources that we can safely ignore.
+ignorable = [
+    'ipaddress',
+    'idna',
+    'argparse',
+    'pyutil',
+    'zbase32',
+    'distribute',
+    'twisted-web',
+    'twisted-core',
+    'twisted-conch',
 ]
 
 def require_more():
diff -Nuar -Naur allmydata-tahoe-1.10.0.post26-old/src/allmydata/__init__.py allmydata-tahoe-1.10.0.post26-new/src/allmydata/__init__.py
--- allmydata-tahoe-1.10.0.post26-old/src/allmydata/__init__.py	2013-06-26 11:50:48.000000000 -0400
+++ allmydata-tahoe-1.10.0.post26-new/src/allmydata/__init__.py	2015-06-10 19:11:10.147772871 -0400
@@ -187,8 +187,17 @@
 
     packages = []
 
-    def get_version(module, attr):
-        return str(getattr(module, attr, 'unknown'))
+    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:
@@ -206,7 +215,7 @@
                 elif pkgname == 'setuptools' and hasattr(module, '_distribute'):
                     # distribute does not report its version in any module variables
                     comment = 'distribute'
-                packages.append( (pkgname, (get_version(module, '__version__'), package_dir(module.__file__), comment)) )
+                packages.append( (pkgname, (get_version(module), package_dir(module.__file__), comment)) )
         elif pkgname == 'python':
             packages.append( (pkgname, (platform.python_version(), sys.executable, None)) )
         elif pkgname == 'platform':
@@ -220,7 +229,7 @@
     # We support only disjunctions of <=, >=, and ==
 
     reqlist = req.split(',')
-    name = reqlist[0].split('<=')[0].split('>=')[0].split('==')[0].strip(' ').split('[')[0]
+    name = reqlist[0].split('<=')[0].split('>=')[0].split('!=')[0].strip(' ').split('[')[0]
     if name not in vers_and_locs:
         raise PackagingError("no version info for %s" % (name,))
     if req.strip(' ') == name:
@@ -233,33 +242,38 @@
         return
     actualver = normalized_version(actual, what="actual version %r of %s from %r" % (actual, name, location))
 
+    if not match_requirement(req, reqlist, actualver):
+        msg = ("We require %s, but could only find version %s.\n" % (req, actual))
+        if location and location != 'unknown':
+            msg += "The version we found is from %r.\n" % (location,)
+        msg += ("To resolve this problem, uninstall that version, either using your\n"
+                "operating system's package manager or by moving aside the directory.")
+        raise PackagingError(msg)
+
+
+def match_requirement(req, reqlist, actualver):
     for r in reqlist:
         s = r.split('<=')
         if len(s) == 2:
             required = s[1].strip(' ')
-            if actualver <= normalized_version(required, what="required maximum version %r in %r" % (required, req)):
-                return  # maximum requirement met
+            if not (actualver <= normalized_version(required, what="required maximum version %r in %r" % (required, req))):
+                return False  # maximum requirement not met
         else:
             s = r.split('>=')
             if len(s) == 2:
                 required = s[1].strip(' ')
-                if actualver >= normalized_version(required, what="required minimum version %r in %r" % (required, req)):
-                    return  # minimum requirement met
+                if not (actualver >= normalized_version(required, what="required minimum version %r in %r" % (required, req))):
+                    return False  # minimum requirement not met
             else:
-                s = r.split('==')
+                s = r.split('!=')
                 if len(s) == 2:
                     required = s[1].strip(' ')
-                    if actualver == normalized_version(required, what="required exact version %r in %r" % (required, req)):
-                        return  # exact requirement met
+                    if not (actualver != normalized_version(required, what="excluded version %r in %r" % (required, req))):
+                        return False  # not-equal requirement not met
                 else:
                     raise PackagingError("no version info or could not understand requirement %r" % (req,))
 
-    msg = ("We require %s, but could only find version %s.\n" % (req, actual))
-    if location and location != 'unknown':
-        msg += "The version we found is from %r.\n" % (location,)
-    msg += ("To resolve this problem, uninstall that version, either using your\n"
-            "operating system's package manager or by moving aside the directory.")
-    raise PackagingError(msg)
+    return True
 
 
 _vers_and_locs_list = get_package_versions_and_locations()
@@ -280,10 +294,10 @@
 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, ignorable
+
     errors = []
-    not_pkg_resourceable = set(['python', 'platform', __appname__.lower()])
-    not_import_versionable = set(['zope.interface', 'mock', 'pyasn1'])
-    ignorable = set(['argparse', 'pyutil', 'zbase32', 'distribute', 'twisted-web', 'twisted-core', 'twisted-conch'])
+    not_pkg_resourceable = ['python', 'platform', __appname__.lower()]
 
     for name, (imp_ver, imp_loc, imp_comment) in imported_vers_and_locs_list:
         name = name.lower()
diff -Nuar -Naur allmydata-tahoe-1.10.0.post26-old/src/allmydata/test/test_version.py allmydata-tahoe-1.10.0.post26-new/src/allmydata/test/test_version.py
--- allmydata-tahoe-1.10.0.post26-old/src/allmydata/test/test_version.py	2013-06-26 11:50:48.000000000 -0400
+++ allmydata-tahoe-1.10.0.post26-new/src/allmydata/test/test_version.py	2015-06-10 18:36:50.114719577 -0400
@@ -1,4 +1,5 @@
 
+from pkg_resources import Requirement
 from twisted.trial import unittest
 
 from allmydata import check_requirement, cross_check, PackagingError
@@ -9,39 +10,45 @@
 
 class CheckRequirement(unittest.TestCase):
     def test_check_requirement(self):
-        check_requirement("setuptools >= 0.6c6", {"setuptools": ("0.6", "", None)})
-        check_requirement("setuptools >= 0.6c6", {"setuptools": ("0.6", "", "distribute")})
-        check_requirement("pycrypto == 2.0.1, == 2.1, >= 2.3", {"pycrypto": ("2.1.0", "", None)})
-        check_requirement("pycrypto == 2.0.1, == 2.1, >= 2.3", {"pycrypto": ("2.4.0", "", None)})
-        check_requirement("zope.interface <= 3.6.2, >= 3.6.6", {"zope.interface": ("3.6.1", "", None)})
-        check_requirement("zope.interface <= 3.6.2, >= 3.6.6", {"zope.interface": ("3.6.6", "", None)})
-
-        check_requirement("zope.interface", {"zope.interface": ("unknown", "", None)})
-        check_requirement("mock", {"mock": ("0.6.0", "", None)})
-        check_requirement("foo >= 1.0", {"foo": ("1.0", "", None), "bar": ("2.0", "", None)})
+        self._check_success("setuptools >= 0.6c6", {"setuptools": ("0.6", "", None)})
+        self._check_success("setuptools >= 0.6c6", {"setuptools": ("0.6", "", "distribute")})
+        self._check_success("pycrypto >= 2.1.0, != 2.2, != 2.4", {"pycrypto": ("2.1.0", "", None)})
+        self._check_success("pycrypto >= 2.1.0, != 2.2, != 2.4", {"pycrypto": ("2.3.0", "", None)})
+        self._check_success("pycrypto >= 2.1.0, != 2.2, != 2.4", {"pycrypto": ("2.4.1", "", None)})
+
+        self._check_success("zope.interface", {"zope.interface": ("unknown", "", None)})
+        self._check_success("mock", {"mock": ("0.6.0", "", None)})
+        self._check_success("foo >= 1.0", {"foo": ("1.0", "", None), "bar": ("2.0", "", None)})
 
-        check_requirement("foolscap[secure_connections] >= 0.6.0", {"foolscap": ("0.7.0", "", None)})
+        self._check_success("foolscap[secure_connections] >= 0.6.0", {"foolscap": ("0.7.0", "", None)})
 
         try:
-            check_requirement("foolscap[secure_connections] >= 0.6.0", {"foolscap": ("0.6.1+", "", None)})
+            self._check_success("foolscap[secure_connections] >= 0.6.0", {"foolscap": ("0.6.1+", "", None)})
             # succeeding is ok
         except PackagingError, e:
             self.failUnlessIn("could not parse", str(e))
 
-        self.failUnlessRaises(PackagingError, check_requirement,
-                              "foolscap[secure_connections] >= 0.6.0", {"foolscap": ("0.5.1", "", None)})
-        self.failUnlessRaises(PackagingError, check_requirement,
-                              "pycrypto == 2.0.1, == 2.1, >= 2.3", {"pycrypto": ("2.2.0", "", None)})
-        self.failUnlessRaises(PackagingError, check_requirement,
-                              "zope.interface <= 3.6.2, >= 3.6.6", {"zope.interface": ("3.6.4", "", None)})
-        self.failUnlessRaises(PackagingError, check_requirement,
-                              "foo >= 1.0", {})
-        self.failUnlessRaises(PackagingError, check_requirement,
-                              "foo >= 1.0", {"foo": ("irrational", "", None)})
+        self._check_failure("foolscap[secure_connections] >= 0.6.0", {"foolscap": ("0.5.1", "", None)})
+        self._check_failure("pycrypto >= 2.1.0, != 2.2, != 2.4", {"pycrypto": ("2.2.0", "", None)})
+        self._check_failure("pycrypto >= 2.1.0, != 2.2, != 2.4", {"pycrypto": ("2.0.0", "", None)})
+        self._check_failure("foo >= 1.0", {})
+        self._check_failure("foo >= 1.0", {"foo": ("irrational", "", None)})
 
         self.failUnlessRaises(ImportError, check_requirement,
                               "foo >= 1.0", {"foo": (None, None, "foomodule")})
 
+        def _check_success(self, req, vers_and_locs):
+            check_requirement(req, vers_and_locs)
+
+            for pkg, ver in vers_and_locs.items():
+                self.failUnless(ver[0] in Requirement.parse(req), str((ver, req)))
+
+        def _check_failure(self, req, vers_and_locs):
+            self.failUnlessRaises(PackagingError, check_requirement, req, vers_and_locs)
+
+            for pkg, ver in vers_and_locs.items():
+                self.failIf(ver[0] in Requirement.parse(req), str((ver, req)))
+
     def test_cross_check_ticket_1355(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.