We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Pubsub.list_topics fails when there are no topics
[Offending line](https://github.com/GoogleCloudPlatform/gcloud-python/blob/0910f9979a45af8cc2826dd4c6ff38d9efa5ccec/gcloud/pubsub/client.py#L80). Reproduce via:

``` python
client = pubsub.Client()
>>> client.list_topics()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "gcloud/pubsub/client.py", line 80, in list_topics
    for resource in resp['topics']]
KeyError: 'topics'
```

@tseaver ISTM we should locate all instances where we assume a key is present and just protect against this. The time between releases behooves us to be "protective" of users. (I realize that we've usually done it this way based on documented outputs.)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gcloud/pubsub/client.py`
Content:
```
1 # Copyright 2015 Google Inc. All rights reserved.
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 """Client for interacting with the Google Cloud Pub/Sub API."""
16 
17 
18 from gcloud.client import JSONClient
19 from gcloud.pubsub.connection import Connection
20 from gcloud.pubsub.subscription import Subscription
21 from gcloud.pubsub.topic import Topic
22 
23 
24 class Client(JSONClient):
25     """Client to bundle configuration needed for API requests.
26 
27     :type project: string
28     :param project: the project which the client acts on behalf of. Will be
29                     passed when creating a topic.  If not passed,
30                     falls back to the default inferred from the environment.
31 
32     :type credentials: :class:`oauth2client.client.OAuth2Credentials` or
33                        :class:`NoneType`
34     :param credentials: The OAuth2 Credentials to use for the connection
35                         owned by this client. If not passed (and if no ``http``
36                         object is passed), falls back to the default inferred
37                         from the environment.
38 
39     :type http: :class:`httplib2.Http` or class that defines ``request()``.
40     :param http: An optional HTTP object to make requests. If not passed, an
41                  ``http`` object is created that is bound to the
42                  ``credentials`` for the current object.
43     """
44 
45     _connection_class = Connection
46 
47     def list_topics(self, page_size=None, page_token=None):
48         """List topics for the project associated with this client.
49 
50         See:
51         https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/list
52 
53         :type page_size: int
54         :param page_size: maximum number of topics to return, If not passed,
55                           defaults to a value set by the API.
56 
57         :type page_token: string
58         :param page_token: opaque marker for the next "page" of topics. If not
59                            passed, the API will return the first page of
60                            topics.
61 
62         :rtype: tuple, (list, str)
63         :returns: list of :class:`gcloud.pubsub.topic.Topic`, plus a
64                   "next page token" string:  if not None, indicates that
65                   more topics can be retrieved with another call (pass that
66                   value as ``page_token``).
67         """
68         params = {}
69 
70         if page_size is not None:
71             params['pageSize'] = page_size
72 
73         if page_token is not None:
74             params['pageToken'] = page_token
75 
76         path = '/projects/%s/topics' % (self.project,)
77         resp = self.connection.api_request(method='GET', path=path,
78                                            query_params=params)
79         topics = [Topic.from_api_repr(resource, self)
80                   for resource in resp['topics']]
81         return topics, resp.get('nextPageToken')
82 
83     def list_subscriptions(self, page_size=None, page_token=None,
84                            topic_name=None):
85         """List subscriptions for the project associated with this client.
86 
87         See:
88         https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/list
89 
90         and (where ``topic_name`` is passed):
91         https://cloud.google.com/pubsub/reference/rest/v1/projects.topics.subscriptions/list
92 
93         :type page_size: int
94         :param page_size: maximum number of topics to return, If not passed,
95                           defaults to a value set by the API.
96 
97         :type page_token: string
98         :param page_token: opaque marker for the next "page" of topics. If not
99                            passed, the API will return the first page of
100                            topics.
101 
102         :type topic_name: string
103         :param topic_name: limit results to subscriptions bound to the given
104                            topic.
105 
106         :rtype: tuple, (list, str)
107         :returns: list of :class:`gcloud.pubsub.subscription.Subscription`,
108                   plus a "next page token" string:  if not None, indicates that
109                   more topics can be retrieved with another call (pass that
110                   value as ``page_token``).
111         """
112         params = {}
113 
114         if page_size is not None:
115             params['pageSize'] = page_size
116 
117         if page_token is not None:
118             params['pageToken'] = page_token
119 
120         if topic_name is None:
121             path = '/projects/%s/subscriptions' % (self.project,)
122         else:
123             path = '/projects/%s/topics/%s/subscriptions' % (self.project,
124                                                              topic_name)
125 
126         resp = self.connection.api_request(method='GET', path=path,
127                                            query_params=params)
128         topics = {}
129         subscriptions = [Subscription.from_api_repr(resource, self,
130                                                     topics=topics)
131                          for resource in resp['subscriptions']]
132         return subscriptions, resp.get('nextPageToken')
133 
134     def topic(self, name, timestamp_messages=False):
135         """Creates a topic bound to the current client.
136 
137         :type name: string
138         :param name: the name of the topic to be constructed.
139 
140         :type timestamp_messages: boolean
141         :param timestamp_messages: To be passed to ``Topic`` constructor.
142 
143         :rtype: :class:`gcloud.pubsub.topic.Topic`
144         :returns: Topic created with the current client.
145         """
146         return Topic(name, client=self, timestamp_messages=timestamp_messages)
147
```
--- 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/gcloud/pubsub/client.py b/gcloud/pubsub/client.py
--- a/gcloud/pubsub/client.py
+++ b/gcloud/pubsub/client.py
@@ -77,7 +77,7 @@
         resp = self.connection.api_request(method='GET', path=path,
                                            query_params=params)
         topics = [Topic.from_api_repr(resource, self)
-                  for resource in resp['topics']]
+                  for resource in resp.get('topics', ())]
         return topics, resp.get('nextPageToken')
 
     def list_subscriptions(self, page_size=None, page_token=None,
@@ -128,7 +128,7 @@
         topics = {}
         subscriptions = [Subscription.from_api_repr(resource, self,
                                                     topics=topics)
-                         for resource in resp['subscriptions']]
+                         for resource in resp.get('subscriptions', ())]
         return subscriptions, resp.get('nextPageToken')
 
     def topic(self, name, timestamp_messages=False):

{"golden_diff": "diff --git a/gcloud/pubsub/client.py b/gcloud/pubsub/client.py\n--- a/gcloud/pubsub/client.py\n+++ b/gcloud/pubsub/client.py\n@@ -77,7 +77,7 @@\n         resp = self.connection.api_request(method='GET', path=path,\n                                            query_params=params)\n         topics = [Topic.from_api_repr(resource, self)\n-                  for resource in resp['topics']]\n+                  for resource in resp.get('topics', ())]\n         return topics, resp.get('nextPageToken')\n \n     def list_subscriptions(self, page_size=None, page_token=None,\n@@ -128,7 +128,7 @@\n         topics = {}\n         subscriptions = [Subscription.from_api_repr(resource, self,\n                                                     topics=topics)\n-                         for resource in resp['subscriptions']]\n+                         for resource in resp.get('subscriptions', ())]\n         return subscriptions, resp.get('nextPageToken')\n \n     def topic(self, name, timestamp_messages=False):\n", "issue": "Pubsub.list_topics fails when there are no topics\n[Offending line](https://github.com/GoogleCloudPlatform/gcloud-python/blob/0910f9979a45af8cc2826dd4c6ff38d9efa5ccec/gcloud/pubsub/client.py#L80). Reproduce via:\n\n``` python\nclient = pubsub.Client()\n>>> client.list_topics()\nTraceback (most recent call last):\n  File \"<stdin>\", line 1, in <module>\n  File \"gcloud/pubsub/client.py\", line 80, in list_topics\n    for resource in resp['topics']]\nKeyError: 'topics'\n```\n\n@tseaver ISTM we should locate all instances where we assume a key is present and just protect against this. The time between releases behooves us to be \"protective\" of users. (I realize that we've usually done it this way based on documented outputs.)\n\n", "before_files": [{"content": "# Copyright 2015 Google Inc. All rights reserved.\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\"\"\"Client for interacting with the Google Cloud Pub/Sub API.\"\"\"\n\n\nfrom gcloud.client import JSONClient\nfrom gcloud.pubsub.connection import Connection\nfrom gcloud.pubsub.subscription import Subscription\nfrom gcloud.pubsub.topic import Topic\n\n\nclass Client(JSONClient):\n    \"\"\"Client to bundle configuration needed for API requests.\n\n    :type project: string\n    :param project: the project which the client acts on behalf of. Will be\n                    passed when creating a topic.  If not passed,\n                    falls back to the default inferred from the environment.\n\n    :type credentials: :class:`oauth2client.client.OAuth2Credentials` or\n                       :class:`NoneType`\n    :param credentials: The OAuth2 Credentials to use for the connection\n                        owned by this client. If not passed (and if no ``http``\n                        object is passed), falls back to the default inferred\n                        from the environment.\n\n    :type http: :class:`httplib2.Http` or class that defines ``request()``.\n    :param http: An optional HTTP object to make requests. If not passed, an\n                 ``http`` object is created that is bound to the\n                 ``credentials`` for the current object.\n    \"\"\"\n\n    _connection_class = Connection\n\n    def list_topics(self, page_size=None, page_token=None):\n        \"\"\"List topics for the project associated with this client.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/list\n\n        :type page_size: int\n        :param page_size: maximum number of topics to return, If not passed,\n                          defaults to a value set by the API.\n\n        :type page_token: string\n        :param page_token: opaque marker for the next \"page\" of topics. If not\n                           passed, the API will return the first page of\n                           topics.\n\n        :rtype: tuple, (list, str)\n        :returns: list of :class:`gcloud.pubsub.topic.Topic`, plus a\n                  \"next page token\" string:  if not None, indicates that\n                  more topics can be retrieved with another call (pass that\n                  value as ``page_token``).\n        \"\"\"\n        params = {}\n\n        if page_size is not None:\n            params['pageSize'] = page_size\n\n        if page_token is not None:\n            params['pageToken'] = page_token\n\n        path = '/projects/%s/topics' % (self.project,)\n        resp = self.connection.api_request(method='GET', path=path,\n                                           query_params=params)\n        topics = [Topic.from_api_repr(resource, self)\n                  for resource in resp['topics']]\n        return topics, resp.get('nextPageToken')\n\n    def list_subscriptions(self, page_size=None, page_token=None,\n                           topic_name=None):\n        \"\"\"List subscriptions for the project associated with this client.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/list\n\n        and (where ``topic_name`` is passed):\n        https://cloud.google.com/pubsub/reference/rest/v1/projects.topics.subscriptions/list\n\n        :type page_size: int\n        :param page_size: maximum number of topics to return, If not passed,\n                          defaults to a value set by the API.\n\n        :type page_token: string\n        :param page_token: opaque marker for the next \"page\" of topics. If not\n                           passed, the API will return the first page of\n                           topics.\n\n        :type topic_name: string\n        :param topic_name: limit results to subscriptions bound to the given\n                           topic.\n\n        :rtype: tuple, (list, str)\n        :returns: list of :class:`gcloud.pubsub.subscription.Subscription`,\n                  plus a \"next page token\" string:  if not None, indicates that\n                  more topics can be retrieved with another call (pass that\n                  value as ``page_token``).\n        \"\"\"\n        params = {}\n\n        if page_size is not None:\n            params['pageSize'] = page_size\n\n        if page_token is not None:\n            params['pageToken'] = page_token\n\n        if topic_name is None:\n            path = '/projects/%s/subscriptions' % (self.project,)\n        else:\n            path = '/projects/%s/topics/%s/subscriptions' % (self.project,\n                                                             topic_name)\n\n        resp = self.connection.api_request(method='GET', path=path,\n                                           query_params=params)\n        topics = {}\n        subscriptions = [Subscription.from_api_repr(resource, self,\n                                                    topics=topics)\n                         for resource in resp['subscriptions']]\n        return subscriptions, resp.get('nextPageToken')\n\n    def topic(self, name, timestamp_messages=False):\n        \"\"\"Creates a topic bound to the current client.\n\n        :type name: string\n        :param name: the name of the topic to be constructed.\n\n        :type timestamp_messages: boolean\n        :param timestamp_messages: To be passed to ``Topic`` constructor.\n\n        :rtype: :class:`gcloud.pubsub.topic.Topic`\n        :returns: Topic created with the current client.\n        \"\"\"\n        return Topic(name, client=self, timestamp_messages=timestamp_messages)\n", "path": "gcloud/pubsub/client.py"}], "after_files": [{"content": "# Copyright 2015 Google Inc. All rights reserved.\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\"\"\"Client for interacting with the Google Cloud Pub/Sub API.\"\"\"\n\n\nfrom gcloud.client import JSONClient\nfrom gcloud.pubsub.connection import Connection\nfrom gcloud.pubsub.subscription import Subscription\nfrom gcloud.pubsub.topic import Topic\n\n\nclass Client(JSONClient):\n    \"\"\"Client to bundle configuration needed for API requests.\n\n    :type project: string\n    :param project: the project which the client acts on behalf of. Will be\n                    passed when creating a topic.  If not passed,\n                    falls back to the default inferred from the environment.\n\n    :type credentials: :class:`oauth2client.client.OAuth2Credentials` or\n                       :class:`NoneType`\n    :param credentials: The OAuth2 Credentials to use for the connection\n                        owned by this client. If not passed (and if no ``http``\n                        object is passed), falls back to the default inferred\n                        from the environment.\n\n    :type http: :class:`httplib2.Http` or class that defines ``request()``.\n    :param http: An optional HTTP object to make requests. If not passed, an\n                 ``http`` object is created that is bound to the\n                 ``credentials`` for the current object.\n    \"\"\"\n\n    _connection_class = Connection\n\n    def list_topics(self, page_size=None, page_token=None):\n        \"\"\"List topics for the project associated with this client.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/list\n\n        :type page_size: int\n        :param page_size: maximum number of topics to return, If not passed,\n                          defaults to a value set by the API.\n\n        :type page_token: string\n        :param page_token: opaque marker for the next \"page\" of topics. If not\n                           passed, the API will return the first page of\n                           topics.\n\n        :rtype: tuple, (list, str)\n        :returns: list of :class:`gcloud.pubsub.topic.Topic`, plus a\n                  \"next page token\" string:  if not None, indicates that\n                  more topics can be retrieved with another call (pass that\n                  value as ``page_token``).\n        \"\"\"\n        params = {}\n\n        if page_size is not None:\n            params['pageSize'] = page_size\n\n        if page_token is not None:\n            params['pageToken'] = page_token\n\n        path = '/projects/%s/topics' % (self.project,)\n        resp = self.connection.api_request(method='GET', path=path,\n                                           query_params=params)\n        topics = [Topic.from_api_repr(resource, self)\n                  for resource in resp.get('topics', ())]\n        return topics, resp.get('nextPageToken')\n\n    def list_subscriptions(self, page_size=None, page_token=None,\n                           topic_name=None):\n        \"\"\"List subscriptions for the project associated with this client.\n\n        See:\n        https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/list\n\n        and (where ``topic_name`` is passed):\n        https://cloud.google.com/pubsub/reference/rest/v1/projects.topics.subscriptions/list\n\n        :type page_size: int\n        :param page_size: maximum number of topics to return, If not passed,\n                          defaults to a value set by the API.\n\n        :type page_token: string\n        :param page_token: opaque marker for the next \"page\" of topics. If not\n                           passed, the API will return the first page of\n                           topics.\n\n        :type topic_name: string\n        :param topic_name: limit results to subscriptions bound to the given\n                           topic.\n\n        :rtype: tuple, (list, str)\n        :returns: list of :class:`gcloud.pubsub.subscription.Subscription`,\n                  plus a \"next page token\" string:  if not None, indicates that\n                  more topics can be retrieved with another call (pass that\n                  value as ``page_token``).\n        \"\"\"\n        params = {}\n\n        if page_size is not None:\n            params['pageSize'] = page_size\n\n        if page_token is not None:\n            params['pageToken'] = page_token\n\n        if topic_name is None:\n            path = '/projects/%s/subscriptions' % (self.project,)\n        else:\n            path = '/projects/%s/topics/%s/subscriptions' % (self.project,\n                                                             topic_name)\n\n        resp = self.connection.api_request(method='GET', path=path,\n                                           query_params=params)\n        topics = {}\n        subscriptions = [Subscription.from_api_repr(resource, self,\n                                                    topics=topics)\n                         for resource in resp.get('subscriptions', ())]\n        return subscriptions, resp.get('nextPageToken')\n\n    def topic(self, name, timestamp_messages=False):\n        \"\"\"Creates a topic bound to the current client.\n\n        :type name: string\n        :param name: the name of the topic to be constructed.\n\n        :type timestamp_messages: boolean\n        :param timestamp_messages: To be passed to ``Topic`` constructor.\n\n        :rtype: :class:`gcloud.pubsub.topic.Topic`\n        :returns: Topic created with the current client.\n        \"\"\"\n        return Topic(name, client=self, timestamp_messages=timestamp_messages)\n", "path": "gcloud/pubsub/client.py"}]}