Repository: googleapis/google-cloud-python

Issue:
STORAGE: _patch_properties is never called with more than one key in the dict
Should we just accept the key and value? Should we rename to `_patch_property`?



Discussion:
@tseaver WDYT of this?

Both changes SGTM.


Resolving patch:
diff --git a/gcloud/storage/_helpers.py b/gcloud/storage/_helpers.py
--- a/gcloud/storage/_helpers.py
+++ b/gcloud/storage/_helpers.py
@@ -57,20 +57,23 @@ def reload(self):
         self._properties = self.connection.api_request(
             method='GET', path=self.path, query_params=query_params)
 
-    def _patch_properties(self, properties):
-        """Update particular fields of this object's properties.
+    def _patch_property(self, name, value):
+        """Update field of this object's properties.
 
-        This method will only update the fields provided and will not
+        This method will only update the field provided and will not
         touch the other fields.
 
         It **will not** reload the properties from the server. The behavior is
         local only and syncing occurs via :meth:`patch`.
 
-        :type properties: dict
-        :param properties: The dictionary of values to update.
+        :type name: string
+        :param name: The field name to update.
+
+        :type value: object
+        :param value: The value being updated.
         """
-        self._changes.update(properties.keys())
-        self._properties.update(properties)
+        self._changes.add(name)
+        self._properties[name] = value
 
     def patch(self):
         """Sends all changed properties in a PATCH request.
@@ -95,7 +98,7 @@ def _getter(self):
 
     def _setter(self, value):
         """Scalar property setter."""
-        self._patch_properties({fieldname: value})
+        self._patch_property(fieldname, value)
 
     return property(_getter, _setter)
 
diff --git a/gcloud/storage/blob.py b/gcloud/storage/blob.py
--- a/gcloud/storage/blob.py
+++ b/gcloud/storage/blob.py
@@ -555,7 +555,7 @@ def metadata(self, value):
 
         :type value: dict
         """
-        self._patch_properties({'metadata': value})
+        self._patch_property('metadata', value)
 
     @property
     def metageneration(self):
diff --git a/gcloud/storage/bucket.py b/gcloud/storage/bucket.py
--- a/gcloud/storage/bucket.py
+++ b/gcloud/storage/bucket.py
@@ -504,7 +504,7 @@ def cors(self, entries):
         :type entries: list of dictionaries
         :param entries: A sequence of mappings describing each CORS policy.
         """
-        self._patch_properties({'cors': entries})
+        self._patch_property('cors', entries)
 
     @property
     def etag(self):
@@ -550,7 +550,7 @@ def lifecycle_rules(self, rules):
         :rtype: list(dict)
         :returns: A sequence of mappings describing each lifecycle rule.
         """
-        self._patch_properties({'lifecycle': {'rule': rules}})
+        self._patch_property('lifecycle', {'rule': rules})
 
     location = _scalar_property('location')
     """Retrieve location configured for this bucket.
@@ -586,14 +586,14 @@ def enable_logging(self, bucket_name, object_prefix=''):
         :param object_prefix: prefix for access log filenames
         """
         info = {'logBucket': bucket_name, 'logObjectPrefix': object_prefix}
-        self._patch_properties({'logging': info})
+        self._patch_property('logging', info)
 
     def disable_logging(self):
         """Disable access logging for this bucket.
 
         See: https://cloud.google.com/storage/docs/accesslogs#disabling
         """
-        self._patch_properties({'logging': None})
+        self._patch_property('logging', None)
 
     @property
     def metageneration(self):
@@ -682,7 +682,7 @@ def versioning_enabled(self, value):
         :type value: convertible to boolean
         :param value: should versioning be anabled for the bucket?
         """
-        self._patch_properties({'versioning': {'enabled': bool(value)}})
+        self._patch_property('versioning', {'enabled': bool(value)})
 
     def configure_website(self, main_page_suffix=None, not_found_page=None):
         """Configure website-related properties.
@@ -719,12 +719,10 @@ def configure_website(self, main_page_suffix=None, not_found_page=None):
         :param not_found_page: The file to use when a page isn't found.
         """
         data = {
-            'website': {
-                'mainPageSuffix': main_page_suffix,
-                'notFoundPage': not_found_page,
-            },
+            'mainPageSuffix': main_page_suffix,
+            'notFoundPage': not_found_page,
         }
-        self._patch_properties(data)
+        self._patch_property('website', data)
 
     def disable_website(self):
         """Disable the website configuration for this bucket.


Test patch:
diff --git a/gcloud/storage/test__helpers.py b/gcloud/storage/test__helpers.py
--- a/gcloud/storage/test__helpers.py
+++ b/gcloud/storage/test__helpers.py
@@ -57,10 +57,10 @@ def test_reload(self):
         self.assertEqual(kw[0]['path'], '/path')
         self.assertEqual(kw[0]['query_params'], {'projection': 'noAcl'})
 
-    def test__patch_properties(self):
+    def test__patch_property(self):
         connection = _Connection({'foo': 'Foo'})
         derived = self._derivedClass(connection, '/path')()
-        derived._patch_properties({'foo': 'Foo'})
+        derived._patch_property('foo', 'Foo')
         derived.patch()
         kw = connection._requested
         self.assertEqual(len(kw), 1)
@@ -89,13 +89,13 @@ def __init__(self, **kw):
     def test_setter(self):
 
         class Test(object):
-            def _patch_properties(self, mapping):
-                self._patched = mapping.copy()
+            def _patch_property(self, name, value):
+                self._patched = (name, value)
             do_re_mi = self._callFUT('solfege')
 
         test = Test()
         test.do_re_mi = 'Latido'
-        self.assertEqual(test._patched, {'solfege': 'Latido'})
+        self.assertEqual(test._patched, ('solfege', 'Latido'))
 
 
 class Test__base64_md5hash(unittest2.TestCase):