[Autotest][PY3] Migrating client/common_lib (file_utils -> log)
Migrating client/common_lib from file_utils.py to log.py to python3.
BUG=chromium:990593
TEST= py_compile in py2 and py3. CQ. dummy_Pass. global_config_unittest
Change-Id: Ibeb840623d709a02094d42f8fcdfa3f3489069de
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/autotest/+/2458770
Tested-by: Derek Beckett <dbeckett@chromium.org>
Commit-Queue: Derek Beckett <dbeckett@chromium.org>
Reviewed-by: Greg Edelston <gredelston@google.com>
diff --git a/client/common_lib/file_utils.py b/client/common_lib/file_utils.py
index b299f0b..7174eea 100644
--- a/client/common_lib/file_utils.py
+++ b/client/common_lib/file_utils.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
# Copyright (c) 2014 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.
@@ -6,8 +7,8 @@
import logging
import os
import shutil
+from six.moves import urllib
import subprocess
-import urllib2
from autotest_lib.client.common_lib import global_config
@@ -138,32 +139,32 @@
proxies[name[:-6]] = value
if proxies:
- proxy_handler = urllib2.ProxyHandler(proxies)
- opener = urllib2.build_opener(proxy_handler)
- urllib2.install_opener(opener)
+ proxy_handler = urllib.request.ProxyHandler(proxies)
+ opener = urllib.request.build_opener(proxy_handler)
+ urllib.request.install_opener(opener)
# Unlike urllib.urlopen urllib2.urlopen will immediately throw on error
# If we could not find the file pointed by remote_path we will get an
# exception, catch the exception to log useful information then re-raise
try:
- remote_file = urllib2.urlopen(remote_path)
+ remote_file = urllib.request.urlopen(remote_path)
# Catch exceptions, extract exception properties and then re-raise
# This helps us with debugging what went wrong quickly as we get to see
# test_that output immediately
- except urllib2.HTTPError as e:
+ except urllib.error.HTTPError as e:
e.msg = (("""HTTPError raised while retrieving file %s\n.
Http Code = %s.\n. Reason = %s\n. Headers = %s.\n
Original Message = %s.\n""")
% (remote_path, e.code, e.reason, e.headers, e.msg))
raise
- except urllib2.URLError as e:
+ except urllib.error.URLError as e:
e.msg = (("""URLError raised while retrieving file %s\n.
Reason = %s\n. Original Message = %s\n.""")
- % (remote_path, e.reason, e.message))
+ % (remote_path, e.reason, str(e)))
raise
with open(local_path, 'wb') as local_file:
@@ -194,7 +195,7 @@
logging.warning(stderr_data)
return 0
- return int(stdout_data.split('\t', 1)[0])
+ return int(stdout_data.split(b'\t', 1)[0])
def recursive_path_permission(path):
diff --git a/client/common_lib/global_config.py b/client/common_lib/global_config.py
index 545045e..42eda8a 100644
--- a/client/common_lib/global_config.py
+++ b/client/common_lib/global_config.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
"""A singleton class for accessing global config values
provides access to global configuration file
@@ -13,16 +14,16 @@
# When the code is running in a non-Moblab host, moblab_config.ini is ignored.
# Config values in shadow config will override values in global config.
-__author__ = 'raphtee@google.com (Travis Miller)'
-
import collections
-import ConfigParser
import os
import re
+import six.moves.configparser as ConfigParser
import sys
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import lsbrelease_utils
+from autotest_lib.client.common_lib import seven
+
class ConfigError(error.AutotestError):
"""Configuration error."""
@@ -160,7 +161,7 @@
@param section: Section we want to turn into a config parser object.
@return: ConfigParser() object containing all the contents of section.
"""
- cfgparser = ConfigParser.ConfigParser()
+ cfgparser = seven.config_parser()
cfgparser.add_section(section)
for option, value in self.config.items(section):
cfgparser.set(section, option, value)
@@ -292,7 +293,7 @@
def parse_config_file(self):
"""Parse config files."""
- self.config = ConfigParser.ConfigParser()
+ self.config = seven.config_parser()
if self.config_file and os.path.exists(self.config_file):
self.config.read(self.config_file)
else:
@@ -302,7 +303,7 @@
# overwrite the value in global config.
if (lsbrelease_utils.is_moblab() and self.moblab_file and
os.path.exists(self.moblab_file)):
- moblab_config = ConfigParser.ConfigParser()
+ moblab_config = seven.config_parser()
moblab_config.read(self.moblab_file)
# now we merge moblab into global
self.merge_configs(moblab_config)
@@ -311,7 +312,7 @@
# this will overwrite anything that is found in the
# other config
if self.shadow_file and os.path.exists(self.shadow_file):
- shadow_config = ConfigParser.ConfigParser()
+ shadow_config = seven.config_parser()
shadow_config.read(self.shadow_file)
# now we merge shadow into global
self.merge_configs(shadow_config)
diff --git a/client/common_lib/global_config_unittest.py b/client/common_lib/global_config_unittest.py
index c8279e9..a8491d4 100755
--- a/client/common_lib/global_config_unittest.py
+++ b/client/common_lib/global_config_unittest.py
@@ -99,14 +99,14 @@
def test_float(self):
"""Test converting float value."""
val = self.conf.get_config_value("SECTION_A", "value_1", float)
- self.assertEquals(type(val), types.FloatType)
+ self.assertEquals(type(val), float)
self.assertEquals(val, 6.0)
def test_int(self):
"""Test converting int value."""
val = self.conf.get_config_value("SECTION_B", "value_1", int)
- self.assertEquals(type(val), types.IntType)
+ self.assertEquals(type(val), int)
self.assertTrue(val < 0)
val = self.conf.get_config_value("SECTION_B", "value_3", int)
self.assertEquals(val, 0)
@@ -117,7 +117,7 @@
def test_string(self):
"""Test converting string value."""
val = self.conf.get_config_value("SECTION_A", "value_2")
- self.assertEquals(type(val),types.StringType)
+ self.assertEquals(type(val),bytes)
self.assertEquals(val, "hello")
diff --git a/client/common_lib/gtest_parser.py b/client/common_lib/gtest_parser.py
index 2599b46..d310678 100644
--- a/client/common_lib/gtest_parser.py
+++ b/client/common_lib/gtest_parser.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
# Copyright (c) 2017 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.
@@ -151,7 +152,7 @@
def SuppressionHashes(self):
"""Returns list of suppression hashes found in the log."""
- return self._suppressions.keys()
+ return list(self._suppressions.keys())
def Suppression(self, suppression_hash):
"""Returns a list containing the suppression for a given hash.
diff --git a/client/common_lib/i2c_node.py b/client/common_lib/i2c_node.py
index 99d86dc..882825a 100644
--- a/client/common_lib/i2c_node.py
+++ b/client/common_lib/i2c_node.py
@@ -1,3 +1,4 @@
+# Lint as: python2, python3
# Copyright (c) 2011 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.
@@ -64,7 +65,7 @@
logging.info('Attempt to load shared library %s', self.load_lib)
try:
return ctypes.cdll.LoadLibrary(self.load_lib)
- except OSError, e:
+ except OSError as e:
raise I2cError('Error loading C library %s: %s' %
(self.load_lib, e))
logging.info('Successfully loaded shared library %s', self.load_lib)
diff --git a/client/common_lib/kernel_versions.py b/client/common_lib/kernel_versions.py
index 1b796c1..605fb9b 100644
--- a/client/common_lib/kernel_versions.py
+++ b/client/common_lib/kernel_versions.py
@@ -1,10 +1,16 @@
+# Lint as: python2, python3
#
# kernel_versions.py -- linux kernel version comparisons
#
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
__author__ = """Copyright Andy Whitcroft 2007"""
import sys,re
+from six.moves import range
+
#
# Sort key for ordering versions chronologically. The key ordering
# problem is between that introduced by -rcN. These come _before_
diff --git a/client/common_lib/log.py b/client/common_lib/log.py
index f79f7de..3505105 100644
--- a/client/common_lib/log.py
+++ b/client/common_lib/log.py
@@ -1,5 +1,9 @@
+# Lint as: python2, python3
# pylint: disable=missing-docstring
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
import sys, re, traceback
# these statuses are ordered such that a status earlier in the list will
@@ -24,7 +28,7 @@
try:
fn(*args, **dargs)
except Exception:
- print >> sys.stderr, msg
+ print(msg, file=sys.stderr)
traceback.print_exc(file=sys.stderr)
return decorated_func
return decorator
diff --git a/client/common_lib/seven.py b/client/common_lib/seven.py
index 729ca02..f766ed3 100644
--- a/client/common_lib/seven.py
+++ b/client/common_lib/seven.py
@@ -9,8 +9,8 @@
"""
import six
+import six.moves.configparser
import socket
-
if six.PY3:
import builtins
SOCKET_ERRORS = (builtins.ConnectionError, socket.timeout, socket.gaierror,
@@ -45,3 +45,14 @@
dont_inherit=1,
)
return six.exec_(code_obj, globals_, locals_)
+
+
+def config_parser():
+ """config_parser returns a non-strict config parser.
+
+ Unfortunately, in six configparser is not same between 2/3. For our .ini's
+ we do not want it to be strict (ie, error upon duplicates).
+ """
+ if six.PY3:
+ return six.moves.configparser.ConfigParser(strict=False)
+ return six.moves.configparser.ConfigParser()