factory: Use `dict.items` instead of `six.iteritems`

`six.iteritems` is equivalent to `dict.items` in python3, so we can
migrate all of this.

BUG=chromium:999876
TEST=make test

Change-Id: I7218c416e694da41996ae3ace6ce23e6f9fcfb72
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/factory/+/2200487
Reviewed-by: Yilin Yang (kerker) <kerker@chromium.org>
Tested-by: Yilin Yang (kerker) <kerker@chromium.org>
Commit-Queue: Yilin Yang (kerker) <kerker@chromium.org>
diff --git a/py/device/chromeos/bluetooth.py b/py/device/chromeos/bluetooth.py
index 287b21c..726fefb 100755
--- a/py/device/chromeos/bluetooth.py
+++ b/py/device/chromeos/bluetooth.py
@@ -11,7 +11,6 @@
 import threading
 import uuid
 
-from six import iteritems
 import yaml
 
 from cros.factory.device.bluetooth import BluetoothManager
@@ -123,7 +122,7 @@
     path_prefix = adapter.object_path
     bus = dbus.SystemBus()
     remote_objects = self._manager.GetManagedObjects()
-    for path, ifaces in iteritems(remote_objects):
+    for path, ifaces in remote_objects.items():
       if path.startswith(path_prefix):
         device = ifaces.get(DEVICE_INTERFACE)
         if device and str(device['Address']) == mac_addr:
@@ -311,7 +310,7 @@
     objects = self._manager.GetManagedObjects()
     bus = dbus.SystemBus()
     adapters = []
-    for path, interfaces in iteritems(objects):
+    for path, interfaces in objects.items():
       adapter = interfaces.get(ADAPTER_INTERFACE)
       if adapter is None:
         continue
@@ -413,7 +412,7 @@
     result = {}
     path_prefix = adapter.object_path
     remote_objects = self._manager.GetManagedObjects()
-    for path, ifaces in iteritems(remote_objects):
+    for path, ifaces in remote_objects.items():
       if path.startswith(path_prefix):
         device = ifaces.get(DEVICE_INTERFACE)
         if device and "Address" in device:
@@ -513,7 +512,7 @@
       if DEVICE_INTERFACE not in interfaces:
         return
       properties = interfaces[DEVICE_INTERFACE]
-      for key, value in iteritems(properties):
+      for key, value in properties.items():
         logging.debug('%s : %s', key, value)
 
       if path in devices:
diff --git a/py/device/device_utils.py b/py/device/device_utils.py
index 1d51698..36dce6e 100644
--- a/py/device/device_utils.py
+++ b/py/device/device_utils.py
@@ -10,8 +10,6 @@
 import logging
 import os
 
-from six import iteritems
-
 from cros.factory.utils import config_utils
 
 
@@ -48,7 +46,7 @@
   if spec.varkw is None:
     # if the function accepts ** arguments, we can just pass everything into it
     # so we only need to filter kargs if spec.keywords is None
-    kargs = {k: v for (k, v) in iteritems(kargs) if k in spec.args}
+    kargs = {k: v for (k, v) in kargs.items() if k in spec.args}
   return kargs
 
 
diff --git a/py/device/gyroscope.py b/py/device/gyroscope.py
index 7795702..5aec692 100644
--- a/py/device/gyroscope.py
+++ b/py/device/gyroscope.py
@@ -9,8 +9,6 @@
 import os
 import re
 
-from six import iteritems
-
 from cros.factory.device import device_types
 from cros.factory.device import sensor_utils
 
@@ -162,7 +160,7 @@
     result = {}
 
     try:
-      for key, re_exp in iteritems(re_dict):
+      for key, re_exp in re_dict.items():
         result[key] = re_exp.search(raw_info).group(1)
     except AttributeError as e:
       raise MotionSensorException('Failed to parse key "%s": %s' % (key, e))
diff --git a/py/device/links/ssh_integration_test.py b/py/device/links/ssh_integration_test.py
index 2cdbc47..63cda92 100755
--- a/py/device/links/ssh_integration_test.py
+++ b/py/device/links/ssh_integration_test.py
@@ -11,8 +11,6 @@
 import tempfile
 import unittest
 
-from six import iteritems
-
 from cros.factory.device.links import local
 from cros.factory.device.links import ssh
 from cros.factory.test.env import paths
@@ -71,7 +69,7 @@
   parser.add_argument('-u', '--user', help='user name')
   parser.add_argument('-p', '--port', type=int, help='port')
   args = parser.parse_args()
-  dut_options.update([x for x in iteritems(vars(args)) if x[1] is not None])
+  dut_options.update([x for x in vars(args).items() if x[1] is not None])
 
   logging.info('dut_options: %s', dut_options)
 
diff --git a/py/device/storage.py b/py/device/storage.py
index 6fc7c2a..2d1487d 100644
--- a/py/device/storage.py
+++ b/py/device/storage.py
@@ -9,8 +9,6 @@
 import re
 import subprocess
 
-from six import iteritems
-
 from cros.factory.device import device_types
 from cros.factory.utils import process_utils
 
@@ -67,7 +65,7 @@
       logging.warning('Invalid keys: %r (keys can only be string)',
                       invalid_keys)
       logging.warning('These keys will be removed')
-      data = {k: v for (k, v) in iteritems(data) if k not in invalid_keys}
+      data = {k: v for (k, v) in data.items() if k not in invalid_keys}
 
     device_data_file_path = self.GetDictFilePath()
 
diff --git a/py/device/thermal.py b/py/device/thermal.py
index eef4a75..8c234d2 100644
--- a/py/device/thermal.py
+++ b/py/device/thermal.py
@@ -15,8 +15,6 @@
 import struct
 import time
 
-from six import iteritems
-
 from cros.factory.device import device_types
 
 
@@ -164,7 +162,7 @@
 
   def GetMainSensorName(self):
     """Returns the sensor name of main (first package) coretemp node."""
-    for name, path in iteritems(self.GetSensors()):
+    for name, path in self.GetSensors().items():
       if 'coretemp.0' in path and path.endswith('temp1_input'):
         return name
     return None
@@ -198,7 +196,7 @@
 
   def GetMainSensorName(self):
     """Returns the main thermal zone (zone0) name."""
-    for name, path in iteritems(self.GetSensors()):
+    for name, path in self.GetSensors().items():
       if path == '/sys/class/thermal/thermal_zone0/temp':
         return name
     return None
@@ -252,7 +250,7 @@
 
     # Remap ID to cached names.
     return dict((name, self._ConvertRawValue(raw_values.get(sensor_id)))
-                for name, sensor_id in iteritems(self.GetSensors()))
+                for name, sensor_id in self.GetSensors().items())
 
   def GetCriticalValue(self, sensor):
     raise NotImplementedError
diff --git a/py/device/thermal_unittest.py b/py/device/thermal_unittest.py
index 98b0272..a03aa6f 100755
--- a/py/device/thermal_unittest.py
+++ b/py/device/thermal_unittest.py
@@ -14,7 +14,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.device import device_types
 from cros.factory.device import thermal
@@ -101,7 +100,7 @@
         '0/temp1_input': '52000',
         '0/temp2_input': '37000',
         '1/hwmon/hwmon0/temp1_input': '47000'}
-    for suffix, value in iteritems(values):
+    for suffix, value in values.items():
       self.mock_files[_CORETEMP_PREFIX + suffix] = value
     self.mockProbe()
     self.assertEqual(self.sensor.GetAllValues(), {'coretemp.0 Package 0': 52,
diff --git a/py/device/usb_c.py b/py/device/usb_c.py
index 37ae411..d7b6bb7 100644
--- a/py/device/usb_c.py
+++ b/py/device/usb_c.py
@@ -5,8 +5,6 @@
 import logging
 import re
 
-from six import iteritems
-
 from cros.factory.device import device_types
 
 
@@ -118,7 +116,7 @@
         'state': <state>
     """
     response = self._CallPD(['usbpd', '%d' % port])
-    for pd_version, re_pattern in iteritems(self.USB_PD_INFO_RE_ALL):
+    for pd_version, re_pattern in self.USB_PD_INFO_RE_ALL.items():
       match = re_pattern.match(response)
       if match:
         status = dict(
diff --git a/py/doc/generate_rsts.py b/py/doc/generate_rsts.py
index 1d8d170..b5b4563 100755
--- a/py/doc/generate_rsts.py
+++ b/py/doc/generate_rsts.py
@@ -24,8 +24,6 @@
 import os
 import re
 
-from six import iteritems
-
 from cros.factory.probe import function as probe_function
 from cros.factory.test.env import paths
 from cros.factory.test.test_lists import manager
@@ -196,7 +194,7 @@
   index_rst = os.path.join(pytests_output_dir, 'index.rst')
   with open(index_rst, 'a') as f:
     rst = RSTWriter(f)
-    for k, v in sorted(iteritems(pytest_info)):
+    for k, v in sorted(pytest_info.items()):
       rst.WriteListTableRow((LinkToDoc(k, k), v))
 
 
@@ -218,7 +216,7 @@
 
   if test_object.get('args'):
     rst.WriteTitle('args', '`')
-    for key, value in iteritems(test_object['args']):
+    for key, value in test_object['args'].items():
       formatted_value = json_utils.DumpStr(value, pretty=True)
       formatted_value = '::\n\n' + Indent(formatted_value, '  ')
       formatted_value = Indent(formatted_value, '  ')
@@ -365,7 +363,7 @@
                       help='Output directory (default: %default)', default='.')
   args = parser.parse_args()
 
-  for dir_name, func in iteritems(DOC_GENERATORS):
+  for dir_name, func in DOC_GENERATORS.items():
     full_path = os.path.join(args.output_dir, dir_name)
     file_utils.TryMakeDirs(full_path)
     func(full_path)
diff --git a/py/dome/backend/models.py b/py/dome/backend/models.py
index 0aae186..fb61223 100644
--- a/py/dome/backend/models.py
+++ b/py/dome/backend/models.py
@@ -29,7 +29,6 @@
 import django
 import rest_framework.exceptions
 import rest_framework.status
-from six import iteritems
 
 from cros.factory.umpire import common as umpire_common
 from cros.factory.umpire.server import resource as umpire_resource
@@ -282,7 +281,7 @@
 
 
     # update attributes assigned in kwargs
-    for attr, value in iteritems(kwargs):
+    for attr, value in kwargs.items():
       if hasattr(self, attr):
         setattr(self, attr, value)
     self.save()
@@ -597,7 +596,7 @@
       project.MapNetbootResourceToTFTP(kwargs['netboot_bundle'])
 
     # update attributes assigned in kwargs
-    for attr, value in iteritems(kwargs):
+    for attr, value in kwargs.items():
       if hasattr(project, attr):
         setattr(project, attr, value)
     project.save()
@@ -798,7 +797,7 @@
 
     # update resources
     if resources is not None:
-      for resource_key, resource in iteritems(resources):
+      for resource_key, resource in resources.items():
         Bundle._UpdateResource(project_name, bundle['id'], resource_key,
                                resource['file_id'])
 
diff --git a/py/gooftool/commands.py b/py/gooftool/commands.py
index 2f45eb2..55bae95 100755
--- a/py/gooftool/commands.py
+++ b/py/gooftool/commands.py
@@ -24,8 +24,6 @@
 import time
 import xmlrpc.client
 
-from six import iteritems
-
 from cros.factory.gooftool.common import ExecFactoryPar
 from cros.factory.gooftool.common import Shell
 from cros.factory.gooftool.core import Gooftool
@@ -901,7 +899,7 @@
   """Get firmware hash from a file"""
   if os.path.exists(options.file):
     value_dict = chromeos_firmware.CalculateFirmwareHashes(options.file)
-    for key, value in iteritems(value_dict):
+    for key, value in value_dict.items():
       print('  %s: %s' % (key, value))
   else:
     raise Error('File does not exist: %s' % options.file)
diff --git a/py/gooftool/common.py b/py/gooftool/common.py
index cdfd590..2f905af 100644
--- a/py/gooftool/common.py
+++ b/py/gooftool/common.py
@@ -11,8 +11,6 @@
 from subprocess import PIPE
 from subprocess import Popen
 
-from six import iteritems
-
 from cros.factory.test.env import paths
 from cros.factory.utils import sys_utils
 from cros.factory.utils.type_utils import Error
@@ -273,7 +271,7 @@
       device = self.GetPrimaryDevicePath()
 
     curr_attrs = self.GetCgptAttributes()
-    for k, v in iteritems(attrs):
+    for k, v in attrs.items():
       if curr_attrs.get(k) == v:
         continue
       if not self.shell('cgpt add %s -i %s -A %s' % (device, k, v)).success:
diff --git a/py/gooftool/core.py b/py/gooftool/core.py
index fa4160f..5f2400e 100644
--- a/py/gooftool/core.py
+++ b/py/gooftool/core.py
@@ -16,7 +16,6 @@
 import tempfile
 import time
 
-from six import iteritems
 import yaml
 
 from cros.factory.gooftool.bmpblk import unpack_bmpblock
@@ -311,7 +310,7 @@
     # TPM device path has been changed in kernel 3.18.
     if not os.path.exists(tpm_root):
       tpm_root = legacy_tpm_root
-    for key, value in iteritems(expected_status):
+    for key, value in expected_status.items():
       if open(os.path.join(tpm_root, key)).read().strip() != value:
         raise Error('TPM is not cleared.')
 
@@ -361,12 +360,12 @@
       checked = []
       known = required.copy()
       known.update(optional)
-      for k, v in iteritems(data):
+      for k, v in data.items():
         if k in known:
           checked.append(MatchWhole(k, known[k], v))
         else:
           # Try if matches optional_re
-          for rk, rv in iteritems(optional_re):
+          for rk, rv in optional_re.items():
             if MatchWhole(k, rk, k, raise_exception=False):
               checked.append(MatchWhole(k, rv, v))
               break
@@ -735,8 +734,8 @@
       return any(name for name in known_names if k.startswith(name))
 
     rw_vpd = self._vpd.GetAllData(partition=vpd.VPD_READWRITE_PARTITION_NAME)
-    dot_entries = dict((k, v) for k, v in iteritems(rw_vpd) if '.' in k)
-    entries = dict((k, v) for k, v in iteritems(dot_entries)
+    dot_entries = dict((k, v) for k, v in rw_vpd.items() if '.' in k)
+    entries = dict((k, v) for k, v in dot_entries.items()
                    if _IsFactoryVPD(k))
     unknown_keys = set(dot_entries) - set(entries)
     if unknown_keys:
diff --git a/py/gooftool/gsctool.py b/py/gooftool/gsctool.py
index 0ea428f..ac74ea2 100644
--- a/py/gooftool/gsctool.py
+++ b/py/gooftool/gsctool.py
@@ -4,8 +4,6 @@
 
 import re
 
-from six import iteritems
-
 from cros.factory.gooftool import common as gooftool_common
 from cros.factory.utils import type_utils
 
@@ -115,10 +113,10 @@
     translated_kwargs = {}
     for line in cmd_result.stdout.splitlines():
       line = line.strip()
-      for field_name, attr_name in iteritems(fields):
+      for field_name, attr_name in fields.items():
         if line.startswith(field_name + '='):
           translated_kwargs[attr_name] = line[len(field_name) + 1:]
-    missing_fields = [field_name for field_name, attr_name in iteritems(fields)
+    missing_fields = [field_name for field_name, attr_name in fields.items()
                       if attr_name not in translated_kwargs]
     if missing_fields:
       raise GSCToolError('%r Field(s) are missing, gsctool stdout=%r' %
diff --git a/py/gooftool/gsctool_unittest.py b/py/gooftool/gsctool_unittest.py
index 16e2283..e4dda62 100755
--- a/py/gooftool/gsctool_unittest.py
+++ b/py/gooftool/gsctool_unittest.py
@@ -6,7 +6,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.gooftool import common
 from cros.factory.gooftool import gsctool
@@ -102,7 +101,7 @@
         'BID_FLAGS': '0000ff00',
         'BID_RLZ': 'ABCD'}
     self._SetGSCToolUtilityResult(
-        stdout=(''.join('%s=%s\n' % (k, v) for k, v in iteritems(fields))))
+        stdout=(''.join('%s=%s\n' % (k, v) for k, v in fields.items())))
     board_id = self.gsctool.GetBoardID()
     self._CheckCalledCommand(['/usr/sbin/gsctool', '-a', '-M', '-i'])
     self.assertEqual(board_id.type, 0x41424344)
@@ -116,7 +115,7 @@
         'BID_FLAGS': '0000ff00',
         'BID_RLZ': '????'}
     self._SetGSCToolUtilityResult(
-        stdout=(''.join('%s=%s\n' % (k, v) for k, v in iteritems(fields2))))
+        stdout=(''.join('%s=%s\n' % (k, v) for k, v in fields2.items())))
     board_id = self.gsctool.GetBoardID()
     self._CheckCalledCommand(['/usr/sbin/gsctool', '-a', '-M', '-i'])
     self.assertEqual(board_id.type, 0xffffffff)
@@ -125,13 +124,13 @@
     # BID_TYPE_INV should be complement to BID_TYPE
     bad_fields = dict(fields, BID_TYPE_INV='aabbccdd')
     self._SetGSCToolUtilityResult(
-        stdout=(''.join('%s=%s\n' % (k, v) for k, v in iteritems(bad_fields))))
+        stdout=(''.join('%s=%s\n' % (k, v) for k, v in bad_fields.items())))
     self.assertRaises(gsctool.GSCToolError, self.gsctool.GetBoardID)
 
     # BID_TYPE should be the ascii codes of BID_RLZ
     bad_fields = dict(fields, BID_RLZ='XXYY')
     self._SetGSCToolUtilityResult(
-        stdout=(''.join('%s=%s\n' % (k, v) for k, v in iteritems(bad_fields))))
+        stdout=(''.join('%s=%s\n' % (k, v) for k, v in bad_fields.items())))
     self.assertRaises(gsctool.GSCToolError, self.gsctool.GetBoardID)
 
     self._SetGSCToolUtilityResult(status=1)
diff --git a/py/goofy/goofy.py b/py/goofy/goofy.py
index 9f5583e..1382c0d 100755
--- a/py/goofy/goofy.py
+++ b/py/goofy/goofy.py
@@ -19,8 +19,6 @@
 import uuid
 import xmlrpc.client
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.goofy.goofy_rpc import GoofyRPC
 from cros.factory.goofy import goofy_server
@@ -306,7 +304,7 @@
     self.state_instance = state.FactoryState()
 
     # Write back the preserved data.
-    for key, value in iteritems(preserved_data):
+    for key, value in preserved_data.items():
       if value is not None:
         self.state_instance.DataShelfSetValue(key, value)
 
@@ -1134,7 +1132,7 @@
       if failed_test_lists:
         logging.info('Failed test list IDs: [%s]',
                      ' '.join(failed_test_lists.keys()))
-        for test_list_id, reason in iteritems(failed_test_lists):
+        for test_list_id, reason in failed_test_lists.items():
           logging.error('Error in test list %s: %s', test_list_id, reason)
           startup_errors.append('Error in test list %s:\n%s'
                                 % (test_list_id, reason))
@@ -1255,7 +1253,7 @@
 
     try:
       goofy_default_options = config_utils.LoadConfig(validate_schema=False)
-      for key, value in iteritems(goofy_default_options):
+      for key, value in goofy_default_options.items():
         if getattr(self.args, key, None) is None:
           logging.info('self.args.%s = %r', key, value)
           setattr(self.args, key, value)
diff --git a/py/goofy/goofy_rpc.py b/py/goofy/goofy_rpc.py
index 23e6286..0ad7439 100755
--- a/py/goofy/goofy_rpc.py
+++ b/py/goofy/goofy_rpc.py
@@ -22,7 +22,6 @@
 import uuid
 import xmlrpc.client
 
-from six import iteritems
 import yaml
 
 from cros.factory.test.diagnosis.diagnosis_tool import DiagnosisToolRPC
@@ -404,7 +403,7 @@
         enabled: Whether this is the current-enabled test list.
     """
     ret = []
-    for k, v in iteritems(self.goofy.test_lists):
+    for k, v in self.goofy.test_lists.items():
       ret.append(
           dict(id=k, name=v.label,
                enabled=(k == self.goofy.test_list.test_list_id)))
@@ -422,7 +421,7 @@
   def GetTestStateMap(self):
     """Returns the test states in JSON serializable struct."""
     states = self.goofy.state_instance.GetTestStates()
-    return {key: state.ToStruct() for key, state in iteritems(states)}
+    return {key: state.ToStruct() for key, state in states.items()}
 
   def GetGoofyStatus(self):
     """Returns a dictionary containing Goofy status information.
diff --git a/py/goofy/invocation.py b/py/goofy/invocation.py
index 93196c0..ea6caa8 100644
--- a/py/goofy/invocation.py
+++ b/py/goofy/invocation.py
@@ -15,8 +15,6 @@
 import threading
 import time
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test import device_data
 from cros.factory.test.env import paths
@@ -586,7 +584,7 @@
           dargs, allow_types=(int, float, str, type(None)))
       for k, v in flattened_dargs:
         testlog_event.AddArgument(k, v)
-    for k, v in iteritems(init_data['serialNumbers']):
+    for k, v in init_data['serialNumbers'].items():
       testlog_event.AddSerialNumber(k, v)
 
     tag = init_data['tag']
diff --git a/py/goofy/plugins/plugin_controller.py b/py/goofy/plugins/plugin_controller.py
index 2c957f6..0394fd5 100644
--- a/py/goofy/plugins/plugin_controller.py
+++ b/py/goofy/plugins/plugin_controller.py
@@ -6,7 +6,6 @@
 import os
 
 from jsonrpclib import ProtocolError
-from six import iteritems
 
 from cros.factory.goofy.plugins import plugin
 from cros.factory.test.env import goofy_proxy
@@ -74,7 +73,7 @@
         plugin_config,
         config_utils.LoadConfig(config_name, 'plugins', allow_inherit=True))
 
-    for name, plugin_args in iteritems(plugin_config['plugins']):
+    for name, plugin_args in plugin_config['plugins'].items():
       if not plugin_args.get('enabled', True):
         logging.debug('Plugin disabled: %s', name)
         continue
@@ -98,7 +97,7 @@
 
   def _RegisterMenuItem(self):
     """Registers plugins' menu items."""
-    for name, instance in iteritems(self._plugins):
+    for name, instance in self._plugins.items():
       try:
         for menu_item in instance.GetMenuItems():
           self._menu_items[menu_item.id] = menu_item
@@ -107,7 +106,7 @@
 
   def _RegisterFrontendPath(self, goofy_server):
     base = os.path.join(paths.FACTORY_PYTHON_PACKAGE_DIR, 'goofy', 'plugins')
-    for name, instance in iteritems(self._plugins):
+    for name, instance in self._plugins.items():
       plugin_paths = name.split('.')
       if len(plugin_paths) < 2:
         continue
@@ -142,7 +141,7 @@
 
   def _RegisterRPC(self, goofy_server):
     """Registers plugins to Goofy server."""
-    for plugin_path, plugin_instance in iteritems(self._plugins):
+    for plugin_path, plugin_instance in self._plugins.items():
       rpc_instance = plugin_instance.GetRPCInstance()
       if rpc_instance is not None:
         goofy_server.AddRPCInstance(
diff --git a/py/goofy/plugins/station_setup/station_setup.py b/py/goofy/plugins/station_setup/station_setup.py
index cdf47b9..8b32813 100644
--- a/py/goofy/plugins/station_setup/station_setup.py
+++ b/py/goofy/plugins/station_setup/station_setup.py
@@ -10,8 +10,6 @@
 import re
 import subprocess
 
-from six import iteritems
-
 from cros.factory.goofy.plugins import plugin
 from cros.factory.test.env import paths
 from cros.factory.test import i18n
@@ -112,7 +110,7 @@
       return False
 
     ls_cmd = [_OVL_BIN, 'ls']
-    for key, value in iteritems(check_dict):
+    for key, value in check_dict.items():
       ls_cmd.extend(['-f', '%s=^%s$' % (key, re.escape(value))])
     match_clients = process_utils.CheckOutput(ls_cmd, log=True).splitlines()
 
@@ -149,7 +147,7 @@
 
   @plugin.RPCFunction
   def UpdateProperties(self, update):
-    for key, value in iteritems(update):
+    for key, value in update.items():
       if not value:
         return {
             'success': False,
diff --git a/py/hwid/service/appengine/hwid_manager.py b/py/hwid/service/appengine/hwid_manager.py
index 947c541..3b8f071 100644
--- a/py/hwid/service/appengine/hwid_manager.py
+++ b/py/hwid/service/appengine/hwid_manager.py
@@ -12,8 +12,6 @@
 import logging
 import re
 
-from six import iteritems
-
 # pylint: disable=import-error, no-name-in-module
 from google.appengine.ext import db
 
@@ -899,9 +897,9 @@
               vol_ltrs.update(self._volatile_map)
             else:
               vol_ltrs.add(hw_vol.rpartition('-')[2])
-      items = list(iteritems(self._bom_map[hw]['primary']['components']))
+      items = list(self._bom_map[hw]['primary']['components'].items())
       for var in self._bom_map[hw]['variants']:
-        items += list(iteritems(self._variant_map[var]['components']))
+        items += list(self._variant_map[var]['components'].items())
       for vol in vol_ltrs:
         for cls, comp in self._volatile_map[vol].items():
           items.append((cls, comp))
diff --git a/py/hwid/service/appengine/ingestion.py b/py/hwid/service/appengine/ingestion.py
index 96f039b..259f1b1 100644
--- a/py/hwid/service/appengine/ingestion.py
+++ b/py/hwid/service/appengine/ingestion.py
@@ -15,7 +15,6 @@
 from google.appengine.api.app_identity import app_identity
 from google.appengine.api import mail
 from google.appengine.api import taskqueue
-from six import iteritems
 import urllib3  # pylint: disable=import-error
 import webapp2  # pylint: disable=import-error
 import yaml
@@ -144,7 +143,7 @@
 
       if limit_models:
         # only process required models
-        metadata = {k: v for (k, v) in iteritems(metadata) if k in limit_models}
+        metadata = {k: v for (k, v) in metadata.items() if k in limit_models}
       self.hwid_manager.UpdateBoards(metadata, delete_missing=not do_limit)
 
     except filesystem_adapter.FileSystemAdaptorException:
@@ -260,7 +259,7 @@
     reviewers = self.hwid_manager.GetCLReviewers()
     ccs = self.hwid_manager.GetCLCCs()
     new_git_files = []
-    for filepath, filecontent in iteritems(new_files):
+    for filepath, filecontent in new_files.items():
       new_git_files.append((
           os.path.join(prefix, filepath), GIT_NORMAL_FILE_MODE, filecontent))
 
@@ -349,7 +348,7 @@
 
     db_lists = self.GetPayloadDBLists()
 
-    for board, db_list in iteritems(db_lists):
+    for board, db_list in db_lists.items():
       result = vpg_module.GenerateVerificationPayload(db_list)
       if result.error_msgs:
         logging.error('Generate Payload fail: %s', ' '.join(result.error_msgs))
@@ -408,5 +407,5 @@
     if force_update:
       self.response.write(json_utils.DumpStr(payload_hash_mapping,
                                              sort_keys=True))
-    for board, payload_hash in iteritems(payload_hash_mapping):
+    for board, payload_hash in payload_hash_mapping.items():
       self.hwid_manager.SetLatestPayloadHash(board, payload_hash)
diff --git a/py/hwid/v3/bom.py b/py/hwid/v3/bom.py
index cb80974..0f094c7 100644
--- a/py/hwid/v3/bom.py
+++ b/py/hwid/v3/bom.py
@@ -25,8 +25,6 @@
 import logging
 import re
 
-from six import iteritems
-
 from cros.factory.utils import type_utils
 
 
@@ -48,7 +46,7 @@
     self.image_id = image_id
     self.components = {}
 
-    for comp_cls, comp_names in iteritems(components):
+    for comp_cls, comp_names in components.items():
       self.SetComponent(comp_cls, comp_names)
 
   def SetComponent(self, comp_cls, comp_names):
diff --git a/py/hwid/v3/builder.py b/py/hwid/v3/builder.py
index 78f1ccc..748f6d6 100644
--- a/py/hwid/v3/builder.py
+++ b/py/hwid/v3/builder.py
@@ -9,8 +9,6 @@
 import re
 import uuid
 
-from six import iteritems
-
 from cros.factory.hwid.v3 import common
 from cros.factory.hwid.v3.database import Database
 from cros.factory.hwid.v3 import probe
@@ -316,7 +314,7 @@
     """
     def _IsSubset(subset, superset):
       return all([subset.get(key) == value
-                  for key, value in iteritems(superset)])
+                  for key, value in superset.items()])
 
     # Only add the unique component to the database.
     # For example, if the given probed values are
@@ -357,7 +355,7 @@
     """
     # Add extra components.
     existed_comp_classes = self.database.GetComponentClasses()
-    for comp_cls, probed_comps in iteritems(probed_results):
+    for comp_cls, probed_comps in probed_results.items():
       if comp_cls not in existed_comp_classes:
         # We only need the probe values here.
         probed_values = [probed_comp['values'] for probed_comp in probed_comps]
@@ -390,7 +388,7 @@
         common.OPERATION_MODE.normal, True)
 
     if mismatched_probed_results:
-      for comp_cls, probed_comps in iteritems(mismatched_probed_results):
+      for comp_cls, probed_comps in mismatched_probed_results.items():
         self._AddComponents(
             comp_cls, [probed_comp['values'] for probed_comp in probed_comps])
 
@@ -441,7 +439,7 @@
 
       for comps in self.database.GetEncodedField(field_name).values():
         if all(comp_names == bom.components[comp_cls]
-               for comp_cls, comp_names in iteritems(comps)):
+               for comp_cls, comp_names in comps.items()):
           break
 
       else:
@@ -524,7 +522,7 @@
         handled_encoded_fields.add(field_name)
 
       # Put the priority components.
-      for comp_cls, bit_length in iteritems(PRIORITY_COMPS):
+      for comp_cls, bit_length in PRIORITY_COMPS.items():
         if comp_cls in handled_comp_classes:
           continue
 
diff --git a/py/hwid/v3/database.py b/py/hwid/v3/database.py
index 2ede61e..596a1b0 100644
--- a/py/hwid/v3/database.py
+++ b/py/hwid/v3/database.py
@@ -41,8 +41,6 @@
 import logging
 import re
 
-from six import iteritems
-
 from cros.factory.hwid.v3 import common
 from cros.factory.hwid.v3.rule import Rule
 from cros.factory.hwid.v3.rule import Value
@@ -335,7 +333,7 @@
     """
     comps = self._components.GetComponents(comp_cls)
     if not include_default:
-      comps = {name: info for name, info in iteritems(comps)
+      comps = {name: info for name, info in comps.items()
                if info.values is not None}
     return comps
 
@@ -397,7 +395,7 @@
     # Each encoded field should be well defined.
     for encoded_field_name in self.encoded_fields:
       for comps in self.GetEncodedField(encoded_field_name).values():
-        for comp_cls, comp_names in iteritems(comps):
+        for comp_cls, comp_names in comps.items():
           missing_comp_names = (
               set(comp_names) - set(self.GetComponents(comp_cls).keys()))
           if missing_comp_names:
@@ -406,7 +404,7 @@
                 missing_comp_names)
 
   def _VerifyEncodedFieldComponents(self, components):
-    for comp_cls, comp_names in iteritems(components):
+    for comp_cls, comp_names in components.items():
       for comp_name in comp_names:
         if comp_name not in self.GetComponents(comp_cls):
           raise common.HWIDException('The component %r is not recorded '
@@ -436,7 +434,7 @@
           'Invalid source %r for `%s` part of a HWID database.' %
           (source, self.PART_TAG))
 
-    for number, name in iteritems(source):
+    for number, name in source.items():
       self[number] = name
 
   def Export(self):
@@ -545,7 +543,7 @@
     Raises:
       common.HWIDException if the image id is not found.
     """
-    for i, name in iteritems(self):
+    for i, name in self.items():
       if name == image_name:
         return i
 
@@ -692,14 +690,14 @@
     self._can_encode = True
     self._region_field_legacy_info = {}
 
-    for field_name, field_data in iteritems(encoded_fields_expr):
+    for field_name, field_data in encoded_fields_expr.items():
       if isinstance(field_data, yaml.RegionField):
         self._region_field_legacy_info[field_name] = field_data.is_legacy_style
       self._RegisterNewEmptyField(field_name,
                                   list(next(iter(field_data.values()))))
-      for index, comps in iteritems(field_data):
+      for index, comps in field_data.items():
         comps = yaml.Dict([(c, self._StandardlizeList(n))
-                           for c, n in iteritems(comps)])
+                           for c, n in comps.items()])
         self.AddFieldComponents(field_name, comps, _index=index)
 
     # Preserve the class type reported by the parser.
@@ -743,8 +741,8 @@
       raise common.HWIDException('The field name %r is invalid.' % field_name)
 
     ret = {}
-    for index, comps in iteritems(self._fields[field_name]):
-      ret[index] = {c: self._StandardlizeList(n) for c, n in iteritems(comps)}
+    for index, comps in self._fields[field_name].items():
+      ret[index] = {c: self._StandardlizeList(n) for c, n in comps.items()}
     return ret
 
   def GetComponentClasses(self, field_name):
@@ -770,7 +768,7 @@
     Returns:
       None if no field for that; otherwise a string of the field name.
     """
-    for field_name, comp_cls_set in iteritems(self._field_to_comp_classes):
+    for field_name, comp_cls_set in self._field_to_comp_classes.items():
       if comp_cls in comp_cls_set:
         return field_name
     return None
@@ -797,10 +795,10 @@
       raise common.HWIDException('Each encoded field should encode a fixed set '
                                  'of component classes.')
 
-    counters = {c: collections.Counter(n) for c, n in iteritems(components)}
-    for existing_index, existing_comps in iteritems(self.GetField(field_name)):
+    counters = {c: collections.Counter(n) for c, n in components.items()}
+    for existing_index, existing_comps in self.GetField(field_name).items():
       if all(counter == collections.Counter(existing_comps[comp_cls])
-             for comp_cls, counter in iteritems(counters)):
+             for comp_cls, counter in counters.items()):
         self._can_encode = False
         logging.warning(
             'The components combination %r already exists (at index %r).',
@@ -809,7 +807,7 @@
     index = (_index if _index is not None
              else max(self._fields[field_name].keys() or [-1]) + 1)
     self._fields[field_name][index] = yaml.Dict(
-        sorted([(c, self._SimplifyList(n)) for c, n in iteritems(components)]))
+        sorted([(c, self._SimplifyList(n)) for c, n in components.items()]))
 
   def AddNewField(self, field_name, components):
     """Adds a new field.
@@ -999,9 +997,9 @@
     self._default_components = set()
     self._non_probeable_component_classes = set()
 
-    for comp_cls, comps_data in iteritems(self._components_expr):
+    for comp_cls, comps_data in self._components_expr.items():
       self._components[comp_cls] = {}
-      for comp_name, comp_attr in iteritems(comps_data['items']):
+      for comp_name, comp_attr in comps_data['items'].items():
         self._AddComponent(comp_cls, comp_name, comp_attr['values'],
                            comp_attr.get('status',
                                          common.COMPONENT_STATUS.supported))
@@ -1033,7 +1031,7 @@
     for comp_cls in self.component_classes:
       components_dict = self._components_expr.setdefault(
           comp_cls, {'items': yaml.Dict()})['items']
-      for comp_name, comp_info in iteritems(self.GetComponents(comp_cls)):
+      for comp_name, comp_info in self.GetComponents(comp_cls).items():
         if comp_name not in components_dict:
           components_dict[comp_name] = yaml.Dict()
           if comp_info.status != common.COMPONENT_STATUS.supported:
@@ -1084,7 +1082,7 @@
     Returns:
       None or a string of the component name.
     """
-    for comp_name, comp_info in iteritems(self._components.get(comp_cls, {})):
+    for comp_name, comp_info in self._components.get(comp_cls, {}).items():
       if comp_info.values is None:
         return comp_name
     return None
@@ -1139,8 +1137,8 @@
                       'mark can_encode=False.', comp_cls)
       self._can_encode = False
 
-    for existed_comp_name, existed_comp_info in iteritems(self.GetComponents(
-        comp_cls)):
+    for existed_comp_name, existed_comp_info in self.GetComponents(
+        comp_cls).items():
       existed_comp_values = existed_comp_info.values
       # At here, we only complain if two components are exactly the same.  There
       # is another case that is not caught here: at least one of the component
@@ -1295,7 +1293,7 @@
     """Exports this `pattern` part of HWID database into a serializable object
     which can be stored into a HWID database file."""
     pattern_list = []
-    for image_id, pattern in sorted(iteritems(self._image_id_to_pattern)):
+    for image_id, pattern in sorted(self._image_id_to_pattern.items()):
       for obj_to_export, existed_pattern in pattern_list:
         if pattern is existed_pattern:
           obj_to_export['image_ids'].append(image_id)
diff --git a/py/hwid/v3/database_unittest.py b/py/hwid/v3/database_unittest.py
index 48efa02..de5b17e 100755
--- a/py/hwid/v3/database_unittest.py
+++ b/py/hwid/v3/database_unittest.py
@@ -6,8 +6,6 @@
 import os
 import unittest
 
-from six import iteritems
-
 from cros.factory.hwid.v3.common import HWIDException
 from cros.factory.hwid.v3.database import Components
 from cros.factory.hwid.v3.database import Database
@@ -23,7 +21,7 @@
 
 def Unordered(data):
   if isinstance(data, dict):
-    return {k: Unordered(v) for k, v in iteritems(data)}
+    return {k: Unordered(v) for k, v in data.items()}
   elif isinstance(data, list):
     return [Unordered(a) for a in data]
   return data
diff --git a/py/hwid/v3/hwid_cmdline.py b/py/hwid/v3/hwid_cmdline.py
index 2eb16ac..f35e69e 100755
--- a/py/hwid/v3/hwid_cmdline.py
+++ b/py/hwid/v3/hwid_cmdline.py
@@ -14,8 +14,6 @@
 import shutil
 import sys
 
-from six import iteritems
-
 from cros.factory.hwid.v3 import builder
 from cros.factory.hwid.v3 import converter
 from cros.factory.hwid.v3.database import Database
@@ -387,7 +385,7 @@
     for k in sorted(hwids):
       Output(k)
   else:
-    for k, v in sorted(iteritems(hwids)):
+    for k, v in sorted(hwids.items()):
       Output('%s: %s' % (k, v))
 
 
diff --git a/py/hwid/v3/hwid_utils.py b/py/hwid/v3/hwid_utils.py
index 12091ab..cdc978e 100644
--- a/py/hwid/v3/hwid_utils.py
+++ b/py/hwid/v3/hwid_utils.py
@@ -8,8 +8,6 @@
 import logging
 import os
 
-from six import iteritems
-
 from cros.factory.hwid.v3.bom import BOM
 from cros.factory.hwid.v3 import common
 from cros.factory.hwid.v3.database import Database
@@ -223,7 +221,7 @@
                      '"released", "all", but got %r.' % status)
 
   def _IsComponentsSetValid(comps):
-    for comp_cls, comp_names in iteritems(comps):
+    for comp_cls, comp_names in comps.items():
       comp_names = type_utils.MakeList(comp_names)
       if (comp_cls in limited_comps and
           sorted(list(limited_comps[comp_cls])) != sorted(comp_names)):
@@ -256,15 +254,15 @@
           combinations, i + 1, selected_combinations)
 
   combinations = []
-  for field_name, bit_length in iteritems(database.GetEncodedFieldsBitLength(
-      image_id)):
+  for field_name, bit_length in database.GetEncodedFieldsBitLength(
+      image_id).items():
     max_index = (1 << bit_length) - 1
     last_combinations = []
-    for index, comps_set in iteritems(database.GetEncodedField(field_name)):
+    for index, comps_set in database.GetEncodedField(field_name).items():
       if index <= max_index and _IsComponentsSetValid(comps_set):
         last_combinations.append(
             {comp_cls: type_utils.MakeList(comp_names)
-             for comp_cls, comp_names in iteritems(comps_set)})
+             for comp_cls, comp_names in comps_set.items()})
 
     if not last_combinations:
       return {}
diff --git a/py/hwid/v3/hwid_utils_unittest.py b/py/hwid/v3/hwid_utils_unittest.py
index 6ff093b..2457d1e 100755
--- a/py/hwid/v3/hwid_utils_unittest.py
+++ b/py/hwid/v3/hwid_utils_unittest.py
@@ -9,7 +9,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.hwid.v3.bom import BOM
 from cros.factory.hwid.v3 import common
@@ -38,7 +37,7 @@
     self.assertEqual(bom1.encoding_pattern_index, bom2.encoding_pattern_index)
     self.assertEqual(bom1.image_id, bom2.image_id)
     self.assertEqual(set(bom1.components.keys()), set(bom2.components.keys()))
-    for comp_cls, bom1_comp_names in iteritems(bom1.components):
+    for comp_cls, bom1_comp_names in bom1.components.items():
       self.assertEqual(bom1_comp_names, bom2.components[comp_cls])
 
   def setUp(self):
@@ -151,7 +150,7 @@
 class ListComponentsTest(_HWIDTestCaseBase):
   def _TestListComponents(self, comp_cls, expected_results):
     def _ConvertToSets(orig_dict):
-      return {key: set(value) for key, value in iteritems(orig_dict)}
+      return {key: set(value) for key, value in orig_dict.items()}
 
     results = hwid_utils.ListComponents(self.database, comp_cls)
     self.assertEqual(_ConvertToSets(results), _ConvertToSets(expected_results))
diff --git a/py/hwid/v3/probe.py b/py/hwid/v3/probe.py
index a2e0fc9..c052126 100644
--- a/py/hwid/v3/probe.py
+++ b/py/hwid/v3/probe.py
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-from six import iteritems
-
 from cros.factory.hwid.v3.bom import BOM
 from cros.factory.hwid.v3 import common
 from cros.factory.hwid.v3.rule import Context
@@ -51,7 +49,7 @@
         the mismatched components.
   """
   def _IsValuesMatch(probed_values, comp_values):
-    for key, value in iteritems(comp_values):
+    for key, value in comp_values.items():
       if not isinstance(value, Value):
         value = Value(value)
       if key not in probed_values or not value.Matches(probed_values[key]):
@@ -89,7 +87,7 @@
     matched_components = {}
     mismatched_components = {}
 
-    for comp_cls, comps in iteritems(probed_results):
+    for comp_cls, comps in probed_results.items():
       matched_components[comp_cls] = [comp['name'] for comp in comps]
   else:
     if mode == common.OPERATION_MODE.rma:
@@ -100,7 +98,7 @@
       component_classes = database.GetComponentClasses()
       # In normal mode, treat unrecognized components as mismatched components.
       mismatched_components = {comp_cls: comps
-                               for comp_cls, comps in iteritems(probed_results)
+                               for comp_cls, comps in probed_results.items()
                                if comp_cls not in component_classes}
 
     # Construct a dict of component classes to list of component names.
@@ -112,8 +110,8 @@
       for probed_comp in probed_results.get(comp_cls, []):
         matched_comp_name = []
         matched_comp_score = float('-inf')
-        for comp_name, comp_info in iteritems(database.GetComponents(
-            comp_cls, include_default=False)):
+        for comp_name, comp_info in database.GetComponents(
+            comp_cls, include_default=False).items():
           if comp_info.status == common.COMPONENT_STATUS.duplicate:
             # A component that is 'duplicate' is covered by another component.
             # Therefore, the duplicate one should not be used for encoding.
diff --git a/py/hwid/v3/rule.py b/py/hwid/v3/rule.py
index 3aab57d..a1ee72e 100644
--- a/py/hwid/v3/rule.py
+++ b/py/hwid/v3/rule.py
@@ -19,8 +19,6 @@
 import threading
 import time
 
-from six import iteritems
-
 from cros.factory.utils import type_utils
 
 
@@ -89,7 +87,7 @@
   """
 
   def __init__(self, **kwargs):
-    for key, value in iteritems(kwargs):
+    for key, value in kwargs.items():
       setattr(self, key, value)
 
 
diff --git a/py/hwid/v3/transformer.py b/py/hwid/v3/transformer.py
index 962710f..e2c8230 100644
--- a/py/hwid/v3/transformer.py
+++ b/py/hwid/v3/transformer.py
@@ -4,8 +4,6 @@
 
 """Implementation of HWID v3 encoder and decoder."""
 
-from six import iteritems
-
 from cros.factory.hwid.v3.bom import BOM
 from cros.factory.hwid.v3 import common
 from cros.factory.hwid.v3.identity import Identity
@@ -38,11 +36,11 @@
   # Try to encode every field and fail if some fields are missing or
   # the bit length of a field recorded in the pattern is not enough.
   encoded_fields = {}
-  for field_name, bit_length in iteritems(database.GetEncodedFieldsBitLength(
-      bom.image_id)):
-    for index, components in iteritems(database.GetEncodedField(field_name)):
+  for field_name, bit_length in database.GetEncodedFieldsBitLength(
+      bom.image_id).items():
+    for index, components in database.GetEncodedField(field_name).items():
       if all(comp_names == bom.components[comp_cls]
-             for comp_cls, comp_names in iteritems(components)):
+             for comp_cls, comp_names in components.items()):
         encoded_fields[field_name] = index
         break
 
@@ -113,7 +111,7 @@
 
   # Construct the components dict.
   components = {comp_cls: [] for comp_cls in database.GetComponentClasses()}
-  for field, index in iteritems(encoded_fields):
+  for field, index in encoded_fields.items():
     database_encoded_field = database.GetEncodedField(field)
     if index not in database_encoded_field:
       raise common.HWIDException('Invalid encoded field index: {%r: %r}' %
diff --git a/py/hwid/v3/validator.py b/py/hwid/v3/validator.py
index e52af1b..906659a 100644
--- a/py/hwid/v3/validator.py
+++ b/py/hwid/v3/validator.py
@@ -4,8 +4,6 @@
 
 """Validator for HWID DB."""
 
-from six import iteritems
-
 from cros.factory.hwid.v3 import common
 from cros.factory.hwid.v3 import bom
 from cros.factory.hwid.v3 import verify_db_pattern
@@ -39,7 +37,7 @@
 
 @_RegisterValidateIntegrityFunc
 def _ValidateDramTag(db):
-  for dram_tag, dram_info in iteritems(db.GetComponents('dram')):
+  for dram_tag, dram_info in db.GetComponents('dram').items():
     if dram_tag in _BLACKLIST_DRAM_TAG:
       continue
     try:
diff --git a/py/hwid/v3/verifier.py b/py/hwid/v3/verifier.py
index 45da54c..6936002 100644
--- a/py/hwid/v3/verifier.py
+++ b/py/hwid/v3/verifier.py
@@ -17,8 +17,6 @@
 import logging
 import re
 
-from six import iteritems
-
 from cros.factory.hwid.v3 import common
 from cros.factory.test.rules import phase
 from cros.factory.hwid.v3.configless_fields import ConfiglessFields
@@ -43,7 +41,7 @@
   Raises:
     HWIDException if verification fails.
   """
-  for comp_cls, comp_names in iteritems(bom.components):
+  for comp_cls, comp_names in bom.components.items():
     for comp_name in comp_names:
       status = database.GetComponents(comp_cls)[comp_name].status
       if status == common.COMPONENT_STATUS.supported:
@@ -154,7 +152,7 @@
         num_comps[comp] -= 1
 
     results = [[comp] * num_comp
-               for comp, num_comp in iteritems(num_comps) if num_comp > 0]
+               for comp, num_comp in num_comps.items() if num_comp > 0]
     return sorted(sum(results, []))
 
   # We only verify the components listed in the pattern.
diff --git a/py/hwid/v3/yaml_wrapper.py b/py/hwid/v3/yaml_wrapper.py
index 56dcf5d..b725a8b 100644
--- a/py/hwid/v3/yaml_wrapper.py
+++ b/py/hwid/v3/yaml_wrapper.py
@@ -11,7 +11,6 @@
 import collections
 import functools
 
-from six import iteritems
 from yaml import *  # pylint: disable=wildcard-import,unused-wildcard-import
 from yaml import constructor
 from yaml import nodes
@@ -127,7 +126,7 @@
 
   @classmethod
   def YAMLRepresenter(cls, dumper, data):
-    return dumper.represent_dict(iteritems(data))
+    return dumper.represent_dict(data.items())
 
 
 class RegionField(dict):
@@ -203,7 +202,7 @@
   def __init__(self, status_lists=None):
     # Load system regions.
     components_dict = {'items': {}}
-    for code, region in iteritems(regions.BuildRegionsDict(include_all=True)):
+    for code, region in regions.BuildRegionsDict(include_all=True).items():
       region_comp = {'values': {'region_code': region.region_code}}
       if code not in regions.REGIONS:
         region_comp['status'] = common.COMPONENT_STATUS.unsupported
diff --git a/py/instalog/core.py b/py/instalog/core.py
index fe54964..da71465 100644
--- a/py/instalog/core.py
+++ b/py/instalog/core.py
@@ -12,8 +12,6 @@
 import time
 import _strptime  # pylint: disable=unused-import
 
-from six import iteritems
-
 from cros.factory.instalog import flow_policy
 from cros.factory.instalog import json_utils
 from cros.factory.instalog import plugin_base
@@ -102,7 +100,7 @@
 
     # Next, convert 'targets' entries to corresponding allow policy rule.
     for dct in [input_plugins, output_plugins]:
-      for plugin_id, plugin_config in iteritems(dct):
+      for plugin_id, plugin_config in dct.items():
         if 'targets' in plugin_config:
           targets = plugin_config.pop('targets')
           if not isinstance(targets, list):
@@ -118,7 +116,7 @@
                                  'position': -1})
 
     # Ensure that all output plugins have at least one event source.
-    for plugin_id, plugin_config in iteritems(output_plugins):
+    for plugin_id, plugin_config in output_plugins.items():
       if not plugin_config.get('allow'):
         raise plugin_base.ConfigError(
             'No plugin is targetting output plugin `%s\'.  Please (1) disable '
@@ -176,7 +174,7 @@
 
   def _ConfigEntriesToSandboxes(self, superclass, entries):
     plugins = {}
-    for plugin_id, plugin_config in iteritems(entries):
+    for plugin_id, plugin_config in entries.items():
       # Parse this particular plugin entry and add to the _plugins map.
       plugin_entry = self._ConfigEntryToSandbox(
           superclass=superclass,
diff --git a/py/instalog/datatypes.py b/py/instalog/datatypes.py
index 6b1ecf9..678fc34 100644
--- a/py/instalog/datatypes.py
+++ b/py/instalog/datatypes.py
@@ -16,8 +16,6 @@
 import logging
 import time
 
-from six import iteritems
-
 from cros.factory.instalog import json_utils
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog.utils import time_utils
@@ -150,7 +148,7 @@
       return False
     if not len(self.attachments) == len(other.attachments):
       return False
-    for att_id, att_path in iteritems(self.attachments):
+    for att_id, att_path in self.attachments.items():
       if att_id not in other.attachments:
         return False
       other_path = other.attachments[att_id]
@@ -188,7 +186,7 @@
 
   def iteritems(self):
     """Implements iteritems function."""
-    return iteritems(self.payload)
+    return iter(self.payload.items())
 
   def setdefault(self, key, default):
     """Implements setdefault function."""
diff --git a/py/instalog/flow_policy.py b/py/instalog/flow_policy.py
index 5170301..4dbdee7 100644
--- a/py/instalog/flow_policy.py
+++ b/py/instalog/flow_policy.py
@@ -9,8 +9,6 @@
 
 import logging
 
-from six import iteritems
-
 # Name of the key used to specify the rule type in the config dictionary.
 _RULE_TYPE_KEY = 'rule'
 
@@ -138,7 +136,7 @@
       logging.debug('%s: %r', position, process_stage)
 
       valid = True
-      for key, operation in iteritems(self.args):
+      for key, operation in self.args.items():
         # Special case for the 'position' key.
         if key == 'position':
           lhs = position
@@ -174,7 +172,7 @@
 
   def MatchEvent(self, event):
     """Checks whether the provided event matches this rule."""
-    for key, operation in iteritems(self.args):
+    for key, operation in self.args.items():
       lhs = event.get(key, None)
       if not lhs:
         logging.debug('The %s is not in the event', key)
diff --git a/py/instalog/plugins/buffer_file_common.py b/py/instalog/plugins/buffer_file_common.py
index 8351ea1..4122d60 100644
--- a/py/instalog/plugins/buffer_file_common.py
+++ b/py/instalog/plugins/buffer_file_common.py
@@ -80,8 +80,6 @@
 import shutil
 import zlib
 
-from six import iteritems
-
 from cros.factory.instalog import datatypes
 from cros.factory.instalog import lock_utils
 from cros.factory.instalog import log_utils
@@ -216,7 +214,7 @@
     f.seek(0, 2)  # 2 means use EOF as the reference point.
     assert f.tell() == cur_pos
     for event in events:
-      for att_id, att_path in iteritems(event.attachments):
+      for att_id, att_path in event.attachments.items():
         target_name = '%s_%s' % (cur_seq, att_id)
         target_path = os.path.join(config_dct['attachments_dir'], target_name)
         event.attachments[att_id] = target_name
@@ -594,12 +592,12 @@
       # that event doesn't exist yet, it will be set to the next (non-existent)
       # sequence ID.  We must subtract 1 to get the "last completed" event.
       cur_seqs = {key: consumer.cur_seq - 1
-                  for key, consumer in iteritems(self.consumers)}
+                  for key, consumer in self.consumers.items()}
       # Grab last_seq at the end, in order to guarantee that for any consumer,
       # last_seq >= cur_seq, and that all last_seq are equal.
       last_seq = self.last_seq
       return {key: (cur_seq, last_seq)
-              for key, cur_seq in iteritems(cur_seqs)}
+              for key, cur_seq in cur_seqs.items()}
 
   def Consume(self, name):
     """See BufferPlugin.Consume."""
diff --git a/py/instalog/plugins/buffer_priority_file.py b/py/instalog/plugins/buffer_priority_file.py
index bb2b542..5ec8f2a 100755
--- a/py/instalog/plugins/buffer_priority_file.py
+++ b/py/instalog/plugins/buffer_priority_file.py
@@ -24,8 +24,6 @@
 import os
 import shutil
 
-from six import iteritems
-
 from cros.factory.instalog import json_utils
 from cros.factory.instalog import lock_utils
 from cros.factory.instalog import log_utils
@@ -219,7 +217,7 @@
     """Recovers metadatas in the temporary file."""
     all_metadata = json_utils.decoder.decode(
         file_utils.ReadFile(tmp_metadata_path))
-    for path, metadata in iteritems(all_metadata):
+    for path, metadata in all_metadata.items():
       self.info('Recover metadata: `%s` New: `%s` Old: `%s`', path, metadata,
                 file_utils.ReadFile(path) if os.path.exists(path) else 'None')
       if metadata is None:
@@ -255,7 +253,7 @@
         # Step 1: Copy attachments.
         source_paths = []
         for event in events:
-          for att_id, att_path in iteritems(event.attachments):
+          for att_id, att_path in event.attachments.items():
             source_paths.append(att_path)
             event.attachments[att_id] = os.path.join(
                 tmp_dir, att_path.replace('/', '_'))
diff --git a/py/instalog/plugins/buffer_simple_file.py b/py/instalog/plugins/buffer_simple_file.py
index 0e4271f..83c03c5 100755
--- a/py/instalog/plugins/buffer_simple_file.py
+++ b/py/instalog/plugins/buffer_simple_file.py
@@ -15,8 +15,6 @@
 import os
 import shutil
 
-from six import iteritems
-
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog.plugins import buffer_file_common
 from cros.factory.instalog.utils.arg_utils import Arg
@@ -94,7 +92,7 @@
         # Step 1: Copy attachments.
         source_paths = []
         for event in events:
-          for att_id, att_path in iteritems(event.attachments):
+          for att_id, att_path in event.attachments.items():
             source_paths.append(att_path)
             event.attachments[att_id] = os.path.join(
                 tmp_dir, att_path.replace('/', '_'))
diff --git a/py/instalog/plugins/input_archive.py b/py/instalog/plugins/input_archive.py
index 38c4e4a..6321074 100755
--- a/py/instalog/plugins/input_archive.py
+++ b/py/instalog/plugins/input_archive.py
@@ -31,8 +31,6 @@
 import os
 import tarfile
 
-from six import iteritems
-
 from cros.factory.instalog import datatypes
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog.utils.arg_utils import Arg
@@ -101,7 +99,7 @@
     with open(path, 'r') as f:
       for line in f:
         event = self.ParseEvent(path, line)
-        for att_id, att_path in iteritems(event.attachments):
+        for att_id, att_path in event.attachments.items():
           event.attachments[att_id] = os.path.join(event_dir, att_path)
         events.append(event)
       self.info('Parsed %d events', len(events))
diff --git a/py/instalog/plugins/input_eventlog_file_vswr.py b/py/instalog/plugins/input_eventlog_file_vswr.py
index 905221e..c3182e0 100755
--- a/py/instalog/plugins/input_eventlog_file_vswr.py
+++ b/py/instalog/plugins/input_eventlog_file_vswr.py
@@ -114,8 +114,6 @@
 
 import datetime
 
-from six import iteritems
-
 from cros.factory.instalog import datatypes
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog.plugins import input_eventlog_file
@@ -175,12 +173,12 @@
     test_run['parameters'] = {}
 
     test_run['series'] = {}
-    for antenna, measurements in iteritems(dct['test']['traces']):
+    for antenna, measurements in dct['test']['traces'].items():
       test_run['series'][antenna] = {}
       test_run['series'][antenna]['keyUnit'] = 'MHz'
       test_run['series'][antenna]['valueUnit'] = 'dB'
       test_run['series'][antenna]['data'] = []
-      for freq, db in iteritems(measurements):
+      for freq, db in measurements.items():
         test_run['series'][antenna]['data'].append({})
         test_run['series'][antenna]['data'][-1]['key'] = freq
         test_run['series'][antenna]['data'][-1]['numericValue'] = db
diff --git a/py/instalog/plugins/input_http.py b/py/instalog/plugins/input_http.py
index 02e6fe9..897e4a8 100755
--- a/py/instalog/plugins/input_http.py
+++ b/py/instalog/plugins/input_http.py
@@ -37,8 +37,6 @@
 import threading
 import time
 
-from six import iteritems
-
 from cros.factory.instalog import datatypes
 from cros.factory.instalog import log_utils
 from cros.factory.instalog import plugin_base
@@ -195,7 +193,7 @@
             if key != 'event':
               event.attachments[key] = key
 
-        for att_id, att_key in iteritems(event.attachments):
+        for att_id, att_key in event.attachments.items():
           if att_key not in form or isinstance(form[att_key], list):
             raise ValueError('Attachment(%s) should have exactly one in the '
                              'request' % att_key)
diff --git a/py/instalog/plugins/input_testlog_file.py b/py/instalog/plugins/input_testlog_file.py
index 96e3d0f..070a369 100755
--- a/py/instalog/plugins/input_testlog_file.py
+++ b/py/instalog/plugins/input_testlog_file.py
@@ -14,8 +14,6 @@
 import json
 import os
 
-from six import iteritems
-
 from cros.factory.instalog import datatypes
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog.plugins import input_log_file
@@ -33,7 +31,7 @@
     #                 (b) Import testlog and use FromJSON directly.
     attachments = {}
     if 'attachments' in data:
-      for att_id, att_data in iteritems(data['attachments']):
+      for att_id, att_data in data['attachments'].items():
         # Only add the attachment if the path exists.
         if os.path.isfile(att_data['path']):
           attachments[att_id] = att_data['path']
diff --git a/py/instalog/plugins/output_bigquery.py b/py/instalog/plugins/output_bigquery.py
index b5b2613..656caf0 100755
--- a/py/instalog/plugins/output_bigquery.py
+++ b/py/instalog/plugins/output_bigquery.py
@@ -27,8 +27,6 @@
 import os
 import time
 
-from six import iteritems
-
 # pylint: disable=import-error, no-name-in-module
 from google.cloud import bigquery
 from google.cloud import exceptions
@@ -160,7 +158,7 @@
 
   def UploadAttachments(self, event):
     """Uploads attachments in an event to Google Cloud Storage."""
-    for att_id, att_path in iteritems(event.attachments):
+    for att_id, att_path in event.attachments.items():
       target_filename = file_utils.SHA1InHex(att_path)
       target_dir = self.args.gcs_target_dir.strip('/')
       target_path = '/%s/%s' % (target_dir, target_filename)
diff --git a/py/instalog/plugins/output_bigquery_testlog.py b/py/instalog/plugins/output_bigquery_testlog.py
index ff5cc8a..269804e 100755
--- a/py/instalog/plugins/output_bigquery_testlog.py
+++ b/py/instalog/plugins/output_bigquery_testlog.py
@@ -15,8 +15,6 @@
 import json
 import math
 
-from six import iteritems
-
 # pylint: disable=import-error, no-name-in-module
 from google.cloud.bigquery.schema import SchemaField
 
@@ -151,13 +149,13 @@
     # station.status
     row['filePath'] = event.get('filePath')  # also in station.message
     row['serialNumbers'] = []
-    for key, value in iteritems(event.get('serialNumbers', {})):
+    for key, value in event.get('serialNumbers', {}).items():
       row['serialNumbers'].append({})
       row['serialNumbers'][-1]['key'] = key
       row['serialNumbers'][-1]['value'] = value
 
     row['parameters'] = []
-    for key, dct in iteritems(event.get('parameters', {})):
+    for key, dct in event.get('parameters', {}).items():
       dct = dct or {}
       row['parameters'].append({})
       row['parameters'][-1]['key'] = key
@@ -169,7 +167,7 @@
 
 
     row['parameters'] = []
-    for key, dct in iteritems(event.get('parameters', {})):
+    for key, dct in event.get('parameters', {}).items():
       row['parameters'].append({})
       row['parameters'][-1]['key'] = key
       row['parameters'][-1]['description'] = dct.get('description')
@@ -222,7 +220,7 @@
     row['testType'] = event.get('testType')
 
     row['arguments'] = []
-    for key, dct in iteritems(event.get('arguments', {})):
+    for key, dct in event.get('arguments', {}).items():
       row['arguments'].append({})
       row['arguments'][-1]['key'] = key
       row['arguments'][-1]['description'] = dct.get('description')
@@ -236,7 +234,7 @@
     row['operatorId'] = event.get('operatorId')
 
     row['attachments'] = []
-    for key, dct in iteritems(event.get('attachments', {})):
+    for key, dct in event.get('attachments', {}).items():
       row['attachments'].append({})
       row['attachments'][-1]['key'] = key
       row['attachments'][-1]['description'] = dct.get('description')
diff --git a/py/instalog/plugins/output_classify.py b/py/instalog/plugins/output_classify.py
index e3266d6..739a6c2 100755
--- a/py/instalog/plugins/output_classify.py
+++ b/py/instalog/plugins/output_classify.py
@@ -28,8 +28,6 @@
 import os
 import shutil
 
-from six import iteritems
-
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog.plugins import output_file
 from cros.factory.instalog.utils import arg_utils
@@ -98,7 +96,7 @@
             type_utils.GetDict(event, classifier_name, '__UNKNOWN__'))
       self.subdir_path = os.path.join(self.subdir_path, subdir_name)
 
-    for att_id, att_path in iteritems(event.attachments):
+    for att_id, att_path in event.attachments.items():
       if os.path.isfile(att_path):
         att_hash = file_utils.SHA1InHex(att_path)
         att_newpath = os.path.join(output_file.ATT_DIR_NAME, att_hash)
diff --git a/py/instalog/plugins/output_classify_unittest.py b/py/instalog/plugins/output_classify_unittest.py
index 716ff7d..19e0501 100755
--- a/py/instalog/plugins/output_classify_unittest.py
+++ b/py/instalog/plugins/output_classify_unittest.py
@@ -15,7 +15,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.instalog import datatypes
 from cros.factory.instalog import log_utils
@@ -107,7 +106,7 @@
       self.assertEqual(event2, datatypes.Event.Deserialize(lines[0]))
 
   def ChangeRelativePath(self, event, base_dir):
-    for att_id, relative_path in iteritems(event.attachments):
+    for att_id, relative_path in event.attachments.items():
       event.attachments[att_id] = os.path.join(
           base_dir, relative_path)
 
diff --git a/py/instalog/plugins/output_file.py b/py/instalog/plugins/output_file.py
index 53f5e97..f4514e1 100755
--- a/py/instalog/plugins/output_file.py
+++ b/py/instalog/plugins/output_file.py
@@ -25,8 +25,6 @@
 import os
 import shutil
 
-from six import iteritems
-
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog.utils.arg_utils import Arg
 from cros.factory.instalog.utils import file_utils
@@ -100,7 +98,7 @@
 
   def PrepareEvent(self, event, base_dir):
     """Copies an event's attachments and returns its serialized form."""
-    for att_id, att_path in iteritems(event.attachments):
+    for att_id, att_path in event.attachments.items():
       if os.path.isfile(att_path):
         att_hash = file_utils.SHA1InHex(att_path)
         att_newpath = os.path.join(ATT_DIR_NAME, att_hash)
@@ -111,7 +109,7 @@
   def GetEventAttachmentSize(self, event):
     """Returns the total size of given event's attachments."""
     total_size = 0
-    for _unused_att_id, att_path in iteritems(event.attachments):
+    for _unused_att_id, att_path in event.attachments.items():
       if os.path.isfile(att_path):
         total_size += os.path.getsize(att_path)
     return total_size
diff --git a/py/instalog/plugins/output_file_unittest.py b/py/instalog/plugins/output_file_unittest.py
index 031fb61..723b74d 100755
--- a/py/instalog/plugins/output_file_unittest.py
+++ b/py/instalog/plugins/output_file_unittest.py
@@ -13,8 +13,6 @@
 import tempfile
 import unittest
 
-from six import iteritems
-
 from cros.factory.instalog import datatypes
 from cros.factory.instalog import log_utils
 from cros.factory.instalog import plugin_sandbox
@@ -86,7 +84,7 @@
       self.assertEqual([], deserialized_event.history)
 
   def ChangeRelativePath(self, event, base_dir):
-    for att_id, relative_path in iteritems(event.attachments):
+    for att_id, relative_path in event.attachments.items():
       event.attachments[att_id] = os.path.join(
           base_dir, relative_path)
 
diff --git a/py/instalog/plugins/output_gcs.py b/py/instalog/plugins/output_gcs.py
index 44f4ac6..f2abed5 100755
--- a/py/instalog/plugins/output_gcs.py
+++ b/py/instalog/plugins/output_gcs.py
@@ -8,8 +8,6 @@
 
 from __future__ import print_function
 
-from six import iteritems
-
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog.utils.arg_utils import Arg
 from cros.factory.instalog.utils import file_utils
@@ -103,7 +101,7 @@
 
   def UploadEvent(self, event):
     """Uploads attachments of given event."""
-    for att_id, att_path in iteritems(event.attachments):
+    for att_id, att_path in event.attachments.items():
       target_filename = (file_utils.SHA1InHex(att_path) if self.args.use_sha1
                          else att_id)
       target_path = '/%s/%s' % (self.target_dir, target_filename)
diff --git a/py/instalog/plugins/output_http.py b/py/instalog/plugins/output_http.py
index 2f42cdb..e9dacc4 100755
--- a/py/instalog/plugins/output_http.py
+++ b/py/instalog/plugins/output_http.py
@@ -17,7 +17,6 @@
 import time
 
 import requests
-from six import iteritems
 
 from cros.factory.instalog import datatypes
 from cros.factory.instalog import plugin_base
@@ -184,7 +183,7 @@
     request_body = []
     att_seq = 0
     for event in events:
-      for att_id, att_path in iteritems(event.attachments):
+      for att_id, att_path in event.attachments.items():
         att_newname = '%s_%03d' % (os.path.basename(att_path), att_seq)
         att_seq += 1
         if self._gpg:
diff --git a/py/instalog/plugins/output_socket.py b/py/instalog/plugins/output_socket.py
index 4e85750..f346339 100755
--- a/py/instalog/plugins/output_socket.py
+++ b/py/instalog/plugins/output_socket.py
@@ -20,8 +20,6 @@
 import socket
 import time
 
-from six import iteritems
-
 from cros.factory.instalog import log_utils
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog.plugins import socket_common
@@ -217,7 +215,7 @@
     serialized_event = event.Serialize()
     total_bytes += self.SendField(serialized_event)
     self.SendInt(len(attachments))
-    for att_id, att_path in iteritems(attachments):
+    for att_id, att_path in attachments.items():
       total_bytes += self.SendAttachment(att_id, att_path)
     return total_bytes
 
diff --git a/py/instalog/plugins/testlog_common.py b/py/instalog/plugins/testlog_common.py
index fb444da..f2b6e1d 100644
--- a/py/instalog/plugins/testlog_common.py
+++ b/py/instalog/plugins/testlog_common.py
@@ -7,8 +7,6 @@
 import datetime
 import json
 
-from six import iteritems
-
 from cros.factory.instalog import json_utils
 from cros.factory.instalog.utils import time_utils
 
@@ -37,12 +35,12 @@
       if event['status'] == 'FAILED':
         event['status'] = 'FAIL'
     if 'arguments' in event:
-      for name, dct in iteritems(event['arguments']):
+      for name, dct in event['arguments'].items():
         dct['value'] = json.dumps(dct['value'])
 
     new_parameters = {}
     if 'series' in event:
-      for name, dct in iteritems(event['series']):
+      for name, dct in event['series'].items():
         key_name = name + '_key'
         value_name = name + '_value'
         new_parameters[key_name] = {'group': name, 'type': 'argument',
@@ -63,7 +61,7 @@
             new_parameters[value_name]['data'].append(data)
       del event.payload['series']
     if 'parameters' in event:
-      for name, dct in iteritems(event['parameters']):
+      for name, dct in event['parameters'].items():
         name = 'parameter_' + name
         new_parameters[name] = {'type': 'measurement'}
         if 'description' in dct:
diff --git a/py/instalog/run_plugin.py b/py/instalog/run_plugin.py
index f4fdeff..f4ec8d6 100755
--- a/py/instalog/run_plugin.py
+++ b/py/instalog/run_plugin.py
@@ -18,8 +18,6 @@
 import tempfile
 import time
 
-from six import iteritems
-
 from cros.factory.instalog import datatypes
 from cros.factory.instalog import log_utils
 from cros.factory.instalog import plugin_base
@@ -266,7 +264,7 @@
     self.debug('Emit %d events: %s', len(events), events)
     for event in events:
       # Move attachments to a temporary directory to simulate buffer.
-      for att_id, att_path in iteritems(event.attachments):
+      for att_id, att_path in event.attachments.items():
         # Use a filename that contains the original one for clarity.
         tmp_path = file_utils.CreateTemporaryFile(
             prefix=os.path.basename(att_path), dir=self._att_dir)
diff --git a/py/instalog/testing.py b/py/instalog/testing.py
index 0f64037..6bbb8e0 100644
--- a/py/instalog/testing.py
+++ b/py/instalog/testing.py
@@ -14,8 +14,6 @@
 import shutil
 import tempfile
 
-from six import iteritems
-
 from cros.factory.instalog import plugin_base
 from cros.factory.instalog import plugin_sandbox
 from cros.factory.instalog.utils import file_utils
@@ -61,7 +59,7 @@
     del plugin
     for event in events:
       # Move attachments to a temporary directory to simulate buffer.
-      for att_id, att_path in iteritems(event.attachments):
+      for att_id, att_path in event.attachments.items():
         # Use a filename that contains the original one for clarity.
         tmp_path = file_utils.CreateTemporaryFile(
             prefix=os.path.basename(att_path) + '_', dir=self._att_dir)
diff --git a/py/probe/common.py b/py/probe/common.py
index 7ab31ab..4fe56b4 100644
--- a/py/probe/common.py
+++ b/py/probe/common.py
@@ -8,8 +8,6 @@
 
 import os
 
-from six import iteritems
-
 from cros.factory.probe import function
 from cros.factory.probe.functions.approx_match import ApproxMatchFunction
 from cros.factory.probe.functions.match import MatchFunction
@@ -73,7 +71,7 @@
     the probe results.
   """
   def _FilterKey(values, statement):
-    return {k: v for k, v in iteritems(values)
+    return {k: v for k, v in values.items()
             if k in statement['keys']}
 
   def _ChooseMatchFunction(approx_match, max_mismatch):
diff --git a/py/probe/functions/approx_match.py b/py/probe/functions/approx_match.py
index ecce164..291c231 100644
--- a/py/probe/functions/approx_match.py
+++ b/py/probe/functions/approx_match.py
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-from six import iteritems
-
 from cros.factory.probe.functions import match
 from cros.factory.utils.arg_utils import Arg
 
@@ -69,12 +67,12 @@
       matched = len(item) == 1 and _Match(self.rule, next(iter(item.values())))
       matched = {list(item)[0]: matched}
       matched_rule = {key: {'result': value, 'info': self.args.rule}
-                      for key, value in iteritems(matched)}
+                      for key, value in matched.items()}
     else:
       matched = {key: key in item and _Match(rule, item[key])
-                 for key, rule in iteritems(self.rule)}
+                 for key, rule in self.rule.items()}
       matched_rule = {key: {'result': value, 'info': self.args.rule[key]}
-                      for key, value in iteritems(matched)}
+                      for key, value in matched.items()}
     return (all(matched.values()), sum(matched.values()), matched_rule, item)
 
   def ApproxMatchFilter(self, match_results):
diff --git a/py/probe/functions/approx_match_unittest.py b/py/probe/functions/approx_match_unittest.py
index 3edacee..bbc6b8b 100755
--- a/py/probe/functions/approx_match_unittest.py
+++ b/py/probe/functions/approx_match_unittest.py
@@ -5,8 +5,6 @@
 
 import unittest
 
-from six import iteritems
-
 from cros.factory.probe.functions.approx_match import ApproxMatchFunction
 
 
@@ -86,7 +84,7 @@
     self.assertEqual(perfect_match, perfect_match_expect)
     self.assertEqual(matched_num, matched_num_expect)
     self.assertEqual(item, item_expect)
-    for rule_name, expect in iteritems(rule_expect):
+    for rule_name, expect in rule_expect.items():
       self.assertEqual(rule[rule_name]['result'], expect)
 
 
diff --git a/py/probe/functions/match.py b/py/probe/functions/match.py
index 180a6f3..665350a 100644
--- a/py/probe/functions/match.py
+++ b/py/probe/functions/match.py
@@ -4,8 +4,6 @@
 
 import re
 
-from six import iteritems
-
 from cros.factory.probe import function
 from cros.factory.utils.arg_utils import Arg
 
@@ -110,7 +108,7 @@
     self.is_dict = isinstance(self.args.rule, dict)
     if self.is_dict:
       self.rule = {key: self.ConstructRule(value)
-                   for key, value in iteritems(self.args.rule)}
+                   for key, value in self.args.rule.items()}
     else:
       self.rule = self.ConstructRule(self.args.rule)
 
@@ -125,7 +123,7 @@
     if not self.is_dict:
       return len(item) == 1 and _Match(self.rule, next(iter(item.values())))
     return all([key in item and _Match(rule, item[key])
-                for key, rule in iteritems(self.rule)])
+                for key, rule in self.rule.items()])
 
   @classmethod
   def ConstructRule(cls, rule):
diff --git a/py/probe/functions/mmc_unittest.py b/py/probe/functions/mmc_unittest.py
index 9ce1fd1..9e1488c 100755
--- a/py/probe/functions/mmc_unittest.py
+++ b/py/probe/functions/mmc_unittest.py
@@ -7,8 +7,6 @@
 import tempfile
 import unittest
 
-from six import iteritems
-
 from cros.factory.probe.functions import mmc
 from cros.factory.utils import file_utils
 
@@ -27,7 +25,7 @@
     real_path = self.my_root + real_path
 
     file_utils.TryMakeDirs(real_path)
-    for key, value in iteritems(values):
+    for key, value in values.items():
       file_utils.WriteFile(os.path.join(real_path, key), value)
 
     link_name = os.path.join(
diff --git a/py/probe/functions/pci_unittest.py b/py/probe/functions/pci_unittest.py
index 001cd62..8451ab2 100755
--- a/py/probe/functions/pci_unittest.py
+++ b/py/probe/functions/pci_unittest.py
@@ -7,8 +7,6 @@
 import tempfile
 import unittest
 
-from six import iteritems
-
 from cros.factory.probe.functions import pci
 from cros.factory.utils import file_utils
 
@@ -27,7 +25,7 @@
     real_path = self.my_root + real_path
 
     file_utils.TryMakeDirs(real_path)
-    for key, value in iteritems(values):
+    for key, value in values.items():
       if key == 'revision_id':
         open(os.path.join(real_path, 'config'), 'wb').write(
             b'x' * 8 + bytes([int(value, 16)]))
diff --git a/py/probe/functions/touchscreen_i2c_unittest.py b/py/probe/functions/touchscreen_i2c_unittest.py
index 41ca8be..6b7160c 100755
--- a/py/probe/functions/touchscreen_i2c_unittest.py
+++ b/py/probe/functions/touchscreen_i2c_unittest.py
@@ -7,8 +7,6 @@
 import tempfile
 import unittest
 
-from six import iteritems
-
 from cros.factory.probe.functions import touchscreen_i2c
 from cros.factory.utils import file_utils
 
@@ -28,7 +26,7 @@
     path = os.path.join(self.my_root, 'sys', 'bus', 'i2c', 'devices', name)
     file_utils.TryMakeDirs(path)
 
-    for key, value in iteritems(values):
+    for key, value in values.items():
       file_utils.WriteFile(os.path.join(path, key), value)
 
     driver_target = self.my_root + driver_target
diff --git a/py/probe/functions/usb_unittest.py b/py/probe/functions/usb_unittest.py
index fcec7cf..26a1dca 100755
--- a/py/probe/functions/usb_unittest.py
+++ b/py/probe/functions/usb_unittest.py
@@ -7,8 +7,6 @@
 import tempfile
 import unittest
 
-from six import iteritems
-
 from cros.factory.probe.functions import usb
 from cros.factory.utils import file_utils
 
@@ -27,7 +25,7 @@
     real_path = self.my_root + real_path
 
     file_utils.TryMakeDirs(real_path)
-    for key, value in iteritems(values):
+    for key, value in values.items():
       file_utils.WriteFile(os.path.join(real_path, key), value)
 
     link_name = os.path.join(
diff --git a/py/probe/lib/cached_probe_function.py b/py/probe/lib/cached_probe_function.py
index ad0c55a..f6246fd 100644
--- a/py/probe/lib/cached_probe_function.py
+++ b/py/probe/lib/cached_probe_function.py
@@ -6,8 +6,6 @@
 import logging
 import os
 
-from six import iteritems
-
 from cros.factory.probe import function
 from cros.factory.probe.lib import probe_function
 from cros.factory.utils.arg_utils import Arg
@@ -79,7 +77,7 @@
       elif isinstance(probed_data, list):
         probed_data = {cls.DUMMY_CATEGORY: probed_data}
       cls._CACHED_DEVICES = {k: v if isinstance(v, list) else [v]
-                             for k, v in iteritems(probed_data)}
+                             for k, v in probed_data.items()}
 
 
 class LazyCachedProbeFunction(probe_function.ProbeFunction):
diff --git a/py/probe/probe_cmdline_unittest.py b/py/probe/probe_cmdline_unittest.py
index a1adda5..4a6baed 100755
--- a/py/probe/probe_cmdline_unittest.py
+++ b/py/probe/probe_cmdline_unittest.py
@@ -9,8 +9,6 @@
 import tempfile
 import unittest
 
-from six import iteritems
-
 from cros.factory.utils import file_utils
 from cros.factory.utils import json_utils
 from cros.factory.utils import process_utils
@@ -23,7 +21,7 @@
 class ProbeCmdTest(unittest.TestCase):
   def assertProbedResultEquals(self, result1, result2):
     self.assertEqual(len(result1), len(result2))
-    for k, v1 in iteritems(result1):
+    for k, v1 in result1.items():
       self.assertIn(k, result2)
       self.assertEqual(sorted(v1, key=lambda d: sorted(d.items())),
                        sorted(result2[k], key=lambda d: sorted(d.items())))
diff --git a/py/probe/probe_utils.py b/py/probe/probe_utils.py
index c9129e7..3896c63 100644
--- a/py/probe/probe_utils.py
+++ b/py/probe/probe_utils.py
@@ -8,8 +8,6 @@
 
 import logging
 
-from six import iteritems
-
 from cros.factory.probe import common
 from cros.factory.utils import config_utils
 
@@ -34,7 +32,7 @@
     if comp_cls not in comps:
       continue
     results[comp_cls] = []
-    for comp_name, statement in iteritems(probe_statement[comp_cls]):
+    for comp_name, statement in probe_statement[comp_cls].items():
       logging.info('Probe %s: %s', comp_cls, comp_name)
 
       for probed_values in common.EvaluateStatement(statement,
diff --git a/py/test/device_data.py b/py/test/device_data.py
index 196e51c..5632214 100644
--- a/py/test/device_data.py
+++ b/py/test/device_data.py
@@ -116,8 +116,6 @@
 import logging
 import os
 
-from six import iteritems
-
 # pylint: disable=wildcard-import,unused-wildcard-import
 from cros.factory.test.device_data_constants import *
 from cros.factory.test import event
@@ -244,7 +242,7 @@
   Raises:
     `ValueError` if the device data is invalid.
   """
-  for key, value in iteritems(device_data):
+  for key, value in device_data.items():
     if key.startswith(JoinKeys(KEY_COMPONENT, 'has_')):
       if value is not None and not isinstance(value, (bool, int)):
         raise ValueError('Values in the "component" domain should be None or'
@@ -327,7 +325,7 @@
   assert isinstance(dict_, dict)
   new_dict = {}
   keys_to_delete = []
-  for key, value in iteritems(dict_):
+  for key, value in dict_.items():
     if value:
       new_dict[_GetSerialNumberName(key)] = value
     else:
@@ -353,7 +351,7 @@
     A flattened dict.
   """
   items = []
-  for k, v in iteritems(data):
+  for k, v in data.items():
     new_key = JoinKeys(parent, k) if parent else k
     if isinstance(v, collections.Mapping):
       items.extend(FlattenData(v, new_key).items())
@@ -404,7 +402,7 @@
     if section not in key_map:
       continue
     vpd_section = vpd_data.get(section, {})
-    for rule in iteritems(key_map[section]):
+    for rule in key_map[section].items():
       for vpd_key in vpd_section:
         if _MatchKey(rule, vpd_key):
           data_key = _DeriveDeviceDataKey(rule, vpd_key)
diff --git a/py/test/diagnosis/task.py b/py/test/diagnosis/task.py
index f5e9736..c6fab91 100644
--- a/py/test/diagnosis/task.py
+++ b/py/test/diagnosis/task.py
@@ -21,8 +21,6 @@
 import threading
 import time
 
-from six import iteritems
-
 from cros.factory.test.diagnosis import common
 from cros.factory.utils import process_utils
 
@@ -506,7 +504,7 @@
   dollar_star = ''
   dollar_at = ''
   splitter = ''
-  for key, value in iteritems(input_values):
+  for key, value in input_values.items():
     value.replace('"', '\\"')
     dollar_star += splitter + value
     dollar_at += splitter + '"' + value + '"'
diff --git a/py/test/event.py b/py/test/event.py
index ea1a589..0b09cbf 100644
--- a/py/test/event.py
+++ b/py/test/event.py
@@ -18,8 +18,6 @@
 import time
 import traceback
 
-from six import iteritems
-
 from cros.factory.utils import file_utils
 from cros.factory.utils import process_utils
 from cros.factory.utils import time_utils
@@ -52,7 +50,7 @@
   returned.
   """
   if isinstance(obj, object):
-    return dict([(k, v) for k, v in iteritems(obj.__dict__)
+    return dict([(k, v) for k, v in obj.__dict__.items()
                  if k[0] != '_'])
   return obj
 
@@ -126,7 +124,7 @@
   def __init__(self, type, **kw):  # pylint: disable=redefined-builtin
     self.type = type
     self.timestamp = time.time()
-    for k, v in iteritems(kw):
+    for k, v in kw.items():
       setattr(self, k, v)
 
   def __repr__(self):
diff --git a/py/test/fixture/whale/host/interrupt_handler.py b/py/test/fixture/whale/host/interrupt_handler.py
index 5177fda..65a5be2 100755
--- a/py/test/fixture/whale/host/interrupt_handler.py
+++ b/py/test/fixture/whale/host/interrupt_handler.py
@@ -14,8 +14,6 @@
 import sys
 import time
 
-from six import iteritems
-
 from cros.factory.test.fixture.whale import keyboard_emulator
 from cros.factory.test.fixture.whale import serial_client
 from cros.factory.test.fixture.whale import servo_client
@@ -305,7 +303,7 @@
       return False
 
     operator_mode = not self._servo.IsOn(self._WHALE_DEBUG_MODE_EN)
-    for button, clicked in iteritems(status):
+    for button, clicked in status.items():
       if not clicked:
         continue
 
@@ -335,7 +333,7 @@
     logging.debug('[Scanning feedback....]')
     feedback_status = self._servo.MultipleIsOn(self._FEEDBACK_LIST)
     feedback_changed = False
-    for name, value in iteritems(feedback_status):
+    for name, value in feedback_status.items():
       if self._last_feedback[name] == value:
         continue
 
diff --git a/py/test/fixture/whale/servo_client.py b/py/test/fixture/whale/servo_client.py
index 6fc2a12..c486f04 100644
--- a/py/test/fixture/whale/servo_client.py
+++ b/py/test/fixture/whale/servo_client.py
@@ -35,8 +35,6 @@
 import time
 import xmlrpc.client
 
-from six import iteritems
-
 from cros.factory.test.fixture.whale import servo_config
 from cros.factory.utils.net_utils import TimeoutXMLRPCServerProxy
 from cros.factory.utils.type_utils import AttrDict
@@ -258,7 +256,7 @@
       ServoClientError: If error occurs when getting value.
     """
     return dict((name, self._OnOffToBool(name, value))
-                for name, value in iteritems(self.MultipleGet(names)))
+                for name, value in self.MultipleGet(names).items())
 
   def Set(self, name, value):
     """Sets the value from servo for control name.
diff --git a/py/test/fixture/whale/whale_bft_fixture.py b/py/test/fixture/whale/whale_bft_fixture.py
index 2d4eae8..577b95f 100644
--- a/py/test/fixture/whale/whale_bft_fixture.py
+++ b/py/test/fixture/whale/whale_bft_fixture.py
@@ -9,8 +9,6 @@
 import logging
 import os
 
-from six import iteritems
-
 from cros.factory.test.fixture import bft_fixture as bft
 from cros.factory.test.fixture.whale import color_sensor
 from cros.factory.test.fixture.whale import keyboard_emulator
@@ -151,7 +149,7 @@
       BFTFixtureException if power rail is problematic.
     """
     inas = self._servo.MultipleGet(self._WHALE_INAS)
-    result = dict((k, int(v)) for k, v in iteritems(inas))
+    result = dict((k, int(v)) for k, v in inas.items())
 
     # Servo returns a string of list of integers
     adc = ast.literal_eval(self._servo.Get(self._WHALE_CONTROL.ADC))
@@ -202,7 +200,7 @@
       is_pass = self._servo.Get(self._WHALE_CONTROL.PASS_LED)
       is_fail = self._servo.Get(self._WHALE_CONTROL.FAIL_LED)
 
-      for color, value in iteritems(WhaleBFTFixture._STATUS_COLOR):
+      for color, value in WhaleBFTFixture._STATUS_COLOR.items():
         if value == (is_pass, is_fail):
           return color
       # If no match, treat as OFF status
diff --git a/py/test/i18n/string_utils.py b/py/test/i18n/string_utils.py
index 67cec0f..ffcca18 100644
--- a/py/test/i18n/string_utils.py
+++ b/py/test/i18n/string_utils.py
@@ -10,8 +10,6 @@
 import logging
 import string
 
-from six import iteritems
-
 from cros.factory.test.i18n import translation
 
 
@@ -75,9 +73,9 @@
   _format_string = translation.Translated(_format_string)
 
   kwargs = {name: translation.Translated(val, translate=False)
-            for name, val in iteritems(kwargs)}
-  for locale, format_str in iteritems(_format_string):
-    format_args = {name: val[locale] for name, val in iteritems(kwargs)}
+            for name, val in kwargs.items()}
+  for locale, format_str in _format_string.items():
+    format_args = {name: val[locale] for name, val in kwargs.items()}
     ret[locale] = _FORMATTER.vformat(format_str, [], format_args)
   return ret
 
@@ -104,4 +102,4 @@
     The new translation dict with all values HTML-escaped.
   """
   return {locale: html.escape(value, quote=False)
-          for locale, value in iteritems(text)}
+          for locale, value in text.items()}
diff --git a/py/test/pytests/accelerometers.py b/py/test/pytests/accelerometers.py
index 99ba700..e4ee13e 100644
--- a/py/test/pytests/accelerometers.py
+++ b/py/test/pytests/accelerometers.py
@@ -52,8 +52,6 @@
 
 """
 
-from six import iteritems
-
 from cros.factory.device import accelerometer
 from cros.factory.device import device_utils
 from cros.factory.test.i18n import _
@@ -99,7 +97,7 @@
       self.args.limits = DEFAULT_LIMITS
     assert self.args.limits.keys() == {'x', 'y', 'z'}, (
         'Limits should be a dictionary with keys "x", "y" and "z"')
-    for unused_axis, [limit_min, limit_max] in iteritems(self.args.limits):
+    for unused_axis, [limit_min, limit_max] in self.args.limits.items():
       assert limit_min <= limit_max
 
     self.dut = device_utils.CreateDUTInterface()
@@ -127,7 +125,7 @@
       self.FailTask('Read raw data failed.')
 
     passed = True
-    for axis, [limit_min, limit_max] in iteritems(self.args.limits):
+    for axis, [limit_min, limit_max] in self.args.limits.items():
       key = 'in_accel_' + axis  # in_accel_(x|y|z)
       passed &= testlog.CheckNumericParam(
           name=key, value=raw_data[key], min=limit_min, max=limit_max)
diff --git a/py/test/pytests/accelerometers_lid_angle.py b/py/test/pytests/accelerometers_lid_angle.py
index 44b2595..0b07afe 100644
--- a/py/test/pytests/accelerometers_lid_angle.py
+++ b/py/test/pytests/accelerometers_lid_angle.py
@@ -27,7 +27,6 @@
 import math
 
 import numpy as np
-from six import iteritems
 
 from cros.factory.device import accelerometer
 from cros.factory.device import device_utils
@@ -80,7 +79,7 @@
     in the w3 spec: http://www.w3.org/TR/orientation-event/#description.
     """
     cal_data = {}
-    for location, accelerometer_controller in iteritems(self.accelerometers):
+    for location, accelerometer_controller in self.accelerometers.items():
       try:
         cal_data[location] = accelerometer_controller.GetData(
             self.args.capture_count, self.args.sample_rate_hz)
diff --git a/py/test/pytests/audio_quality.py b/py/test/pytests/audio_quality.py
index 6b7654b..eb99015 100644
--- a/py/test/pytests/audio_quality.py
+++ b/py/test/pytests/audio_quality.py
@@ -62,7 +62,6 @@
 import threading
 import zipfile
 
-from six import iteritems
 import yaml
 
 from cros.factory.device import device_utils
@@ -754,7 +753,7 @@
     cmd = event.data.get('cmd', '')
     if cmd == 'reset':
       self.SetMessage(_LABEL_SPACE_TO_START)
-    for key, handler in iteritems(self._handlers):
+    for key, handler in self._handlers.items():
       if key.match(cmd):
         handler()
         break
diff --git a/py/test/pytests/bluetooth.py b/py/test/pytests/bluetooth.py
index 7bc1ea0..6412871 100644
--- a/py/test/pytests/bluetooth.py
+++ b/py/test/pytests/bluetooth.py
@@ -85,8 +85,6 @@
 import threading
 import time
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test import event_log  # TODO(chuntsen): Deprecate event log.
 from cros.factory.test.i18n import _
@@ -657,7 +655,7 @@
         return devices
 
       filtered_devices = {}
-      for mac, props in iteritems(devices):
+      for mac, props in devices.items():
         if 'Name' not in props:
           logging.warning('Device %s: %s does not have "Name" property.',
                           mac, props)
@@ -678,7 +676,7 @@
         devices: A dict. Keys are mac addresses and values are dicts of
           properties.
       """
-      for mac, props in iteritems(devices):
+      for mac, props in devices.items():
         if 'RSSI' not in props:
           logging.warning('Device %s: %s does not have "RSSI" property.',
                           mac, props)
@@ -702,7 +700,7 @@
         devices = self.btmgmt.FindDevices()
 
       logging.info('Found %d device(s).', len(devices))
-      for mac, props in iteritems(devices):
+      for mac, props in devices.items():
         try:
           logging.info('Device found: %s. Name: %s, RSSI: %d',
                        mac, props['Name'], props['RSSI'])
@@ -725,7 +723,7 @@
 
     # Calculates maximum average RSSI.
     max_average_rssi_mac, max_average_rssi = None, -sys.float_info.max
-    for mac, rssis in iteritems(candidate_rssis):
+    for mac, rssis in candidate_rssis.items():
       average_rssi = sum(rssis) / len(rssis)
       logging.info('Device %s has average RSSI: %f', mac, average_rssi)
       event_log.Log('avg_rssi', mac=mac, average_rssi=average_rssi)
@@ -853,7 +851,7 @@
           _('Detect RSSI (count {count}/{total})', count=i, total=scan_counts))
       with self.TimedProgressBar(timeout_secs):
         devices = self.btmgmt.FindDevices()
-      for mac, props in iteritems(devices):
+      for mac, props in devices.items():
         if mac == mac_to_scan and 'RSSI' in props:
           session.console.info('RSSI of count %d: %.2f', i, props['RSSI'])
           rssis.append(props['RSSI'])
diff --git a/py/test/pytests/check_cr50_board_id.py b/py/test/pytests/check_cr50_board_id.py
index 9b6ef49..6d49dc4 100644
--- a/py/test/pytests/check_cr50_board_id.py
+++ b/py/test/pytests/check_cr50_board_id.py
@@ -51,8 +51,6 @@
 
 import functools
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.gooftool import common as gooftool_common
 from cros.factory.gooftool import gsctool
@@ -80,7 +78,7 @@
           'either an integer or a string.  If the value is a string, '
           'the value can be either the hex code of the board ID flags or %s.' %
           ', '.join('%s for %08x' % (k, v)
-                    for k, v in iteritems(_PREDEFINED_PHASES)),
+                    for k, v in _PREDEFINED_PHASES.items()),
           default=None),
   ]
 
diff --git a/py/test/pytests/exec_shell.py b/py/test/pytests/exec_shell.py
index 77312dd..b3cb69e 100644
--- a/py/test/pytests/exec_shell.py
+++ b/py/test/pytests/exec_shell.py
@@ -113,8 +113,6 @@
 import subprocess
 import time
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test.i18n import _
 from cros.factory.test import test_case
@@ -204,7 +202,7 @@
     threads = [
         process_utils.StartDaemonThread(
             target=self.UpdateOutput, args=(handle, name, output))
-        for name, handle in iteritems(handles)
+        for name, handle in handles.items()
     ]
 
     process.wait()
diff --git a/py/test/pytests/gps.py b/py/test/pytests/gps.py
index 85d47e5..1272ad3 100644
--- a/py/test/pytests/gps.py
+++ b/py/test/pytests/gps.py
@@ -40,7 +40,6 @@
 import unittest
 
 import numpy
-from six import iteritems
 
 from cros.factory import device
 from cros.factory.device import device_utils
@@ -232,7 +231,7 @@
       # Print parsed values.
       current_values_str = ' '.join(
           '%s=%.1f' % (key, value)
-          for key, value in iteritems(current_values))
+          for key, value in current_values.items())
       session.console.info('[%d] %s', time_left, current_values_str)
 
     logging.debug('Timeout has been reached (%d secs)', self.args.timeout)
@@ -258,12 +257,12 @@
       field_stats = None
     else:
       field_stats = {key: {} for key in self.args.nmea_fields}
-      for key, values in iteritems(all_values):
-        for fn_name, fn in iteritems(STAT_FNS):
+      for key, values in all_values.items():
+        for fn_name, fn in STAT_FNS.items():
           field_stats[key][fn_name] = fn(values)
         field_stats_str = ' '.join(
             '%s=%.1f' % (k, v)
-            for k, v in iteritems(field_stats[key]))
+            for k, v in field_stats[key].items())
         session.console.info('%s: %s', key, field_stats_str)
 
     # Do limit testing.
diff --git a/py/test/pytests/gyroscope.py b/py/test/pytests/gyroscope.py
index d8e4bff..a860777 100644
--- a/py/test/pytests/gyroscope.py
+++ b/py/test/pytests/gyroscope.py
@@ -42,8 +42,6 @@
 
 import collections
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test.i18n import _
 from cros.factory.test import test_case
@@ -112,7 +110,7 @@
 
   def _UpdateState(self, max_values):
     html = []
-    for k, v in iteritems(max_values):
+    for k, v in max_values.items():
       state = ('test-status-passed'
                if v > self.args.rotation_threshold else 'test-status-failed')
       html.append('<div class="%s">%s=%s</div>' % (state, test_ui.Escape(k), v))
@@ -133,7 +131,7 @@
     max_values = collections.defaultdict(float)
     def CheckSensorMaxValues():
       data = self.gyroscope.GetData()
-      for sensor_name, value in iteritems(data):
+      for sensor_name, value in data.items():
         max_values[sensor_name] = max(max_values[sensor_name], abs(value))
       self._UpdateState(max_values)
       return min(max_values.values()) > self.args.rotation_threshold
diff --git a/py/test/pytests/keyboard.py b/py/test/pytests/keyboard.py
index e165e8d..29ca84f 100644
--- a/py/test/pytests/keyboard.py
+++ b/py/test/pytests/keyboard.py
@@ -92,8 +92,6 @@
 import os
 import re
 
-from six import iteritems
-
 from cros.factory.external import evdev
 from cros.factory.test.l10n import regions
 from cros.factory.test import session
@@ -176,7 +174,7 @@
     self.bindings = self.ReadBindings(self.layout)
 
     # Apply any replacement keymap
-    for old_key, new_key in iteritems(self.args.replacement_keymap):
+    for old_key, new_key in self.args.replacement_keymap.items():
       if old_key in self.bindings:
         self.bindings[new_key] = self.bindings[old_key]
         del self.bindings[old_key]
@@ -328,7 +326,7 @@
   def FailTestTimeout(self):
     """Fail the test due to timeout, and log untested keys."""
     failed_keys = [
-        key for key, num_left in iteritems(self.number_to_press) if num_left
+        key for key, num_left in self.number_to_press.items() if num_left
     ]
     for failed_key in failed_keys:
       testlog.LogParam('malfunction_key', failed_key)
diff --git a/py/test/pytests/probe/probe.py b/py/test/pytests/probe/probe.py
index b4ca755..32d69e9 100644
--- a/py/test/pytests/probe/probe.py
+++ b/py/test/pytests/probe/probe.py
@@ -150,8 +150,6 @@
 import operator
 import os
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test import device_data
 from cros.factory.test import session
@@ -244,7 +242,7 @@
       for result in probed_results[category]:
         counter[result['name']] += 1
       comp_summary = '<br>'.join('%d %s found.' % (num_comp, comp_name)
-                                 for comp_name, num_comp in iteritems(counter))
+                                 for comp_name, num_comp in counter.items())
       summary_str = comp_summary or 'No component found.'
       rule_str = 'count (%s) %s %s' % (count, op_str, value)
       status_str = 'passed' if status else 'failed'
diff --git a/py/test/pytests/probe_cellular_info.py b/py/test/pytests/probe_cellular_info.py
index 051802f..7a511ad 100644
--- a/py/test/pytests/probe_cellular_info.py
+++ b/py/test/pytests/probe_cellular_info.py
@@ -11,8 +11,6 @@
 import re
 import unittest
 
-from six import iteritems
-
 from cros.factory.test import device_data
 from cros.factory.test import event_log  # TODO(chuntsen): Deprecate event log.
 from cros.factory.testlog import testlog
@@ -48,10 +46,10 @@
 
     event_log.Log('cellular_info', modem_status_stdout=output, **data)
     testlog.LogParam('modem_status_stdout', output)
-    for k, v in iteritems(data):
+    for k, v in data.items():
       testlog.LogParam(k, v)
 
-    missing = set(k for k, v in iteritems(data) if v is None)
+    missing = set(k for k, v in data.items() if v is None)
     self.assertFalse(
         missing,
         "Missing elements in 'modem status' output: %s" % sorted(missing))
@@ -59,4 +57,4 @@
     logging.info('Probed data: %s', data)
     device_data.UpdateDeviceData({
         device_data.JoinKeys(device_data.KEY_COMPONENT, 'cellular', name): value
-        for name, value in iteritems(data)})
+        for name, value in data.items()})
diff --git a/py/test/pytests/read_device_data_from_vpd.py b/py/test/pytests/read_device_data_from_vpd.py
index fde7c59..212ca35 100644
--- a/py/test/pytests/read_device_data_from_vpd.py
+++ b/py/test/pytests/read_device_data_from_vpd.py
@@ -84,8 +84,6 @@
   }
 """
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test import device_data
 from cros.factory.test.i18n import _
@@ -116,7 +114,7 @@
       sections['ro'] = device_data.DEFAULT_RO_VPD_KEY_MAP
       sections['rw'] = device_data.DEFAULT_RW_VPD_KEY_MAP
 
-    for name, key_map in iteritems(sections):
+    for name, key_map in sections.items():
       self.ui.SetState(
           _('Reading device data from {vpd_section} VPD...',
             vpd_section=name.upper()))
diff --git a/py/test/pytests/removable_storage.py b/py/test/pytests/removable_storage.py
index f756673..30b7643 100644
--- a/py/test/pytests/removable_storage.py
+++ b/py/test/pytests/removable_storage.py
@@ -111,8 +111,6 @@
 import subprocess
 import threading
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test.event_log import Log
 from cros.factory.test import session
@@ -436,7 +434,7 @@
         'if': ifile, 'of': ofile, 'seek': seek, 'skip': skip,
         'bs': bs, 'count': count, 'conv': conv
     }
-    for key, value in iteritems(args):
+    for key, value in args.items():
       if value:
         cmd.append('%s=%s' % (key, value))
     return cmd
diff --git a/py/test/pytests/rf_graphyte/rf_graphyte.py b/py/test/pytests/rf_graphyte/rf_graphyte.py
index c855647..bbefb08 100644
--- a/py/test/pytests/rf_graphyte/rf_graphyte.py
+++ b/py/test/pytests/rf_graphyte/rf_graphyte.py
@@ -69,8 +69,6 @@
 import os
 import time
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test import device_data
 from cros.factory.test.env import paths
@@ -281,7 +279,7 @@
                 name='result', value=result_value,
                 min=_ConvertToNumber(data['lower_bound']),
                 max=_ConvertToNumber(data['upper_bound']))
-            for k, v in iteritems(parameters):
+            for k, v in parameters.items():
               testlog.LogParam(k, v)
 
 
diff --git a/py/test/pytests/shopfloor_service.py b/py/test/pytests/shopfloor_service.py
index 2349d16..52d1e01 100644
--- a/py/test/pytests/shopfloor_service.py
+++ b/py/test/pytests/shopfloor_service.py
@@ -81,8 +81,6 @@
 import pprint
 import threading
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test import device_data
 from cros.factory.test.i18n import _
@@ -179,7 +177,7 @@
   def UpdateAutoResults(self, method, result, args):
     """Updates auto values (based on method) to results."""
     auto_values = self.METHODS[method].auto_values
-    for k, v in iteritems(auto_values):
+    for k, v in auto_values.items():
       result[k.format(*args)] = v
 
   def UpdateDeviceData(self, data):
@@ -189,16 +187,16 @@
     illegal_keys = [k for k in data if k.partition('.')[0] not in prefixes]
     if illegal_keys:
       raise ValueError('Invalid response keys: %r' % illegal_keys)
-    keys_to_delete = [k for k, v in iteritems(data) if v is None]
+    keys_to_delete = [k for k, v in data.items() if v is None]
     device_data.DeleteDeviceData(keys_to_delete)
-    data = dict((k, v) for k, v in iteritems(data) if k not in keys_to_delete)
+    data = dict((k, v) for k, v in data.items() if k not in keys_to_delete)
     device_data.UpdateDeviceData(data)
 
   @staticmethod
   def FilterDict(data):
     """Returns a dict with privacy data filtered."""
     result = shelve_utils.DictShelfView(shelve_utils.InMemoryShelf())
-    for k, v in iteritems(data):
+    for k, v in data.items():
       result.SetValue(k, v)
     if not result.GetKeys():
       return {}
diff --git a/py/test/pytests/shutdown.py b/py/test/pytests/shutdown.py
index 7953325..87d56f1 100644
--- a/py/test/pytests/shutdown.py
+++ b/py/test/pytests/shutdown.py
@@ -49,8 +49,6 @@
 import re
 import time
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test import event as test_event
 from cros.factory.test import event_log  # TODO(chuntsen): Deprecate event log.
@@ -233,7 +231,7 @@
     def LogAndEndTest(status, error_msg, **kw):
       event_log.Log('rebooted', status=status, error_msg=error_msg, **kw)
       testlog.LogParam('status', status)
-      for k, v in iteritems(kw):
+      for k, v in kw.items():
         testlog.LogParam(k, v)
       logging.info('Rebooted: status=%s, %s', status,
                    (('error_msg=%s' % error_msg) if error_msg else None))
diff --git a/py/test/pytests/start.py b/py/test/pytests/start.py
index 24a8be3..33331f7 100644
--- a/py/test/pytests/start.py
+++ b/py/test/pytests/start.py
@@ -48,8 +48,6 @@
 import logging
 import os
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test.event_log import Log
 from cros.factory.test import session
@@ -129,6 +127,6 @@
 
   def InitializeSharedData(self):
     self.ui.SetState(_('Initialize some shared data...'))
-    for key, value in iteritems(self.args.init_shared_data):
+    for key, value in self.args.init_shared_data.items():
       session.console.debug('DataShelfSetValue[%s] = "%s"', key, value)
       state.DataShelfSetValue(key, value)
diff --git a/py/test/pytests/station_entry_unittest.py b/py/test/pytests/station_entry_unittest.py
index 748e794..8369d17 100755
--- a/py/test/pytests/station_entry_unittest.py
+++ b/py/test/pytests/station_entry_unittest.py
@@ -9,7 +9,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.device import device_utils
 from cros.factory.test import device_data
@@ -23,7 +22,7 @@
 
 class FakeArgs(object):
   def __init__(self, dargs):
-    for key, value in iteritems(dargs):
+    for key, value in dargs.items():
       self.__dict__[key] = value
 
 
diff --git a/py/test/pytests/thermal_sensors.py b/py/test/pytests/thermal_sensors.py
index 6159541..4cfda7b 100644
--- a/py/test/pytests/thermal_sensors.py
+++ b/py/test/pytests/thermal_sensors.py
@@ -42,8 +42,6 @@
 import logging
 import unittest
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.utils.arg_utils import Arg
 
@@ -84,7 +82,7 @@
 
     logging.info('Got temperatures: %r', values)
     min_temp, max_temp = self.args.temp_range
-    for name, temperature in iteritems(values):
+    for name, temperature in values.items():
       self.assertTrue(
           min_temp <= temperature <= max_temp,
           'Abnormal temperature reading on sensor %s: %s' % (name, temperature))
diff --git a/py/test/pytests/update_device_data.py b/py/test/pytests/update_device_data.py
index 8a35147..8ed7f28 100644
--- a/py/test/pytests/update_device_data.py
+++ b/py/test/pytests/update_device_data.py
@@ -157,8 +157,6 @@
 import queue
 import re
 
-from six import iteritems
-
 from cros.factory.test import device_data
 from cros.factory.test import i18n
 from cros.factory.test.i18n import _
@@ -310,7 +308,7 @@
 
     if self.args.config_name:
       fields += [(k, v, None, None) for k, v in
-                 iteritems(device_data.LoadConfig(self.args.config_name))]
+                 device_data.LoadConfig(self.args.config_name).items()]
 
     if self.args.fields:
       fields += self.args.fields
diff --git a/py/test/pytests/verify_component.py b/py/test/pytests/verify_component.py
index 85ac661..70c04ce 100644
--- a/py/test/pytests/verify_component.py
+++ b/py/test/pytests/verify_component.py
@@ -13,8 +13,6 @@
 
 import hashlib
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.hwid.v3 import common
 from cros.factory.test import device_data
@@ -79,7 +77,7 @@
          '{}'.format(self.args.max_mismatch)]))
     self.perfect_match_results = self._GetPerfectMatchProbeResult()
     self.component_data = {k[4:]: int(v) for k, v in
-                           iteritems(device_data.GetDeviceData('component'))
+                           device_data.GetDeviceData('component').items()
                            if k.startswith('has_')}
 
     self._VerifyNumMismatch()
@@ -106,7 +104,7 @@
     def _ExtractInfoToName(comp_info):
       return [comp['name'] for comp in comp_info]
 
-    for comp_cls, correct_num in iteritems(self.component_data):
+    for comp_cls, correct_num in self.component_data.items():
       comp_info = self.perfect_match_results.get(comp_cls, [])
       actual_num = len(comp_info)
       if correct_num != actual_num:
@@ -115,7 +113,7 @@
 
     # The number of component should be _NUMBER_NOT_IN_DEVICE_DATA
     # when the component is not in device data.
-    for comp_cls, comp_info in iteritems(self.perfect_match_results):
+    for comp_cls, comp_info in self.perfect_match_results.items():
       if comp_cls not in self.component_data:
         actual_num = len(comp_info)
         if actual_num != _NUMBER_NOT_IN_DEVICE_DATA:
@@ -125,7 +123,7 @@
 
   def _VerifyNotSupported(self):
     if self._CheckPhase():
-      for comp_cls, comp_info in iteritems(self.perfect_match_results):
+      for comp_cls, comp_info in self.perfect_match_results.items():
         for comp_item in comp_info:
           status = comp_item['information']['status']
           if status != common.COMPONENT_STATUS.supported:
@@ -146,7 +144,7 @@
 
   def _GetPerfectMatchProbeResult(self):
     res = {}
-    for comp_cls, comp_info in iteritems(self.probed_results):
+    for comp_cls, comp_info in self.probed_results.items():
       res[comp_cls] = [item for item in comp_info if item['perfect_match']]
 
     return res
diff --git a/py/test/pytests/vswr/vswr.py b/py/test/pytests/vswr/vswr.py
index 14d937b..2ed7fde 100644
--- a/py/test/pytests/vswr/vswr.py
+++ b/py/test/pytests/vswr/vswr.py
@@ -33,7 +33,6 @@
 import string
 import uuid
 
-from six import iteritems
 import yaml
 
 from cros.factory.device import device_utils
@@ -489,13 +488,13 @@
     """
     # pylint: disable=redefined-builtin
     if min is None and max is None:
-      for freq, data in iteritems(trace):
+      for freq, data in trace.items():
         with self._group_checker:
           testlog.LogParam('name', name)
           testlog.LogParam('trace_data', data)
           testlog.LogParam('frequency', freq)
     else:
-      for freq, data in iteritems(trace):
+      for freq, data in trace.items():
         with self._group_checker:
           testlog.LogParam('name', name)
           testlog.CheckNumericParam('trace_data', data, min=min, max=max)
diff --git a/py/test/pytests/wifi_throughput.py b/py/test/pytests/wifi_throughput.py
index 07ff99f..f039c68 100644
--- a/py/test/pytests/wifi_throughput.py
+++ b/py/test/pytests/wifi_throughput.py
@@ -91,8 +91,6 @@
 import sys
 import time
 
-from six import iteritems
-
 from cros.factory.device import CalledProcessError
 from cros.factory.device import device_utils
 from cros.factory.test import event_log  # TODO(chuntsen): Deprecate event log.
@@ -1038,7 +1036,7 @@
 
     # Check for any failures and report an aggregation.
     all_failures = []
-    for ssid, ap_log in iteritems(self.log['test']):
+    for ssid, ap_log in self.log['test'].items():
       for error_msg in ap_log['failures']:
         all_failures.append((ssid, error_msg))
     if all_failures:
diff --git a/py/test/pytests/write_device_data_to_vpd.py b/py/test/pytests/write_device_data_to_vpd.py
index 87e2309..ea8e8ec 100644
--- a/py/test/pytests/write_device_data_to_vpd.py
+++ b/py/test/pytests/write_device_data_to_vpd.py
@@ -64,8 +64,6 @@
   }
 """
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.test import device_data
 from cros.factory.test.i18n import _
@@ -105,25 +103,25 @@
     else:
       data['ro'] = {
           vpd_name: device_data.GetDeviceData(data_key)
-          for vpd_name, data_key in iteritems((self.args.ro_key_map or {}))
+          for vpd_name, data_key in (self.args.ro_key_map or {}).items()
       }
       data['rw'] = {
           vpd_name: device_data.GetDeviceData(data_key)
-          for vpd_name, data_key in iteritems((self.args.rw_key_map or {}))
+          for vpd_name, data_key in (self.args.rw_key_map or {}).items()
       }
 
-    missing_keys = [k for section in data for k, v in iteritems(data[section])
+    missing_keys = [k for section in data for k, v in data[section].items()
                     if v is None]
     if missing_keys:
       self.FailTask('Missing device data keys: %r' % sorted(missing_keys))
 
-    for section, entries in iteritems(data):
+    for section, entries in data.items():
       self.ui.SetState(
           _('Writing device data to {vpd_section} VPD...',
             vpd_section=section.upper()))
       if not entries:
         continue
       # Normalize boolean and integer types to strings.
-      output = dict((k, str(v)) for k, v in iteritems(entries))
+      output = dict((k, str(v)) for k, v in entries.items())
       vpd = getattr(self.dut.vpd, section)
       vpd.Update(output)
diff --git a/py/test/rules/privacy.py b/py/test/rules/privacy.py
index 86d03cf..6584295 100644
--- a/py/test/rules/privacy.py
+++ b/py/test/rules/privacy.py
@@ -7,7 +7,6 @@
 
 import copy
 
-from six import iteritems
 
 BLACKLIST_KEYS = [
     'ubind_attribute',
@@ -36,7 +35,7 @@
   if isinstance(data, (list, set)):
     ret = [FilterDict(x) for x in data]
   elif isinstance(data, dict):
-    for k, v in iteritems(ret):
+    for k, v in ret.items():
       if v is None:
         continue
       if str(k) in BLACKLIST_KEYS:
diff --git a/py/test/test_lists/checker.py b/py/test/test_lists/checker.py
index 1ed4208..cf05bbc 100644
--- a/py/test/test_lists/checker.py
+++ b/py/test/test_lists/checker.py
@@ -7,8 +7,6 @@
 import copy
 import inspect
 
-from six import iteritems
-
 from cros.factory.test.test_lists import test_list as test_list_module
 from cros.factory.test.utils import pytest_utils
 from cros.factory.utils import arg_utils
@@ -255,7 +253,7 @@
 
     resolved_args = {}
 
-    for key, value in iteritems(test.dargs):
+    for key, value in test.dargs.items():
       try:
         tmp_dict = test_list.ResolveTestArgs(
             {key: value}, locals_=test.locals_,
diff --git a/py/test/test_lists/checker_unittest.py b/py/test/test_lists/checker_unittest.py
index 70e773a..f1a3cc6 100755
--- a/py/test/test_lists/checker_unittest.py
+++ b/py/test/test_lists/checker_unittest.py
@@ -5,8 +5,6 @@
 
 import unittest
 
-from six import iteritems
-
 from cros.factory.test.test_lists import checker
 from cros.factory.test.test_lists import manager
 from cros.factory.utils import arg_utils
@@ -84,7 +82,7 @@
     }
 
     resolved_args = self.checker.StaticallyResolveTestArgs(test, test_list)
-    for key, expected_value in iteritems(expected_args):
+    for key, expected_value in expected_args.items():
       if expected_value == checker.UnresolvableException:
         self.assertEqual(resolved_args[key].eval_string, test.dargs[key])
       else:
diff --git a/py/test/test_lists/manager.py b/py/test/test_lists/manager.py
index d8f95ec..dae83ef 100644
--- a/py/test/test_lists/manager.py
+++ b/py/test/test_lists/manager.py
@@ -9,8 +9,6 @@
 import os
 import zipimport
 
-from six import iteritems
-
 from cros.factory.test.test_lists import checker as checker_module
 from cros.factory.test.test_lists import test_list as test_list_module
 from cros.factory.test.test_lists import test_list_common
@@ -216,7 +214,7 @@
         failed_test_lists[test_list_id] = str(e)
 
     valid_test_lists = {}  # test lists that will be returned
-    for test_list_id, test_list in iteritems(self.test_lists):
+    for test_list_id, test_list in self.test_lists.items():
       if isinstance(test_list, test_list_module.TestList):
         # if the test list does not have subtests, don't return it.
         # (this is a base test list)
diff --git a/py/test/test_lists/manager_unittest.py b/py/test/test_lists/manager_unittest.py
index ec37c67..0014571 100755
--- a/py/test/test_lists/manager_unittest.py
+++ b/py/test/test_lists/manager_unittest.py
@@ -12,7 +12,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.test import device_data
 from cros.factory.test import state
@@ -150,7 +149,7 @@
         list(expected),
         [test.path for test in factory_test_list.Walk() if test.IsLeaf()])
 
-    for key, value in iteritems(expected):
+    for key, value in expected.items():
       self.assertEqual(
           value,
           factory_test_list.LookupPath(key).action_on_failure)
@@ -170,7 +169,7 @@
         'SMT.LEDTest_2': ['WHITE'],
     }
 
-    for path, colors in iteritems(expected):
+    for path, colors in expected.items():
       self.assertEqual(
           colors, test_list.LookupPath(path).dargs['colors'])
 
diff --git a/py/test/test_lists/test_list.py b/py/test/test_lists/test_list.py
index 9bd0ec7..8ec9761 100644
--- a/py/test/test_lists/test_list.py
+++ b/py/test/test_lists/test_list.py
@@ -12,8 +12,6 @@
 import logging
 import os
 
-from six import iteritems
-
 from cros.factory.test import i18n
 from cros.factory.test.i18n import translation
 from cros.factory.test.rules import phase
@@ -227,7 +225,7 @@
     """
     result = {
         k: v
-        for k, v in iteritems(self.__class__.__dict__) if k[0].islower()
+        for k, v in self.__class__.__dict__.items() if k[0].islower()
     }
     result.update(self.__dict__)
     return result
@@ -347,7 +345,7 @@
     # or the TestState object itself. Convert accordingly.
     return dict(
         (self.LookupPath(k), TestState.FromDictOrObject(v))
-        for k, v in iteritems(self.state_instance.GetTestStates()))
+        for k, v in self.state_instance.GetTestStates().items())
 
   def LookupPath(self, path):
     """Looks up a test from its path."""
@@ -449,7 +447,7 @@
 
     def ConvertToBasicType(value):
       if isinstance(value, collections.Mapping):
-        return {k: ConvertToBasicType(v) for k, v in iteritems(value)}
+        return {k: ConvertToBasicType(v) for k, v in value.items()}
       elif isinstance(value, str):
         return value
       elif isinstance(value, (list, tuple)):
@@ -461,7 +459,7 @@
     def ResolveArg(key, value):
       if isinstance(value, collections.Mapping):
         return {k: ResolveArg('%s[%r]' % (key, k), v)
-                for k, v in iteritems(value)}
+                for k, v in value.items()}
 
       if isinstance(value, collections.Sequence):
         if not isinstance(value, str):
@@ -481,7 +479,7 @@
 
       return MayTranslate(value)
     return ConvertToBasicType(
-        {k: ResolveArg(k, v) for k, v in iteritems(test_args)})
+        {k: ResolveArg(k, v) for k, v in test_args.items()})
 
   @debug_utils.CatchException(_LOGGED_NAME)
   def SetSkippedAndWaivedTests(self):
@@ -549,7 +547,7 @@
     _CollectPatterns(self.options.skipped_tests, _MarkSkipped)
     _CollectPatterns(self.options.waived_tests, _MarkWaived)
 
-    for test_path, test in iteritems(self.path_map):
+    for test_path, test in self.path_map.items():
       test_path = test_path.split(':')[-1]  # To remove test_list_id
       for match, action in patterns:
         if match(test_path):
@@ -742,7 +740,7 @@
 
     # Handle override_args
     if 'override_args' in self._config:
-      for key, override in iteritems(self._config['override_args']):
+      for key, override in self._config['override_args'].items():
         test = self._cached_test_list.LookupPath(key)
         if test:
           config_utils.OverrideConfig(test.dargs, override)
@@ -940,7 +938,7 @@
     # Note that this method can't catch all kind of potential modification.
     # For example, this property won't become `True` if the user add an
     # additional test list in /var/factory/config/ to override an existing one.
-    for config_file, timestamp in iteritems(self._config.GetDepend()):
+    for config_file, timestamp in self._config.GetDepend().items():
       if os.path.exists(config_file):
         if timestamp != os.stat(config_file).st_mtime:
           return True
@@ -977,7 +975,7 @@
         options=NotAccessable(),
         dut=None,
         station=None)
-    for key, value in iteritems(resolved_options):
+    for key, value in resolved_options.items():
       setattr(self._cached_options, key, value)
 
     self._cached_options.CheckValid()
diff --git a/py/test/test_ui_unittest.py b/py/test/test_ui_unittest.py
index 636bb97..3ad8600 100755
--- a/py/test/test_ui_unittest.py
+++ b/py/test/test_ui_unittest.py
@@ -15,7 +15,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.test import event as test_event
 from cros.factory.test import state
@@ -441,7 +440,7 @@
     self.event_loop.Run()
 
     self.assertEqual(sorted(called_times), called_times)
-    for name, expected_times in iteritems(expected_calls):
+    for name, expected_times in expected_calls.items():
       expected_times = sorted(expected_times)
       actual_times = calls.get(name, [])
       if name.startswith('handler'):
@@ -522,7 +521,7 @@
     """
     strip_js = re.sub(r'\s', '', js)
     strip_event_js = event_js
-    for name, arg in iteritems(event_args):
+    for name, arg in event_args.items():
       strip_event_js = re.sub(r'\b%s\b' % re.escape('args.%s' % name),
                               json.dumps(arg), strip_event_js)
     strip_event_js = re.sub(r'\s', '', strip_event_js)
diff --git a/py/test/utils/dhcp_utils.py b/py/test/utils/dhcp_utils.py
index fe203db..40259df 100755
--- a/py/test/utils/dhcp_utils.py
+++ b/py/test/utils/dhcp_utils.py
@@ -12,7 +12,6 @@
 import sys
 
 import jsonrpclib
-from six import iteritems
 
 from cros.factory.test.utils import network_utils
 from cros.factory.utils import jsonrpc_utils
@@ -264,7 +263,7 @@
       'on_del': on_del}
 
   # remove None to use default value
-  kargs = {k: v for k, v in iteritems(kargs) if v is not None}
+  kargs = {k: v for k, v in kargs.items() if v is not None}
 
   manager = DHCPManager(**kargs)
   manager.StartDHCP()
diff --git a/py/test_list_editor/backend/rpc.py b/py/test_list_editor/backend/rpc.py
index 23368ab..c862f0a 100644
--- a/py/test_list_editor/backend/rpc.py
+++ b/py/test_list_editor/backend/rpc.py
@@ -8,8 +8,6 @@
 import numbers
 import os
 
-from six import iteritems
-
 from cros.factory.test import i18n
 from cros.factory.test.test_lists import test_list_common
 from cros.factory.test.utils import pytest_utils
@@ -106,7 +104,7 @@
           return False
       return True
 
-    for filepath, content in iteritems(requests):
+    for filepath, content in requests.items():
       if IsForbidden(filepath):
         raise RuntimeError('Writing to %r is disallowed.' % filepath)
       file_utils.WriteFile(filepath, content)
diff --git a/py/test_list_editor/backend/test_list_editor_unittest.py b/py/test_list_editor/backend/test_list_editor_unittest.py
index 6ac68ee..a75e832 100755
--- a/py/test_list_editor/backend/test_list_editor_unittest.py
+++ b/py/test_list_editor/backend/test_list_editor_unittest.py
@@ -9,7 +9,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.test_list_editor.backend import common
 from cros.factory.test_list_editor.backend import test_list_editor
@@ -31,7 +30,7 @@
 
 
 def _CreateDirectories(path, schema):
-  for k, v in iteritems(schema):
+  for k, v in schema.items():
     new_path = os.path.join(path, k)
     os.makedirs(new_path)
     _CreateDirectories(new_path, v)
diff --git a/py/testlog/testlog.py b/py/testlog/testlog.py
index 8cd787e..8b4d12e 100644
--- a/py/testlog/testlog.py
+++ b/py/testlog/testlog.py
@@ -46,8 +46,6 @@
 import threading
 import time
 
-from six import iteritems
-
 from . import hooks
 from . import testlog_seq
 from . import testlog_utils
@@ -791,7 +789,7 @@
     for cls in mro:
       if cls is object:
         break
-      for field_name, metadata in iteritems(cls.FIELDS):
+      for field_name, metadata in cls.FIELDS.items():
         if metadata[0] and field_name not in self._data:
           missing_fields.append(field_name)
 
@@ -859,7 +857,7 @@
       elif data_type == dict:
         if not data[key]:
           raise testlog_utils.TestlogError('Empty dict is invalid: %r' % key)
-        for sub_key, value in iteritems(data[key]):
+        for sub_key, value in data[key].items():
           self[key] = {'key': sub_key, 'value': value}
       else:
         self[key] = data[key]
diff --git a/py/testlog/testlog_unittest.py b/py/testlog/testlog_unittest.py
index a250301..5cf9d3b 100755
--- a/py/testlog/testlog_unittest.py
+++ b/py/testlog/testlog_unittest.py
@@ -16,8 +16,6 @@
 import time
 import unittest
 
-from six import iteritems
-
 from cros.factory.testlog.testlog_pkg import testlog
 from cros.factory.testlog.testlog_pkg import testlog_utils
 from cros.factory.testlog.testlog_pkg.utils import file_utils
@@ -408,7 +406,7 @@
         description=DESCRIPTION)
     # Examine the result
     paths = set()
-    for att_name, att_dict in iteritems(event['attachments']):
+    for att_name, att_dict in event['attachments'].items():
       description = att_dict['description']
       self.assertEqual(DESCRIPTION, description)
       path = att_dict['path']
@@ -515,7 +513,7 @@
                         'numericValue': 30.5,
                         'expectedMaximum': 31}]}})
     paths = set()
-    for att_name, att_dict in iteritems(event['attachments']):
+    for att_name, att_dict in event['attachments'].items():
       path = att_dict['path']
       text = open(path, 'r').read()
       self.assertEqual(CONTENT, text)
diff --git a/py/testlog/testlog_utils.py b/py/testlog/testlog_utils.py
index f236e30..9fbd863 100644
--- a/py/testlog/testlog_utils.py
+++ b/py/testlog/testlog_utils.py
@@ -8,8 +8,6 @@
 import inspect
 import traceback
 
-from six import iteritems
-
 from .utils import time_utils
 
 
@@ -89,7 +87,7 @@
 
     # Dict node.
     if isinstance(node, dict):
-      for key, value in iteritems(node):
+      for key, value in node.items():
         if key in ignore_keys:
           continue
         for ret in FlattenAttrs(
diff --git a/py/tools/deps.py b/py/tools/deps.py
index f60010e..30f9151 100755
--- a/py/tools/deps.py
+++ b/py/tools/deps.py
@@ -23,7 +23,6 @@
 import subprocess
 import sys
 
-from six import iteritems
 import yaml
 
 
@@ -252,7 +251,7 @@
 
   groups = config[CONFIG_GROUPS]
   rules = {}
-  for key, value in iteritems(config[CONFIG_RULES]):
+  for key, value in config[CONFIG_RULES].items():
     # Expand value into imports
     imports = []
     for package in value:
diff --git a/py/tools/disk_space.py b/py/tools/disk_space.py
index 35b896d..27a2a14 100755
--- a/py/tools/disk_space.py
+++ b/py/tools/disk_space.py
@@ -12,7 +12,6 @@
 import logging
 import os
 
-from six import iteritems
 
 # Stub for mockability.
 _Open = open
@@ -150,7 +149,7 @@
   logging.debug('stateful usage: %s', stateful_usage)
 
   max_partition, max_usage_type, max_usage = None, None, 0
-  for partition, usage in iteritems(stateful_usage):
+  for partition, usage in stateful_usage.items():
     larger_usage = max(usage.bytes_used_pct, usage.inodes_used_pct)
     larger_usage_type = (
         'bytes'
diff --git a/py/tools/download_patch.py b/py/tools/download_patch.py
index 0596b66..8952222 100755
--- a/py/tools/download_patch.py
+++ b/py/tools/download_patch.py
@@ -17,8 +17,6 @@
 import subprocess
 import sys
 
-from six import iteritems
-
 from cros.factory.test.env import paths
 from cros.factory.utils import cros_board_utils
 from cros.factory.utils import process_utils
@@ -164,7 +162,7 @@
 
   # sort CLs in topological order
   def walk(d):
-    for k, v in iteritems(d):
+    for k, v in d.items():
       yield {
           'url': v['url'],
           'fetch': v['fetch'],
diff --git a/py/tools/finalize_bundle.py b/py/tools/finalize_bundle.py
index ed6517d..ab4b541 100755
--- a/py/tools/finalize_bundle.py
+++ b/py/tools/finalize_bundle.py
@@ -21,7 +21,6 @@
 import time
 import urllib.parse
 
-from six import iteritems
 import yaml
 
 from cros.factory.tools import get_version
@@ -721,7 +720,7 @@
     def _ExtractFirmwareVersions(updater_file, updater_name):
       firmware_versions = _GetFirmwareVersions(updater_file, self.has_firmware)
       return [('%s %s' % (updater_name, firmware_type), version)
-              for firmware_type, version in iteritems(firmware_versions)
+              for firmware_type, version in firmware_versions.items()
               if version is not None]
 
     # Get some vital information
diff --git a/py/tools/format_json_test_list.py b/py/tools/format_json_test_list.py
index e90f091..990126f 100755
--- a/py/tools/format_json_test_list.py
+++ b/py/tools/format_json_test_list.py
@@ -10,7 +10,6 @@
 import json
 import sys
 
-from six import iteritems
 
 def ReorderDictKey(obj, key_order=None):
   if key_order is None:
@@ -81,7 +80,7 @@
   if 'definitions' in test_list:
     test_list['definitions'] = collections.OrderedDict(
         (k, RecursiveFormatTestObject(v))
-        for k, v in iteritems(test_list['definitions']))
+        for k, v in test_list['definitions'].items())
   if 'tests' in test_list:
     test_list['tests'] = [
         RecursiveFormatTestObject(test_obj) for test_obj in test_list['tests']
diff --git a/py/tools/image_tool.py b/py/tools/image_tool.py
index 871d12b..88806d8 100755
--- a/py/tools/image_tool.py
+++ b/py/tools/image_tool.py
@@ -39,8 +39,6 @@
 except ImportError:
   pass
 
-from six import iteritems
-
 # This file needs to run on various environments, for example a fresh Ubuntu
 # that does not have Chromium OS source tree nor chroot. So we do want to
 # prevent introducing more cros.factory dependency except very few special
@@ -444,7 +442,7 @@
       metadata = json.load(f)
       component_versions = {
           component: resource.get(PAYLOAD_SUBTYPE_VERSION, '<unknown>')
-          for component, resource in iteritems(metadata)}
+          for component, resource in metadata.items()}
       # Make sure that there are no unknown components
       for component in component_versions:
         assert component in PAYLOAD_COMPONENTS, (
@@ -1182,7 +1180,7 @@
   __slots__ = ['board', 'install_shim'] + PAYLOAD_COMPONENTS
 
   def __init__(self, **kargs):
-    for component, version in iteritems(kargs):
+    for component, version in kargs.items():
       assert component in self.__slots__, 'Unknown component "%s"' % component
       setattr(self, component, version)
 
@@ -1264,7 +1262,7 @@
     for i, option in enumerate(options_list, 1):
       print_with_split_line(
           '(%d)%s%s' % (i, ' ' if single_line_option else '\n', option))
-    for key, option in iteritems(options_dict):
+    for key, option in options_dict.items():
       print_with_split_line(
           '(%s)%s%s' % (key, ' ' if single_line_option else '\n', option))
 
@@ -1949,7 +1947,7 @@
         with open(json_path) as f:
           metadata = json.load(f)
           for resource in metadata.values():
-            for subtype, payload in iteritems(resource):
+            for subtype, payload in resource.items():
               if subtype == PAYLOAD_SUBTYPE_VERSION:
                 continue
               path = os.path.join(payloads_dir, payload)
@@ -2139,7 +2137,7 @@
         board_map[entry.board].append(entry)
 
       selected_entries = set()
-      for board_name, board_entries in iteritems(board_map):
+      for board_name, board_entries in board_map.items():
         if len(board_entries) == 1 or auto_select:
           selected = len(board_entries) - 1
         else:
@@ -2185,7 +2183,7 @@
     """Replace payloads in an RMA shim."""
 
     replaced_payloads = {
-        component: payload for component, payload in iteritems(kargs)
+        component: payload for component, payload in kargs.items()
         if payload is not None}
     if not replaced_payloads:
       print('Nothing to replace.')
@@ -2206,7 +2204,7 @@
     with CrosPayloadUtils.TempPayloadsDir() as temp_dir:
       CrosPayloadUtils.CopyComponentsInImage(image, board, [], temp_dir)
       json_path = CrosPayloadUtils.GetJSONPath(temp_dir, board)
-      for component, payload in iteritems(replaced_payloads):
+      for component, payload in replaced_payloads.items():
         CrosPayloadUtils.ReplaceComponent(json_path, component, payload)
       CrosPayloadUtils.ReplaceComponentsInImage(image, board, temp_dir)
 
@@ -2243,7 +2241,7 @@
       targets = {'main': 'bios.bin', 'ec': 'ec.bin'}
       # TODO(hungte) Read VERSION.signer for signing keys.
       results = {}
-      for target, image in iteritems(targets):
+      for target, image in targets.items():
         image_path = os.path.join(extract_dir, image)
         if not os.path.exists(image_path):
           continue
@@ -3421,7 +3419,7 @@
           SPLIT_LINE])
       options_list = [arg.__doc__.splitlines()[0] for arg in args]
       options_dict = {
-          k: v.__doc__.splitlines()[0] for k, v in iteritems(kargs)}
+          k: v.__doc__.splitlines()[0] for k, v in kargs.items()}
 
       selected = UserInput.Select(title, options_list, options_dict)
 
@@ -3653,7 +3651,7 @@
 
       options_list = [arg.__doc__.splitlines()[0] for arg in args]
       options_dict = {
-          k: v.__doc__.splitlines()[0] for k, v in iteritems(kargs)}
+          k: v.__doc__.splitlines()[0] for k, v in kargs.items()}
 
       selected = UserInput.Select(title, options_list, options_dict)
 
diff --git a/py/tools/migrate_board_dir_unittest.py b/py/tools/migrate_board_dir_unittest.py
index ab56614..15a9f09 100755
--- a/py/tools/migrate_board_dir_unittest.py
+++ b/py/tools/migrate_board_dir_unittest.py
@@ -14,7 +14,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.tools import migrate_board_dir
 from cros.factory.tools.migrate_board_dir import MigrateBoardException
@@ -30,7 +29,7 @@
         'path2', content2'} indicating the expected content for each file.
         A special content 'linkto: source' means a symlink pointing to source.
   """
-  for path, expected_content in iteritems(path_contents_dict):
+  for path, expected_content in path_contents_dict.items():
     if expected_content.startswith('linkto:'):
       expected_linkto = expected_content.split(':')[1].strip()
       actual_linkto = os.readlink(path)
@@ -53,7 +52,7 @@
         A special content 'linkto: source' means creating a symlink pointing
         to source.
   """
-  for path, content in iteritems(path_contents_dict):
+  for path, content in path_contents_dict.items():
     if not os.path.exists(os.path.dirname(path)):
       os.makedirs(os.path.dirname(path))
 
diff --git a/py/tools/netboot_firmware_settings.py b/py/tools/netboot_firmware_settings.py
index 29f4c2d..b11b604 100755
--- a/py/tools/netboot_firmware_settings.py
+++ b/py/tools/netboot_firmware_settings.py
@@ -13,8 +13,6 @@
 import struct
 import sys
 
-from six import iteritems
-
 from cros.factory.utils import fmap
 
 
@@ -214,7 +212,7 @@
     """
     value = self.signature
     value += struct.pack('<I', len(self.attributes))
-    for unused_i, attr in iteritems(self.attributes):
+    for unused_i, attr in self.attributes.items():
       value += attr.pack()
     return value
 
diff --git a/py/tools/ovl.py b/py/tools/ovl.py
index b1603a1..a6b4cfe 100755
--- a/py/tools/ovl.py
+++ b/py/tools/ovl.py
@@ -39,7 +39,6 @@
 import jsonrpclib
 from jsonrpclib.config import Config
 from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer
-from six import iteritems
 from ws4py.client import WebSocketBaseClient
 import yaml
 
@@ -674,7 +673,7 @@
   This decorator retrieve command info from each method and append it in to the
   SUBCOMMANDS class variable, which is later used to construct parser.
   """
-  for unused_key, method in iteritems(cls.__dict__):
+  for unused_key, method in cls.__dict__.items():
     if hasattr(method, '__arg_attr'):
       # pylint: disable=protected-access
       cls.SUBCOMMANDS.append(method.__arg_attr)
diff --git a/py/tools/run_tests.py b/py/tools/run_tests.py
index c745b2a..b24eb5b 100755
--- a/py/tools/run_tests.py
+++ b/py/tools/run_tests.py
@@ -22,8 +22,6 @@
 import threading
 import time
 
-from six import iteritems
-
 from cros.factory.utils.debug_utils import SetupLogging
 from cros.factory.utils import file_utils
 from cros.factory.utils import net_utils
@@ -344,7 +342,7 @@
     for pid in self._running_proc:
       os.kill(pid, signal.SIGINT)
     time.sleep(1)
-    for pid, (proc, unused_test_name) in iteritems(self._running_proc):
+    for pid, (proc, unused_test_name) in self._running_proc.items():
       if os.waitpid(pid, os.WNOHANG)[0] == 0:
         # Test still alive, kill with SIGKILL
         os.kill(pid, signal.SIGKILL)
diff --git a/py/umpire/client/umpire_client.py b/py/umpire/client/umpire_client.py
index 8ac92e6..c706066 100644
--- a/py/umpire/client/umpire_client.py
+++ b/py/umpire/client/umpire_client.py
@@ -6,8 +6,6 @@
 
 import logging
 
-from six import iteritems
-
 from cros.factory.device import device_utils
 from cros.factory.umpire import common
 
@@ -158,7 +156,7 @@
         # With prefix 'mac', output should be
         # 'mac.eth0='xxxx', 'mac.wlan0=xxxx'.
         values = getattr(self, UmpireClientInfo.KEY_TRANSLATION[key_prefix])
-        for subkey, value in iteritems(values):
+        for subkey, value in values.items():
           info_dict['%s.%s' % (key_prefix, subkey)] = value
     except KeyError as e:
       raise UmpireClientInfoException(
diff --git a/py/umpire/server/daemon.py b/py/umpire/server/daemon.py
index e549606..924cf42 100644
--- a/py/umpire/server/daemon.py
+++ b/py/umpire/server/daemon.py
@@ -15,7 +15,6 @@
 import logging
 import signal
 
-from six import iteritems
 from twisted.internet import defer
 from twisted.internet import reactor
 from twisted.python import failure as twisted_failure
@@ -187,7 +186,7 @@
       Yields:
         Active service names.
       """
-      for name, service_config in iteritems(config.services):
+      for name, service_config in config.services.items():
         if getattr(service_config, 'active', True):
           yield name
 
diff --git a/py/umpire/server/download_slots_manager.py b/py/umpire/server/download_slots_manager.py
index 8b369d0..f5fce21 100644
--- a/py/umpire/server/download_slots_manager.py
+++ b/py/umpire/server/download_slots_manager.py
@@ -19,7 +19,6 @@
 import time
 import uuid
 
-from six import iteritems
 from twisted.internet import reactor
 
 
@@ -140,10 +139,10 @@
 
   def _RemoveExpiredSession(self):
     now = time.time()
-    self.slots = {identity: t for identity, t in iteritems(self.slots)
+    self.slots = {identity: t for identity, t in self.slots.items()
                   if now - t < _SLOT_ALIVE_TIME}
     self.wait_queue = collections.OrderedDict(
-        (identity, t) for identity, t in iteritems(self.wait_queue)
+        (identity, t) for identity, t in self.wait_queue.items()
         if now - t < _SLOT_ALIVE_TIME)
     self._CheckAvailableSlot()
 
diff --git a/py/umpire/server/e2e_test/e2e_test.py b/py/umpire/server/e2e_test/e2e_test.py
index d0fd4b0..aee5ec8 100755
--- a/py/umpire/server/e2e_test/e2e_test.py
+++ b/py/umpire/server/e2e_test/e2e_test.py
@@ -27,7 +27,6 @@
 import xmlrpc.client
 
 import requests  # pylint: disable=import-error
-from six import iteritems
 
 from cros.factory.umpire import common
 from cros.factory.utils import file_utils
@@ -345,7 +344,7 @@
                       if bundle['id'] == 'umpire_test')
     new_payload = self.proxy.GetPayloadsDict(new_bundle['payloads'])
 
-    for resource_type, resource in iteritems(resources):
+    for resource_type, resource in resources.items():
       self.assertTrue(
           os.path.exists(os.path.join(HOST_RESOURCE_DIR, resource)))
       self.assertEqual(new_payload[resource_type]['file'], resource)
diff --git a/py/umpire/server/migrations/0004.py b/py/umpire/server/migrations/0004.py
index 4f441d8..596f8e8 100644
--- a/py/umpire/server/migrations/0004.py
+++ b/py/umpire/server/migrations/0004.py
@@ -6,8 +6,6 @@
 import json
 import os
 
-from six import iteritems
-
 _ENV_DIR = '/var/db/factory/umpire'
 _CONFIG_PATH = os.path.join(_ENV_DIR, 'active_umpire.json')
 
@@ -20,7 +18,7 @@
   """Migrates a config by moving key values to new location."""
   modified = False
 
-  for old_key, new_key in iteritems(migrate_keys):
+  for old_key, new_key in migrate_keys.items():
     if old_key not in config:
       continue
 
diff --git a/py/umpire/server/service/umpire_service.py b/py/umpire/server/service/umpire_service.py
index 4ce3bb9..86ed156 100644
--- a/py/umpire/server/service/umpire_service.py
+++ b/py/umpire/server/service/umpire_service.py
@@ -20,7 +20,6 @@
 import os
 import uuid
 
-from six import iteritems
 from twisted.internet import defer
 from twisted.internet import protocol
 from twisted.internet import reactor
@@ -166,7 +165,7 @@
       raise ValueError('Found unknown config keys: %s' %
                        ','.join(config_keys - all_keys))
 
-    for key, value in iteritems(config_dict):
+    for key, value in config_dict.items():
       if isinstance(self.config[key], list):
         if not isinstance(value, list):
           raise ValueError('Config %s should be a list' % key)
@@ -526,7 +525,7 @@
     The JSON schema of field 'service' in Umpire config.
   """
   properties = {}
-  for name, module in iteritems(_SERVICE_MAP):
+  for name, module in _SERVICE_MAP.items():
     module_path = os.path.dirname(os.path.realpath(module.__file__))
     config_path = os.path.join(module_path, "%s_config.schema.json" % name)
     properties[name] = copy.deepcopy(_COMMON_SERVICE_SCHEMA)
diff --git a/py/umpire/server/umpire_env.py b/py/umpire/server/umpire_env.py
index 3fde1ff..d97f2aa 100644
--- a/py/umpire/server/umpire_env.py
+++ b/py/umpire/server/umpire_env.py
@@ -15,8 +15,6 @@
 import tempfile
 import urllib.parse
 
-from six import iteritems
-
 from cros.factory.umpire import common
 from cros.factory.umpire.server.commands import parameters
 from cros.factory.umpire.server import config
@@ -330,8 +328,8 @@
     """
     files = set()
     payloads = self.GetPayloadsDict(payloads_name)
-    for type_name, payload_dict in iteritems(payloads):
-      for part, res_name in iteritems(payload_dict):
+    for type_name, payload_dict in payloads.items():
+      for part, res_name in payload_dict.items():
         if part == 'file' or re.match(r'part\d+$', part) or part == 'crx_cache':
           files.add((type_name, part, res_name))
     return files
diff --git a/py/umpire/server/web/wsgi.py b/py/umpire/server/web/wsgi.py
index 380c005..4bc8950 100644
--- a/py/umpire/server/web/wsgi.py
+++ b/py/umpire/server/web/wsgi.py
@@ -10,7 +10,6 @@
 import logging
 import time
 
-from six import iteritems
 from twisted.web import http
 
 from cros.factory.utils import type_utils
@@ -49,7 +48,7 @@
       start_response: WSGI start_response object.
     """
     super(WSGISession, self).__init__(environ)
-    for key, value in iteritems(environ):
+    for key, value in environ.items():
       if key.startswith('wsgi.'):
         key = 'wsgi_' + key[5:]
       self[key] = value
diff --git a/py/umpire/server/webapp_utils.py b/py/umpire/server/webapp_utils.py
index 9e03701..9145e28 100644
--- a/py/umpire/server/webapp_utils.py
+++ b/py/umpire/server/webapp_utils.py
@@ -6,8 +6,6 @@
 
 import http.cookies
 
-from six import iteritems
-
 from cros.factory.umpire import common
 
 
@@ -43,5 +41,5 @@
   if invalid_keys:
     raise ValueError('Invalid key(s): %r' % invalid_keys)
 
-  return {k: v.value for k, v in iteritems(dut_info)
+  return {k: v.value for k, v in dut_info.items()
           if k not in common.LEGACY_DUT_INFO_KEYS}
diff --git a/py/utils/arg_utils.py b/py/utils/arg_utils.py
index aa84d87..e51e539 100644
--- a/py/utils/arg_utils.py
+++ b/py/utils/arg_utils.py
@@ -23,8 +23,6 @@
       self.assertEqual(self.args.explode, device.exploded)
 """
 
-from six import iteritems
-
 from .type_utils import Enum
 
 
@@ -168,7 +166,7 @@
   """A class to hold all the parsed arguments for a factory test."""
 
   def __init__(self, **kwargs):
-    for key, value in iteritems(kwargs):
+    for key, value in kwargs.items():
       setattr(self, key, value)
 
   def ToDict(self):
diff --git a/py/utils/arg_utils_unittest.py b/py/utils/arg_utils_unittest.py
index bbb011b..6e844c6 100755
--- a/py/utils/arg_utils_unittest.py
+++ b/py/utils/arg_utils_unittest.py
@@ -6,8 +6,6 @@
 
 import unittest
 
-from six import iteritems
-
 from cros.factory.utils.arg_utils import Arg
 from cros.factory.utils.arg_utils import Args
 from cros.factory.utils.type_utils import Enum
@@ -31,7 +29,7 @@
       A dictionary of attributes from the resultant object.
     """
     values = self.parser.Parse(dargs)
-    return dict((k, v) for k, v in iteritems(values.__dict__)
+    return dict((k, v) for k, v in values.__dict__.items()
                 if not k.startswith('_'))
 
   def testIntOrNone(self):
diff --git a/py/utils/config_utils.py b/py/utils/config_utils.py
index 4b99e1e..2b6ba3a 100644
--- a/py/utils/config_utils.py
+++ b/py/utils/config_utils.py
@@ -52,8 +52,6 @@
 import sys
 import zipimport
 
-from six import iteritems
-
 from . import file_utils
 
 # To simplify portability issues, validating JSON schema is optional.
@@ -155,7 +153,7 @@
 
   changed = False
   result = base.copy() if copy_on_write else base
-  for k, v in iteritems(overrides):
+  for k, v in overrides.items():
     if isinstance(v, collections.Mapping):
       v = v.copy()
       if pop_bool(v, _OVERRIDE_DELETE_KEY):
@@ -189,7 +187,7 @@
   """
   if not isinstance(mapping, collections.Mapping):
     return mapping
-  new_mapping = dict((k, GetNamedTuple(v)) for k, v in iteritems(mapping))
+  new_mapping = dict((k, GetNamedTuple(v)) for k, v in mapping.items())
   return collections.namedtuple('Config', new_mapping.keys())(**new_mapping)
 
 
diff --git a/py/utils/cros_board_utils.py b/py/utils/cros_board_utils.py
index 82c7a26..8131255 100644
--- a/py/utils/cros_board_utils.py
+++ b/py/utils/cros_board_utils.py
@@ -9,8 +9,6 @@
 import re
 import subprocess
 
-from six import iteritems
-
 from . import process_utils
 from . import sys_utils
 from . import type_utils
@@ -195,7 +193,7 @@
           'arm': 'arm',
           'aarch64': 'arm64'
       }
-      for key, value in iteritems(machine_arch_map):
+      for key, value in machine_arch_map.items():
         if uname_machine.startswith(key):
           return value
       return None
diff --git a/py/utils/json_utils_unittest.py b/py/utils/json_utils_unittest.py
index 2249a04..ce9f1b6 100755
--- a/py/utils/json_utils_unittest.py
+++ b/py/utils/json_utils_unittest.py
@@ -9,8 +9,6 @@
 import os
 import unittest
 
-from six import iteritems
-
 from cros.factory.utils import file_utils
 from cros.factory.utils import json_utils
 
@@ -29,7 +27,7 @@
     elif isinstance(a, dict):
       self.assertIsInstance(b, dict)
       self.assertEqual(len(a), len(b))
-      for key, value in iteritems(a):
+      for key, value in a.items():
         self.assertJSONObjEqual(value, b[key])
     else:
       self.assertIs(type(a), type(b))
diff --git a/py/utils/jsonrpc_utils.py b/py/utils/jsonrpc_utils.py
index d758804..352a0b1 100644
--- a/py/utils/jsonrpc_utils.py
+++ b/py/utils/jsonrpc_utils.py
@@ -13,7 +13,6 @@
 
 import jsonrpclib
 from jsonrpclib import SimpleJSONRPCServer
-from six import iteritems
 
 from . import net_utils
 from .net_utils import TimeoutXMLRPCTransport
@@ -55,7 +54,7 @@
     self._server.register_function(lambda: True, 'IsAlive')
     self._server.register_function(lambda: self._uuid, 'GetUuid')
     if self._methods:
-      for k, v in iteritems(self._methods):
+      for k, v in self._methods.items():
         self._server.register_function(v, k)
     self._server_thread = threading.Thread(target=self._ServeRPCForever,
                                            name='RPCServer')
diff --git a/py/utils/process_utils.py b/py/utils/process_utils.py
index 08555c4..cf2a132 100644
--- a/py/utils/process_utils.py
+++ b/py/utils/process_utils.py
@@ -19,8 +19,6 @@
 import time
 import traceback
 
-from six import iteritems
-
 # Use subprocess.CalledProcessError for invocation exceptions.
 class CalledProcessError(subprocess.CalledProcessError):
   """A CalledProcessError with a workaround repr."""
@@ -485,19 +483,19 @@
              within the context.
   """
   args = {'stdin': stdin, 'stdout': stdout, 'stderr': stderr}
-  redirect_streams = dict((k, v) for k, v in iteritems(args) if v is not None)
+  redirect_streams = dict((k, v) for k, v in args.items() if v is not None)
   old_streams = dict((k, sys.__dict__[k]) for k in redirect_streams)
 
-  for k, v in iteritems(redirect_streams):
+  for k, v in redirect_streams.items():
     sys.__dict__[k] = v
 
   yield
 
-  changed = dict((k, sys.__dict__[k]) for k, v in iteritems(redirect_streams)
+  changed = dict((k, sys.__dict__[k]) for k, v in redirect_streams.items()
                  if v is not sys.__dict__[k])
   if changed:
     raise IOError('Unexpected standard stream redirections: %r' % changed)
-  for k, v in iteritems(old_streams):
+  for k, v in old_streams.items():
     sys.__dict__[k] = v
 
 
diff --git a/py/utils/pygpt.py b/py/utils/pygpt.py
index 0f1d9a7..6e0e0de 100755
--- a/py/utils/pygpt.py
+++ b/py/utils/pygpt.py
@@ -40,8 +40,6 @@
 import sys
 import uuid
 
-from six import iteritems
-
 
 class StructError(Exception):
   """Exceptions in packing and unpacking from/to struct fields."""
@@ -285,7 +283,7 @@
       self.Zero()
 
     all_names = [f for f in self.__slots__]
-    for name, value in iteritems(kargs):
+    for name, value in kargs.items():
       if name not in all_names:
         raise GPTError('%s does not support keyword arg <%s>.' %
                        (type(self).__name__, name))
@@ -351,7 +349,7 @@
 
   def Update(self, **dargs):
     """Applies multiple values in current object."""
-    for name, value in iteritems(dargs):
+    for name, value in dargs.items():
       setattr(self, name, value)
 
   def Zero(self):
@@ -398,7 +396,7 @@
   }
   TYPE_GUID_FROM_NAME = dict(
       ('efi' if v.startswith('EFI') else v.lower().split()[-1], k)
-      for k, v in iteritems(TYPE_GUID_MAP))
+      for k, v in TYPE_GUID_MAP.items())
   TYPE_GUID_UNUSED = TYPE_GUID_FROM_NAME['unused']
   TYPE_GUID_CHROMEOS_KERNEL = TYPE_GUID_FROM_NAME['kernel']
   TYPE_GUID_LIST_BOOTABLE = [
@@ -969,7 +967,7 @@
   def DefineArgs(self, parser):
     """Defines all available commands to an argparser subparsers instance."""
     subparsers = parser.add_subparsers(help='Sub-command help.', dest='command')
-    for name, instance in sorted(iteritems(self.commands)):
+    for name, instance in sorted(self.commands.items()):
       parser = subparsers.add_parser(
           name, description=instance.__doc__,
           formatter_class=argparse.RawDescriptionHelpFormatter,
diff --git a/py/utils/schema.py b/py/utils/schema.py
index 7b8a7f9..a8d0dad 100644
--- a/py/utils/schema.py
+++ b/py/utils/schema.py
@@ -50,8 +50,6 @@
 
 import copy
 
-from six import iteritems
-
 from .type_utils import MakeList
 
 # To simplify portability issues, validating JSON schema is optional.
@@ -233,7 +231,7 @@
       raise SchemaException('Size mismatch on %r: expected size <= %r' %
                             (self.label, self.max_size))
 
-    for k, v in iteritems(data):
+    for k, v in data.items():
       self.key_type.Validate(k)
       self.value_type.Validate(v)
 
@@ -305,7 +303,7 @@
                             (self.label, type(data)))
     data_key_list = list(data)
     # Check that every key-value pair in items exists in data
-    for key, value_schema in iteritems(self.items):
+    for key, value_schema in self.items.items():
       if key not in data:
         raise SchemaException(
             'Required item %r does not exist in FixedDict %r' %
@@ -314,7 +312,7 @@
       data_key_list.remove(key)
     # Check that all the remaining unmatched key-value pairs matches any
     # definition in items or optional_items.
-    for key, value_schema in iteritems(self.optional_items):
+    for key, value_schema in self.optional_items.items():
       if key not in data:
         continue
       value_schema.Validate(data[key])
diff --git a/py/utils/service_utils.py b/py/utils/service_utils.py
index b1cbd10..403b886 100644
--- a/py/utils/service_utils.py
+++ b/py/utils/service_utils.py
@@ -5,8 +5,6 @@
 import logging
 import threading
 
-from six import iteritems
-
 from . import sync_utils
 from . import type_utils
 from .process_utils import CheckOutput
@@ -220,7 +218,7 @@
 
     # Restore services if there's only 1 setup record left, which means this
     # should be the last restore request.
-    for service, status in iteritems(ServiceManager._original_status_map):
+    for service, status in ServiceManager._original_status_map.items():
       SetServiceStatus(service, status, self.dut)
     ServiceManager._original_status_map.clear()
     ServiceManager._enable_services = []
diff --git a/py/utils/service_utils_unittest.py b/py/utils/service_utils_unittest.py
index 5d7a9a7..c883e78 100755
--- a/py/utils/service_utils_unittest.py
+++ b/py/utils/service_utils_unittest.py
@@ -7,7 +7,6 @@
 import unittest
 
 import mock
-from six import iteritems
 
 from cros.factory.utils import service_utils
 from cros.factory.utils.service_utils import Status
@@ -58,7 +57,7 @@
         Status.START: 'start',
         Status.STOP: 'stop'}
 
-    for status, cmd in iteritems(commands):
+    for status, cmd in commands.items():
       check_output_mock.reset_mock()
       parse_status_mock.reset_mock()
 
@@ -78,7 +77,7 @@
         Status.START: 'start',
         Status.STOP: 'stop'}
 
-    for status, cmd in iteritems(commands):
+    for status, cmd in commands.items():
       self.dut.CheckOutput.reset_mock()
       parse_status_mock.reset_mock()
 
diff --git a/py/utils/type_utils.py b/py/utils/type_utils.py
index 4ed1a38..8da92e9 100644
--- a/py/utils/type_utils.py
+++ b/py/utils/type_utils.py
@@ -10,7 +10,6 @@
 import queue
 import re
 
-from six import iteritems
 
 # The regular expression used by Overrides.
 _OVERRIDES_CLASS_RE = re.compile(r'^\s*class([^#]+)\(\s*([^\s#]+)\s*\)\s*\:')
@@ -223,7 +222,7 @@
 
   def __init__(self, *args, **kwargs):
     super(AttrDict, self).__init__(*args, **kwargs)
-    for key, val in iteritems(self):
+    for key, val in self.items():
       self[key] = self._Convert(val)
     self.__dict__ = self
 
diff --git a/py/utils/yaml_utils.py b/py/utils/yaml_utils.py
index 16a6f37..07c4c2d 100644
--- a/py/utils/yaml_utils.py
+++ b/py/utils/yaml_utils.py
@@ -6,7 +6,6 @@
 
 import collections
 
-from six import iteritems
 import yaml
 
 
@@ -48,7 +47,7 @@
     enable: if enable is True, load and dump yaml as OrderedDict.
   """
   def DictRepresenter(dumper, data):
-    return dumper.represent_dict(iteritems(data))
+    return dumper.represent_dict(data.items())
 
   def OrderedDictRepresenter(dumper, data):
     return dumper.represent_object(data)