Remove some py2 workarounds. (#715)

diff --git a/mobly/controllers/android_device_lib/services/base_service.py b/mobly/controllers/android_device_lib/services/base_service.py
index 5140a6a..a284581 100644
--- a/mobly/controllers/android_device_lib/services/base_service.py
+++ b/mobly/controllers/android_device_lib/services/base_service.py
@@ -13,9 +13,10 @@
 # limitations under the License.
 """Module for the BaseService."""
 
+import abc
 
-#TODO(xpconanfan): use `abc` after py2 deprecation.
-class BaseService(object):
+
+class BaseService(abc.ABC):
   """Base class of a Mobly AndroidDevice service.
 
   This class defines the interface for Mobly's AndroidDevice service.
@@ -52,18 +53,18 @@
   @property
   def is_alive(self):
     """True if the service is active; False otherwise."""
-    raise NotImplementedError('"is_alive" is a required service property.')
+    pass
 
   def start(self):
     """Starts the service."""
-    raise NotImplementedError('"start" is a required service method.')
+    pass
 
   def stop(self):
     """Stops the service and cleans up all resources.
 
     This method should handle any error and not throw.
     """
-    raise NotImplementedError('"stop" is a required service method.')
+    pass
 
   def pause(self):
     """Pauses a service temporarily.
diff --git a/mobly/records.py b/mobly/records.py
index 5b9e0a2..c4f05cd 100644
--- a/mobly/records.py
+++ b/mobly/records.py
@@ -236,12 +236,7 @@
     # Record stacktrace of the exception.
     # This check cannot be based on try...except, which messes up
     # `exc_info`.
-    if hasattr(e, '__traceback__'):
-      exc_traceback = e.__traceback__
-    else:
-      # In py2, exception objects don't have built-in traceback, so we
-      # have to immediately retrieve stacktrace from `sys.exc_info`.
-      _, _, exc_traceback = sys.exc_info()
+    exc_traceback = e.__traceback__
     if exc_traceback:
       self.stacktrace = ''.join(
           traceback.format_exception(e.__class__, e, exc_traceback))
diff --git a/tests/lib/jsonrpc_client_test_base.py b/tests/lib/jsonrpc_client_test_base.py
index 7623360..c37a0c5 100755
--- a/tests/lib/jsonrpc_client_test_base.py
+++ b/tests/lib/jsonrpc_client_test_base.py
@@ -75,11 +75,8 @@
     return fake_file
 
   def generate_rpc_response(self, response_length=1024):
-    # TODO: Py2 deprecation
-    # .encode('utf-8') is for py2 compatibility, after py2 deprecation, it
-    # could be modified to byte('xxxxx', 'utf-8')
-    return bytes((self.MOCK_RESP_FLEXIABLE_RESULT_LENGTH % ''.join(
-        random.choice(string.ascii_lowercase)
-        for i in range(response_length -
-                       len(self.MOCK_RESP_FLEXIABLE_RESULT_LENGTH) + 2))
-                 ).encode('utf-8'))
+    length = response_length - len(self.MOCK_RESP_FLEXIABLE_RESULT_LENGTH) + 2
+    chars = string.ascii_letters + string.digits
+    random_msg = ''.join(random.choice(chars) for i in range(length))
+    mock_response = self.MOCK_RESP_FLEXIABLE_RESULT_LENGTH % random_msg
+    return bytes(mock_response, 'utf-8')
diff --git a/tests/mobly/controllers/android_device_test.py b/tests/mobly/controllers/android_device_test.py
index 12b4b04..ceea844 100755
--- a/tests/mobly/controllers/android_device_test.py
+++ b/tests/mobly/controllers/android_device_test.py
@@ -420,12 +420,6 @@
     """Verifies that the serial is a primitive string type and serializable.
     """
     ad = android_device.AndroidDevice(serial=1)
-    # In py2, checks that ad.serial is not the backported py3 str type,
-    # which is not dumpable by yaml in py2.
-    # In py3, new_str is equivalent to str, so this check is not
-    # appropirate in py3.
-    if sys.version_info < (3, 0):
-      self.assertFalse(isinstance(ad.serial, new_str))
     self.assertTrue(isinstance(ad.serial, str))
     yaml.safe_dump(ad.serial)