[Autotest][PY3] Migrating client/common_lib (time_utils_unittest -> end)
Migrating client/common_lib from time_utils_unittest.py to the end of the dir to python3.
time_utils_unittest, utils_unittest passed. Both client/server tests passed.
utils.py is a major backbone of autotest, so this CL should likely be watched
carefully as it merges.
BUG=chromium:990593
TEST= py_compile in py2 and py3. CQ. dummy_Pass. applicable_unittest
Change-Id: If9f1b20e7c280475a9153fccef4c2f51e327019e
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2460722
Reviewed-by: Gregory Nisbet <gregorynisbet@google.com>
Reviewed-by: Greg Edelston <gredelston@google.com>
Commit-Queue: Derek Beckett <dbeckett@chromium.org>
Tested-by: Derek Beckett <dbeckett@chromium.org>
diff --git a/client/common_lib/cros/dev_server.py b/client/common_lib/cros/dev_server.py
index 843c518..b2dbb46 100644
--- a/client/common_lib/cros/dev_server.py
+++ b/client/common_lib/cros/dev_server.py
@@ -1,26 +1,33 @@
+# Lint as: python2, python3
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
from distutils import version
-import cStringIO
-import HTMLParser
-import httplib
import json
import logging
import multiprocessing
import os
import re
+import six
+from six.moves import urllib
+import six.moves.html_parser
+import six.moves.http_client
+import six.moves.urllib.parse
import time
-import urllib2
-import urlparse
from autotest_lib.client.bin import utils as bin_utils
from autotest_lib.client.common_lib import android_utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import global_config
+from autotest_lib.client.common_lib import seven
from autotest_lib.client.common_lib import utils
from autotest_lib.client.common_lib.cros import retry
+
# TODO(cmasone): redo this class using requests module; http://crosbug.com/30107
try:
@@ -139,7 +146,7 @@
pass
-class MarkupStripper(HTMLParser.HTMLParser):
+class MarkupStripper(six.moves.html_parser.HTMLParser):
"""HTML parser that strips HTML tags, coded characters like &
Works by, basically, not doing anything for any tags, and only recording
@@ -169,7 +176,7 @@
"""
strip = MarkupStripper()
try:
- strip.feed(message.decode('utf_32'))
+ strip.feed(seven.ensure_text(message, 'utf_32'))
except UnicodeDecodeError:
strip.feed(message)
return strip.get_data()
@@ -236,7 +243,7 @@
@param address: IP address string
@returns: hostname string, or original input if not found
"""
- for hostname, addr in _get_hostname_addr_map().iteritems():
+ for hostname, addr in six.iteritems(_get_hostname_addr_map()):
if addr == address:
return hostname
return address
@@ -272,7 +279,7 @@
def inner_decorator(method):
label = method.__name__ if hasattr(method, '__name__') else None
def metrics_wrapper(*args, **kwargs):
- @retry.retry((urllib2.URLError, error.CmdError,
+ @retry.retry((urllib.error.URLError, error.CmdError,
DevServerOverloadException),
timeout_min=timeout_min,
exception_to_raise=exception_to_raise,
@@ -281,7 +288,7 @@
"""This wrapper actually catches the HTTPError."""
try:
return method(*args, **kwargs)
- except urllib2.HTTPError as e:
+ except urllib.error.HTTPError as e:
error_markup = e.read()
raise DevServerException(_strip_http_message(error_markup))
@@ -317,7 +324,7 @@
@param url: a Url string
@return: a hostname string
"""
- return urlparse.urlparse(url).hostname
+ return six.moves.urllib.parse.urlparse(url).hostname
def get_resolved_hostname(url):
@@ -399,7 +406,7 @@
@return A devserver url, e.g., http://127.0.0.10:8080
"""
- res = urlparse.urlparse(url)
+ res = six.moves.urllib.parse.urlparse(url)
if res.netloc:
return res.scheme + '://' + res.netloc
@@ -438,7 +445,7 @@
return cls.run_call(call, timeout=timeout_min*60)
try:
- return json.load(cStringIO.StringIO(get_load(devserver=devserver)))
+ return json.load(six.StringIO(get_load(devserver=devserver)))
except Exception as e:
logging.error('Devserver call failed: "%s", timeout: %s seconds,'
' Error: %s', call, timeout_min * 60, e)
@@ -557,8 +564,10 @@
archive_url_args = _gs_or_local_archive_url_args(
kwargs.pop('archive_url', None))
kwargs.update(archive_url_args)
-
- argstr = '&'.join(map(lambda x: "%s=%s" % x, kwargs.iteritems()))
+ if 'is_async' in kwargs:
+ f = kwargs.pop('is_async')
+ kwargs['async'] = f
+ argstr = '&'.join(["%s=%s" % x for x in six.iteritems(kwargs)])
return "%(host)s/%(method)s?%(argstr)s" % dict(
host=host, method=method, argstr=argstr)
@@ -609,10 +618,10 @@
return utils.urlopen_socket_timeout(
call, timeout=timeout).read()
elif readline:
- response = urllib2.urlopen(call)
+ response = urllib.request.urlopen(call)
return [line.rstrip() for line in response]
else:
- return urllib2.urlopen(call).read()
+ return urllib.request.urlopen(call).read()
@staticmethod
@@ -853,8 +862,8 @@
if request.status_code == requests.codes.OK:
return request.text
- error_fd = cStringIO.StringIO(request.text)
- raise urllib2.HTTPError(
+ error_fd = six.StringIO(request.text)
+ raise urllib.error.HTTPError(
call, request.status_code, request.text, request.headers,
error_fd)
@@ -1060,10 +1069,10 @@
result = self.run_call(call)
logging.debug('whether artifact is staged: %r', result)
return result == 'True'
- except urllib2.HTTPError as e:
+ except urllib.error.HTTPError as e:
error_markup = e.read()
raise DevServerException(_strip_http_message(error_markup))
- except urllib2.URLError as e:
+ except urllib.error.URLError as e:
# Could be connection issue, retry it.
# For example: <urlopen error [Errno 111] Connection refused>
logging.error('URLError happens in is_stage: %r', e)
@@ -1099,7 +1108,7 @@
@raise DevServerException upon any return code that's expected_response.
"""
- call = self.build_call(call_name, async=True, **kwargs)
+ call = self.build_call(call_name, is_async=True, **kwargs)
try:
response = self.run_call(call)
logging.debug('response for RPC: %r', response)
@@ -1108,7 +1117,7 @@
'will retry in 30 seconds')
time.sleep(30)
raise DevServerOverloadException()
- except httplib.BadStatusLine as e:
+ except six.moves.http_client.BadStatusLine as e:
logging.error(e)
raise DevServerException('Received Bad Status line, Devserver %s '
'might have gone down while handling '
@@ -1320,11 +1329,11 @@
else:
build_path = build
kwargs['build'] = build
- call = self.build_call('locate_file', async=False, **kwargs)
+ call = self.build_call('locate_file', is_async=False, **kwargs)
try:
file_path = self.run_call(call)
return os.path.join(self.url(), 'static', build_path, file_path)
- except httplib.BadStatusLine as e:
+ except six.moves.http_client.BadStatusLine as e:
logging.error(e)
raise DevServerException('Received Bad Status line, Devserver %s '
'might have gone down while handling '
@@ -1382,7 +1391,7 @@
build = self.translate(build)
call = self.build_call('list_suite_controls', build=build,
suite_name=suite_name)
- return json.load(cStringIO.StringIO(self.run_call(call)))
+ return json.load(six.StringIO(self.run_call(call)))
class ImageServer(ImageServerBase):
@@ -1542,7 +1551,7 @@
call = self.build_call('setup_telemetry', archive_url=archive_url)
try:
response = self.run_call(call)
- except httplib.BadStatusLine as e:
+ except six.moves.http_client.BadStatusLine as e:
logging.error(e)
raise DevServerException('Received Bad Status line, Devserver %s '
'might have gone down while handling '
diff --git a/client/common_lib/cros/dev_server_unittest.py b/client/common_lib/cros/dev_server_unittest.py
index 2338b68..a923cbd 100755
--- a/client/common_lib/cros/dev_server_unittest.py
+++ b/client/common_lib/cros/dev_server_unittest.py
@@ -6,14 +6,14 @@
"""Unit tests for client/common_lib/cros/dev_server.py."""
-import httplib
+import six.moves.http_client
import json
import mox
import os
-import StringIO
+import six
+from six.moves import urllib
import time
import unittest
-import urllib2
import mock
@@ -64,16 +64,16 @@
self.result_obj = MockSshResponse('error', exit_status=255)
-E403 = urllib2.HTTPError(url='',
- code=httplib.FORBIDDEN,
+E403 = urllib.error.HTTPError(url='',
+ code=six.moves.http_client.FORBIDDEN,
msg='Error 403',
hdrs=None,
- fp=StringIO.StringIO('Expected.'))
-E500 = urllib2.HTTPError(url='',
- code=httplib.INTERNAL_SERVER_ERROR,
+ fp=six.StringIO('Expected.'))
+E500 = urllib.error.HTTPError(url='',
+ code=six.moves.http_client.INTERNAL_SERVER_ERROR,
msg='Error 500',
hdrs=None,
- fp=StringIO.StringIO('Expected.'))
+ fp=six.StringIO('Expected.'))
CMD_ERROR = error.CmdError('error_cmd', MockSshError().result_obj)
@@ -88,7 +88,7 @@
self.contents_readline = ['file/one', 'file/two']
self.save_ssh_config = dev_server.ENABLE_SSH_CONNECTION_FOR_DEVSERVER
super(RunCallTest, self).setUp()
- self.mox.StubOutWithMock(urllib2, 'urlopen')
+ self.mox.StubOutWithMock(urllib.request, 'urlopen')
self.mox.StubOutWithMock(utils, 'run')
sleep = mock.patch('time.sleep', autospec=True)
@@ -107,11 +107,11 @@
(call)."""
dev_server.ENABLE_SSH_CONNECTION_FOR_DEVSERVER = False
- urllib2.urlopen(mox.StrContains(self.test_call)).AndReturn(
- StringIO.StringIO(dev_server.ERR_MSG_FOR_DOWN_DEVSERVER))
+ urllib.request.urlopen(mox.StrContains(self.test_call)).AndReturn(
+ six.StringIO(dev_server.ERR_MSG_FOR_DOWN_DEVSERVER))
time.sleep(mox.IgnoreArg())
- urllib2.urlopen(mox.StrContains(self.test_call)).AndReturn(
- StringIO.StringIO(self.contents))
+ urllib.request.urlopen(mox.StrContains(self.test_call)).AndReturn(
+ six.StringIO(self.contents))
self.mox.ReplayAll()
response = dev_server.ImageServerBase.run_call(self.test_call)
self.assertEquals(self.contents, response)
@@ -145,8 +145,8 @@
(call)."""
dev_server.ENABLE_SSH_CONNECTION_FOR_DEVSERVER = False
- urllib2.urlopen(mox.StrContains(self.test_call)).AndReturn(
- StringIO.StringIO(self.contents))
+ urllib.request.urlopen(mox.StrContains(self.test_call)).AndReturn(
+ six.StringIO(self.contents))
self.mox.ReplayAll()
response = dev_server.ImageServerBase.run_call(self.test_call)
self.assertEquals(self.contents, response)
@@ -157,8 +157,8 @@
(call, readline=True)."""
dev_server.ENABLE_SSH_CONNECTION_FOR_DEVSERVER = False
- urllib2.urlopen(mox.StrContains(self.test_call)).AndReturn(
- StringIO.StringIO('\n'.join(self.contents_readline)))
+ urllib.request.urlopen(mox.StrContains(self.test_call)).AndReturn(
+ six.StringIO('\n'.join(self.contents_readline)))
self.mox.ReplayAll()
response = dev_server.ImageServerBase.run_call(
self.test_call, readline=True)
@@ -170,8 +170,8 @@
(call, timeout=xxx)."""
dev_server.ENABLE_SSH_CONNECTION_FOR_DEVSERVER = False
- urllib2.urlopen(mox.StrContains(self.test_call), data=None).AndReturn(
- StringIO.StringIO(self.contents))
+ urllib.request.urlopen(mox.StrContains(self.test_call), data=None).AndReturn(
+ six.StringIO(self.contents))
self.mox.ReplayAll()
response = dev_server.ImageServerBase.run_call(
self.test_call, timeout=60)
@@ -235,9 +235,9 @@
"""Test dev_server.ImageServerBase.run_call using http with raising
exception."""
dev_server.ENABLE_SSH_CONNECTION_FOR_DEVSERVER = False
- urllib2.urlopen(mox.StrContains(self.test_call)).AndRaise(E500)
+ urllib.request.urlopen(mox.StrContains(self.test_call)).AndRaise(E500)
self.mox.ReplayAll()
- self.assertRaises(urllib2.HTTPError,
+ self.assertRaises(urllib.error.HTTPError,
dev_server.ImageServerBase.run_call,
self.test_call)
@@ -262,9 +262,9 @@
def testRunCallByDevServerHTTP(self):
"""Test dev_server.DevServer.run_call, which uses http, and can be
directly called by CrashServer."""
- urllib2.urlopen(
+ urllib.request.urlopen(
mox.StrContains(self.test_call), data=None).AndReturn(
- StringIO.StringIO(self.contents))
+ six.StringIO(self.contents))
self.mox.ReplayAll()
response = dev_server.DevServer.run_call(
self.test_call, timeout=60)
@@ -290,7 +290,7 @@
self.android_dev_server = dev_server.AndroidBuildServer(
DevServerTest._HOST)
self.mox.StubOutWithMock(dev_server.ImageServerBase, 'run_call')
- self.mox.StubOutWithMock(urllib2, 'urlopen')
+ self.mox.StubOutWithMock(urllib.request, 'urlopen')
self.mox.StubOutWithMock(utils, 'run')
self.mox.StubOutWithMock(os.path, 'exists')
# Hide local restricted_subnets setting.
@@ -360,7 +360,7 @@
# Mock out bad ping failure to bad_host by raising devserver exception.
dev_server.ImageServerBase.run_call(
argument1, timeout=mox.IgnoreArg()).MultipleTimes().AndRaise(
- urllib2.URLError('urlopen connection timeout'))
+ urllib.error.URLError('urlopen connection timeout'))
# Good host is good.
dev_server.ImageServerBase.run_call(
@@ -443,7 +443,7 @@
"""Should retry on URLError, but pass through real exception."""
self.mox.StubOutWithMock(time, 'sleep')
- refused = urllib2.URLError('[Errno 111] Connection refused')
+ refused = urllib.error.URLError('[Errno 111] Connection refused')
dev_server.ImageServerBase.run_call(
mox.IgnoreArg()).AndRaise(refused)
time.sleep(mox.IgnoreArg())
diff --git a/client/common_lib/seven.py b/client/common_lib/seven.py
index f766ed3..4b6fd65 100644
--- a/client/common_lib/seven.py
+++ b/client/common_lib/seven.py
@@ -11,12 +11,29 @@
import six
import six.moves.configparser
import socket
+import sys
+import types
+
if six.PY3:
import builtins
SOCKET_ERRORS = (builtins.ConnectionError, socket.timeout, socket.gaierror,
socket.herror)
+ string_types = (str,)
+ integer_types = (int,)
+ class_types = (type,)
+ text_type = str
+ binary_type = bytes
+
+ MAXSIZE = sys.maxsize
else:
SOCKET_ERRORS = (socket.error, )
+ string_types = (basestring,)
+ integer_types = (int, long)
+ class_types = (type, types.ClassType)
+ text_type = unicode
+ binary_type = str
+
+ MAXSIZE = float("inf")
def exec_file(filename, globals_, locals_):
@@ -56,3 +73,21 @@
if six.PY3:
return six.moves.configparser.ConfigParser(strict=False)
return six.moves.configparser.ConfigParser()
+
+
+def ensure_text(s, encoding='utf-8', errors='strict'):
+ """Coerce *s* to six.text_type. Copied from six lib.
+
+ For Python 2:
+ - `unicode` -> `unicode`
+ - `str` -> `unicode`
+ For Python 3:
+ - `str` -> `str`
+ - `bytes` -> decoded to `str`
+ """
+ if isinstance(s, binary_type):
+ return s.decode(encoding, errors)
+ elif isinstance(s, text_type):
+ return s
+ else:
+ raise TypeError("not expecting type '%s'" % type(s))
diff --git a/client/common_lib/ui_utils.py b/client/common_lib/ui_utils.py
index ba3a55a..0054a68 100644
--- a/client/common_lib/ui_utils.py
+++ b/client/common_lib/ui_utils.py
@@ -1,6 +1,13 @@
+# Lint as: python2, python3
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
import logging
import os
+from six.moves import range
import time
+
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
@@ -13,7 +20,7 @@
def __init__(self):
if not os.path.exists(self._SCREENSHOT_DIR_PATH):
- os.mkdir(self._SCREENSHOT_DIR_PATH, 0755)
+ os.mkdir(self._SCREENSHOT_DIR_PATH, 0o755)
self.screenshot_num = 0
def take_ss(self):
@@ -296,7 +303,7 @@
self.doDefault_on_obj(item_to_click,
role=click_role,
isRegex=isRegex_click)
- for retry in xrange(3):
+ for retry in range(3):
try:
self.wait_for_ui_obj(item_to_wait_for,
role=wait_role,
diff --git a/client/common_lib/utils.py b/client/common_lib/utils.py
index 975be78..bcd43ee 100644
--- a/client/common_lib/utils.py
+++ b/client/common_lib/utils.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
# Copyright (c) 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -11,7 +12,10 @@
# pylint: disable=missing-docstring
-import StringIO
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
import collections
import datetime
import errno
@@ -20,7 +24,6 @@
import logging
import os
import pickle
-import Queue
import random
import re
import resource
@@ -28,22 +31,31 @@
import shutil
import signal
import socket
+import six
+from six.moves import input
+from six.moves import range
+from six.moves import urllib
+from six.moves import zip
+from six.moves import zip_longest
+import six.moves.urllib.parse
import string
import struct
import subprocess
import textwrap
import threading
import time
-import urllib2
-import urlparse
+import six.moves.queue
import uuid
import warnings
try:
import hashlib
-except ImportError:
- import md5
- import sha
+except ImportError as e:
+ if six.PY2:
+ import md5
+ import sha
+ else:
+ raise ImportError("Broken hashlib imports %s", e)
import common
@@ -202,7 +214,7 @@
# allow for easy stdin input by string, we'll let subprocess create
# a pipe for stdin input and we'll write to it in the wait loop
- if isinstance(stdin, basestring):
+ if isinstance(stdin, six.string_types):
self.string_stdin = stdin
stdin = subprocess.PIPE
else:
@@ -242,9 +254,9 @@
env=env, close_fds=False)
self._cleanup_called = False
self._stdout_file = (
- None if stdout_tee == DEVNULL else StringIO.StringIO())
+ None if stdout_tee == DEVNULL else six.StringIO())
self._stderr_file = (
- None if stderr_tee == DEVNULL else StringIO.StringIO())
+ None if stderr_tee == DEVNULL else six.StringIO())
def process_output(self, stdout=True, final_read=False):
"""Read from process's output stream, and write data to destinations.
@@ -395,7 +407,7 @@
if find != None:
return re.split("%s" % sep, find.group(1))[param]
else:
- print "There is no line which starts with %s in data." % linestart
+ print("There is no line which starts with %s in data." % linestart)
return None
@@ -453,7 +465,7 @@
lengths.append(len(column))
for row in matrix:
for i, column in enumerate(row):
- column = unicode(column).encode("utf-8")
+ column = six.ensure_binary(six.text_type(column), "utf-8")
cl = len(column)
try:
ml = lengths[i]
@@ -556,7 +568,7 @@
def is_url(path):
"""Return true if path looks like a URL"""
# for now, just handle http and ftp
- url_parts = urlparse.urlparse(path)
+ url_parts = six.moves.urllib.parse.urlparse(path)
return (url_parts[0] in ('http', 'ftp'))
@@ -567,7 +579,7 @@
old_timeout = socket.getdefaulttimeout()
socket.setdefaulttimeout(timeout)
try:
- return urllib2.urlopen(url, data=data)
+ return urllib.request.urlopen(url, data=data)
finally:
socket.setdefaulttimeout(old_timeout)
@@ -645,7 +657,7 @@
(after retrieving it)
"""
if is_url(src):
- url_parts = urlparse.urlparse(src)
+ url_parts = six.moves.urllib.parse.urlparse(src)
filename = os.path.basename(url_parts[2])
dest = os.path.join(destdir, filename)
return get_file(src, dest)
@@ -730,7 +742,7 @@
@raise CmdError: the exit code of the command execution was not 0
@raise CmdTimeoutError: the command timed out and ignore_timeout is False.
"""
- if isinstance(args, basestring):
+ if isinstance(args, six.string_types):
raise TypeError('Got a string for the "args" keyword argument, '
'need a sequence.')
@@ -738,7 +750,7 @@
# (For example, see get_user_hash in client/cros/cryptohome.py.)
# So, to cover that case, detect if it's a string or not and convert it
# into one if necessary.
- if not isinstance(command, basestring):
+ if not isinstance(command, six.string_types):
command = ' '.join([sh_quote_word(arg) for arg in command])
command = ' '.join([command] + [sh_quote_word(arg) for arg in args])
@@ -783,7 +795,7 @@
bg_jobs = []
if nicknames is None:
nicknames = []
- for (command, nickname) in itertools.izip_longest(commands, nicknames):
+ for (command, nickname) in zip_longest(commands, nicknames):
bg_jobs.append(BgJob(command, stdout_tee, stderr_tee,
stderr_level=get_stderr_level(ignore_status),
nickname=nickname))
@@ -1103,7 +1115,7 @@
for key in input_obj.keys():
output[str(key)] = strip_unicode(input_obj[key])
return output
- elif type(input_obj) == unicode:
+ elif type(input_obj) == six.text_type:
return str(input_obj)
else:
return input_obj
@@ -1164,7 +1176,7 @@
cmd = 'file --brief --dereference /bin/sh'
filestr = run_function(cmd).stdout.rstrip()
- for a, regex in archs.iteritems():
+ for a, regex in six.iteritems(archs):
if re.match(regex, filestr):
return a
@@ -1593,7 +1605,7 @@
ref_list = reference.split(os.path.sep)[1:]
# find the longest leading common path
- for i in xrange(min(len(path_list), len(ref_list))):
+ for i in range(min(len(path_list), len(ref_list))):
if path_list[i] != ref_list[i]:
# decrement i so when exiting this loop either by no match or by
# end of range we are one step behind
@@ -1790,7 +1802,7 @@
if auto:
logging.info("%s (y/n) y", question)
return "y"
- return raw_input("%s INFO | %s (y/n) " %
+ return input("%s INFO | %s (y/n) " %
(time.strftime("%H:%M:%S", time.localtime()), question))
@@ -2103,7 +2115,7 @@
for view in job_views:
if (view.get('attributes')
- and constants.CHROME_VERSION in view['attributes'].keys()):
+ and constants.CHROME_VERSION in list(view['attributes'].keys())):
return view['attributes'].get(constants.CHROME_VERSION)
@@ -2248,7 +2260,7 @@
signal_queue = [signal.SIGTERM, signal.SIGKILL]
sig_count = {}
# Though this is slightly hacky it beats hardcoding names anyday.
- sig_names = dict((k, v) for v, k in signal.__dict__.iteritems()
+ sig_names = dict((k, v) for v, k in six.iteritems(signal.__dict__)
if v.startswith('SIG'))
for sig in signal_queue:
logging.debug('Sending signal %s to the following pids:', sig)
@@ -2312,8 +2324,8 @@
old_timeout = socket.getdefaulttimeout()
socket.setdefaulttimeout(timeout)
try:
- return urllib2.urlopen(url, data=data)
- except urllib2.URLError as e:
+ return urllib.request.urlopen(url, data=data)
+ except urllib.error.URLError as e:
if type(e.reason) is socket.timeout:
raise error.TimeoutException(str(e))
raise
@@ -2590,7 +2602,7 @@
@return: True if the two IP addresses are in the same subnet.
"""
- mask = ((2L<<mask_bits-1) -1)<<(32-mask_bits)
+ mask = ((2<<mask_bits-1) -1)<<(32-mask_bits)
ip_1_num = struct.unpack('!I', socket.inet_aton(ip_1))[0]
ip_2_num = struct.unpack('!I', socket.inet_aton(ip_2))[0]
return ip_1_num & mask == ip_2_num & mask
@@ -2638,7 +2650,7 @@
if not servers and not server_ip_map:
raise ValueError('Either `servers` or `server_ip_map` must be given.')
if not servers:
- servers = server_ip_map.keys()
+ servers = list(server_ip_map.keys())
# Make sure server_ip_map is an empty dict if it's not set.
if not server_ip_map:
server_ip_map = {}
@@ -3068,7 +3080,7 @@
Creates the queue and starts the thread, then assigns extra attributes
to the thread to give it result-storing capability.
"""
- q = Queue.Queue()
+ q = six.moves.queue.Queue()
t = threading.Thread(target=wrapped_t, args=(q,) + args, kwargs=kwargs)
t.start()
t.result_queue = q
@@ -3198,14 +3210,20 @@
A tuple of: (args tuple, keyword arguments dictionary)
"""
# Cherry pick args:
- if func.func_code.co_flags & 0x04:
+ if hasattr(func, "func_code"):
+ # Moock doesn't have __code__ in either py2 or 3 :(
+ flags = func.func_code.co_flags
+ else:
+ flags = func.__code__.co_flags
+
+ if flags & 0x04:
# func accepts *args, so return the entire args.
p_args = args
else:
p_args = ()
# Cherry pick dargs:
- if func.func_code.co_flags & 0x08:
+ if flags & 0x08:
# func accepts **dargs, so return the entire dargs.
p_dargs = dargs
else:
@@ -3235,7 +3253,7 @@
@return: A tuple of parameters accepted by the function.
"""
- return func.func_code.co_varnames[:func.func_code.co_argcount]
+ return func.__code__.co_varnames[:func.__code__.co_argcount]
def crc8(buf):
"""Calculate CRC8 for a given int list.
diff --git a/client/common_lib/utils_unittest.py b/client/common_lib/utils_unittest.py
index 4d71d69..10571dc 100755
--- a/client/common_lib/utils_unittest.py
+++ b/client/common_lib/utils_unittest.py
@@ -2,7 +2,12 @@
# pylint: disable=missing-docstring
-import StringIO
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
+from six.moves import range
+import six
import errno
import itertools
import logging
@@ -12,7 +17,7 @@
import subprocess
import time
import unittest
-import urllib2
+from six.moves import urllib
import common
from autotest_lib.client.common_lib import autotemp
@@ -69,7 +74,7 @@
def create_test_file(self, contents):
- test_file = StringIO.StringIO(contents)
+ test_file = six.StringIO(contents)
utils.open.expect_call("filename", "r").and_return(test_file)
@@ -180,7 +185,7 @@
def create_test_file(self, filename, contents):
- test_file = StringIO.StringIO(contents)
+ test_file = six.StringIO(contents)
os.path.exists.expect_call(filename).and_return(True)
utils.open.expect_call(filename).and_return(test_file)
@@ -290,7 +295,7 @@
type_tag=None):
if expected_filename is None:
expected_filename = filename
- test_file = StringIO.StringIO()
+ test_file = six.StringIO()
self.god.stub_function(test_file, "close")
utils.open.expect_call(expected_filename, "a").and_return(test_file)
test_file.close.expect_call()
@@ -393,7 +398,7 @@
self.assertEquals(expected_args, (url,data))
test_func(socket.getdefaulttimeout())
return expected_return
- self.god.stub_with(urllib2, "urlopen", urlopen)
+ self.god.stub_with(urllib.request, "urlopen", urlopen)
def stub_urlopen_with_timeout_check(self, expected_timeout,
@@ -515,35 +520,43 @@
def test_file_only_at_src(self):
- print >> open(self.src("src_only"), "w"), "line 1"
+ with open(self.src("src_only"), "w") as wf:
+ print("line 1", file=wf)
utils.merge_trees(*self.paths("src_only"))
self.assertFileEqual("src_only")
def test_file_only_at_dest(self):
- print >> open(self.dest("dest_only"), "w"), "line 1"
+ with open(self.dest("dest_only"), "w") as wf:
+ print("line 1", file=wf)
utils.merge_trees(*self.paths("dest_only"))
self.assertEqual(False, os.path.exists(self.src("dest_only")))
self.assertFileContents("line 1\n", "dest_only")
def test_file_at_both(self):
- print >> open(self.dest("in_both"), "w"), "line 1"
- print >> open(self.src("in_both"), "w"), "line 2"
+ with open(self.dest("in_both"), "w") as wf1:
+ print("line 1", file=wf1)
+ with open(self.src("in_both"), "w") as wf2:
+ print("line 2", file=wf2)
utils.merge_trees(*self.paths("in_both"))
self.assertFileContents("line 1\nline 2\n", "in_both")
def test_directory_with_files_in_both(self):
- print >> open(self.dest("in_both"), "w"), "line 1"
- print >> open(self.src("in_both"), "w"), "line 3"
+ with open(self.dest("in_both"), "w") as wf1:
+ print("line 1", file=wf1)
+ with open(self.src("in_both"), "w") as wf2:
+ print("line 3", file=wf2)
utils.merge_trees(*self.paths())
self.assertFileContents("line 1\nline 3\n", "in_both")
def test_directory_with_mix_of_files(self):
- print >> open(self.dest("in_dest"), "w"), "dest line"
- print >> open(self.src("in_src"), "w"), "src line"
+ with open(self.dest("in_dest"), "w") as wf1:
+ print("dest line", file=wf1)
+ with open(self.src("in_src"), "w") as wf2:
+ print("src line", file=wf2)
utils.merge_trees(*self.paths())
self.assertFileContents("dest line\n", "in_dest")
self.assertFileContents("src line\n", "in_src")
@@ -551,11 +564,14 @@
def test_directory_with_subdirectories(self):
os.mkdir(self.src("src_subdir"))
- print >> open(self.src("src_subdir", "subfile"), "w"), "subdir line"
+ with open(self.src("src_subdir", "subfile"), "w") as wf1:
+ print("subdir line", file=wf1)
os.mkdir(self.src("both_subdir"))
os.mkdir(self.dest("both_subdir"))
- print >> open(self.src("both_subdir", "subfile"), "w"), "src line"
- print >> open(self.dest("both_subdir", "subfile"), "w"), "dest line"
+ with open(self.src("both_subdir", "subfile"), "w") as wf2:
+ print("src line", file=wf2)
+ with open(self.dest("both_subdir", "subfile"), "w") as wf3:
+ print("dest line", file=wf3)
utils.merge_trees(*self.paths())
self.assertFileContents("subdir line\n", "src_subdir", "subfile")
self.assertFileContents("dest line\nsrc line\n", "both_subdir",
@@ -709,7 +725,7 @@
# Log level -> StringIO.StringIO.
self.logs = {}
for level in self.LOG_LEVELS:
- self.logs[level] = StringIO.StringIO()
+ self.logs[level] = six.StringIO()
# Override logging_manager.LoggingFile to return buffers.
def logging_file(level=None, prefix=None):
@@ -748,7 +764,7 @@
cmd = 'exit 11'
try:
utils.run(cmd, verbose=False)
- except utils.error.CmdError, err:
+ except utils.error.CmdError as err:
self.__check_result(err.result_obj, cmd, exit_status=11)
@@ -763,14 +779,14 @@
utils.logging.warning.expect_any_call()
try:
utils.run('echo -n output && sleep 10', timeout=1, verbose=False)
- except utils.error.CmdError, err:
+ except utils.error.CmdError as err:
self.assertEquals(err.result_obj.stdout, 'output')
def test_stdout_stderr_tee(self):
cmd = 'echo output && echo error >&2'
- stdout_tee = StringIO.StringIO()
- stderr_tee = StringIO.StringIO()
+ stdout_tee = six.StringIO()
+ stderr_tee = six.StringIO()
self.__check_result(utils.run(
cmd, stdout_tee=stdout_tee, stderr_tee=stderr_tee,
@@ -925,7 +941,7 @@
def test_get_port(self):
- for _ in xrange(100):
+ for _ in range(100):
p = utils.get_unused_port()
s = self.do_bind(p, socket.SOCK_STREAM, socket.IPPROTO_TCP)
self.assert_(s.getsockname())