Repository: googleapis/google-cloud-python

Issue:
gcloud.storage.bucket.Bucket.save_default_object_acl with empty ACL doesn't clear
The following test:

```
acl = acl or self.default_object_acl
```

should test for None instead:

```
if acl is None:
    acl = self.default_object_acl
```

This bug prevents 'clear_default_object_acl' from working (calling it just saves the existing ACL).



Discussion:
Can you link to source in these bugs?

For example, the relevant [line](https://github.com/GoogleCloudPlatform/gcloud-python/blob/1f2aaf3606802f4f02eeb30e22e1082ef7f4594e/gcloud/storage/bucket.py#L527) for this bug along with the commit where it's relevant (can get it by pressing `y` while in the GitHub UI).

This will make bugs easier to track as the code changes underneath.

https://github.com/GoogleCloudPlatform/gcloud-python/blob/master/gcloud/storage/bucket.py#L527

Thanks, but note the `...blog/master/gcloud/...` part of the link. That always points to `HEAD` in master, rather than the explicit commit that was the tip of `master` when you referenced it. That's why I recommended pressing `y` in the UI.

I'm sorry not to know that part of the UI well -- I don't really _like_ browsing code there, compared to using filesystem tools.

I suppose that's fine as well, just include a line number and the commit hash of `HEAD` at the time of posting.


Resolving patch:
diff --git a/gcloud/storage/bucket.py b/gcloud/storage/bucket.py
--- a/gcloud/storage/bucket.py
+++ b/gcloud/storage/bucket.py
@@ -517,12 +517,15 @@ def save_default_object_acl(self, acl=None):
                 and save that.
     """
 
-    acl = acl or self.default_object_acl
+    if acl is None:
+        acl = self.default_object_acl
 
     if acl is None:
       return self
 
-    return self.patch_metadata({'defaultObjectAcl': list(acl)})
+    self.patch_metadata({'defaultObjectAcl': list(acl)})
+    self.reload_default_object_acl()
+    return self
 
   def clear_default_object_acl(self):
     """Remove the Default Object ACL from 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
@@ -628,54 +628,69 @@ def test_save_default_object_acl_none_set_none_passed(self):
     def test_save_default_object_acl_existing_set_none_passed(self):
         NAME = 'name'
         connection = _Connection({'foo': 'Foo', 'acl': []})
+        connection = _Connection({'foo': 'Foo', 'acl': []},
+                                 {'foo': 'Foo', 'acl': [],
+                                    'defaultObjectAcl': []},
+                                )
         metadata = {'defaultObjectAcl': []}
         bucket = self._makeOne(connection, NAME, metadata)
         bucket.reload_default_object_acl()
         self.assertTrue(bucket.save_default_object_acl() is bucket)
         kw = connection._requested
-        self.assertEqual(len(kw), 1)
+        self.assertEqual(len(kw), 2)
         self.assertEqual(kw[0]['method'], 'PATCH')
         self.assertEqual(kw[0]['path'], '/b/%s' % NAME)
         self.assertEqual(kw[0]['data'], metadata)
         self.assertEqual(kw[0]['query_params'], {'projection': 'full'})
+        self.assertEqual(kw[1]['method'], 'GET')
+        self.assertEqual(kw[1]['path'], '/b/%s' % NAME)
+        self.assertEqual(kw[1]['query_params'], {'projection': 'full'})
 
     def test_save_default_object_acl_existing_set_new_passed(self):
         NAME = 'name'
         ROLE = 'role'
         new_acl = [{'entity': 'allUsers', 'role': ROLE}]
-        connection = _Connection({'foo': 'Foo', 'acl': new_acl})
+        connection = _Connection({'foo': 'Foo', 'acl': new_acl},
+                                 {'foo': 'Foo', 'acl': new_acl,
+                                    'defaultObjectAcl': new_acl},
+                                )
         metadata = {'defaultObjectAcl': []}
         bucket = self._makeOne(connection, NAME, metadata)
         bucket.reload_default_object_acl()
         self.assertTrue(bucket.save_default_object_acl(new_acl) is bucket)
-        # See: https://github.com/GoogleCloudPlatform/gcloud-python/issues/138
-        #self.assertEqual(list(bucket.default_object_acl), new_acl)
+        self.assertEqual(list(bucket.default_object_acl), new_acl)
         kw = connection._requested
-        self.assertEqual(len(kw), 1)
+        self.assertEqual(len(kw), 2)
         self.assertEqual(kw[0]['method'], 'PATCH')
         self.assertEqual(kw[0]['path'], '/b/%s' % NAME)
         self.assertEqual(kw[0]['data'], {'defaultObjectAcl': new_acl})
         self.assertEqual(kw[0]['query_params'], {'projection': 'full'})
+        self.assertEqual(kw[1]['method'], 'GET')
+        self.assertEqual(kw[1]['path'], '/b/%s' % NAME)
+        self.assertEqual(kw[1]['query_params'], {'projection': 'full'})
 
     def test_clear_default_object_acl(self):
         NAME = 'name'
         ROLE = 'role'
         old_acl = [{'entity': 'allUsers', 'role': ROLE}]
-        connection = _Connection({'foo': 'Foo', 'acl': []})
+        connection = _Connection({'foo': 'Foo', 'acl': []},
+                                 {'foo': 'Foo', 'acl': [],
+                                    'defaultObjectAcl': []},
+                                )
         metadata = {'defaultObjectAcl': old_acl}
         bucket = self._makeOne(connection, NAME, metadata)
         bucket.reload_default_object_acl()
         self.assertTrue(bucket.clear_default_object_acl() is bucket)
-        # See: https://github.com/GoogleCloudPlatform/gcloud-python/issues/138
-        #self.assertEqual(list(bucket.default_object_acl), [])
+        self.assertEqual(list(bucket.default_object_acl), [])
         kw = connection._requested
-        self.assertEqual(len(kw), 1)
+        self.assertEqual(len(kw), 2)
         self.assertEqual(kw[0]['method'], 'PATCH')
         self.assertEqual(kw[0]['path'], '/b/%s' % NAME)
-        # See: https://github.com/GoogleCloudPlatform/gcloud-python/issues/139
-        #self.assertEqual(list(bucket.default_object_acl), [])
-        #self.assertEqual(kw[0]['data'], {'defaultObjectAcl': []})
+        self.assertEqual(kw[0]['data'], {'defaultObjectAcl': []})
         self.assertEqual(kw[0]['query_params'], {'projection': 'full'})
+        self.assertEqual(kw[1]['method'], 'GET')
+        self.assertEqual(kw[1]['path'], '/b/%s' % NAME)
+        self.assertEqual(kw[1]['query_params'], {'projection': 'full'})
 
     def test_make_public_defaults(self):
         from gcloud.storage.acl import ACL