fix: add back python 2.7 for gcloud usage only (#892)

* fix: add back python 2.7 for gcloud

* fix: fix setup and tests

* fix: add enum34 for python 2.7

* fix: add app engine app and fix noxfile

* fix: move test_app_engine.py

* fix: fix downscoped

* fix: fix downscoped

* fix: remove py2 from classifiers
diff --git a/google/oauth2/credentials.py b/google/oauth2/credentials.py
index 6d34edf..9b59f8c 100644
--- a/google/oauth2/credentials.py
+++ b/google/oauth2/credentials.py
@@ -35,6 +35,8 @@
 import io
 import json
 
+import six
+
 from google.auth import _cloud_sdk
 from google.auth import _helpers
 from google.auth import credentials
@@ -262,7 +264,7 @@
         if self._refresh_token is None and self.refresh_handler:
             token, expiry = self.refresh_handler(request, scopes=scopes)
             # Validate returned data.
-            if not isinstance(token, str):
+            if not isinstance(token, six.string_types):
                 raise exceptions.RefreshError(
                     "The refresh_handler returned token is not a string."
                 )
@@ -344,7 +346,7 @@
             ValueError: If the info is not in the expected format.
         """
         keys_needed = set(("refresh_token", "client_id", "client_secret"))
-        missing = keys_needed.difference(info)
+        missing = keys_needed.difference(six.iterkeys(info))
 
         if missing:
             raise ValueError(
@@ -364,7 +366,7 @@
         # process scopes, which needs to be a seq
         if scopes is None and "scopes" in info:
             scopes = info.get("scopes")
-            if isinstance(scopes, str):
+            if isinstance(scopes, six.string_types):
                 scopes = scopes.split(" ")
 
         return cls(