We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Pub/Sub API lists the wrong (slightly incompatible) type for Message.attributes
When a subscriber receives a message, the API says it has an 'attributes' member that is a dict:

https://github.com/GoogleCloudPlatform/google-cloud-python/blob/11e310ab9f63f06252ff2b9ada201fd8c11ce06c/pubsub/google/cloud/pubsub_v1/subscriber/message.py#L36

However, it is not, in fact, a dict; it is a protobuf map. The behaviour is quite different, which the Python protobuf API documentation explains at some length:

https://developers.google.com/protocol-buffers/docs/reference/python-generated#map-fields

This is not a small difference... the semantic gap is substantial, because using the `.attributes` type in place of a dict breaks code like this:

```
message_rev = None
if some_condition:
  try:
    message_rev = int(message.attributes['revision'])
  except KeyError:
    message_rev = DEFAULT
```

In this case, instead of assigning the value `DEFAULT`, this code simply raises a new exception that doesn't happen with dicts (it's a ValueError, because the try-block will execute `int('')`). This is an incompatible, breaking change.

Again, this is a subtle, but important, API difference. At a minimum, it seems like the PubSub API docs should point to the Protobuf docs, instead of simply listing the incorrect type.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pubsub/google/cloud/pubsub_v1/subscriber/message.py`
Content:
```
1 # Copyright 2017, Google LLC 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 from __future__ import absolute_import
16 
17 import math
18 import time
19 
20 
21 class Message(object):
22     """A representation of a single Pub/Sub message.
23 
24     The common way to interact with
25     :class:`~.pubsub_v1.subscriber.message.Message` objects is to receive
26     them in callbacks on subscriptions; most users should never have a need
27     to instantiate them by hand. (The exception to this is if you are
28     implementing a custom subclass to
29     :class:`~.pubsub_v1.subscriber._consumer.Consumer`.)
30 
31     Attributes:
32         message_id (str): The message ID. In general, you should not need
33             to use this directly.
34         data (bytes): The data in the message. Note that this will be a
35             :class:`bytes`, not a text string.
36         attributes (dict): The attributes sent along with the message.
37         publish_time (datetime): The time that this message was originally
38             published.
39     """
40 
41     def __init__(self, message, ack_id, request_queue):
42         """Construct the Message.
43 
44         .. note::
45 
46             This class should not be constructed directly; it is the
47             responsibility of :class:`BasePolicy` subclasses to do so.
48 
49         Args:
50             message (~.pubsub_v1.types.PubsubMessage): The message received
51                 from Pub/Sub.
52             ack_id (str): The ack_id received from Pub/Sub.
53             request_queue (queue.Queue): A queue provided by the policy that
54                 can accept requests; the policy is responsible for handling
55                 those requests.
56         """
57         self._message = message
58         self._ack_id = ack_id
59         self._request_queue = request_queue
60         self.message_id = message.message_id
61 
62         # The instantiation time is the time that this message
63         # was received. Tracking this provides us a way to be smart about
64         # the default lease deadline.
65         self._received_timestamp = time.time()
66 
67         # The policy should lease this message, telling PubSub that it has
68         # it until it is acked or otherwise dropped.
69         self.lease()
70 
71     def __repr__(self):
72         # Get an abbreviated version of the data.
73         abbv_data = self._message.data
74         if len(abbv_data) > 50:
75             abbv_data = abbv_data[0:50] + b'...'
76 
77         # Return a useful representation.
78         answer = 'Message {\n'
79         answer += '    data: {0!r}\n'.format(abbv_data)
80         answer += '    attributes: {0!r}\n'.format(self.attributes)
81         answer += '}'
82         return answer
83 
84     @property
85     def attributes(self):
86         """Return the attributes of the underlying Pub/Sub Message.
87 
88         Returns:
89             dict: The message's attributes.
90         """
91         return self._message.attributes
92 
93     @property
94     def data(self):
95         """Return the data for the underlying Pub/Sub Message.
96 
97         Returns:
98             bytes: The message data. This is always a bytestring; if you
99                 want a text string, call :meth:`bytes.decode`.
100         """
101         return self._message.data
102 
103     @property
104     def publish_time(self):
105         """Return the time that the message was originally published.
106 
107         Returns:
108             datetime: The date and time that the message was published.
109         """
110         return self._message.publish_time
111 
112     @property
113     def size(self):
114         """Return the size of the underlying message, in bytes."""
115         return self._message.ByteSize()
116 
117     def ack(self):
118         """Acknowledge the given message.
119 
120         Acknowledging a message in Pub/Sub means that you are done
121         with it, and it will not be delivered to this subscription again.
122         You should avoid acknowledging messages until you have
123         *finished* processing them, so that in the event of a failure,
124         you receive the message again.
125 
126         .. warning::
127             Acks in Pub/Sub are best effort. You should always
128             ensure that your processing code is idempotent, as you may
129             receive any given message more than once.
130         """
131         time_to_ack = math.ceil(time.time() - self._received_timestamp)
132         self._request_queue.put(
133             (
134                 'ack',
135                 {
136                     'ack_id': self._ack_id,
137                     'byte_size': self.size,
138                     'time_to_ack': time_to_ack,
139                 },
140             ),
141         )
142 
143     def drop(self):
144         """Release the message from lease management.
145 
146         This informs the policy to no longer hold on to the lease for this
147         message. Pub/Sub will re-deliver the message if it is not acknowledged
148         before the existing lease expires.
149 
150         .. warning::
151             For most use cases, the only reason to drop a message from
152             lease management is on :meth:`ack` or :meth:`nack`; these methods
153             both call this one. You probably do not want to call this method
154             directly.
155         """
156         self._request_queue.put(
157             (
158                 'drop',
159                 {
160                     'ack_id': self._ack_id,
161                     'byte_size': self.size,
162                 },
163             ),
164         )
165 
166     def lease(self):
167         """Inform the policy to lease this message continually.
168 
169         .. note::
170             This method is called by the constructor, and you should never
171             need to call it manually.
172         """
173         self._request_queue.put(
174             (
175                 'lease',
176                 {
177                     'ack_id': self._ack_id,
178                     'byte_size': self.size,
179                 },
180             ),
181         )
182 
183     def modify_ack_deadline(self, seconds):
184         """Set the deadline for acknowledgement to the given value.
185 
186         The default implementation handles this for you; you should not need
187         to manually deal with setting ack deadlines. The exception case is
188         if you are implementing your own custom subclass of
189         :class:`~.pubsub_v1.subcriber._consumer.Consumer`.
190 
191         .. note::
192             This is not an extension; it *sets* the deadline to the given
193             number of seconds from right now. It is even possible to use this
194             method to make a deadline shorter.
195 
196         Args:
197             seconds (int): The number of seconds to set the lease deadline
198                 to. This should be between 0 and 600. Due to network latency,
199                 values below 10 are advised against.
200         """
201         self._request_queue.put(
202             (
203                 'modify_ack_deadline',
204                 {
205                     'ack_id': self._ack_id,
206                     'seconds': seconds,
207                 },
208             ),
209         )
210 
211     def nack(self):
212         """Decline to acknowldge the given message.
213 
214         This will cause the message to be re-delivered to the subscription.
215         """
216         self._request_queue.put(
217             (
218                 'nack',
219                 {
220                     'ack_id': self._ack_id,
221                     'byte_size': self.size,
222                 },
223             ),
224         )
225
```
--- 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/pubsub/google/cloud/pubsub_v1/subscriber/message.py b/pubsub/google/cloud/pubsub_v1/subscriber/message.py
--- a/pubsub/google/cloud/pubsub_v1/subscriber/message.py
+++ b/pubsub/google/cloud/pubsub_v1/subscriber/message.py
@@ -33,7 +33,8 @@
             to use this directly.
         data (bytes): The data in the message. Note that this will be a
             :class:`bytes`, not a text string.
-        attributes (dict): The attributes sent along with the message.
+        attributes (.ScalarMapContainer): The attributes sent along with the
+            message. See :attr:`attributes` for more information on this type.
         publish_time (datetime): The time that this message was originally
             published.
     """
@@ -85,8 +86,18 @@
     def attributes(self):
         """Return the attributes of the underlying Pub/Sub Message.
 
+        .. warning::
+
+            A ``ScalarMapContainer`` behaves slightly differently than a
+            ``dict``. For a Pub / Sub message this is a ``string->string`` map.
+            When trying to access a value via ``map['key']``, if the key is
+            not in the map, then the default value for the string type will
+            be returned, which is an empty string. It may be more intuitive
+            to just cast the map to a ``dict`` or to one use ``map.get``.
+
         Returns:
-            dict: The message's attributes.
+            .ScalarMapContainer: The message's attributes. This is a
+            ``dict``-like object provided by ``google.protobuf``.
         """
         return self._message.attributes

{"golden_diff": "diff --git a/pubsub/google/cloud/pubsub_v1/subscriber/message.py b/pubsub/google/cloud/pubsub_v1/subscriber/message.py\n--- a/pubsub/google/cloud/pubsub_v1/subscriber/message.py\n+++ b/pubsub/google/cloud/pubsub_v1/subscriber/message.py\n@@ -33,7 +33,8 @@\n             to use this directly.\n         data (bytes): The data in the message. Note that this will be a\n             :class:`bytes`, not a text string.\n-        attributes (dict): The attributes sent along with the message.\n+        attributes (.ScalarMapContainer): The attributes sent along with the\n+            message. See :attr:`attributes` for more information on this type.\n         publish_time (datetime): The time that this message was originally\n             published.\n     \"\"\"\n@@ -85,8 +86,18 @@\n     def attributes(self):\n         \"\"\"Return the attributes of the underlying Pub/Sub Message.\n \n+        .. warning::\n+\n+            A ``ScalarMapContainer`` behaves slightly differently than a\n+            ``dict``. For a Pub / Sub message this is a ``string->string`` map.\n+            When trying to access a value via ``map['key']``, if the key is\n+            not in the map, then the default value for the string type will\n+            be returned, which is an empty string. It may be more intuitive\n+            to just cast the map to a ``dict`` or to one use ``map.get``.\n+\n         Returns:\n-            dict: The message's attributes.\n+            .ScalarMapContainer: The message's attributes. This is a\n+            ``dict``-like object provided by ``google.protobuf``.\n         \"\"\"\n         return self._message.attributes\n", "issue": "Pub/Sub API lists the wrong (slightly incompatible) type for Message.attributes\nWhen a subscriber receives a message, the API says it has an 'attributes' member that is a dict:\r\n\r\nhttps://github.com/GoogleCloudPlatform/google-cloud-python/blob/11e310ab9f63f06252ff2b9ada201fd8c11ce06c/pubsub/google/cloud/pubsub_v1/subscriber/message.py#L36\r\n\r\nHowever, it is not, in fact, a dict; it is a protobuf map. The behaviour is quite different, which the Python protobuf API documentation explains at some length:\r\n\r\nhttps://developers.google.com/protocol-buffers/docs/reference/python-generated#map-fields\r\n\r\nThis is not a small difference... the semantic gap is substantial, because using the `.attributes` type in place of a dict breaks code like this:\r\n\r\n```\r\nmessage_rev = None\r\nif some_condition:\r\n  try:\r\n    message_rev = int(message.attributes['revision'])\r\n  except KeyError:\r\n    message_rev = DEFAULT\r\n```\r\n\r\nIn this case, instead of assigning the value `DEFAULT`, this code simply raises a new exception that doesn't happen with dicts (it's a ValueError, because the try-block will execute `int('')`). This is an incompatible, breaking change.\r\n\r\nAgain, this is a subtle, but important, API difference. At a minimum, it seems like the PubSub API docs should point to the Protobuf docs, instead of simply listing the incorrect type.\n", "before_files": [{"content": "# Copyright 2017, Google LLC 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\nfrom __future__ import absolute_import\n\nimport math\nimport time\n\n\nclass Message(object):\n    \"\"\"A representation of a single Pub/Sub message.\n\n    The common way to interact with\n    :class:`~.pubsub_v1.subscriber.message.Message` objects is to receive\n    them in callbacks on subscriptions; most users should never have a need\n    to instantiate them by hand. (The exception to this is if you are\n    implementing a custom subclass to\n    :class:`~.pubsub_v1.subscriber._consumer.Consumer`.)\n\n    Attributes:\n        message_id (str): The message ID. In general, you should not need\n            to use this directly.\n        data (bytes): The data in the message. Note that this will be a\n            :class:`bytes`, not a text string.\n        attributes (dict): The attributes sent along with the message.\n        publish_time (datetime): The time that this message was originally\n            published.\n    \"\"\"\n\n    def __init__(self, message, ack_id, request_queue):\n        \"\"\"Construct the Message.\n\n        .. note::\n\n            This class should not be constructed directly; it is the\n            responsibility of :class:`BasePolicy` subclasses to do so.\n\n        Args:\n            message (~.pubsub_v1.types.PubsubMessage): The message received\n                from Pub/Sub.\n            ack_id (str): The ack_id received from Pub/Sub.\n            request_queue (queue.Queue): A queue provided by the policy that\n                can accept requests; the policy is responsible for handling\n                those requests.\n        \"\"\"\n        self._message = message\n        self._ack_id = ack_id\n        self._request_queue = request_queue\n        self.message_id = message.message_id\n\n        # The instantiation time is the time that this message\n        # was received. Tracking this provides us a way to be smart about\n        # the default lease deadline.\n        self._received_timestamp = time.time()\n\n        # The policy should lease this message, telling PubSub that it has\n        # it until it is acked or otherwise dropped.\n        self.lease()\n\n    def __repr__(self):\n        # Get an abbreviated version of the data.\n        abbv_data = self._message.data\n        if len(abbv_data) > 50:\n            abbv_data = abbv_data[0:50] + b'...'\n\n        # Return a useful representation.\n        answer = 'Message {\\n'\n        answer += '    data: {0!r}\\n'.format(abbv_data)\n        answer += '    attributes: {0!r}\\n'.format(self.attributes)\n        answer += '}'\n        return answer\n\n    @property\n    def attributes(self):\n        \"\"\"Return the attributes of the underlying Pub/Sub Message.\n\n        Returns:\n            dict: The message's attributes.\n        \"\"\"\n        return self._message.attributes\n\n    @property\n    def data(self):\n        \"\"\"Return the data for the underlying Pub/Sub Message.\n\n        Returns:\n            bytes: The message data. This is always a bytestring; if you\n                want a text string, call :meth:`bytes.decode`.\n        \"\"\"\n        return self._message.data\n\n    @property\n    def publish_time(self):\n        \"\"\"Return the time that the message was originally published.\n\n        Returns:\n            datetime: The date and time that the message was published.\n        \"\"\"\n        return self._message.publish_time\n\n    @property\n    def size(self):\n        \"\"\"Return the size of the underlying message, in bytes.\"\"\"\n        return self._message.ByteSize()\n\n    def ack(self):\n        \"\"\"Acknowledge the given message.\n\n        Acknowledging a message in Pub/Sub means that you are done\n        with it, and it will not be delivered to this subscription again.\n        You should avoid acknowledging messages until you have\n        *finished* processing them, so that in the event of a failure,\n        you receive the message again.\n\n        .. warning::\n            Acks in Pub/Sub are best effort. You should always\n            ensure that your processing code is idempotent, as you may\n            receive any given message more than once.\n        \"\"\"\n        time_to_ack = math.ceil(time.time() - self._received_timestamp)\n        self._request_queue.put(\n            (\n                'ack',\n                {\n                    'ack_id': self._ack_id,\n                    'byte_size': self.size,\n                    'time_to_ack': time_to_ack,\n                },\n            ),\n        )\n\n    def drop(self):\n        \"\"\"Release the message from lease management.\n\n        This informs the policy to no longer hold on to the lease for this\n        message. Pub/Sub will re-deliver the message if it is not acknowledged\n        before the existing lease expires.\n\n        .. warning::\n            For most use cases, the only reason to drop a message from\n            lease management is on :meth:`ack` or :meth:`nack`; these methods\n            both call this one. You probably do not want to call this method\n            directly.\n        \"\"\"\n        self._request_queue.put(\n            (\n                'drop',\n                {\n                    'ack_id': self._ack_id,\n                    'byte_size': self.size,\n                },\n            ),\n        )\n\n    def lease(self):\n        \"\"\"Inform the policy to lease this message continually.\n\n        .. note::\n            This method is called by the constructor, and you should never\n            need to call it manually.\n        \"\"\"\n        self._request_queue.put(\n            (\n                'lease',\n                {\n                    'ack_id': self._ack_id,\n                    'byte_size': self.size,\n                },\n            ),\n        )\n\n    def modify_ack_deadline(self, seconds):\n        \"\"\"Set the deadline for acknowledgement to the given value.\n\n        The default implementation handles this for you; you should not need\n        to manually deal with setting ack deadlines. The exception case is\n        if you are implementing your own custom subclass of\n        :class:`~.pubsub_v1.subcriber._consumer.Consumer`.\n\n        .. note::\n            This is not an extension; it *sets* the deadline to the given\n            number of seconds from right now. It is even possible to use this\n            method to make a deadline shorter.\n\n        Args:\n            seconds (int): The number of seconds to set the lease deadline\n                to. This should be between 0 and 600. Due to network latency,\n                values below 10 are advised against.\n        \"\"\"\n        self._request_queue.put(\n            (\n                'modify_ack_deadline',\n                {\n                    'ack_id': self._ack_id,\n                    'seconds': seconds,\n                },\n            ),\n        )\n\n    def nack(self):\n        \"\"\"Decline to acknowldge the given message.\n\n        This will cause the message to be re-delivered to the subscription.\n        \"\"\"\n        self._request_queue.put(\n            (\n                'nack',\n                {\n                    'ack_id': self._ack_id,\n                    'byte_size': self.size,\n                },\n            ),\n        )\n", "path": "pubsub/google/cloud/pubsub_v1/subscriber/message.py"}], "after_files": [{"content": "# Copyright 2017, Google LLC 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\nfrom __future__ import absolute_import\n\nimport math\nimport time\n\n\nclass Message(object):\n    \"\"\"A representation of a single Pub/Sub message.\n\n    The common way to interact with\n    :class:`~.pubsub_v1.subscriber.message.Message` objects is to receive\n    them in callbacks on subscriptions; most users should never have a need\n    to instantiate them by hand. (The exception to this is if you are\n    implementing a custom subclass to\n    :class:`~.pubsub_v1.subscriber._consumer.Consumer`.)\n\n    Attributes:\n        message_id (str): The message ID. In general, you should not need\n            to use this directly.\n        data (bytes): The data in the message. Note that this will be a\n            :class:`bytes`, not a text string.\n        attributes (.ScalarMapContainer): The attributes sent along with the\n            message. See :attr:`attributes` for more information on this type.\n        publish_time (datetime): The time that this message was originally\n            published.\n    \"\"\"\n\n    def __init__(self, message, ack_id, request_queue):\n        \"\"\"Construct the Message.\n\n        .. note::\n\n            This class should not be constructed directly; it is the\n            responsibility of :class:`BasePolicy` subclasses to do so.\n\n        Args:\n            message (~.pubsub_v1.types.PubsubMessage): The message received\n                from Pub/Sub.\n            ack_id (str): The ack_id received from Pub/Sub.\n            request_queue (queue.Queue): A queue provided by the policy that\n                can accept requests; the policy is responsible for handling\n                those requests.\n        \"\"\"\n        self._message = message\n        self._ack_id = ack_id\n        self._request_queue = request_queue\n        self.message_id = message.message_id\n\n        # The instantiation time is the time that this message\n        # was received. Tracking this provides us a way to be smart about\n        # the default lease deadline.\n        self._received_timestamp = time.time()\n\n        # The policy should lease this message, telling PubSub that it has\n        # it until it is acked or otherwise dropped.\n        self.lease()\n\n    def __repr__(self):\n        # Get an abbreviated version of the data.\n        abbv_data = self._message.data\n        if len(abbv_data) > 50:\n            abbv_data = abbv_data[0:50] + b'...'\n\n        # Return a useful representation.\n        answer = 'Message {\\n'\n        answer += '    data: {0!r}\\n'.format(abbv_data)\n        answer += '    attributes: {0!r}\\n'.format(self.attributes)\n        answer += '}'\n        return answer\n\n    @property\n    def attributes(self):\n        \"\"\"Return the attributes of the underlying Pub/Sub Message.\n\n        .. warning::\n\n            A ``ScalarMapContainer`` behaves slightly differently than a\n            ``dict``. For a Pub / Sub message this is a ``string->string`` map.\n            When trying to access a value via ``map['key']``, if the key is\n            not in the map, then the default value for the string type will\n            be returned, which is an empty string. It may be more intuitive\n            to just cast the map to a ``dict`` or to one use ``map.get``.\n\n        Returns:\n            .ScalarMapContainer: The message's attributes. This is a\n            ``dict``-like object provided by ``google.protobuf``.\n        \"\"\"\n        return self._message.attributes\n\n    @property\n    def data(self):\n        \"\"\"Return the data for the underlying Pub/Sub Message.\n\n        Returns:\n            bytes: The message data. This is always a bytestring; if you\n                want a text string, call :meth:`bytes.decode`.\n        \"\"\"\n        return self._message.data\n\n    @property\n    def publish_time(self):\n        \"\"\"Return the time that the message was originally published.\n\n        Returns:\n            datetime: The date and time that the message was published.\n        \"\"\"\n        return self._message.publish_time\n\n    @property\n    def size(self):\n        \"\"\"Return the size of the underlying message, in bytes.\"\"\"\n        return self._message.ByteSize()\n\n    def ack(self):\n        \"\"\"Acknowledge the given message.\n\n        Acknowledging a message in Pub/Sub means that you are done\n        with it, and it will not be delivered to this subscription again.\n        You should avoid acknowledging messages until you have\n        *finished* processing them, so that in the event of a failure,\n        you receive the message again.\n\n        .. warning::\n            Acks in Pub/Sub are best effort. You should always\n            ensure that your processing code is idempotent, as you may\n            receive any given message more than once.\n        \"\"\"\n        time_to_ack = math.ceil(time.time() - self._received_timestamp)\n        self._request_queue.put(\n            (\n                'ack',\n                {\n                    'ack_id': self._ack_id,\n                    'byte_size': self.size,\n                    'time_to_ack': time_to_ack,\n                },\n            ),\n        )\n\n    def drop(self):\n        \"\"\"Release the message from lease management.\n\n        This informs the policy to no longer hold on to the lease for this\n        message. Pub/Sub will re-deliver the message if it is not acknowledged\n        before the existing lease expires.\n\n        .. warning::\n            For most use cases, the only reason to drop a message from\n            lease management is on :meth:`ack` or :meth:`nack`; these methods\n            both call this one. You probably do not want to call this method\n            directly.\n        \"\"\"\n        self._request_queue.put(\n            (\n                'drop',\n                {\n                    'ack_id': self._ack_id,\n                    'byte_size': self.size,\n                },\n            ),\n        )\n\n    def lease(self):\n        \"\"\"Inform the policy to lease this message continually.\n\n        .. note::\n            This method is called by the constructor, and you should never\n            need to call it manually.\n        \"\"\"\n        self._request_queue.put(\n            (\n                'lease',\n                {\n                    'ack_id': self._ack_id,\n                    'byte_size': self.size,\n                },\n            ),\n        )\n\n    def modify_ack_deadline(self, seconds):\n        \"\"\"Set the deadline for acknowledgement to the given value.\n\n        The default implementation handles this for you; you should not need\n        to manually deal with setting ack deadlines. The exception case is\n        if you are implementing your own custom subclass of\n        :class:`~.pubsub_v1.subcriber._consumer.Consumer`.\n\n        .. note::\n            This is not an extension; it *sets* the deadline to the given\n            number of seconds from right now. It is even possible to use this\n            method to make a deadline shorter.\n\n        Args:\n            seconds (int): The number of seconds to set the lease deadline\n                to. This should be between 0 and 600. Due to network latency,\n                values below 10 are advised against.\n        \"\"\"\n        self._request_queue.put(\n            (\n                'modify_ack_deadline',\n                {\n                    'ack_id': self._ack_id,\n                    'seconds': seconds,\n                },\n            ),\n        )\n\n    def nack(self):\n        \"\"\"Decline to acknowldge the given message.\n\n        This will cause the message to be re-delivered to the subscription.\n        \"\"\"\n        self._request_queue.put(\n            (\n                'nack',\n                {\n                    'ack_id': self._ack_id,\n                    'byte_size': self.size,\n                },\n            ),\n        )\n", "path": "pubsub/google/cloud/pubsub_v1/subscriber/message.py"}]}