Merge lp:~xnox/lazr.restfulclient/fixes into lp:lazr.restfulclient
- fixes
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 137 |
Proposed branch: | lp:~xnox/lazr.restfulclient/fixes |
Merge into: | lp:lazr.restfulclient |
Diff against target: |
743 lines (+84/-310) 9 files modified
buildout.cfg (+1/-1) ez_setup.py (+0/-241) setup.py (+6/-7) src/lazr/restfulclient/_browser.py (+14/-23) src/lazr/restfulclient/authorize/oauth.py (+2/-1) src/lazr/restfulclient/resource.py (+22/-12) src/lazr/restfulclient/tests/test_atomicfilecache.py (+29/-15) src/lazr/restfulclient/tests/test_error.py (+2/-2) src/lazr/restfulclient/tests/test_oauth.py (+8/-8) |
To merge this branch: | bzr merge lp:~xnox/lazr.restfulclient/fixes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Barry Warsaw | Needs Information | ||
LAZR Developers | Pending | ||
Review via email: mp+224945@code.launchpad.net |
Commit message
Simplify setup.py and fix one python3 syntax error.
Description of the change
- 139. By Dimitri John Ledkov
-
SSLHandshakeError is gone in python3, add compat.
- 140. By Dimitri John Ledkov
-
Resurect bootstrap.py
- 141. By Dimitri John Ledkov
-
Depreciation warning readfp -> read_file
- 142. By Dimitri John Ledkov
-
Take 1 at unicode
- 143. By Dimitri John Ledkov
-
More stuff
- 144. By Dimitri John Ledkov
-
Distch six
- 145. By Dimitri John Ledkov
-
Fix standalone buildout
- 146. By Dimitri John Ledkov
-
drop unused things
- 147. By Dimitri John Ledkov
-
Revert to minimise diff
- 148. By Dimitri John Ledkov
-
url must be string
- 149. By Dimitri John Ledkov
-
More crap
Dimitri John Ledkov (xnox) wrote : | # |
Replied.
Barry Warsaw (barry) wrote : | # |
On Jul 14, 2014, at 10:20 PM, Dimitri John Ledkov wrote:
>> try:
>> + from httplib2 import SSLHandshakeError
>> +except ImportError:
>> + from httplib2 import HttpLib2Error as SSLHandshakeError
>> +try:
>
>yes, it does. But it's only used to catch the error, and re-raise it with a
>helpful message that "there is an option to ignore ssl certificate
>errors". The actual class of the error has changed, but i believe the text of
>the error comes from the underlying library. This keeps compat in python2,
>and the worst case scenario the error is re-raised regardless.
So I had a look at the actual code where this is used. Ug.
>Maybe I should remove all error catching and thus not use either
>SSLHandshakeError nor HttpLib2Error?
That does seem better. Then release notes or documentation can describe
LP_DISABLE_
- 150. By Dimitri John Ledkov
-
Whitespace and review fixes, drop SSLHandshakeError handling.
Preview Diff
1 | === modified file 'buildout.cfg' | |||
2 | --- buildout.cfg 2012-06-19 13:28:22 +0000 | |||
3 | +++ buildout.cfg 2014-07-28 15:39:09 +0000 | |||
4 | @@ -17,7 +17,7 @@ | |||
5 | 17 | 17 | ||
6 | 18 | [standalone_test] | 18 | [standalone_test] |
7 | 19 | recipe = zc.recipe.testrunner | 19 | recipe = zc.recipe.testrunner |
9 | 20 | eggs = lazr.restfulclient | 20 | eggs = lazr.restfulclient [test] |
10 | 21 | defaults = '--tests-pattern ^tests --exit-with-status --suite-name standalone_tests'.split() | 21 | defaults = '--tests-pattern ^tests --exit-with-status --suite-name standalone_tests'.split() |
11 | 22 | 22 | ||
12 | 23 | [docs] | 23 | [docs] |
13 | 24 | 24 | ||
14 | === removed file 'ez_setup.py' | |||
15 | --- ez_setup.py 2010-03-24 15:14:12 +0000 | |||
16 | +++ ez_setup.py 1970-01-01 00:00:00 +0000 | |||
17 | @@ -1,241 +0,0 @@ | |||
18 | 1 | #!python | ||
19 | 2 | """Bootstrap setuptools installation | ||
20 | 3 | |||
21 | 4 | If you want to use setuptools in your package's setup.py, just include this | ||
22 | 5 | file in the same directory with it, and add this to the top of your setup.py:: | ||
23 | 6 | |||
24 | 7 | from ez_setup import use_setuptools | ||
25 | 8 | use_setuptools() | ||
26 | 9 | |||
27 | 10 | If you want to require a specific version of setuptools, set a download | ||
28 | 11 | mirror, or use an alternate download directory, you can do so by supplying | ||
29 | 12 | the appropriate options to ``use_setuptools()``. | ||
30 | 13 | |||
31 | 14 | This file can also be run as a script to install or upgrade setuptools. | ||
32 | 15 | """ | ||
33 | 16 | import sys | ||
34 | 17 | DEFAULT_VERSION = "0.6c11" | ||
35 | 18 | DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] | ||
36 | 19 | |||
37 | 20 | md5_data = { | ||
38 | 21 | 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', | ||
39 | 22 | 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', | ||
40 | 23 | 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', | ||
41 | 24 | 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', | ||
42 | 25 | 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', | ||
43 | 26 | 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', | ||
44 | 27 | 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', | ||
45 | 28 | 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', | ||
46 | 29 | 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', | ||
47 | 30 | 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', | ||
48 | 31 | 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', | ||
49 | 32 | 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', | ||
50 | 33 | 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', | ||
51 | 34 | 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', | ||
52 | 35 | 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', | ||
53 | 36 | 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', | ||
54 | 37 | 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', | ||
55 | 38 | 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', | ||
56 | 39 | 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', | ||
57 | 40 | 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', | ||
58 | 41 | 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', | ||
59 | 42 | 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', | ||
60 | 43 | 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', | ||
61 | 44 | 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', | ||
62 | 45 | 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', | ||
63 | 46 | 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', | ||
64 | 47 | 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', | ||
65 | 48 | 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', | ||
66 | 49 | 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', | ||
67 | 50 | 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', | ||
68 | 51 | } | ||
69 | 52 | |||
70 | 53 | import sys, os | ||
71 | 54 | |||
72 | 55 | def _validate_md5(egg_name, data): | ||
73 | 56 | if egg_name in md5_data: | ||
74 | 57 | from md5 import md5 | ||
75 | 58 | digest = md5(data).hexdigest() | ||
76 | 59 | if digest != md5_data[egg_name]: | ||
77 | 60 | print >>sys.stderr, ( | ||
78 | 61 | "md5 validation of %s failed! (Possible download problem?)" | ||
79 | 62 | % egg_name | ||
80 | 63 | ) | ||
81 | 64 | sys.exit(2) | ||
82 | 65 | return data | ||
83 | 66 | |||
84 | 67 | |||
85 | 68 | def use_setuptools( | ||
86 | 69 | version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, | ||
87 | 70 | download_delay=15, min_version=None | ||
88 | 71 | ): | ||
89 | 72 | """Automatically find/download setuptools and make it available on sys.path | ||
90 | 73 | |||
91 | 74 | `version` should be a valid setuptools version number that is available | ||
92 | 75 | as an egg for download under the `download_base` URL (which should end with | ||
93 | 76 | a '/'). `to_dir` is the directory where setuptools will be downloaded, if | ||
94 | 77 | it is not already available. If `download_delay` is specified, it should | ||
95 | 78 | be the number of seconds that will be paused before initiating a download, | ||
96 | 79 | should one be required. If an older version of setuptools is installed, | ||
97 | 80 | this routine will print a message to ``sys.stderr`` and raise SystemExit in | ||
98 | 81 | an attempt to abort the calling script. | ||
99 | 82 | """ | ||
100 | 83 | # Work around a hack in the ez_setup.py file from simplejson==1.7.3. | ||
101 | 84 | if min_version: | ||
102 | 85 | version = min_version | ||
103 | 86 | |||
104 | 87 | was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules | ||
105 | 88 | def do_download(): | ||
106 | 89 | egg = download_setuptools(version, download_base, to_dir, download_delay) | ||
107 | 90 | sys.path.insert(0, egg) | ||
108 | 91 | import setuptools; setuptools.bootstrap_install_from = egg | ||
109 | 92 | try: | ||
110 | 93 | import pkg_resources | ||
111 | 94 | except ImportError: | ||
112 | 95 | return do_download() | ||
113 | 96 | try: | ||
114 | 97 | pkg_resources.require("setuptools>="+version); return | ||
115 | 98 | except pkg_resources.VersionConflict, e: | ||
116 | 99 | if was_imported: | ||
117 | 100 | print >>sys.stderr, ( | ||
118 | 101 | "The required version of setuptools (>=%s) is not available, and\n" | ||
119 | 102 | "can't be installed while this script is running. Please install\n" | ||
120 | 103 | " a more recent version first, using 'easy_install -U setuptools'." | ||
121 | 104 | "\n\n(Currently using %r)" | ||
122 | 105 | ) % (version, e.args[0]) | ||
123 | 106 | sys.exit(2) | ||
124 | 107 | else: | ||
125 | 108 | del pkg_resources, sys.modules['pkg_resources'] # reload ok | ||
126 | 109 | return do_download() | ||
127 | 110 | except pkg_resources.DistributionNotFound: | ||
128 | 111 | return do_download() | ||
129 | 112 | |||
130 | 113 | def download_setuptools( | ||
131 | 114 | version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, | ||
132 | 115 | delay = 15 | ||
133 | 116 | ): | ||
134 | 117 | """Download setuptools from a specified location and return its filename | ||
135 | 118 | |||
136 | 119 | `version` should be a valid setuptools version number that is available | ||
137 | 120 | as an egg for download under the `download_base` URL (which should end | ||
138 | 121 | with a '/'). `to_dir` is the directory where the egg will be downloaded. | ||
139 | 122 | `delay` is the number of seconds to pause before an actual download attempt. | ||
140 | 123 | """ | ||
141 | 124 | import urllib2, shutil | ||
142 | 125 | egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) | ||
143 | 126 | url = download_base + egg_name | ||
144 | 127 | saveto = os.path.join(to_dir, egg_name) | ||
145 | 128 | src = dst = None | ||
146 | 129 | if not os.path.exists(saveto): # Avoid repeated downloads | ||
147 | 130 | try: | ||
148 | 131 | from distutils import log | ||
149 | 132 | if delay: | ||
150 | 133 | log.warn(""" | ||
151 | 134 | --------------------------------------------------------------------------- | ||
152 | 135 | This script requires setuptools version %s to run (even to display | ||
153 | 136 | help). I will attempt to download it for you (from | ||
154 | 137 | %s), but | ||
155 | 138 | you may need to enable firewall access for this script first. | ||
156 | 139 | I will start the download in %d seconds. | ||
157 | 140 | |||
158 | 141 | (Note: if this machine does not have network access, please obtain the file | ||
159 | 142 | |||
160 | 143 | %s | ||
161 | 144 | |||
162 | 145 | and place it in this directory before rerunning this script.) | ||
163 | 146 | ---------------------------------------------------------------------------""", | ||
164 | 147 | version, download_base, delay, url | ||
165 | 148 | ); from time import sleep; sleep(delay) | ||
166 | 149 | log.warn("Downloading %s", url) | ||
167 | 150 | src = urllib2.urlopen(url) | ||
168 | 151 | # Read/write all in one block, so we don't create a corrupt file | ||
169 | 152 | # if the download is interrupted. | ||
170 | 153 | data = _validate_md5(egg_name, src.read()) | ||
171 | 154 | dst = open(saveto,"wb"); dst.write(data) | ||
172 | 155 | finally: | ||
173 | 156 | if src: src.close() | ||
174 | 157 | if dst: dst.close() | ||
175 | 158 | return os.path.realpath(saveto) | ||
176 | 159 | |||
177 | 160 | def main(argv, version=DEFAULT_VERSION): | ||
178 | 161 | """Install or upgrade setuptools and EasyInstall""" | ||
179 | 162 | try: | ||
180 | 163 | import setuptools | ||
181 | 164 | except ImportError: | ||
182 | 165 | egg = None | ||
183 | 166 | try: | ||
184 | 167 | egg = download_setuptools(version, delay=0) | ||
185 | 168 | sys.path.insert(0,egg) | ||
186 | 169 | from setuptools.command.easy_install import main | ||
187 | 170 | return main(list(argv)+[egg]) # we're done here | ||
188 | 171 | finally: | ||
189 | 172 | if egg and os.path.exists(egg): | ||
190 | 173 | os.unlink(egg) | ||
191 | 174 | else: | ||
192 | 175 | if setuptools.__version__ == '0.0.1': | ||
193 | 176 | print >>sys.stderr, ( | ||
194 | 177 | "You have an obsolete version of setuptools installed. Please\n" | ||
195 | 178 | "remove it from your system entirely before rerunning this script." | ||
196 | 179 | ) | ||
197 | 180 | sys.exit(2) | ||
198 | 181 | |||
199 | 182 | req = "setuptools>="+version | ||
200 | 183 | import pkg_resources | ||
201 | 184 | try: | ||
202 | 185 | pkg_resources.require(req) | ||
203 | 186 | except pkg_resources.VersionConflict: | ||
204 | 187 | try: | ||
205 | 188 | from setuptools.command.easy_install import main | ||
206 | 189 | except ImportError: | ||
207 | 190 | from easy_install import main | ||
208 | 191 | main(list(argv)+[download_setuptools(delay=0)]) | ||
209 | 192 | sys.exit(0) # try to force an exit | ||
210 | 193 | else: | ||
211 | 194 | if argv: | ||
212 | 195 | from setuptools.command.easy_install import main | ||
213 | 196 | main(argv) | ||
214 | 197 | else: | ||
215 | 198 | print "Setuptools version",version,"or greater has been installed." | ||
216 | 199 | print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' | ||
217 | 200 | |||
218 | 201 | def update_md5(filenames): | ||
219 | 202 | """Update our built-in md5 registry""" | ||
220 | 203 | |||
221 | 204 | import re | ||
222 | 205 | from md5 import md5 | ||
223 | 206 | |||
224 | 207 | for name in filenames: | ||
225 | 208 | base = os.path.basename(name) | ||
226 | 209 | f = open(name,'rb') | ||
227 | 210 | md5_data[base] = md5(f.read()).hexdigest() | ||
228 | 211 | f.close() | ||
229 | 212 | |||
230 | 213 | data = [" %r: %r,\n" % it for it in md5_data.items()] | ||
231 | 214 | data.sort() | ||
232 | 215 | repl = "".join(data) | ||
233 | 216 | |||
234 | 217 | import inspect | ||
235 | 218 | srcfile = inspect.getsourcefile(sys.modules[__name__]) | ||
236 | 219 | f = open(srcfile, 'rb'); src = f.read(); f.close() | ||
237 | 220 | |||
238 | 221 | match = re.search("\nmd5_data = {\n([^}]+)}", src) | ||
239 | 222 | if not match: | ||
240 | 223 | print >>sys.stderr, "Internal error!" | ||
241 | 224 | sys.exit(2) | ||
242 | 225 | |||
243 | 226 | src = src[:match.start(1)] + repl + src[match.end(1):] | ||
244 | 227 | f = open(srcfile,'w') | ||
245 | 228 | f.write(src) | ||
246 | 229 | f.close() | ||
247 | 230 | |||
248 | 231 | |||
249 | 232 | if __name__=='__main__': | ||
250 | 233 | if len(sys.argv)>2 and sys.argv[1]=='--md5update': | ||
251 | 234 | update_md5(sys.argv[2:]) | ||
252 | 235 | else: | ||
253 | 236 | main(sys.argv[1:]) | ||
254 | 237 | |||
255 | 238 | |||
256 | 239 | |||
257 | 240 | |||
258 | 241 | |||
259 | 242 | 0 | ||
260 | === modified file 'setup.py' | |||
261 | --- setup.py 2014-06-05 11:25:42 +0000 | |||
262 | +++ setup.py 2014-07-28 15:39:09 +0000 | |||
263 | @@ -16,9 +16,6 @@ | |||
264 | 16 | # You should have received a copy of the GNU Lesser General Public License | 16 | # You should have received a copy of the GNU Lesser General Public License |
265 | 17 | # along with lazr.restfulclient. If not, see <http://www.gnu.org/licenses/>. | 17 | # along with lazr.restfulclient. If not, see <http://www.gnu.org/licenses/>. |
266 | 18 | 18 | ||
267 | 19 | import ez_setup | ||
268 | 20 | ez_setup.use_setuptools() | ||
269 | 21 | |||
270 | 22 | import sys | 19 | import sys |
271 | 23 | from setuptools import setup, find_packages | 20 | from setuptools import setup, find_packages |
272 | 24 | 21 | ||
273 | @@ -45,6 +42,7 @@ | |||
274 | 45 | namespace_packages=['lazr'], | 42 | namespace_packages=['lazr'], |
275 | 46 | packages=find_packages('src'), | 43 | packages=find_packages('src'), |
276 | 47 | package_dir={'':'src'}, | 44 | package_dir={'':'src'}, |
277 | 45 | package_data={'lazr.restfulclient': ['version.txt']}, | ||
278 | 48 | include_package_data=True, | 46 | include_package_data=True, |
279 | 49 | zip_safe=False, | 47 | zip_safe=False, |
280 | 50 | maintainer='LAZR Developers', | 48 | maintainer='LAZR Developers', |
281 | @@ -56,11 +54,9 @@ | |||
282 | 56 | license='LGPL v3', | 54 | license='LGPL v3', |
283 | 57 | install_requires=[ | 55 | install_requires=[ |
284 | 58 | 'httplib2', | 56 | 'httplib2', |
285 | 59 | 'lazr.authentication', | ||
286 | 60 | 'oauth', | 57 | 'oauth', |
287 | 61 | 'setuptools', | 58 | 'setuptools', |
288 | 62 | 'wadllib>=1.1.4', | 59 | 'wadllib>=1.1.4', |
289 | 63 | 'wsgi_intercept', | ||
290 | 64 | ], | 60 | ], |
291 | 65 | url='https://launchpad.net/lazr.restfulclient', | 61 | url='https://launchpad.net/lazr.restfulclient', |
292 | 66 | download_url= 'https://launchpad.net/lazr.restfulclient/+download', | 62 | download_url= 'https://launchpad.net/lazr.restfulclient/+download', |
293 | @@ -73,8 +69,11 @@ | |||
294 | 73 | extras_require=dict( | 69 | extras_require=dict( |
295 | 74 | docs=['Sphinx', | 70 | docs=['Sphinx', |
296 | 75 | 'z3c.recipe.sphinxdoc'], | 71 | 'z3c.recipe.sphinxdoc'], |
299 | 76 | test=['lazr.restful>=0.11.0', | 72 | test=[ |
300 | 77 | 'van.testing'], | 73 | 'lazr.authentication', |
301 | 74 | 'lazr.restful>=0.11.0', | ||
302 | 75 | 'wsgi_intercept', | ||
303 | 76 | ], | ||
304 | 78 | ), | 77 | ), |
305 | 79 | test_suite='lazr.restfulclient.tests', | 78 | test_suite='lazr.restfulclient.tests', |
306 | 80 | ) | 79 | ) |
307 | 81 | 80 | ||
308 | === modified file 'src/lazr/restfulclient/_browser.py' | |||
309 | --- src/lazr/restfulclient/_browser.py 2014-06-05 11:25:42 +0000 | |||
310 | +++ src/lazr/restfulclient/_browser.py 2014-07-28 15:39:09 +0000 | |||
311 | @@ -41,7 +41,6 @@ | |||
312 | 41 | from time import sleep | 41 | from time import sleep |
313 | 42 | from httplib2 import ( | 42 | from httplib2 import ( |
314 | 43 | Http, | 43 | Http, |
315 | 44 | SSLHandshakeError, | ||
316 | 45 | urlnorm, | 44 | urlnorm, |
317 | 46 | ) | 45 | ) |
318 | 47 | try: | 46 | try: |
319 | @@ -86,7 +85,12 @@ | |||
320 | 86 | """ | 85 | """ |
321 | 87 | 86 | ||
322 | 88 | try: | 87 | try: |
324 | 89 | if re_url_scheme.match(filename): | 88 | if isinstance(filename, unicode_type): |
325 | 89 | filename_match = filename.encode('utf-8') | ||
326 | 90 | else: | ||
327 | 91 | filename_match = filename | ||
328 | 92 | |||
329 | 93 | if re_url_scheme.match(filename_match): | ||
330 | 90 | if isinstance(filename, bytes): | 94 | if isinstance(filename, bytes): |
331 | 91 | filename = filename.decode('utf-8') | 95 | filename = filename.decode('utf-8') |
332 | 92 | filename = filename.encode('idna') | 96 | filename = filename.encode('idna') |
333 | @@ -97,8 +101,8 @@ | |||
334 | 97 | if isinstance(filename, unicode_type): | 101 | if isinstance(filename, unicode_type): |
335 | 98 | filename = filename.encode('utf-8') | 102 | filename = filename.encode('utf-8') |
336 | 99 | filemd5 = _md5(filename).hexdigest() | 103 | filemd5 = _md5(filename).hexdigest() |
339 | 100 | filename = re_url_scheme.sub("", filename) | 104 | filename = re_url_scheme.sub(b"", filename) |
340 | 101 | filename = re_slash.sub(",", filename) | 105 | filename = re_slash.sub(b",", filename) |
341 | 102 | 106 | ||
342 | 103 | # This is the part that we changed. In stock httplib2, the | 107 | # This is the part that we changed. In stock httplib2, the |
343 | 104 | # filename is trimmed if it's longer than 200 characters, and then | 108 | # filename is trimmed if it's longer than 200 characters, and then |
344 | @@ -118,7 +122,7 @@ | |||
345 | 118 | maximum_length_before_md5_sum = maximum_filename_length - 32 - 1 | 122 | maximum_length_before_md5_sum = maximum_filename_length - 32 - 1 |
346 | 119 | if len(filename) > maximum_length_before_md5_sum: | 123 | if len(filename) > maximum_length_before_md5_sum: |
347 | 120 | filename=filename[:maximum_length_before_md5_sum] | 124 | filename=filename[:maximum_length_before_md5_sum] |
349 | 121 | return ",".join((filename, filemd5)) | 125 | return ",".join((filename.decode('utf-8'), filemd5)) |
350 | 122 | 126 | ||
351 | 123 | 127 | ||
352 | 124 | def ssl_certificate_validation_disabled(): | 128 | def ssl_certificate_validation_disabled(): |
353 | @@ -162,7 +166,7 @@ | |||
354 | 162 | def _request(self, conn, host, absolute_uri, request_uri, method, body, | 166 | def _request(self, conn, host, absolute_uri, request_uri, method, body, |
355 | 163 | headers, redirections, cachekey): | 167 | headers, redirections, cachekey): |
356 | 164 | """Use the authorizer to authorize an outgoing request.""" | 168 | """Use the authorizer to authorize an outgoing request.""" |
358 | 165 | if headers.has_key('authorization'): | 169 | if 'authorization' in headers: |
359 | 166 | # There's an authorization header left over from a | 170 | # There's an authorization header left over from a |
360 | 167 | # previous request that resulted in a redirect. Resources | 171 | # previous request that resulted in a redirect. Resources |
361 | 168 | # protected by OAuth or HTTP Digest must send a distinct | 172 | # protected by OAuth or HTTP Digest must send a distinct |
362 | @@ -308,7 +312,6 @@ | |||
363 | 308 | key = key + '-' + self.request_media_type | 312 | key = key + '-' + self.request_media_type |
364 | 309 | return safename(key) | 313 | return safename(key) |
365 | 310 | 314 | ||
366 | 311 | |||
367 | 312 | def _getCachedHeader(self, uri, header): | 315 | def _getCachedHeader(self, uri, header): |
368 | 313 | """Retrieve a cached value for an HTTP header.""" | 316 | """Retrieve a cached value for an HTTP header.""" |
369 | 314 | (scheme, authority, request_uri, cachekey) = urlnorm(uri) | 317 | (scheme, authority, request_uri, cachekey) = urlnorm(uri) |
370 | @@ -370,25 +373,15 @@ | |||
371 | 370 | "don't have the server-side permission to see.") | 373 | "don't have the server-side permission to see.") |
372 | 371 | 374 | ||
373 | 372 | # Add extra headers for the request. | 375 | # Add extra headers for the request. |
375 | 373 | headers = {'Accept' : media_type} | 376 | headers = {'Accept': media_type} |
376 | 374 | if self.user_agent is not None: | 377 | if self.user_agent is not None: |
377 | 375 | headers['User-Agent'] = self.user_agent | 378 | headers['User-Agent'] = self.user_agent |
378 | 376 | if isinstance(self._connection.cache, MultipleRepresentationCache): | 379 | if isinstance(self._connection.cache, MultipleRepresentationCache): |
379 | 377 | self._connection.cache.request_media_type = media_type | 380 | self._connection.cache.request_media_type = media_type |
380 | 378 | if extra_headers is not None: | 381 | if extra_headers is not None: |
381 | 379 | headers.update(extra_headers) | 382 | headers.update(extra_headers) |
394 | 380 | # Make the request. | 383 | response, content = self._request_and_retry( |
395 | 381 | try: | 384 | str(url), method=method, body=data, headers=headers) |
384 | 382 | response, content = self._request_and_retry( | ||
385 | 383 | str(url), method=method, body=data, headers=headers) | ||
386 | 384 | except SSLHandshakeError, e: | ||
387 | 385 | msg = str(e) | ||
388 | 386 | if "SSL3_GET_SERVER_CERTIFICATE:certificate verify failed" in msg: | ||
389 | 387 | raise SSLHandshakeError( | ||
390 | 388 | "%s: perhaps set LP_DISABLE_SSL_CERTIFICATE_VALIDATION if " | ||
391 | 389 | "certificate validation failed and you genuinely trust the " | ||
392 | 390 | "remote server." % (e,)) | ||
393 | 391 | raise | ||
396 | 392 | if response.status == 304: | 385 | if response.status == 304: |
397 | 393 | # The resource didn't change. | 386 | # The resource didn't change. |
398 | 394 | if content == '': | 387 | if content == '': |
399 | @@ -447,10 +440,8 @@ | |||
400 | 447 | wadl_type = 'application/vnd.sun.wadl+xml' | 440 | wadl_type = 'application/vnd.sun.wadl+xml' |
401 | 448 | response, content = self._request(url, media_type=wadl_type) | 441 | response, content = self._request(url, media_type=wadl_type) |
402 | 449 | url = str(url) | 442 | url = str(url) |
403 | 450 | if not isinstance(url, bytes): | ||
404 | 451 | url = url.encode('utf-8') | ||
405 | 452 | if not isinstance(content, bytes): | 443 | if not isinstance(content, bytes): |
407 | 453 | content = content.encode('utf-8') | 444 | content = content.encode('utf-8') |
408 | 454 | return Application(url, content) | 445 | return Application(url, content) |
409 | 455 | 446 | ||
410 | 456 | def post(self, url, method_name, **kws): | 447 | def post(self, url, method_name, **kws): |
411 | 457 | 448 | ||
412 | === modified file 'src/lazr/restfulclient/authorize/oauth.py' | |||
413 | --- src/lazr/restfulclient/authorize/oauth.py 2012-06-04 19:54:58 +0000 | |||
414 | +++ src/lazr/restfulclient/authorize/oauth.py 2014-07-28 15:39:09 +0000 | |||
415 | @@ -159,7 +159,8 @@ | |||
416 | 159 | """ | 159 | """ |
417 | 160 | # Attempt to load the access token from the file. | 160 | # Attempt to load the access token from the file. |
418 | 161 | parser = SafeConfigParser() | 161 | parser = SafeConfigParser() |
420 | 162 | parser.readfp(readable_file) | 162 | reader = getattr(parser, 'read_file', parser.readfp) |
421 | 163 | reader(readable_file) | ||
422 | 163 | # Check the version number and extract the access token and | 164 | # Check the version number and extract the access token and |
423 | 164 | # secret. Then convert these to the appropriate instances. | 165 | # secret. Then convert these to the appropriate instances. |
424 | 165 | if not parser.has_section(CREDENTIALS_FILE_VERSION): | 166 | if not parser.has_section(CREDENTIALS_FILE_VERSION): |
425 | 166 | 167 | ||
426 | === modified file 'src/lazr/restfulclient/resource.py' | |||
427 | --- src/lazr/restfulclient/resource.py 2014-06-06 23:21:56 +0000 | |||
428 | +++ src/lazr/restfulclient/resource.py 2014-07-28 15:39:09 +0000 | |||
429 | @@ -55,6 +55,14 @@ | |||
430 | 55 | import types | 55 | import types |
431 | 56 | import urllib | 56 | import urllib |
432 | 57 | 57 | ||
433 | 58 | import sys | ||
434 | 59 | if sys.version_info[0] >= 3: | ||
435 | 60 | text_type = str | ||
436 | 61 | binary_type = bytes | ||
437 | 62 | else: | ||
438 | 63 | text_type = unicode | ||
439 | 64 | binary_type = str | ||
440 | 65 | |||
441 | 58 | from lazr.uri import URI | 66 | from lazr.uri import URI |
442 | 59 | from wadllib.application import Resource as WadlResource | 67 | from wadllib.application import Resource as WadlResource |
443 | 60 | 68 | ||
444 | @@ -371,7 +379,9 @@ | |||
445 | 371 | if self._wadl_resource.representation is None: | 379 | if self._wadl_resource.representation is None: |
446 | 372 | # Get a representation of the linked resource. | 380 | # Get a representation of the linked resource. |
447 | 373 | representation = self._root._browser.get(self._wadl_resource) | 381 | representation = self._root._browser.get(self._wadl_resource) |
449 | 374 | representation = loads(unicode(representation)) | 382 | if isinstance(representation, binary_type): |
450 | 383 | representation = representation.decode('utf-8') | ||
451 | 384 | representation = loads(text_type(representation)) | ||
452 | 375 | 385 | ||
453 | 376 | # In rare cases, the resource type served by the | 386 | # In rare cases, the resource type served by the |
454 | 377 | # server conflicts with the type the client thought | 387 | # server conflicts with the type the client thought |
455 | @@ -381,7 +391,7 @@ | |||
456 | 381 | # XXX This should probably be moved into a hook method | 391 | # XXX This should probably be moved into a hook method |
457 | 382 | # defined by Entry, since it's not relevant to other | 392 | # defined by Entry, since it's not relevant to other |
458 | 383 | # resource types. | 393 | # resource types. |
460 | 384 | if type(representation) == types.DictType: | 394 | if isinstance(representation, dict): |
461 | 385 | type_link = representation['resource_type_link'] | 395 | type_link = representation['resource_type_link'] |
462 | 386 | if (type_link is not None | 396 | if (type_link is not None |
463 | 387 | and type_link != self._wadl_resource.type_url): | 397 | and type_link != self._wadl_resource.type_url): |
464 | @@ -521,7 +531,7 @@ | |||
465 | 521 | url = str(self._root_uri.append(url)) | 531 | url = str(self._root_uri.append(url)) |
466 | 522 | document = self._browser.get(url) | 532 | document = self._browser.get(url) |
467 | 523 | try: | 533 | try: |
469 | 524 | representation = loads(unicode(document)) | 534 | representation = loads(text_type(document)) |
470 | 525 | except ValueError: | 535 | except ValueError: |
471 | 526 | raise ValueError("%s doesn't serve a JSON document." % url) | 536 | raise ValueError("%s doesn't serve a JSON document." % url) |
472 | 527 | type_link = representation.get("resource_type_link") | 537 | type_link = representation.get("resource_type_link") |
473 | @@ -574,7 +584,7 @@ | |||
474 | 574 | # and option values (because JSON-encoding them will screw | 584 | # and option values (because JSON-encoding them will screw |
475 | 575 | # up wadllib's parameter validation). The option value thing | 585 | # up wadllib's parameter validation). The option value thing |
476 | 576 | # is a little hacky, but it's the best solution for now. | 586 | # is a little hacky, but it's the best solution for now. |
478 | 577 | if not key in send_as_is_params: | 587 | if key not in send_as_is_params: |
479 | 578 | args[key] = dumps(value, cls=DatetimeJSONEncoder) | 588 | args[key] = dumps(value, cls=DatetimeJSONEncoder) |
480 | 579 | if http_method in ('get', 'head', 'delete'): | 589 | if http_method in ('get', 'head', 'delete'): |
481 | 580 | url = self.wadl_method.build_request_url(**args) | 590 | url = self.wadl_method.build_request_url(**args) |
482 | @@ -616,7 +626,7 @@ | |||
483 | 616 | HeaderDictionary(response)) | 626 | HeaderDictionary(response)) |
484 | 617 | wadl_parameter = wadl_response.get_parameter('Location') | 627 | wadl_parameter = wadl_response.get_parameter('Location') |
485 | 618 | wadl_resource = wadl_parameter.linked_resource | 628 | wadl_resource = wadl_parameter.linked_resource |
487 | 619 | # Fetch a representation of the new resource. | 629 | # Fetch a representation of the new resource. |
488 | 620 | response, content = self.root._browser._request( | 630 | response, content = self.root._browser._request( |
489 | 621 | wadl_resource.url) | 631 | wadl_resource.url) |
490 | 622 | # Return an instance of the appropriate lazr.restful | 632 | # Return an instance of the appropriate lazr.restful |
491 | @@ -637,13 +647,13 @@ | |||
492 | 637 | # The operation returned a document with nothing | 647 | # The operation returned a document with nothing |
493 | 638 | # special about it. | 648 | # special about it. |
494 | 639 | if content_type == self.JSON_MEDIA_TYPE: | 649 | if content_type == self.JSON_MEDIA_TYPE: |
496 | 640 | return loads(unicode(content)) | 650 | return loads(text_type(content)) |
497 | 641 | # We don't know how to process the content. | 651 | # We don't know how to process the content. |
498 | 642 | return content | 652 | return content |
499 | 643 | 653 | ||
500 | 644 | # The operation returned a representation of some | 654 | # The operation returned a representation of some |
501 | 645 | # resource. Instantiate a Resource object for it. | 655 | # resource. Instantiate a Resource object for it. |
503 | 646 | document = loads(unicode(content)) | 656 | document = loads(text_type(content)) |
504 | 647 | if document is None: | 657 | if document is None: |
505 | 648 | # The operation returned a null value. | 658 | # The operation returned a null value. |
506 | 649 | return document | 659 | return document |
507 | @@ -767,7 +777,7 @@ | |||
508 | 767 | if response.status == 209 and content_type == self.JSON_MEDIA_TYPE: | 777 | if response.status == 209 and content_type == self.JSON_MEDIA_TYPE: |
509 | 768 | # The server sent back a new representation of the object. | 778 | # The server sent back a new representation of the object. |
510 | 769 | # Use it in preference to the existing representation. | 779 | # Use it in preference to the existing representation. |
512 | 770 | new_representation = loads(unicode(content)) | 780 | new_representation = loads(text_type(content)) |
513 | 771 | self._wadl_resource.representation = new_representation | 781 | self._wadl_resource.representation = new_representation |
514 | 772 | self._wadl_resource.media_type = content_type | 782 | self._wadl_resource.media_type = content_type |
515 | 773 | 783 | ||
516 | @@ -786,7 +796,7 @@ | |||
517 | 786 | :rtype: int | 796 | :rtype: int |
518 | 787 | """ | 797 | """ |
519 | 788 | total_size = self.total_size | 798 | total_size = self.total_size |
521 | 789 | if type(total_size) == types.IntType: | 799 | if isinstance(total_size, int): |
522 | 790 | # The size was a number present in the collection | 800 | # The size was a number present in the collection |
523 | 791 | # representation. | 801 | # representation. |
524 | 792 | return total_size | 802 | return total_size |
525 | @@ -813,7 +823,7 @@ | |||
526 | 813 | if next_link is None: | 823 | if next_link is None: |
527 | 814 | break | 824 | break |
528 | 815 | current_page = loads( | 825 | current_page = loads( |
530 | 816 | unicode(self._root._browser.get(URI(next_link)))) | 826 | text_type(self._root._browser.get(URI(next_link)))) |
531 | 817 | 827 | ||
532 | 818 | def __getitem__(self, key): | 828 | def __getitem__(self, key): |
533 | 819 | """Look up a slice, or a subordinate resource by index. | 829 | """Look up a slice, or a subordinate resource by index. |
534 | @@ -886,7 +896,7 @@ | |||
535 | 886 | # Iterate over pages until we have the correct number of entries. | 896 | # Iterate over pages until we have the correct number of entries. |
536 | 887 | while more_needed > 0 and page_url is not None: | 897 | while more_needed > 0 and page_url is not None: |
537 | 888 | representation = loads( | 898 | representation = loads( |
539 | 889 | unicode(self._root._browser.get(page_url))) | 899 | text_type(self._root._browser.get(page_url))) |
540 | 890 | current_page_entries = representation['entries'] | 900 | current_page_entries = representation['entries'] |
541 | 891 | entry_dicts += current_page_entries[:more_needed] | 901 | entry_dicts += current_page_entries[:more_needed] |
542 | 892 | more_needed = desired_size - len(entry_dicts) | 902 | more_needed = desired_size - len(entry_dicts) |
543 | @@ -1011,7 +1021,7 @@ | |||
544 | 1011 | # the resource describes itself. | 1021 | # the resource describes itself. |
545 | 1012 | try: | 1022 | try: |
546 | 1013 | representation = loads( | 1023 | representation = loads( |
548 | 1014 | unicode(self._root._browser.get(url))) | 1024 | text_type(self._root._browser.get(url))) |
549 | 1015 | except HTTPError as error: | 1025 | except HTTPError as error: |
550 | 1016 | # There's no resource corresponding to the given ID. | 1026 | # There's no resource corresponding to the given ID. |
551 | 1017 | if error.response.status == 404: | 1027 | if error.response.status == 404: |
552 | 1018 | 1028 | ||
553 | === modified file 'src/lazr/restfulclient/tests/test_atomicfilecache.py' | |||
554 | --- src/lazr/restfulclient/tests/test_atomicfilecache.py 2012-06-04 19:54:58 +0000 | |||
555 | +++ src/lazr/restfulclient/tests/test_atomicfilecache.py 2014-07-28 15:39:09 +0000 | |||
556 | @@ -23,6 +23,13 @@ | |||
557 | 23 | import tempfile | 23 | import tempfile |
558 | 24 | import unittest | 24 | import unittest |
559 | 25 | 25 | ||
560 | 26 | import sys | ||
561 | 27 | PY3 = sys.version_info[0] >= 3 | ||
562 | 28 | if PY3: | ||
563 | 29 | binary_type = bytes | ||
564 | 30 | else: | ||
565 | 31 | binary_type = str | ||
566 | 32 | |||
567 | 26 | import httplib2 | 33 | import httplib2 |
568 | 27 | 34 | ||
569 | 28 | from lazr.restfulclient._browser import AtomicFileCache | 35 | from lazr.restfulclient._browser import AtomicFileCache |
570 | @@ -56,15 +63,15 @@ | |||
571 | 56 | def test_set_key(self): | 63 | def test_set_key(self): |
572 | 57 | # A key set with set() can be got by get(). | 64 | # A key set with set() can be got by get(). |
573 | 58 | cache = self.make_file_cache() | 65 | cache = self.make_file_cache() |
576 | 59 | cache.set('key', 'value') | 66 | cache.set('key', b'value') |
577 | 60 | self.assertEqual('value', cache.get('key')) | 67 | self.assertEqual(b'value', cache.get('key')) |
578 | 61 | 68 | ||
579 | 62 | def test_set_twice_overrides(self): | 69 | def test_set_twice_overrides(self): |
580 | 63 | # Setting a key again overrides the value. | 70 | # Setting a key again overrides the value. |
581 | 64 | cache = self.make_file_cache() | 71 | cache = self.make_file_cache() |
585 | 65 | cache.set('key', 'value') | 72 | cache.set('key', b'value') |
586 | 66 | cache.set('key', 'new-value') | 73 | cache.set('key', b'new-value') |
587 | 67 | self.assertEqual('new-value', cache.get('key')) | 74 | self.assertEqual(b'new-value', cache.get('key')) |
588 | 68 | 75 | ||
589 | 69 | def test_delete_absent_key(self): | 76 | def test_delete_absent_key(self): |
590 | 70 | # Deleting a key that's not there does nothing. | 77 | # Deleting a key that's not there does nothing. |
591 | @@ -76,7 +83,7 @@ | |||
592 | 76 | # A key once set can be deleted. Further attempts to get that key | 83 | # A key once set can be deleted. Further attempts to get that key |
593 | 77 | # return None. | 84 | # return None. |
594 | 78 | cache = self.make_file_cache() | 85 | cache = self.make_file_cache() |
596 | 79 | cache.set('key', 'value') | 86 | cache.set('key', b'value') |
597 | 80 | cache.delete('key') | 87 | cache.delete('key') |
598 | 81 | self.assertIs(None, cache.get('key')) | 88 | self.assertIs(None, cache.get('key')) |
599 | 82 | 89 | ||
600 | @@ -101,7 +108,7 @@ | |||
601 | 101 | # probably a bug in httplib2.FileCache. | 108 | # probably a bug in httplib2.FileCache. |
602 | 102 | cache = self.make_file_cache() | 109 | cache = self.make_file_cache() |
603 | 103 | self.assertRaises(TypeError, cache.set, 'answer', 42) | 110 | self.assertRaises(TypeError, cache.set, 'answer', 42) |
605 | 104 | self.assertEqual('', cache.get('answer')) | 111 | self.assertEqual(b'', cache.get('answer')) |
606 | 105 | 112 | ||
607 | 106 | def test_get_unicode(self): | 113 | def test_get_unicode(self): |
608 | 107 | # get() can retrieve unicode keys. | 114 | # get() can retrieve unicode keys. |
609 | @@ -110,19 +117,20 @@ | |||
610 | 110 | 117 | ||
611 | 111 | def test_set_unicode_keys(self): | 118 | def test_set_unicode_keys(self): |
612 | 112 | cache = self.make_file_cache() | 119 | cache = self.make_file_cache() |
615 | 113 | cache.set(self.unicode_text, 'value') | 120 | cache.set(self.unicode_text, b'value') |
616 | 114 | self.assertEqual('value', cache.get(self.unicode_text)) | 121 | self.assertEqual(b'value', cache.get(self.unicode_text)) |
617 | 115 | 122 | ||
618 | 116 | def test_set_unicode_value(self): | 123 | def test_set_unicode_value(self): |
619 | 117 | # set() cannot store unicode values. Values must be bytes. | 124 | # set() cannot store unicode values. Values must be bytes. |
620 | 118 | cache = self.make_file_cache() | 125 | cache = self.make_file_cache() |
621 | 126 | error = TypeError if PY3 else UnicodeEncodeError | ||
622 | 119 | self.assertRaises( | 127 | self.assertRaises( |
624 | 120 | UnicodeEncodeError, cache.set, 'key', self.unicode_text) | 128 | error, cache.set, 'key', self.unicode_text) |
625 | 121 | 129 | ||
626 | 122 | def test_delete_unicode(self): | 130 | def test_delete_unicode(self): |
627 | 123 | # delete() can remove unicode keys. | 131 | # delete() can remove unicode keys. |
628 | 124 | cache = self.make_file_cache() | 132 | cache = self.make_file_cache() |
630 | 125 | cache.set(self.unicode_text, 'value') | 133 | cache.set(self.unicode_text, b'value') |
631 | 126 | cache.delete(self.unicode_text) | 134 | cache.delete(self.unicode_text) |
632 | 127 | self.assertIs(None, cache.get(self.unicode_text)) | 135 | self.assertIs(None, cache.get(self.unicode_text)) |
633 | 128 | 136 | ||
634 | @@ -132,6 +140,12 @@ | |||
635 | 132 | 140 | ||
636 | 133 | file_cache_factory = AtomicFileCache | 141 | file_cache_factory = AtomicFileCache |
637 | 134 | 142 | ||
638 | 143 | @staticmethod | ||
639 | 144 | def prefix_safename(x): | ||
640 | 145 | if isinstance(x, binary_type): | ||
641 | 146 | x = x.decode('utf-8') | ||
642 | 147 | return AtomicFileCache.TEMPFILE_PREFIX + x | ||
643 | 148 | |||
644 | 135 | def test_set_non_string_value(self): | 149 | def test_set_non_string_value(self): |
645 | 136 | # set() raises TypeError if asked to set a key to a non-string value. | 150 | # set() raises TypeError if asked to set a key to a non-string value. |
646 | 137 | # Attempts to retrieve that value act is if it were never set. | 151 | # Attempts to retrieve that value act is if it were never set. |
647 | @@ -144,16 +158,16 @@ | |||
648 | 144 | # Implementation-specific tests follow. | 158 | # Implementation-specific tests follow. |
649 | 145 | 159 | ||
650 | 146 | def test_bad_safename_get(self): | 160 | def test_bad_safename_get(self): |
652 | 147 | safename = lambda x: AtomicFileCache.TEMPFILE_PREFIX + x | 161 | safename = self.prefix_safename |
653 | 148 | cache = AtomicFileCache(self.cache_dir, safename) | 162 | cache = AtomicFileCache(self.cache_dir, safename) |
654 | 149 | self.assertRaises(ValueError, cache.get, 'key') | 163 | self.assertRaises(ValueError, cache.get, 'key') |
655 | 150 | 164 | ||
656 | 151 | def test_bad_safename_set(self): | 165 | def test_bad_safename_set(self): |
658 | 152 | safename = lambda x: AtomicFileCache.TEMPFILE_PREFIX + x | 166 | safename = self.prefix_safename |
659 | 153 | cache = AtomicFileCache(self.cache_dir, safename) | 167 | cache = AtomicFileCache(self.cache_dir, safename) |
661 | 154 | self.assertRaises(ValueError, cache.set, 'key', 'value') | 168 | self.assertRaises(ValueError, cache.set, 'key', b'value') |
662 | 155 | 169 | ||
663 | 156 | def test_bad_safename_delete(self): | 170 | def test_bad_safename_delete(self): |
665 | 157 | safename = lambda x: AtomicFileCache.TEMPFILE_PREFIX + x | 171 | safename = self.prefix_safename |
666 | 158 | cache = AtomicFileCache(self.cache_dir, safename) | 172 | cache = AtomicFileCache(self.cache_dir, safename) |
667 | 159 | self.assertRaises(ValueError, cache.delete, 'key') | 173 | self.assertRaises(ValueError, cache.delete, 'key') |
668 | 160 | 174 | ||
669 | === modified file 'src/lazr/restfulclient/tests/test_error.py' | |||
670 | --- src/lazr/restfulclient/tests/test_error.py 2010-07-19 14:15:11 +0000 | |||
671 | +++ src/lazr/restfulclient/tests/test_error.py 2014-07-28 15:39:09 +0000 | |||
672 | @@ -39,10 +39,10 @@ | |||
673 | 39 | request = DummyRequest(status) | 39 | request = DummyRequest(status) |
674 | 40 | error = error_for(request, content) | 40 | error = error_for(request, content) |
675 | 41 | if expected_error is None: | 41 | if expected_error is None: |
677 | 42 | self.assertEquals(error, None) | 42 | self.assertIsNone(error) |
678 | 43 | else: | 43 | else: |
679 | 44 | self.assertTrue(isinstance(error, expected_error)) | 44 | self.assertTrue(isinstance(error, expected_error)) |
681 | 45 | self.assertEquals(content, error.content) | 45 | self.assertEqual(content, error.content) |
682 | 46 | 46 | ||
683 | 47 | def test_no_error_for_2xx(self): | 47 | def test_no_error_for_2xx(self): |
684 | 48 | """Make sure a 2xx response code yields no error.""" | 48 | """Make sure a 2xx response code yields no error.""" |
685 | 49 | 49 | ||
686 | === modified file 'src/lazr/restfulclient/tests/test_oauth.py' | |||
687 | --- src/lazr/restfulclient/tests/test_oauth.py 2010-10-28 22:22:32 +0000 | |||
688 | +++ src/lazr/restfulclient/tests/test_oauth.py 2014-07-28 15:39:09 +0000 | |||
689 | @@ -39,14 +39,14 @@ | |||
690 | 39 | 39 | ||
691 | 40 | def test_data_fields(self): | 40 | def test_data_fields(self): |
692 | 41 | consumer = Consumer("key", "secret", "application") | 41 | consumer = Consumer("key", "secret", "application") |
696 | 42 | self.assertEquals(consumer.key, "key") | 42 | self.assertEqual(consumer.key, "key") |
697 | 43 | self.assertEquals(consumer.secret, "secret") | 43 | self.assertEqual(consumer.secret, "secret") |
698 | 44 | self.assertEquals(consumer.application_name, "application") | 44 | self.assertEqual(consumer.application_name, "application") |
699 | 45 | 45 | ||
700 | 46 | def test_default_application_name(self): | 46 | def test_default_application_name(self): |
701 | 47 | # Application name defaults to None | 47 | # Application name defaults to None |
702 | 48 | consumer = Consumer("key", "secret") | 48 | consumer = Consumer("key", "secret") |
704 | 49 | self.assertEquals(consumer.application_name, None) | 49 | self.assertEqual(consumer.application_name, None) |
705 | 50 | 50 | ||
706 | 51 | 51 | ||
707 | 52 | class TestSystemWideConsumer(unittest.TestCase): | 52 | class TestSystemWideConsumer(unittest.TestCase): |
708 | @@ -105,7 +105,7 @@ | |||
709 | 105 | self._set_platform(('Fooix', 'String2', 'String3'), 'FooOS') | 105 | self._set_platform(('Fooix', 'String2', 'String3'), 'FooOS') |
710 | 106 | self._set_hostname("foo") | 106 | self._set_hostname("foo") |
711 | 107 | consumer = oauth.SystemWideConsumer("app name") | 107 | consumer = oauth.SystemWideConsumer("app name") |
713 | 108 | self.assertEquals( | 108 | self.assertEqual( |
714 | 109 | consumer.key, 'System-wide: Fooix (foo)') | 109 | consumer.key, 'System-wide: Fooix (foo)') |
715 | 110 | 110 | ||
716 | 111 | def test_empty_linux_distribution(self): | 111 | def test_empty_linux_distribution(self): |
717 | @@ -115,7 +115,7 @@ | |||
718 | 115 | self._set_platform(('', '', ''), 'BarOS') | 115 | self._set_platform(('', '', ''), 'BarOS') |
719 | 116 | self._set_hostname("bar") | 116 | self._set_hostname("bar") |
720 | 117 | consumer = oauth.SystemWideConsumer("app name") | 117 | consumer = oauth.SystemWideConsumer("app name") |
722 | 118 | self.assertEquals( | 118 | self.assertEqual( |
723 | 119 | consumer.key, 'System-wide: BarOS (bar)') | 119 | consumer.key, 'System-wide: BarOS (bar)') |
724 | 120 | 120 | ||
725 | 121 | def test_broken_linux_distribution(self): | 121 | def test_broken_linux_distribution(self): |
726 | @@ -125,7 +125,7 @@ | |||
727 | 125 | self._set_platform(self._broken, 'BazOS') | 125 | self._set_platform(self._broken, 'BazOS') |
728 | 126 | self._set_hostname("baz") | 126 | self._set_hostname("baz") |
729 | 127 | consumer = oauth.SystemWideConsumer("app name") | 127 | consumer = oauth.SystemWideConsumer("app name") |
731 | 128 | self.assertEquals( | 128 | self.assertEqual( |
732 | 129 | consumer.key, 'System-wide: BazOS (baz)') | 129 | consumer.key, 'System-wide: BazOS (baz)') |
733 | 130 | 130 | ||
734 | 131 | 131 | ||
735 | @@ -150,7 +150,7 @@ | |||
736 | 150 | 150 | ||
737 | 151 | # Make sure the file is readable and writable by the user, but | 151 | # Make sure the file is readable and writable by the user, but |
738 | 152 | # not by anyone else. | 152 | # not by anyone else. |
740 | 153 | self.assertEquals(stat.S_IMODE(os.stat(credentials_path).st_mode), | 153 | self.assertEqual(stat.S_IMODE(os.stat(credentials_path).st_mode), |
741 | 154 | stat.S_IREAD | stat.S_IWRITE) | 154 | stat.S_IREAD | stat.S_IWRITE) |
742 | 155 | 155 | ||
743 | 156 | loaded_credentials = OAuthAuthorizer.load_from_path(credentials_path) | 156 | loaded_credentials = OAuthAuthorizer.load_from_path(credentials_path) |
A few minor comments and one important question. (inline of course)