We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Getting project ID using Application Default Credentials fails when gcloud command writes anything to stderr
  - OS: Ubuntu 20.04
  - Python version: 3.8
  - pip version: 20.0.2
  - `google-auth` version: 1.19.2

#### Steps to reproduce

  1. Arrange for gcloud to throw a warning. For example I'm suffering from this https://github.com/GoogleCloudPlatform/gsutil/issues/999
  2. Attempt to use ADC e.g. `credentials, project = google.auth.default()`
  3. Note that project always comes back at None even if `gcloud config set project` is correctly set
  4. Root cause seems to be that in _cloud_sdk.py/get_project_id() the subprocess.check_output command merges stderr and stdout. So in the case that stderr is not empty and the subprocess does not fail, you might get badly formed JSON on which json.loads a few lines later chokes.

For example, my raw gcloud output is like:

/snap/google-cloud-sdk/165/lib/third_party/requests/__init__.py:83: RequestsDependencyWarning: Old version of cryptography ([1, 2, 3]) may cause slowdown.\n  warnings.warn(warning, RequestsDependencyWarning)\n{\n  "configuration": {\n    "active_configuration": "default",\n    "properties": {\n      "core": {\n        "account": "me@myemailaddress.com",\n        "disable_usage_reporting": "False",\n        "project": "my-test-project"\n      },\n      "deployment_manager": {\n        "glob_imports": "True"\n      }\n    }\n  },\n  "credential": {\n    "access_token".... etc etc.

Expected behaviour: non-fatal errors or warnings from gcloud should not corrupt the output and cause the project ID lookup to fail.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `google/auth/_cloud_sdk.py`
Content:
```
1 # Copyright 2015 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """Helpers for reading the Google Cloud SDK's configuration."""
16 
17 import json
18 import os
19 import subprocess
20 
21 import six
22 
23 from google.auth import environment_vars
24 from google.auth import exceptions
25 
26 
27 # The ~/.config subdirectory containing gcloud credentials.
28 _CONFIG_DIRECTORY = "gcloud"
29 # Windows systems store config at %APPDATA%\gcloud
30 _WINDOWS_CONFIG_ROOT_ENV_VAR = "APPDATA"
31 # The name of the file in the Cloud SDK config that contains default
32 # credentials.
33 _CREDENTIALS_FILENAME = "application_default_credentials.json"
34 # The name of the Cloud SDK shell script
35 _CLOUD_SDK_POSIX_COMMAND = "gcloud"
36 _CLOUD_SDK_WINDOWS_COMMAND = "gcloud.cmd"
37 # The command to get the Cloud SDK configuration
38 _CLOUD_SDK_CONFIG_COMMAND = ("config", "config-helper", "--format", "json")
39 # The command to get google user access token
40 _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND = ("auth", "print-access-token")
41 # Cloud SDK's application-default client ID
42 CLOUD_SDK_CLIENT_ID = (
43     "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com"
44 )
45 
46 
47 def get_config_path():
48     """Returns the absolute path the the Cloud SDK's configuration directory.
49 
50     Returns:
51         str: The Cloud SDK config path.
52     """
53     # If the path is explicitly set, return that.
54     try:
55         return os.environ[environment_vars.CLOUD_SDK_CONFIG_DIR]
56     except KeyError:
57         pass
58 
59     # Non-windows systems store this at ~/.config/gcloud
60     if os.name != "nt":
61         return os.path.join(os.path.expanduser("~"), ".config", _CONFIG_DIRECTORY)
62     # Windows systems store config at %APPDATA%\gcloud
63     else:
64         try:
65             return os.path.join(
66                 os.environ[_WINDOWS_CONFIG_ROOT_ENV_VAR], _CONFIG_DIRECTORY
67             )
68         except KeyError:
69             # This should never happen unless someone is really
70             # messing with things, but we'll cover the case anyway.
71             drive = os.environ.get("SystemDrive", "C:")
72             return os.path.join(drive, "\\", _CONFIG_DIRECTORY)
73 
74 
75 def get_application_default_credentials_path():
76     """Gets the path to the application default credentials file.
77 
78     The path may or may not exist.
79 
80     Returns:
81         str: The full path to application default credentials.
82     """
83     config_path = get_config_path()
84     return os.path.join(config_path, _CREDENTIALS_FILENAME)
85 
86 
87 def get_project_id():
88     """Gets the project ID from the Cloud SDK.
89 
90     Returns:
91         Optional[str]: The project ID.
92     """
93     if os.name == "nt":
94         command = _CLOUD_SDK_WINDOWS_COMMAND
95     else:
96         command = _CLOUD_SDK_POSIX_COMMAND
97 
98     try:
99         output = subprocess.check_output(
100             (command,) + _CLOUD_SDK_CONFIG_COMMAND, stderr=subprocess.STDOUT
101         )
102     except (subprocess.CalledProcessError, OSError, IOError):
103         return None
104 
105     try:
106         configuration = json.loads(output.decode("utf-8"))
107     except ValueError:
108         return None
109 
110     try:
111         return configuration["configuration"]["properties"]["core"]["project"]
112     except KeyError:
113         return None
114 
115 
116 def get_auth_access_token(account=None):
117     """Load user access token with the ``gcloud auth print-access-token`` command.
118 
119     Args:
120         account (Optional[str]): Account to get the access token for. If not
121             specified, the current active account will be used.
122 
123     Returns:
124         str: The user access token.
125 
126     Raises:
127         google.auth.exceptions.UserAccessTokenError: if failed to get access
128             token from gcloud.
129     """
130     if os.name == "nt":
131         command = _CLOUD_SDK_WINDOWS_COMMAND
132     else:
133         command = _CLOUD_SDK_POSIX_COMMAND
134 
135     try:
136         if account:
137             command = (
138                 (command,)
139                 + _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND
140                 + ("--account=" + account,)
141             )
142         else:
143             command = (command,) + _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND
144 
145         access_token = subprocess.check_output(command, stderr=subprocess.STDOUT)
146         # remove the trailing "\n"
147         return access_token.decode("utf-8").strip()
148     except (subprocess.CalledProcessError, OSError, IOError) as caught_exc:
149         new_exc = exceptions.UserAccessTokenError(
150             "Failed to obtain access token", caught_exc
151         )
152         six.raise_from(new_exc, caught_exc)
153
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/google/auth/_cloud_sdk.py b/google/auth/_cloud_sdk.py
--- a/google/auth/_cloud_sdk.py
+++ b/google/auth/_cloud_sdk.py
@@ -84,6 +84,13 @@
     return os.path.join(config_path, _CREDENTIALS_FILENAME)
 
 
+def _run_subprocess_ignore_stderr(command):
+    """ Return subprocess.check_output with the given command and ignores stderr."""
+    with open(os.devnull, "w") as devnull:
+        output = subprocess.check_output(command, stderr=devnull)
+    return output
+
+
 def get_project_id():
     """Gets the project ID from the Cloud SDK.
 
@@ -96,9 +103,9 @@
         command = _CLOUD_SDK_POSIX_COMMAND
 
     try:
-        output = subprocess.check_output(
-            (command,) + _CLOUD_SDK_CONFIG_COMMAND, stderr=subprocess.STDOUT
-        )
+        # Ignore the stderr coming from gcloud, so it won't be mixed into the output.
+        # https://github.com/googleapis/google-auth-library-python/issues/673
+        output = _run_subprocess_ignore_stderr((command,) + _CLOUD_SDK_CONFIG_COMMAND)
     except (subprocess.CalledProcessError, OSError, IOError):
         return None

{"golden_diff": "diff --git a/google/auth/_cloud_sdk.py b/google/auth/_cloud_sdk.py\n--- a/google/auth/_cloud_sdk.py\n+++ b/google/auth/_cloud_sdk.py\n@@ -84,6 +84,13 @@\n     return os.path.join(config_path, _CREDENTIALS_FILENAME)\n \n \n+def _run_subprocess_ignore_stderr(command):\n+    \"\"\" Return subprocess.check_output with the given command and ignores stderr.\"\"\"\n+    with open(os.devnull, \"w\") as devnull:\n+        output = subprocess.check_output(command, stderr=devnull)\n+    return output\n+\n+\n def get_project_id():\n     \"\"\"Gets the project ID from the Cloud SDK.\n \n@@ -96,9 +103,9 @@\n         command = _CLOUD_SDK_POSIX_COMMAND\n \n     try:\n-        output = subprocess.check_output(\n-            (command,) + _CLOUD_SDK_CONFIG_COMMAND, stderr=subprocess.STDOUT\n-        )\n+        # Ignore the stderr coming from gcloud, so it won't be mixed into the output.\n+        # https://github.com/googleapis/google-auth-library-python/issues/673\n+        output = _run_subprocess_ignore_stderr((command,) + _CLOUD_SDK_CONFIG_COMMAND)\n     except (subprocess.CalledProcessError, OSError, IOError):\n         return None\n", "issue": "Getting project ID using Application Default Credentials fails when gcloud command writes anything to stderr\n  - OS: Ubuntu 20.04\r\n  - Python version: 3.8\r\n  - pip version: 20.0.2\r\n  - `google-auth` version: 1.19.2\r\n\r\n#### Steps to reproduce\r\n\r\n  1. Arrange for gcloud to throw a warning. For example I'm suffering from this https://github.com/GoogleCloudPlatform/gsutil/issues/999\r\n  2. Attempt to use ADC e.g. `credentials, project = google.auth.default()`\r\n  3. Note that project always comes back at None even if `gcloud config set project` is correctly set\r\n  4. Root cause seems to be that in _cloud_sdk.py/get_project_id() the subprocess.check_output command merges stderr and stdout. So in the case that stderr is not empty and the subprocess does not fail, you might get badly formed JSON on which json.loads a few lines later chokes.\r\n\r\nFor example, my raw gcloud output is like:\r\n\r\n/snap/google-cloud-sdk/165/lib/third_party/requests/__init__.py:83: RequestsDependencyWarning: Old version of cryptography ([1, 2, 3]) may cause slowdown.\\n  warnings.warn(warning, RequestsDependencyWarning)\\n{\\n  \"configuration\": {\\n    \"active_configuration\": \"default\",\\n    \"properties\": {\\n      \"core\": {\\n        \"account\": \"me@myemailaddress.com\",\\n        \"disable_usage_reporting\": \"False\",\\n        \"project\": \"my-test-project\"\\n      },\\n      \"deployment_manager\": {\\n        \"glob_imports\": \"True\"\\n      }\\n    }\\n  },\\n  \"credential\": {\\n    \"access_token\".... etc etc.\r\n\r\nExpected behaviour: non-fatal errors or warnings from gcloud should not corrupt the output and cause the project ID lookup to fail.\n", "before_files": [{"content": "# Copyright 2015 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Helpers for reading the Google Cloud SDK's configuration.\"\"\"\n\nimport json\nimport os\nimport subprocess\n\nimport six\n\nfrom google.auth import environment_vars\nfrom google.auth import exceptions\n\n\n# The ~/.config subdirectory containing gcloud credentials.\n_CONFIG_DIRECTORY = \"gcloud\"\n# Windows systems store config at %APPDATA%\\gcloud\n_WINDOWS_CONFIG_ROOT_ENV_VAR = \"APPDATA\"\n# The name of the file in the Cloud SDK config that contains default\n# credentials.\n_CREDENTIALS_FILENAME = \"application_default_credentials.json\"\n# The name of the Cloud SDK shell script\n_CLOUD_SDK_POSIX_COMMAND = \"gcloud\"\n_CLOUD_SDK_WINDOWS_COMMAND = \"gcloud.cmd\"\n# The command to get the Cloud SDK configuration\n_CLOUD_SDK_CONFIG_COMMAND = (\"config\", \"config-helper\", \"--format\", \"json\")\n# The command to get google user access token\n_CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND = (\"auth\", \"print-access-token\")\n# Cloud SDK's application-default client ID\nCLOUD_SDK_CLIENT_ID = (\n    \"764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com\"\n)\n\n\ndef get_config_path():\n    \"\"\"Returns the absolute path the the Cloud SDK's configuration directory.\n\n    Returns:\n        str: The Cloud SDK config path.\n    \"\"\"\n    # If the path is explicitly set, return that.\n    try:\n        return os.environ[environment_vars.CLOUD_SDK_CONFIG_DIR]\n    except KeyError:\n        pass\n\n    # Non-windows systems store this at ~/.config/gcloud\n    if os.name != \"nt\":\n        return os.path.join(os.path.expanduser(\"~\"), \".config\", _CONFIG_DIRECTORY)\n    # Windows systems store config at %APPDATA%\\gcloud\n    else:\n        try:\n            return os.path.join(\n                os.environ[_WINDOWS_CONFIG_ROOT_ENV_VAR], _CONFIG_DIRECTORY\n            )\n        except KeyError:\n            # This should never happen unless someone is really\n            # messing with things, but we'll cover the case anyway.\n            drive = os.environ.get(\"SystemDrive\", \"C:\")\n            return os.path.join(drive, \"\\\\\", _CONFIG_DIRECTORY)\n\n\ndef get_application_default_credentials_path():\n    \"\"\"Gets the path to the application default credentials file.\n\n    The path may or may not exist.\n\n    Returns:\n        str: The full path to application default credentials.\n    \"\"\"\n    config_path = get_config_path()\n    return os.path.join(config_path, _CREDENTIALS_FILENAME)\n\n\ndef get_project_id():\n    \"\"\"Gets the project ID from the Cloud SDK.\n\n    Returns:\n        Optional[str]: The project ID.\n    \"\"\"\n    if os.name == \"nt\":\n        command = _CLOUD_SDK_WINDOWS_COMMAND\n    else:\n        command = _CLOUD_SDK_POSIX_COMMAND\n\n    try:\n        output = subprocess.check_output(\n            (command,) + _CLOUD_SDK_CONFIG_COMMAND, stderr=subprocess.STDOUT\n        )\n    except (subprocess.CalledProcessError, OSError, IOError):\n        return None\n\n    try:\n        configuration = json.loads(output.decode(\"utf-8\"))\n    except ValueError:\n        return None\n\n    try:\n        return configuration[\"configuration\"][\"properties\"][\"core\"][\"project\"]\n    except KeyError:\n        return None\n\n\ndef get_auth_access_token(account=None):\n    \"\"\"Load user access token with the ``gcloud auth print-access-token`` command.\n\n    Args:\n        account (Optional[str]): Account to get the access token for. If not\n            specified, the current active account will be used.\n\n    Returns:\n        str: The user access token.\n\n    Raises:\n        google.auth.exceptions.UserAccessTokenError: if failed to get access\n            token from gcloud.\n    \"\"\"\n    if os.name == \"nt\":\n        command = _CLOUD_SDK_WINDOWS_COMMAND\n    else:\n        command = _CLOUD_SDK_POSIX_COMMAND\n\n    try:\n        if account:\n            command = (\n                (command,)\n                + _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND\n                + (\"--account=\" + account,)\n            )\n        else:\n            command = (command,) + _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND\n\n        access_token = subprocess.check_output(command, stderr=subprocess.STDOUT)\n        # remove the trailing \"\\n\"\n        return access_token.decode(\"utf-8\").strip()\n    except (subprocess.CalledProcessError, OSError, IOError) as caught_exc:\n        new_exc = exceptions.UserAccessTokenError(\n            \"Failed to obtain access token\", caught_exc\n        )\n        six.raise_from(new_exc, caught_exc)\n", "path": "google/auth/_cloud_sdk.py"}], "after_files": [{"content": "# Copyright 2015 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Helpers for reading the Google Cloud SDK's configuration.\"\"\"\n\nimport json\nimport os\nimport subprocess\n\nimport six\n\nfrom google.auth import environment_vars\nfrom google.auth import exceptions\n\n\n# The ~/.config subdirectory containing gcloud credentials.\n_CONFIG_DIRECTORY = \"gcloud\"\n# Windows systems store config at %APPDATA%\\gcloud\n_WINDOWS_CONFIG_ROOT_ENV_VAR = \"APPDATA\"\n# The name of the file in the Cloud SDK config that contains default\n# credentials.\n_CREDENTIALS_FILENAME = \"application_default_credentials.json\"\n# The name of the Cloud SDK shell script\n_CLOUD_SDK_POSIX_COMMAND = \"gcloud\"\n_CLOUD_SDK_WINDOWS_COMMAND = \"gcloud.cmd\"\n# The command to get the Cloud SDK configuration\n_CLOUD_SDK_CONFIG_COMMAND = (\"config\", \"config-helper\", \"--format\", \"json\")\n# The command to get google user access token\n_CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND = (\"auth\", \"print-access-token\")\n# Cloud SDK's application-default client ID\nCLOUD_SDK_CLIENT_ID = (\n    \"764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com\"\n)\n\n\ndef get_config_path():\n    \"\"\"Returns the absolute path the the Cloud SDK's configuration directory.\n\n    Returns:\n        str: The Cloud SDK config path.\n    \"\"\"\n    # If the path is explicitly set, return that.\n    try:\n        return os.environ[environment_vars.CLOUD_SDK_CONFIG_DIR]\n    except KeyError:\n        pass\n\n    # Non-windows systems store this at ~/.config/gcloud\n    if os.name != \"nt\":\n        return os.path.join(os.path.expanduser(\"~\"), \".config\", _CONFIG_DIRECTORY)\n    # Windows systems store config at %APPDATA%\\gcloud\n    else:\n        try:\n            return os.path.join(\n                os.environ[_WINDOWS_CONFIG_ROOT_ENV_VAR], _CONFIG_DIRECTORY\n            )\n        except KeyError:\n            # This should never happen unless someone is really\n            # messing with things, but we'll cover the case anyway.\n            drive = os.environ.get(\"SystemDrive\", \"C:\")\n            return os.path.join(drive, \"\\\\\", _CONFIG_DIRECTORY)\n\n\ndef get_application_default_credentials_path():\n    \"\"\"Gets the path to the application default credentials file.\n\n    The path may or may not exist.\n\n    Returns:\n        str: The full path to application default credentials.\n    \"\"\"\n    config_path = get_config_path()\n    return os.path.join(config_path, _CREDENTIALS_FILENAME)\n\n\ndef _run_subprocess_ignore_stderr(command):\n    \"\"\" Return subprocess.check_output with the given command and ignores stderr.\"\"\"\n    with open(os.devnull, \"w\") as devnull:\n        output = subprocess.check_output(command, stderr=devnull)\n    return output\n\n\ndef get_project_id():\n    \"\"\"Gets the project ID from the Cloud SDK.\n\n    Returns:\n        Optional[str]: The project ID.\n    \"\"\"\n    if os.name == \"nt\":\n        command = _CLOUD_SDK_WINDOWS_COMMAND\n    else:\n        command = _CLOUD_SDK_POSIX_COMMAND\n\n    try:\n        # Ignore the stderr coming from gcloud, so it won't be mixed into the output.\n        # https://github.com/googleapis/google-auth-library-python/issues/673\n        output = _run_subprocess_ignore_stderr((command,) + _CLOUD_SDK_CONFIG_COMMAND)\n    except (subprocess.CalledProcessError, OSError, IOError):\n        return None\n\n    try:\n        configuration = json.loads(output.decode(\"utf-8\"))\n    except ValueError:\n        return None\n\n    try:\n        return configuration[\"configuration\"][\"properties\"][\"core\"][\"project\"]\n    except KeyError:\n        return None\n\n\ndef get_auth_access_token(account=None):\n    \"\"\"Load user access token with the ``gcloud auth print-access-token`` command.\n\n    Args:\n        account (Optional[str]): Account to get the access token for. If not\n            specified, the current active account will be used.\n\n    Returns:\n        str: The user access token.\n\n    Raises:\n        google.auth.exceptions.UserAccessTokenError: if failed to get access\n            token from gcloud.\n    \"\"\"\n    if os.name == \"nt\":\n        command = _CLOUD_SDK_WINDOWS_COMMAND\n    else:\n        command = _CLOUD_SDK_POSIX_COMMAND\n\n    try:\n        if account:\n            command = (\n                (command,)\n                + _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND\n                + (\"--account=\" + account,)\n            )\n        else:\n            command = (command,) + _CLOUD_SDK_USER_ACCESS_TOKEN_COMMAND\n\n        access_token = subprocess.check_output(command, stderr=subprocess.STDOUT)\n        # remove the trailing \"\\n\"\n        return access_token.decode(\"utf-8\").strip()\n    except (subprocess.CalledProcessError, OSError, IOError) as caught_exc:\n        new_exc = exceptions.UserAccessTokenError(\n            \"Failed to obtain access token\", caught_exc\n        )\n        six.raise_from(new_exc, caught_exc)\n", "path": "google/auth/_cloud_sdk.py"}]}