Repository: googleapis/google-cloud-python

Issue:
Return the new Key/Blob from gcloud.storage.bucket.upload_file_obj()
Right now it doesn't appear that [gcloud.storage.bucket.upload_file_object()](https://github.com/GoogleCloudPlatform/gcloud-python/blob/master/gcloud/storage/bucket.py#L415) returns anything. This is in contrast to [gcloud.storage.bucket.upload_file()](https://github.com/GoogleCloudPlatform/gcloud-python/blob/master/gcloud/storage/bucket.py#L375), which does return the new blob. It would be much handier if the newly created Key/Blob was returned instead.



Discussion:

Resolving patch:
diff --git a/gcloud/storage/blob.py b/gcloud/storage/blob.py
--- a/gcloud/storage/blob.py
+++ b/gcloud/storage/blob.py
@@ -374,9 +374,6 @@ def upload_from_string(self, data, content_type='text/plain'):
         :type data: bytes or text
         :param data: The data to store in this blob.  If the value is
                      text, it will be encoded as UTF-8.
-
-        :rtype: :class:`Blob`
-        :returns: The updated Blob object.
         """
         if isinstance(data, six.text_type):
             data = data.encode('utf-8')
@@ -385,7 +382,6 @@ def upload_from_string(self, data, content_type='text/plain'):
         self.upload_from_file(file_obj=string_buffer, rewind=True,
                               size=len(data),
                               content_type=content_type)
-        return self
 
     def make_public(self):
         """Make this blob public giving all users read access.
diff --git a/gcloud/storage/bucket.py b/gcloud/storage/bucket.py
--- a/gcloud/storage/bucket.py
+++ b/gcloud/storage/bucket.py
@@ -405,6 +405,9 @@ def upload_file(self, filename, blob=None):
                      to put the file.  If this is blank, we will try to
                      upload the file to the root of the bucket with the
                      same name as on your local file system.
+
+        :rtype: :class:`Blob`
+        :returns: The updated Blob object.
         """
         if blob is None:
             blob = os.path.basename(filename)
@@ -445,12 +448,16 @@ def upload_file_object(self, file_obj, blob=None):
                      to put the file.  If this is blank, we will try to
                      upload the file to the root of the bucket with the
                      same name as on your local file system.
+
+        :rtype: :class:`Blob`
+        :returns: The updated Blob object.
         """
         if blob:
             blob = self.new_blob(blob)
         else:
             blob = self.new_blob(os.path.basename(file_obj.name))
-        return blob.upload_from_file(file_obj)
+        blob.upload_from_file(file_obj)
+        return blob
 
     def get_cors(self):
         """Retrieve CORS policies configured for this bucket.


Test patch:
diff --git a/gcloud/storage/test_bucket.py b/gcloud/storage/test_bucket.py
--- a/gcloud/storage/test_bucket.py
+++ b/gcloud/storage/test_bucket.py
@@ -517,8 +517,11 @@ def upload_from_file(self, fh):
 
         bucket = self._makeOne()
         with _Monkey(MUT, Blob=_Blob):
-            bucket.upload_file_object(FILEOBJECT)
+            found = bucket.upload_file_object(FILEOBJECT)
         self.assertEqual(_uploaded, [(bucket, FILENAME, FILEOBJECT)])
+        self.assertTrue(isinstance(found, _Blob))
+        self.assertEqual(found._name, FILENAME)
+        self.assertTrue(found._bucket is bucket)
 
     def test_upload_file_object_explicit_blob(self):
         from gcloud._testing import _Monkey
@@ -539,8 +542,11 @@ def upload_from_file(self, fh):
 
         bucket = self._makeOne()
         with _Monkey(MUT, Blob=_Blob):
-            bucket.upload_file_object(FILEOBJECT, BLOB_NAME)
+            found = bucket.upload_file_object(FILEOBJECT, BLOB_NAME)
         self.assertEqual(_uploaded, [(bucket, BLOB_NAME, FILEOBJECT)])
+        self.assertTrue(isinstance(found, _Blob))
+        self.assertEqual(found._name, BLOB_NAME)
+        self.assertTrue(found._bucket is bucket)
 
     def test_get_cors_eager(self):
         NAME = 'name'