internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: googleapis/google-cloud-python

Issue:
Add documentation for storage.Blob's special methods (contains, next, etc)
Right now it's not really clear how to check for a key's existence (do I need to do if `Key('name') in bucket`? or just `'name' in bucket`?

We need to make sure these special methods are documented with examples in the API docs for the Key class.



Discussion:
The implementation of `bucket.__contains__` "wants" a string, but is actually willing to take a string and convert to a key.  I would be in favor of dropping that myself, and asking the user to create the key, either via `bucket.new_key(name)` or by instantiating `Key` directly.

I think it'd be annoying to need to create the key to check for existence -- I kind of like the magical "we know what to do if you pass us a string".

So:

``` python
print 'my-key-name' in bucket
print Key('my-key-name') in bucket
print bucket.new_key('my-key-name') in bucket
```

should all return a boolean IMO.

You're in luck then:  we already DTRT.


Resolving patch:
diff --git a/gcloud/storage/bucket.py b/gcloud/storage/bucket.py
--- a/gcloud/storage/bucket.py
+++ b/gcloud/storage/bucket.py
@@ -12,7 +12,26 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Create / interact with gcloud storage buckets."""
+"""Create / interact with gcloud storage buckets.
+
+If you want to check whether a blob exists, you can use the ``in`` operator
+in Python::
+
+  >>> print 'kitten.jpg' in bucket
+  True
+  >>> print 'does-not-exist' in bucket
+  False
+
+If you want to get all the blobs in the bucket, you can use
+:func:`get_all_blobs <gcloud.storage.bucket.Bucket.get_all_blobs>`::
+
+  >>> blobs = bucket.get_all_blobs()
+
+You can also use the bucket as an iterator::
+
+  >>> for blob in bucket:
+  ...   print blob
+"""
 
 import os
 import six


Test patch:
Repository: googleapis/google-cloud-python

Issue:
Version the docs
The docs at http://googlecloudplatform.github.io/gcloud-python/datastore-api.html document the current API at git head - and include a version tag of 0.3.0

This matches the current released version on pypi (that does not have the recent change for implicit credentials)

Please consider using something like readthedocs and provide versioned docs - so that what users find actually matches what they are likely to install :)

Or at least mark the version in master as -dev with a warning in docs, and tag to stable version in a branch.



Discussion:
Thanks for the suggestion @ptone, we've had some other great docs feedback lately. Hopefully we can reach a more stable API soon and versions will become more meaningful.

I think first and foremost, not building docs from HEAD should be done.

My bad, I left in the version string without providing a version history. I think it's fine to build from master, as long as it's properly built in a `-dev` version as suggested by @ptone (and that is what we do with [gcloud-node](http://googlecloudplatform.github.io/gcloud-node/#/docs/history) where we have a `master` version).
I'll fix it.

+1 for this. I'm starting reading source code at the specific commit / tag in order to know what's supported in that version.

+1 for this. The coding example under Getting Started for Storage doesn't work because the signature for get_buckets() has changed. This is really confusing because the docs say `0.3.0` which matches the version on PyPi as already pointed out. The only way to figure it out is the read the source code which probably isn't ideal.

Something like http://googlecloudplatform.github.io/gcloud-node/#/docs/history is preferred so hopefully we can borrow from `gcloud-node`

@silvolu you mentioned you had started this, do you have any half-finished work to go from?

@dhermes I mentioned I would start this, but then I got side tracked, so nope, I got nothing :/

@rstuart85 in the short term https://github.com/GoogleCloudPlatform/gcloud-python/releases/tag/v0.4.0 means the docs reflect the latest version on PyPI. I'm hoping to resolve this issue soon-ish.

Starting on this right now.

@dhermes great news!


Resolving patch:
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -54,9 +54,7 @@
 # built documents.
 #
 # The short X.Y version.
-version = get_distribution('gcloud').version
-# The full version, including alpha/beta/rc tags.
-release = get_distribution('gcloud').version
+release = os.getenv('SPHINX_RELEASE', get_distribution('gcloud').version)
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/scripts/get_version.py b/scripts/get_version.py
new file mode 100644
--- /dev/null
+++ b/scripts/get_version.py
@@ -0,0 +1,3 @@
+"""Simple script to get the gcloud version."""
+from pkg_resources import get_distribution
+print get_distribution('gcloud').version


Test patch:
Repository: googleapis/google-cloud-python

Issue:
Silent error when calling datastore.put() on nonlist
Repro instructions:

```
ent = datastore.Entity(key=datastore.Key('test',1))
datastore.put(ent)
```

Entity is not put in the datastore, and call completes successfully. 



Discussion:
@elibixby Thanks for reporting, this is bad! The entity is False-y, hence [nothing](https://github.com/GoogleCloudPlatform/gcloud-python/blob/8e68a20cce2306f055557362b0c4a34909a36d1e/gcloud/datastore/api.py#L253-L254) is added to the batch.

By using a non-empty entity, the type mismatch actually causes an error (which is a "positive" in some sense):

``` python
>>> ent['foo'] = 10
>>> datastore.put(ent)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "gcloud/datastore/api.py", line 257, in put
    dataset_id = _require_dataset_id(dataset_id, entities[0].key)
KeyError: 0
```

---

**PROPOSED FIX**: Define `__bool__` and `__nonzero__` on the class so that `Entity` objects are never False-y.


Resolving patch:
diff --git a/gcloud/datastore/api.py b/gcloud/datastore/api.py
--- a/gcloud/datastore/api.py
+++ b/gcloud/datastore/api.py
@@ -20,6 +20,7 @@
 
 from gcloud.datastore import _implicit_environ
 from gcloud.datastore.batch import Batch
+from gcloud.datastore.entity import Entity
 from gcloud.datastore.transaction import Transaction
 from gcloud.datastore import helpers
 
@@ -252,6 +253,9 @@ def put(entities, connection=None, dataset_id=None):
              one or more entities has a key with a dataset ID not matching
              the passed / inferred dataset ID.
     """
+    if isinstance(entities, Entity):
+        raise ValueError("Pass a sequence of entities")
+
     if not entities:
         return
 


Test patch:
diff --git a/gcloud/datastore/test_api.py b/gcloud/datastore/test_api.py
--- a/gcloud/datastore/test_api.py
+++ b/gcloud/datastore/test_api.py
@@ -627,6 +627,11 @@ def test_no_entities(self):
         result = self._callFUT([])
         self.assertEqual(result, None)
 
+    def test_w_single_empty_entity(self):
+        # https://github.com/GoogleCloudPlatform/gcloud-python/issues/649
+        from gcloud.datastore.entity import Entity
+        self.assertRaises(ValueError, self._callFUT, Entity())
+
     def test_no_batch_w_partial_key(self):
         from gcloud.datastore.test_batch import _Connection
         from gcloud.datastore.test_batch import _Entity
Repository: googleapis/google-cloud-python

Issue:
Looks like we don't expose the `Dataset` class as datastore.Dataset?
There are some docs that use the following syntax:

``` python
>>> from gcloud import datastore
>>> dataset = datastore.get_dataset('dataset-id')
```

I'm not sure if this is accurate, but either way, if we're following the convention of datastore/**init**.py, this should be:

``` python
>>> from gcloud import datastore
>>> dataset = datastore.Dataset('dataset-id')
```

However I don't see the import in `__init__.py`, so I'm guessing that neither of these work...?



Discussion:
Yeah `get_dataset` doesn't exist, I'm on it.

I did a `git blame` and that text was added in #509, a looooong time ago.


Resolving patch:
diff --git a/gcloud/datastore/__init__.py b/gcloud/datastore/__init__.py
--- a/gcloud/datastore/__init__.py
+++ b/gcloud/datastore/__init__.py
@@ -28,6 +28,10 @@
   which represents a connection between your machine and the Cloud Datastore
   API.
 
+- :class:`gcloud.datastore.dataset.Dataset`
+  which represents a dataset ID (string) bundled with a connection and has
+  convenience methods for constructing objects with that dataset ID.
+
 - :class:`gcloud.datastore.entity.Entity`
   which represents a single entity in the datastore
   (akin to a row in relational database world).
@@ -56,6 +60,7 @@
 from gcloud.datastore.api import put
 from gcloud.datastore.batch import Batch
 from gcloud.datastore.connection import Connection
+from gcloud.datastore.dataset import Dataset
 from gcloud.datastore.entity import Entity
 from gcloud.datastore.key import Key
 from gcloud.datastore.query import Query
diff --git a/gcloud/datastore/batch.py b/gcloud/datastore/batch.py
--- a/gcloud/datastore/batch.py
+++ b/gcloud/datastore/batch.py
@@ -51,8 +51,6 @@ class Batch(object):
 
     By default, no updates will be sent if the block exits with an error::
 
-      >>> from gcloud import datastore
-      >>> dataset = datastore.get_dataset('dataset-id')
       >>> with Batch() as batch:
       ...   do_some_work(batch)
       ...   raise Exception() # rolls back


Test patch:
Repository: googleapis/google-cloud-python

Issue:
docs: transaction doesn't have property succeeded
The docs still mention the `succeeded` property on transactions run with `with` even though it has been removed in ed0762b9531bc68f7a9e90835a0f0fbb75ddf383. It's not clear to me how to check for a successful transaction now. I suspect it throws an exception otherwise, which mirrors `ndb` behaviour, but I still check for `_status == 3` just in case.



Discussion:
@pdknsk Thanks for pointing it out. I was hoping it was in an old docs build, but I confirmed it is [present](https://github.com/GoogleCloudPlatform/gcloud-python/blob/65341aebbfe8f03ce0b907061bce796ebbfb7f00/gcloud/datastore/transaction.py#L73-L88) in `HEAD`.

---

As for how you can check it going forward, see my [comment](https://github.com/GoogleCloudPlatform/gcloud-python/pull/595#issuecomment-73312546) in the PR.

The context manager doesn't swallow exceptions. So `__exit__`ing the context manager without a failure is equivalent to `success`.

The only reason we kept the `_status` around is so that a `Transaction` object is "tombstoned" after one use. In other words, so people can't mistakenly try to re-enter a transaction.


Resolving patch:
diff --git a/gcloud/datastore/transaction.py b/gcloud/datastore/transaction.py
--- a/gcloud/datastore/transaction.py
+++ b/gcloud/datastore/transaction.py
@@ -70,23 +70,6 @@ class Transaction(Batch):
          ...
          >>> assert not entity.key.is_partial  # There *is* an ID.
 
-       After completion, you can determine if a commit succeeded or failed.
-       For example, trying to delete a key that doesn't exist::
-
-         >>> with datastore.Transaction() as xact:
-         ...     xact.delete(key)
-         ...
-         >>> xact.succeeded
-         False
-
-       or successfully storing two entities:
-
-         >>> with datastore.Transaction() as xact:
-         ...     datastore.put([entity1, entity2])
-         ...
-         >>> xact.succeeded
-         True
-
     If you don't want to use the context manager you can initialize a
     transaction manually::
 


Test patch:
Repository: googleapis/google-cloud-python

Issue:
Sphinx needs to document methods from _implicit_environ
See https://github.com/GoogleCloudPlatform/gcloud-python/issues/841#issuecomment-94521450 for context.



Discussion:

Resolving patch:
diff --git a/gcloud/datastore/__init__.py b/gcloud/datastore/__init__.py
--- a/gcloud/datastore/__init__.py
+++ b/gcloud/datastore/__init__.py
@@ -71,10 +71,12 @@ def set_defaults(dataset_id=None, connection=None):
     """Set defaults either explicitly or implicitly as fall-back.
 
     Uses the arguments to call the individual default methods
+
     - set_default_dataset_id
     - set_default_connection
 
     In the future we will likely enable methods like
+
     - set_default_namespace
 
     :type dataset_id: string


Test patch:
Repository: googleapis/google-cloud-python

Issue:
Subscription.pull() fails with KeyError
Hi,

My code below fails with a KeyError coming from the library:

``` python
  sub = Subscription(SUBSCRIPTION_NAME, Topic(INCOMING_TOPIC_NAME))

  while True:
    try:
      msgs = sub.pull()
      ...
    except:
      msg = 'poll %s: %s' % (SUBSCRIPTION_NAME, traceback.format_exc())
      print msg
```

Fails with the message:

```
poll extractors: Traceback (most recent call last):
  File "main.py", line 46, in main
    msgs = sub.pull()
  File "/usr/local/lib/python2.7/dist-packages/gcloud/pubsub/subscription.py", line 176, in pull
    for info in response['receivedMessages']]
KeyError: 'receivedMessages'
```

This seems like a bug on the pubsub library code.



Discussion:
Indeed it does! Thanks @campoy for filing.

I'm wondering how to reproduce a response without that key, but an easy "fix" (for us) is to just use

``` python
response.get('receivedMessages', ())
```

FWIW: this is the hardening I mentioned in #893.


Resolving patch:
diff --git a/gcloud/pubsub/subscription.py b/gcloud/pubsub/subscription.py
--- a/gcloud/pubsub/subscription.py
+++ b/gcloud/pubsub/subscription.py
@@ -188,7 +188,7 @@ def pull(self, return_immediately=False, max_messages=1, connection=None):
                                           path='%s:pull' % self.path,
                                           data=data)
         return [(info['ackId'], Message.from_api_repr(info['message']))
-                for info in response['receivedMessages']]
+                for info in response.get('receivedMessages', ())]
 
     def acknowledge(self, ack_ids, connection=None):
         """API call:  acknowledge retrieved messages for the subscription.


Test patch:
diff --git a/gcloud/pubsub/test_subscription.py b/gcloud/pubsub/test_subscription.py
--- a/gcloud/pubsub/test_subscription.py
+++ b/gcloud/pubsub/test_subscription.py
@@ -335,6 +335,23 @@ def test_pull_w_return_immediately_w_max_messages_w_explicit_conn(self):
         self.assertEqual(req['data'],
                          {'returnImmediately': True, 'maxMessages': 3})
 
+    def test_pull_wo_receivedMessages(self):
+        PROJECT = 'PROJECT'
+        SUB_NAME = 'sub_name'
+        SUB_PATH = 'projects/%s/subscriptions/%s' % (PROJECT, SUB_NAME)
+        TOPIC_NAME = 'topic_name'
+        conn = _Connection({})
+        topic = _Topic(TOPIC_NAME, project=PROJECT)
+        subscription = self._makeOne(SUB_NAME, topic)
+        pulled = subscription.pull(return_immediately=False, connection=conn)
+        self.assertEqual(len(pulled), 0)
+        self.assertEqual(len(conn._requested), 1)
+        req = conn._requested[0]
+        self.assertEqual(req['method'], 'POST')
+        self.assertEqual(req['path'], '/%s:pull' % SUB_PATH)
+        self.assertEqual(req['data'],
+                         {'returnImmediately': False, 'maxMessages': 1})
+
     def test_acknowledge_w_implicit_connection(self):
         from gcloud.pubsub._testing import _monkey_defaults
         PROJECT = 'PROJECT'
Repository: googleapis/google-cloud-python

Issue:
GCloudErrors (like NotFound) should show the URL that was referenced
Saying "the requested entity was not found" is useful if you're working with one entity only... otherwise it's just sort of like saying "something went wrong".

If we're able to figure out the URL that raised the error, we should include it in the exception (and the `__str__` version of the exception.



Discussion:

Resolving patch:
diff --git a/gcloud/connection.py b/gcloud/connection.py
--- a/gcloud/connection.py
+++ b/gcloud/connection.py
@@ -415,7 +415,8 @@ def api_request(self, method, path, query_params=None,
             target_object=_target_object)
 
         if not 200 <= response.status < 300:
-            raise make_exception(response, content)
+            raise make_exception(response, content,
+                                 error_info=method + ' ' + url)
 
         string_or_bytes = (six.binary_type, six.text_type)
         if content and expect_json and isinstance(content, string_or_bytes):
diff --git a/gcloud/exceptions.py b/gcloud/exceptions.py
--- a/gcloud/exceptions.py
+++ b/gcloud/exceptions.py
@@ -157,7 +157,7 @@ class ServiceUnavailable(ServerError):
     code = 503
 
 
-def make_exception(response, content, use_json=True):
+def make_exception(response, content, error_info=None, use_json=True):
     """Factory:  create exception based on HTTP response code.
 
     :type response: :class:`httplib2.Response` or other HTTP response object
@@ -167,6 +167,10 @@ def make_exception(response, content, use_json=True):
     :type content: string or dictionary
     :param content: The body of the HTTP error response.
 
+    :type error_info: string
+    :param error_info: Optional string giving extra information about the
+                       failed request.
+
     :type use_json: boolean
     :param use_json: Flag indicating if ``content`` is expected to be JSON.
 
@@ -187,6 +191,9 @@ def make_exception(response, content, use_json=True):
     message = payload.get('error', {}).get('message', '')
     errors = payload.get('error', {}).get('errors', ())
 
+    if error_info is not None:
+        message += ' (%s)' % (error_info,)
+
     try:
         klass = _HTTP_CODE_TO_EXCEPTION[response.status]
     except KeyError:


Test patch:
Repository: googleapis/google-cloud-python

Issue:
[Documentation Issue] Include doc for exclusion of GCE credentials for generate_signed_url
Page Name: storage-blobs
Release: 0.6.0

Since generate_signed_url parameter 'credentials' isn't supported currently by GCE, should include notice.



Discussion:
Good call. Thanks! Related to #922

any idea of a workaround? or if it will be supported in the future? 

Can you chime in on #922? I don't have visibility into internal feature development at Google. You can support it today by just using a service account via a JSON key file on GCE. Put it in your VM image or as a metadata value.


Resolving patch:
diff --git a/gcloud/credentials.py b/gcloud/credentials.py
--- a/gcloud/credentials.py
+++ b/gcloud/credentials.py
@@ -301,6 +301,13 @@ def generate_signed_url(credentials, resource, expiration,
                         content_type=None):
     """Generate signed URL to provide query-string auth'n to a resource.
 
+    .. note::
+      If you are on Google Compute Engine, you can't generate a signed URL.
+      Follow https://github.com/GoogleCloudPlatform/gcloud-python/issues/922
+      for updates on this. If you'd like to be able to generate a signed URL
+      from GCE, you can use a standard service account from a JSON file
+      rather than a GCE service account.
+
     :type credentials: :class:`oauth2client.appengine.AppAssertionCredentials`
     :param credentials: Credentials object with an associated private key to
                         sign text.
diff --git a/gcloud/storage/blob.py b/gcloud/storage/blob.py
--- a/gcloud/storage/blob.py
+++ b/gcloud/storage/blob.py
@@ -157,6 +157,14 @@ def generate_signed_url(self, expiration, method='GET',
                             connection=None, credentials=None):
         """Generates a signed URL for this blob.
 
+        .. note::
+          If you are on Google Compute Engine, you can't generate a signed URL.
+          Follow
+              https://github.com/GoogleCloudPlatform/gcloud-python/issues/922
+          for updates on this. If you'd like to be able to generate a signed
+          URL from GCE, you can use a standard service account from a JSON
+          file rather than a GCE service account.
+
         If you have a blob that you want to allow access to for a set
         amount of time, you can use this method to generate a URL that
         is only valid within a certain time period.


Test patch:
Repository: googleapis/google-cloud-python

Issue:
Migrate to pubsub API to v1
See https://github.com/GoogleCloudPlatform/gcloud-node/issues/699



Discussion:

Resolving patch:
diff --git a/gcloud/pubsub/connection.py b/gcloud/pubsub/connection.py
--- a/gcloud/pubsub/connection.py
+++ b/gcloud/pubsub/connection.py
@@ -28,7 +28,7 @@ class Connection(base_connection.JSONConnection):
     API_BASE_URL = 'https://pubsub.googleapis.com'
     """The base of the API call URL."""
 
-    API_VERSION = 'v1beta2'
+    API_VERSION = 'v1'
     """The version of the API, used in building the API call's URL."""
 
     API_URL_TEMPLATE = '{api_base_url}/{api_version}{path}'
diff --git a/gcloud/pubsub/subscription.py b/gcloud/pubsub/subscription.py
--- a/gcloud/pubsub/subscription.py
+++ b/gcloud/pubsub/subscription.py
@@ -246,7 +246,7 @@ def modify_ack_deadline(self, ack_id, ack_deadline, client=None):
                        ``client`` stored on the current subscription's topic.
         """
         client = self._require_client(client)
-        data = {'ackId': ack_id, 'ackDeadlineSeconds': ack_deadline}
+        data = {'ackIds': [ack_id], 'ackDeadlineSeconds': ack_deadline}
         client.connection.api_request(
             method='POST', path='%s:modifyAckDeadline' % (self.path,),
             data=data)


Test patch:
diff --git a/gcloud/pubsub/test_subscription.py b/gcloud/pubsub/test_subscription.py
--- a/gcloud/pubsub/test_subscription.py
+++ b/gcloud/pubsub/test_subscription.py
@@ -427,7 +427,7 @@ def test_modify_ack_deadline_w_bound_client(self):
         self.assertEqual(req['method'], 'POST')
         self.assertEqual(req['path'], '/%s:modifyAckDeadline' % SUB_PATH)
         self.assertEqual(req['data'],
-                         {'ackId': ACK_ID, 'ackDeadlineSeconds': DEADLINE})
+                         {'ackIds': [ACK_ID], 'ackDeadlineSeconds': DEADLINE})
 
     def test_modify_ack_deadline_w_alternate_client(self):
         PROJECT = 'PROJECT'
@@ -449,7 +449,7 @@ def test_modify_ack_deadline_w_alternate_client(self):
         self.assertEqual(req['method'], 'POST')
         self.assertEqual(req['path'], '/%s:modifyAckDeadline' % SUB_PATH)
         self.assertEqual(req['data'],
-                         {'ackId': ACK_ID, 'ackDeadlineSeconds': DEADLINE})
+                         {'ackIds': [ACK_ID], 'ackDeadlineSeconds': DEADLINE})
 
     def test_delete_w_bound_client(self):
         PROJECT = 'PROJECT'
Repository: googleapis/google-cloud-python

Issue:
Make sure @property's are near constructor in methods
See https://github.com/GoogleCloudPlatform/gcloud-python/pull/987/files#r35029989



Discussion:

Resolving patch:
diff --git a/gcloud/storage/bucket.py b/gcloud/storage/bucket.py
--- a/gcloud/storage/bucket.py
+++ b/gcloud/storage/bucket.py
@@ -98,6 +98,11 @@ def __init__(self, client, name=None):
     def __repr__(self):
         return '<Bucket: %s>' % self.name
 
+    @property
+    def client(self):
+        """The client bound to this bucket."""
+        return self._client
+
     def blob(self, blob_name, chunk_size=None):
         """Factory constructor for blob object.
 
@@ -197,11 +202,6 @@ def path(self):
 
         return self.path_helper(self.name)
 
-    @property
-    def client(self):
-        """The client bound to this bucket."""
-        return self._client
-
     def get_blob(self, blob_name, client=None):
         """Get a blob object by name.
 


Test patch: