Merge lp:~dobey/ubuntuone-dev-tools/update-4-0 into lp:ubuntuone-dev-tools/stable-4-0

Proposed by dobey
Status: Merged
Approved by: dobey
Approved revision: no longer in the source branch.
Merged at revision: 81
Proposed branch: lp:~dobey/ubuntuone-dev-tools/update-4-0
Merge into: lp:ubuntuone-dev-tools/stable-4-0
Diff against target: 494 lines (+141/-51)
14 files modified
bin/u1lint (+24/-14)
run-tests (+5/-0)
ubuntuone/devtools/compat.py (+49/-0)
ubuntuone/devtools/handlers.py (+9/-7)
ubuntuone/devtools/runners/__init__.py (+5/-4)
ubuntuone/devtools/services/dbus.py (+7/-1)
ubuntuone/devtools/services/squid.py (+4/-2)
ubuntuone/devtools/services/tests/test_dbus.py (+7/-1)
ubuntuone/devtools/services/tests/test_squid.py (+4/-4)
ubuntuone/devtools/testcases/__init__.py (+4/-4)
ubuntuone/devtools/testcases/dbus.py (+8/-2)
ubuntuone/devtools/testing/tests/test_txwebserver.py (+11/-10)
ubuntuone/devtools/testing/txcheck.py (+1/-1)
ubuntuone/devtools/testing/txwebserver.py (+3/-1)
To merge this branch: bzr merge lp:~dobey/ubuntuone-dev-tools/update-4-0
Reviewer Review Type Date Requested Status
Eric Casteleijn (community) Approve
Review via email: mp+121704@code.launchpad.net

Commit message

[Brian Curtin]

    - Store a list for ignore keys rather than a list on Python 2 and an iterator on Python 3
    - Add support for a -3 flag to enable the tests to run against Python 3
    - Enable unicode_literals for accurate text/bytes distinction to work with Python 3
    - Prepare u1lint for Python 3 usage. Update imports for 3x and use the print function.
    - Convert unicode type usage to use the bytes/text compatibility layer.
    - Update octal literal use for Python 3
    - Import StringIO from the io module for Python 3 compatibility
    - Use items instead of iteritems for Python 3 compatibility.
    - Adjust exception handling to work on Python 3
    - Change to Python 3's print function usage via "from __future__ import print_function"
    - Move long usage to int.
    - Import urllib names by trying Python 3 first and falling back to Python 2
    - Add a small compatibility module for Python 2 and 3 Unicode/bytes distinction
    - Remove xrange usage, instead moving to range regardless of version.

To post a comment you must log in.
Revision history for this message
Eric Casteleijn (thisfred) :
review: Approve
81. By Brian Curtin

[Brian Curtin]

    - Store a list for ignore keys rather than a list on Python 2 and an iterator on Python 3
    - Add support for a -3 flag to enable the tests to run against Python 3
    - Enable unicode_literals for accurate text/bytes distinction to work with Python 3
    - Prepare u1lint for Python 3 usage. Update imports for 3x and use the print function.
    - Convert unicode type usage to use the bytes/text compatibility layer.
    - Update octal literal use for Python 3
    - Import StringIO from the io module for Python 3 compatibility
    - Use items instead of iteritems for Python 3 compatibility.
    - Adjust exception handling to work on Python 3
    - Change to Python 3's print function usage via "from __future__ import print_function"
    - Move long usage to int.
    - Import urllib names by trying Python 3 first and falling back to Python 2
    - Add a small compatibility module for Python 2 and 3 Unicode/bytes distinction
    - Remove xrange usage, instead moving to range regardless of version.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/u1lint'
2--- bin/u1lint 2012-06-08 11:55:53 +0000
3+++ bin/u1lint 2012-08-28 20:35:21 +0000
4@@ -28,7 +28,15 @@
5 # files in the program, then also delete it here.
6 """Wrapper script for pylint command."""
7
8-import ConfigParser
9+from __future__ import print_function
10+
11+# pylint: disable=F0401
12+try:
13+ import configparser
14+except ImportError:
15+ import ConfigParser as configparser
16+# pylint: disable=F0401
17+
18 import os
19 import subprocess
20 import sys
21@@ -54,31 +62,34 @@
22 return path
23
24 # pylint: disable=F0401
25- import _winreg
26+ try:
27+ import winreg
28+ except ImportError:
29+ import _winreg as winreg
30 # pylint: enable=F0401
31- software_key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'Software')
32+ software_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'Software')
33 python_key = None
34 try:
35- python_key = _winreg.OpenKey(software_key, 'Python')
36+ python_key = winreg.OpenKey(software_key, 'Python')
37 # pylint: disable=E0602
38 except WindowsError:
39 # pylint: enable=E0602
40 try:
41 # look in the WoW6432node, we are running python
42 # 32 on a 64 machine
43- wow6432node_key = _winreg.OpenKey(software_key, 'WoW6432Node')
44- python_key = _winreg.OpenKey(wow6432node_key, 'Python')
45+ wow6432node_key = winreg.OpenKey(software_key, 'WoW6432Node')
46+ python_key = winreg.OpenKey(wow6432node_key, 'Python')
47 # pylint: disable=E0602
48 except WindowsError:
49 # pylint: enable=E0602
50 raise InvalidSetupException(
51 'Could not located python installation path.')
52 try:
53- core_key = _winreg.OpenKey(python_key, 'PythonCore')
54+ core_key = winreg.OpenKey(python_key, 'PythonCore')
55 # pylint: disable=E1101
56- version_key = _winreg.OpenKey(core_key, sys.winver)
57+ version_key = winreg.OpenKey(core_key, sys.winver)
58 # pylint: enable=E1101
59- return _winreg.QueryValue(version_key, 'InstallPath')
60+ return winreg.QueryValue(version_key, 'InstallPath')
61 # pylint: disable=E0602
62 except WindowsError:
63 # pylint: enable=E0602
64@@ -139,13 +150,13 @@
65 def _read_pylintrc_ignored():
66 """Get the ignored files list from pylintrc"""
67 try:
68- config = ConfigParser.ConfigParser()
69+ config = configparser.ConfigParser()
70 config.read([PYLINTRC])
71
72 # pylint: disable=E1103
73 return [os.path.join(SRCDIR, item) for item in
74 config.get("MASTER", "ignore").split(",")]
75- except (TypeError, ConfigParser.NoOptionError):
76+ except (TypeError, configparser.NoOptionError):
77 return []
78 # pylint: enable=E1103
79
80@@ -245,10 +256,9 @@
81
82 output = "".join(notices.readlines())
83 if output != "":
84- print "== Python Lint Notices =="
85+ print("== Python Lint Notices ==")
86 (failed, grouped) = _group_lines_by_file(output)
87- print grouped
88- print ""
89+ print(grouped, end="\n\n")
90
91 returncode = sp.wait()
92 # XXX Testing that W0511 does not cause a failure
93
94=== modified file 'run-tests'
95--- run-tests 2012-07-27 19:02:53 +0000
96+++ run-tests 2012-08-28 20:35:21 +0000
97@@ -17,6 +17,11 @@
98
99 PYTHON="python"
100
101+if [ "$1" = "-3" ]
102+then
103+ PYTHON="python3"
104+fi
105+
106 $PYTHON bin/u1trial -i "test_squid_windows.py" -c ubuntuone
107 $PYTHON bin/u1trial --reactor=twisted -i "test_squid_windows.py" ubuntuone
108 echo "Running style checks..."
109
110=== added file 'ubuntuone/devtools/compat.py'
111--- ubuntuone/devtools/compat.py 1970-01-01 00:00:00 +0000
112+++ ubuntuone/devtools/compat.py 2012-08-28 20:35:21 +0000
113@@ -0,0 +1,49 @@
114+# -*- coding: utf-8 -*-
115+#
116+# Copyright 2012 Canonical Ltd.
117+#
118+# This program is free software: you can redistribute it and/or modify it
119+# under the terms of the GNU General Public License version 3, as published
120+# by the Free Software Foundation.
121+#
122+# This program is distributed in the hope that it will be useful, but
123+# WITHOUT ANY WARRANTY; without even the implied warranties of
124+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
125+# PURPOSE. See the GNU General Public License for more details.
126+#
127+# You should have received a copy of the GNU General Public License along
128+# with this program. If not, see <http://www.gnu.org/licenses/>.
129+#
130+# In addition, as a special exception, the copyright holders give
131+# permission to link the code of portions of this program with the
132+# OpenSSL library under certain conditions as described in each
133+# individual source file, and distribute linked combinations
134+# including the two.
135+# You must obey the GNU General Public License in all respects
136+# for all of the code used other than OpenSSL. If you modify
137+# file(s) with this exception, you may extend this exception to your
138+# version of the file(s), but you are not obligated to do so. If you
139+# do not wish to do so, delete this exception statement from your
140+# version. If you delete this exception statement from all source
141+# files in the program, then also delete it here.
142+"""Python 2 and 3 compatibility."""
143+
144+from __future__ import unicode_literals
145+
146+# The following approach was outlined in Lennart Regebro's
147+# "Porting to Python 3" book.
148+# http://python3porting.com/noconv.html#more-bytes-strings-and-unicode
149+
150+import sys
151+
152+# Disable redefined builtin, invalid name warning
153+# pylint: disable=W0622,C0103
154+
155+if sys.version_info < (3,):
156+ text_type = unicode
157+ binary_type = str
158+ basestring = basestring
159+else:
160+ text_type = str
161+ binary_type = bytes
162+ basestring = str
163
164=== modified file 'ubuntuone/devtools/handlers.py'
165--- ubuntuone/devtools/handlers.py 2012-04-04 19:13:46 +0000
166+++ ubuntuone/devtools/handlers.py 2012-08-28 20:35:21 +0000
167@@ -31,6 +31,8 @@
168 # files in the program, then also delete it here.
169 """Set of helpers handlers."""
170
171+from __future__ import print_function
172+
173 import logging
174
175
176@@ -51,15 +53,15 @@
177 def dump_contents(self, msgs):
178 """Dumps the contents of the MementoHandler."""
179 if self.debug:
180- print "Expecting:"
181+ print("Expecting:")
182 for msg in msgs:
183- print "\t", msg
184- print "MementoHandler contents:"
185+ print("\t", msg)
186+ print("MementoHandler contents:")
187 for rec in self.records:
188- print "\t", rec.exc_info
189- print "\t", logging.getLevelName(rec.levelno)
190- print "\t\t", rec.message
191- print "\t\t", rec.exc_text
192+ print("\t", rec.exc_info)
193+ print("\t", logging.getLevelName(rec.levelno))
194+ print("\t\t", rec.message)
195+ print("\t\t", rec.exc_text)
196
197 def check(self, level, *msgs):
198 """Verifies that the msgs are logged in the specified level"""
199
200=== modified file 'ubuntuone/devtools/runners/__init__.py'
201--- ubuntuone/devtools/runners/__init__.py 2012-08-13 21:07:54 +0000
202+++ ubuntuone/devtools/runners/__init__.py 2012-08-28 20:35:21 +0000
203@@ -39,6 +39,7 @@
204 from ubuntuone.devtools.errors import TestError, UsageError
205 from ubuntuone.devtools.testing.txcheck import TXCheckSuite
206 from ubuntuone.devtools.utils import OptionParser
207+from ubuntuone.devtools.compat import text_type
208
209 __all__ = ['BaseTestOptions', 'BaseTestRunner', 'main']
210
211@@ -173,7 +174,7 @@
212 if config['loop']:
213 old_suite = suite
214 suite = unittest.TestSuite()
215- for _ in xrange(config['loop']):
216+ for _ in range(config['loop']):
217 suite.addTest(old_suite)
218
219 return suite
220@@ -212,18 +213,18 @@
221 """Comma-separate list of test modules to ignore,
222 e.g: test_gtk.py, test_account.py
223 """
224- self['ignore-modules'] = map(unicode.strip, option.split(','))
225+ self['ignore-modules'] = list(map(text_type.strip, option.split(',')))
226
227 def opt_ignore_paths(self, option):
228 """Comma-separated list of relative paths to ignore,
229 e.g: tests/platform/windows, tests/platform/macosx
230 """
231- self['ignore-paths'] = map(unicode.strip, option.split(','))
232+ self['ignore-paths'] = list(map(text_type.strip, option.split(',')))
233
234 def opt_loop(self, option):
235 """Loop tests the specified number of times."""
236 try:
237- self['loop'] = long(option)
238+ self['loop'] = int(option)
239 except ValueError:
240 raise UsageError('A positive integer value must be specified.')
241
242
243=== modified file 'ubuntuone/devtools/services/dbus.py'
244--- ubuntuone/devtools/services/dbus.py 2012-03-30 17:44:03 +0000
245+++ ubuntuone/devtools/services/dbus.py 2012-08-28 20:35:21 +0000
246@@ -34,7 +34,13 @@
247 import subprocess
248
249 from distutils.spawn import find_executable
250-from urllib import quote
251+
252+# pylint: disable=F0401,E0611
253+try:
254+ from urllib.parse import quote
255+except ImportError:
256+ from urllib import quote
257+# pylint: enable=F0401,E0611
258
259 from ubuntuone.devtools.services import find_config_file
260 DBUS_CONFIG_FILE = 'dbus-session.conf.in'
261
262=== modified file 'ubuntuone/devtools/services/squid.py'
263--- ubuntuone/devtools/services/squid.py 2012-06-05 20:52:54 +0000
264+++ ubuntuone/devtools/services/squid.py 2012-08-28 20:35:21 +0000
265@@ -27,6 +27,8 @@
266 # files in the program, then also delete it here.
267 """Utilities for finding and running a squid proxy for testing."""
268
269+from __future__ import print_function
270+
271 import random
272 import signal
273 # pylint:disable=W0402
274@@ -263,7 +265,7 @@
275 def _is_squid_running(self):
276 """Return if squid is running."""
277 squid_args = ['-k', 'check', '-f', self.config_file]
278- print 'Starting squid version...'
279+ print('Starting squid version...')
280 message = 'Waiting for squid to start...'
281 for timeout in (0.4, 0.1, 0.1, 0.2, 0.5, 1, 3, 5):
282 try:
283@@ -274,7 +276,7 @@
284 return True
285 except subprocess.CalledProcessError:
286 message += '.'
287- print message
288+ print(message)
289 time.sleep(timeout)
290 return False
291
292
293=== modified file 'ubuntuone/devtools/services/tests/test_dbus.py'
294--- ubuntuone/devtools/services/tests/test_dbus.py 2012-03-30 17:44:03 +0000
295+++ ubuntuone/devtools/services/tests/test_dbus.py 2012-08-28 20:35:21 +0000
296@@ -32,7 +32,13 @@
297
298 from ubuntuone.devtools.testcases.dbus import DBusTestCase
299 from ubuntuone.devtools.services.dbus import DBusRunner
300-from urllib import unquote
301+
302+# pylint: disable=F0401,E0611
303+try:
304+ from urllib.parse import unquote
305+except ImportError:
306+ from urllib import unquote
307+# pylint: enable=F0401,E0611
308
309
310 class TestWithDBus(DBusTestCase):
311
312=== modified file 'ubuntuone/devtools/services/tests/test_squid.py'
313--- ubuntuone/devtools/services/tests/test_squid.py 2012-04-24 17:58:16 +0000
314+++ ubuntuone/devtools/services/tests/test_squid.py 2012-08-28 20:35:21 +0000
315@@ -30,7 +30,7 @@
316 import json
317 import os
318
319-from StringIO import StringIO
320+from io import BytesIO
321
322 from twisted.internet import defer
323
324@@ -237,7 +237,7 @@
325 self._assert_missing_binary('htpasswd')
326
327
328-class Pipe(StringIO):
329+class Pipe(BytesIO):
330 """A read write pipe."""
331
332 def read(self):
333@@ -364,8 +364,8 @@
334 def test_start_error(self):
335 """Test that we do raise an exception correctly."""
336 # set the error in the pipes
337- out = 'Normal out'
338- err = 'Error goes here'
339+ out = b'Normal out'
340+ err = b'Error goes here'
341 self.subprocess.stdout.write(out)
342 self.subprocess.stderr.write(err)
343 no_op = lambda _: None
344
345=== modified file 'ubuntuone/devtools/testcases/__init__.py'
346--- ubuntuone/devtools/testcases/__init__.py 2012-06-08 11:55:53 +0000
347+++ ubuntuone/devtools/testcases/__init__.py 2012-08-28 20:35:21 +0000
348@@ -169,19 +169,19 @@
349 return
350 # change perms to rw, so we can delete the temp dir
351 if path != getattr(self, '__root', None):
352- os.chmod(os.path.dirname(path), 0755)
353+ os.chmod(os.path.dirname(path), 0o755)
354 if not os.access(path, os.W_OK):
355- os.chmod(path, 0755)
356+ os.chmod(path, 0o755)
357 # pylint: disable=W0612
358 for dirpath, dirs, files in os.walk(path):
359 for dirname in dirs:
360 if not os.access(os.path.join(dirpath, dirname), os.W_OK):
361- os.chmod(os.path.join(dirpath, dirname), 0777)
362+ os.chmod(os.path.join(dirpath, dirname), 0o777)
363 shutil.rmtree(path)
364
365 def makedirs(self, path):
366 """Custom makedirs that handle ro parent."""
367 parent = os.path.dirname(path)
368 if os.path.exists(parent):
369- os.chmod(parent, 0755)
370+ os.chmod(parent, 0o755)
371 os.makedirs(path)
372
373=== modified file 'ubuntuone/devtools/testcases/dbus.py'
374--- ubuntuone/devtools/testcases/dbus.py 2012-07-27 19:02:53 +0000
375+++ ubuntuone/devtools/testcases/dbus.py 2012-08-28 20:35:21 +0000
376@@ -45,7 +45,7 @@
377 # pylint: disable=F0401,C0103,W0406,E0611
378 try:
379 import dbus
380-except ImportError, e:
381+except ImportError as e:
382 dbus = None
383
384 try:
385@@ -93,7 +93,13 @@
386 yield super(DBusTestCase, self).setUp()
387
388 # We need to ensure DBUS_SESSION_BUS_ADDRESS is private here
389- from urllib import unquote
390+ # pylint: disable=F0401,E0611
391+ try:
392+ from urllib.parse import unquote
393+ except ImportError:
394+ from urllib import unquote
395+ # pylint: enable=F0401,E0611
396+
397 bus_address = os.environ.get('DBUS_SESSION_BUS_ADDRESS', None)
398 if os.path.dirname(unquote(bus_address.split(',')[0].split('=')[1])) \
399 != os.path.dirname(os.getcwd()):
400
401=== modified file 'ubuntuone/devtools/testing/tests/test_txwebserver.py'
402--- ubuntuone/devtools/testing/tests/test_txwebserver.py 2012-04-17 15:53:14 +0000
403+++ ubuntuone/devtools/testing/tests/test_txwebserver.py 2012-08-28 20:35:21 +0000
404@@ -28,6 +28,7 @@
405
406 """Test the twisted webserver."""
407
408+from __future__ import unicode_literals
409
410 from twisted.internet import defer
411 from twisted.trial.unittest import TestCase
412@@ -36,13 +37,13 @@
413 from ubuntuone.devtools.testing.txwebserver import HTTPWebServer
414
415
416-SAMPLE_KEY = "result"
417-SAMPLE_VALUE = "sample result"
418-SAMPLE_RESOURCE = '{{"{0}": "{1}"}}'.format(SAMPLE_KEY, SAMPLE_VALUE)
419-SIMPLERESOURCE = "simpleresource"
420-OTHER_SIMPLERESOURCE = "othersimpleresource"
421-THROWERROR = "throwerror"
422-UNAUTHORIZED = "unauthorized"
423+SAMPLE_KEY = b"result"
424+SAMPLE_VALUE = b"sample result"
425+SAMPLE_RESOURCE = b'{{"{0}": "{1}"}}'.format(SAMPLE_KEY, SAMPLE_VALUE)
426+SIMPLERESOURCE = b"simpleresource"
427+OTHER_SIMPLERESOURCE = b"othersimpleresource"
428+THROWERROR = b"throwerror"
429+UNAUTHORIZED = b"unauthorized"
430
431 # no init
432 # pylint: disable=W0232
433@@ -76,7 +77,7 @@
434 root.putChild(UNAUTHORIZED, unauthorized_resource)
435 self.server = HTTPWebServer(root)
436 self.server.start()
437- self.uri = "http://127.0.0.1:{port}/".format(
438+ self.uri = b"http://127.0.0.1:{port}/".format(
439 port=self.server.get_port())
440 self.addCleanup(self.server.stop)
441
442@@ -104,7 +105,7 @@
443
444 def test_get_iri(self):
445 """Test getting the iri from the server."""
446- expected = u"http://127.0.0.1:{port}/"
447+ expected = "http://127.0.0.1:{port}/"
448 self.assert_url(expected)
449
450 def test_get_port(self):
451@@ -133,7 +134,7 @@
452
453 def get_uri(self, server):
454 """Return the uri for the server."""
455- url = "http://127.0.0.1:{port}/"
456+ url = b"http://127.0.0.1:{port}/"
457 return url.format(port=server.get_port())
458
459 @defer.inlineCallbacks
460
461=== modified file 'ubuntuone/devtools/testing/txcheck.py'
462--- ubuntuone/devtools/testing/txcheck.py 2012-03-30 17:44:03 +0000
463+++ ubuntuone/devtools/testing/txcheck.py 2012-08-28 20:35:21 +0000
464@@ -70,7 +70,7 @@
465 def __hash__(self):
466 """Return hash."""
467 member_hash = 0
468- for (key, value) in self.__dict__.iteritems():
469+ for (key, value) in self.__dict__.items():
470 member_hash ^= hash(key) ^ hash(value)
471 return hash(type(self)) ^ member_hash
472
473
474=== modified file 'ubuntuone/devtools/testing/txwebserver.py'
475--- ubuntuone/devtools/testing/txwebserver.py 2012-04-26 11:23:19 +0000
476+++ ubuntuone/devtools/testing/txwebserver.py 2012-08-28 20:35:21 +0000
477@@ -28,6 +28,8 @@
478
479 """A tx based web server."""
480
481+from __future__ import unicode_literals
482+
483 from twisted.internet import defer, reactor, ssl
484 from twisted.protocols.policies import WrappingFactory
485 from twisted.web import server
486@@ -65,7 +67,7 @@
487
488 def get_iri(self):
489 """Build the iri for this mock server."""
490- return u"{scheme}://127.0.0.1:{port}/".format(scheme=self.scheme,
491+ return "{scheme}://127.0.0.1:{port}/".format(scheme=self.scheme,
492 port=self.get_port())
493
494 def get_port(self):

Subscribers

People subscribed via source and target branches

to all changes: