fix!: drop support for Python 2.7 (#778)

Drop use of 'six' wrapper library.

Drop 'u"' prefixes.

Drop support for app_engine 'classic' mode (Python 2.7-only).

Release-As: 2.0.0b1

Closes #777.
diff --git a/system_tests/noxfile.py b/system_tests/noxfile.py
index 11c398b..33e49c3 100644
--- a/system_tests/noxfile.py
+++ b/system_tests/noxfile.py
@@ -171,7 +171,7 @@
 TEST_DEPENDENCIES_ASYNC = ["aiohttp", "pytest-asyncio", "nest-asyncio"]
 TEST_DEPENDENCIES_SYNC = ["pytest", "requests", "mock"]
 PYTHON_VERSIONS_ASYNC = ["3.7"]
-PYTHON_VERSIONS_SYNC = ["2.7", "3.7"]
+PYTHON_VERSIONS_SYNC = ["3.7"]
 
 
 def default(session, *test_paths):
@@ -287,50 +287,6 @@
     )
 
 
-@nox.session(python=["2.7"])
-def app_engine(session):
-    if SKIP_GAE_TEST_ENV in os.environ:
-        session.log("Skipping App Engine tests.")
-        return
-
-    session.install(LIBRARY_DIR)
-    # Unlike the default tests above, the App Engine system test require a
-    # 'real' gcloud sdk installation that is configured to deploy to an
-    # app engine project.
-    # Grab the project ID from the cloud sdk.
-    project_id = (
-        subprocess.check_output(
-            ["gcloud", "config", "list", "project", "--format", "value(core.project)"]
-        )
-        .decode("utf-8")
-        .strip()
-    )
-
-    if not project_id:
-        session.error(
-            "The Cloud SDK must be installed and configured to deploy to App " "Engine."
-        )
-
-    application_url = GAE_APP_URL_TMPL.format(GAE_TEST_APP_SERVICE, project_id)
-
-    # Vendor in the test application's dependencies
-    session.chdir(os.path.join(HERE, "system_tests_sync/app_engine_test_app"))
-    session.install(*TEST_DEPENDENCIES_SYNC)
-    session.run(
-        "pip", "install", "--target", "lib", "-r", "requirements.txt", silent=True
-    )
-
-    # Deploy the application.
-    session.run("gcloud", "app", "deploy", "-q", "app.yaml")
-
-    # Run the tests
-    session.env["TEST_APP_URL"] = application_url
-    session.chdir(HERE)
-    default(
-        session, "system_tests_sync/test_app_engine.py",
-    )
-
-
 @nox.session(python=PYTHON_VERSIONS_SYNC)
 def grpc(session):
     session.install(LIBRARY_DIR)
diff --git a/system_tests/system_tests_sync/app_engine_test_app/.gitignore b/system_tests/system_tests_sync/app_engine_test_app/.gitignore
deleted file mode 100644
index a65b417..0000000
--- a/system_tests/system_tests_sync/app_engine_test_app/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-lib
diff --git a/system_tests/system_tests_sync/app_engine_test_app/app.yaml b/system_tests/system_tests_sync/app_engine_test_app/app.yaml
deleted file mode 100644
index 872efb3..0000000
--- a/system_tests/system_tests_sync/app_engine_test_app/app.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-api_version: 1
-service: google-auth-system-tests
-runtime: python27
-threadsafe: true
-
-handlers:
-- url: .*
-  script: main.app
-
-libraries:
-- name: ssl
-  version: 2.7.11
diff --git a/system_tests/system_tests_sync/app_engine_test_app/appengine_config.py b/system_tests/system_tests_sync/app_engine_test_app/appengine_config.py
deleted file mode 100644
index 5a832ac..0000000
--- a/system_tests/system_tests_sync/app_engine_test_app/appengine_config.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2016 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from google.appengine.ext import vendor
-
-# Add any libraries installed in the "lib" folder.
-vendor.add("lib")
-
-
-# Patch os.path.expanduser. This should be fixed in GAE
-# versions released after Nov 2016.
-import os.path
-
-
-def patched_expanduser(path):
-    return path
-
-
-os.path.expanduser = patched_expanduser
diff --git a/system_tests/system_tests_sync/app_engine_test_app/main.py b/system_tests/system_tests_sync/app_engine_test_app/main.py
deleted file mode 100644
index 33e61d0..0000000
--- a/system_tests/system_tests_sync/app_engine_test_app/main.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# Copyright 2016 Google LLC All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""App Engine standard application that runs basic system tests for
-google.auth.app_engine.
-
-This application has to run tests manually instead of using pytest because
-pytest currently doesn't work on App Engine standard.
-"""
-
-import contextlib
-import json
-import sys
-from StringIO import StringIO
-import traceback
-
-from google.appengine.api import app_identity
-import google.auth
-from google.auth import _helpers
-from google.auth import app_engine
-import google.auth.transport.urllib3
-import urllib3.contrib.appengine
-import webapp2
-
-FAILED_TEST_TMPL = """
-Test {} failed: {}
-
-Stacktrace:
-{}
-
-Captured output:
-{}
-"""
-TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo"
-EMAIL_SCOPE = "https://www.googleapis.com/auth/userinfo.email"
-HTTP = urllib3.contrib.appengine.AppEngineManager()
-HTTP_REQUEST = google.auth.transport.urllib3.Request(HTTP)
-
-
-def test_credentials():
-    credentials = app_engine.Credentials()
-    scoped_credentials = credentials.with_scopes([EMAIL_SCOPE])
-
-    scoped_credentials.refresh(None)
-
-    assert scoped_credentials.valid
-    assert scoped_credentials.token is not None
-
-    # Get token info and verify scope
-    url = _helpers.update_query(
-        TOKEN_INFO_URL, {"access_token": scoped_credentials.token}
-    )
-    response = HTTP_REQUEST(url=url, method="GET")
-    token_info = json.loads(response.data.decode("utf-8"))
-
-    assert token_info["scope"] == EMAIL_SCOPE
-
-
-def test_default():
-    credentials, project_id = google.auth.default()
-
-    assert isinstance(credentials, app_engine.Credentials)
-    assert project_id == app_identity.get_application_id()
-
-
-@contextlib.contextmanager
-def capture():
-    """Context manager that captures stderr and stdout."""
-    oldout, olderr = sys.stdout, sys.stderr
-    try:
-        out = StringIO()
-        sys.stdout, sys.stderr = out, out
-        yield out
-    finally:
-        sys.stdout, sys.stderr = oldout, olderr
-
-
-def run_test_func(func):
-    with capture() as capsys:
-        try:
-            func()
-            return True, ""
-        except Exception as exc:
-            output = FAILED_TEST_TMPL.format(
-                func.func_name, exc, traceback.format_exc(), capsys.getvalue()
-            )
-            return False, output
-
-
-def run_tests():
-    """Runs all tests.
-
-    Returns:
-        Tuple[bool, str]: A tuple containing True if all tests pass, False
-        otherwise, and any captured output from the tests.
-    """
-    status = True
-    output = ""
-
-    tests = (test_credentials, test_default)
-
-    for test in tests:
-        test_status, test_output = run_test_func(test)
-        status = status and test_status
-        output += test_output
-
-    return status, output
-
-
-class MainHandler(webapp2.RequestHandler):
-    def get(self):
-        self.response.headers["content-type"] = "text/plain"
-
-        status, output = run_tests()
-
-        if not status:
-            self.response.status = 500
-
-        self.response.write(output)
-
-
-app = webapp2.WSGIApplication([("/", MainHandler)], debug=True)
diff --git a/system_tests/system_tests_sync/app_engine_test_app/requirements.txt b/system_tests/system_tests_sync/app_engine_test_app/requirements.txt
deleted file mode 100644
index bd5c476..0000000
--- a/system_tests/system_tests_sync/app_engine_test_app/requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-urllib3
-# Relative path to google-auth-python's source.
-../../..
diff --git a/system_tests/system_tests_sync/test_app_engine.py b/system_tests/system_tests_sync/test_app_engine.py
deleted file mode 100644
index 45a1989..0000000
--- a/system_tests/system_tests_sync/test_app_engine.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2016 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-
-TEST_APP_URL = os.environ["TEST_APP_URL"]
-
-
-def test_live_application(http_request):
-    response = http_request(method="GET", url=TEST_APP_URL)
-    assert response.status == 200, response.data.decode("utf-8")
diff --git a/system_tests/system_tests_sync/test_external_accounts.py b/system_tests/system_tests_sync/test_external_accounts.py
index e24c7b4..c2855a2 100644
--- a/system_tests/system_tests_sync/test_external_accounts.py
+++ b/system_tests/system_tests_sync/test_external_accounts.py
@@ -32,20 +32,22 @@
 # original service account key.
 
 
+from http.server import BaseHTTPRequestHandler
+from http.server import HTTPServer
 import json
 import os
 import socket
+import sys
 from tempfile import NamedTemporaryFile
 import threading
 
-import sys
-import google.auth
-from googleapiclient import discovery
-from six.moves import BaseHTTPServer
-from google.oauth2 import service_account
 import pytest
 from mock import patch
 
+import google.auth
+from googleapiclient import discovery
+from google.oauth2 import service_account
+
 # Populate values from the output of scripts/setup_external_accounts.sh.
 _AUDIENCE_OIDC = "//iam.googleapis.com/projects/79992041559/locations/global/workloadIdentityPools/pool-73wslmxn/providers/oidc-73wslmxn"
 _AUDIENCE_AWS = "//iam.googleapis.com/projects/79992041559/locations/global/workloadIdentityPools/pool-73wslmxn/providers/aws-73wslmxn"
@@ -175,7 +177,7 @@
 # This test makes sure that setting up an http server to provide credentials
 # works to allow access to Google resources.
 def test_url_based_external_account(dns_access, oidc_credentials, service_account_info):
-    class TestResponseHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+    class TestResponseHandler(BaseHTTPRequestHandler):
         def do_GET(self):
             if self.headers["my-header"] != "expected-value":
                 self.send_response(400)
@@ -199,7 +201,7 @@
                     json.dumps({"access_token": oidc_credentials.token}).encode("utf-8")
                 )
 
-    class TestHTTPServer(BaseHTTPServer.HTTPServer, object):
+    class TestHTTPServer(HTTPServer, object):
         def __init__(self):
             self.port = self._find_open_port()
             super(TestHTTPServer, self).__init__(("", self.port), TestResponseHandler)