Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions packages/google-cloud-storage/google/cloud/storage/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ class Client(ClientWithProject):
(Optional) An API key. Mutually exclusive with any other credentials.
This parameter is an alias for setting `client_options.api_key` and
will supercede any api key set in the `client_options` parameter.

:type enable_bucket_metadata_cache: bool
:param enable_bucket_metadata_cache:
(Optional, default True) Enables the background bucket-metadata cache
(App-centric Observability / ACO). Setting this to False disables the
cache and the background ``storage.buckets.get`` probe it triggers on
object-level operations, for principals granted object-only IAM roles.
"""

SCOPE = (
Expand All @@ -146,6 +153,7 @@ def __init__(
extra_headers={},
*,
api_key=None,
enable_bucket_metadata_cache: bool = True,
):
self._base_connection = None

Expand Down Expand Up @@ -292,7 +300,10 @@ def __init__(
connection.extra_headers = extra_headers
self._connection = connection
self._batch_stack = _LocalStack()
self._bucket_metadata_cache = BucketMetadataCache(self)
self._enable_bucket_metadata_cache = enable_bucket_metadata_cache
self._bucket_metadata_cache = (
BucketMetadataCache(self) if enable_bucket_metadata_cache else None
)
Comment on lines +304 to +306

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Setting _bucket_metadata_cache to None when enable_bucket_metadata_cache is False can lead to AttributeErrors if other parts of the codebase (such as bucket operations or trace helpers) attempt to access its methods (e.g., get, set, clear) without checking for None. To prevent potential runtime crashes, consider using a No-Op cache implementation that conforms to the BucketMetadataCache interface but performs no operations, or add explicit None checks before all accesses to _bucket_metadata_cache across the codebase.

References
  1. Specifically enforce defensive programming: for languages that support nullable references (e.g., Go, Python, Java), ensure appropriate null/nil/None checks or other language-idiomatic guards exist before object property accesses.


def close(self):
"""Close the client and clear any cached metadata or active connections."""
Expand Down Expand Up @@ -1189,9 +1200,9 @@ def create_bucket(
predefined_default_object_acl = DefaultObjectACL.validate_predefined(
predefined_default_object_acl
)
query_params["predefinedDefaultObjectAcl"] = (
predefined_default_object_acl
)
query_params[
"predefinedDefaultObjectAcl"
] = predefined_default_object_acl

if user_project is not None:
query_params["userProject"] = user_project
Expand Down
26 changes: 26 additions & 0 deletions packages/google-cloud-storage/tests/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,32 @@ def _get_default_timeout():
def _make_one(self, *args, **kw):
return self._get_target_class()(*args, **kw)

def test_ctor_bucket_metadata_cache_enabled_by_default(self):
credentials = _make_credentials()
client = self._make_one(project="PROJECT", credentials=credentials)

self.assertIsNotNone(client._bucket_metadata_cache)

def test_ctor_bucket_metadata_cache_opt_out(self):
credentials = _make_credentials()
client = self._make_one(
project="PROJECT",
credentials=credentials,
enable_bucket_metadata_cache=False,
)

self.assertIsNone(client._bucket_metadata_cache)

def test_close_ok_with_disabled_bucket_metadata_cache(self):
credentials = _make_credentials()
client = self._make_one(
project="PROJECT",
credentials=credentials,
enable_bucket_metadata_cache=False,
)

client.close()

def test_ctor_connection_type(self):
from google.cloud._http import ClientInfo

Expand Down
Loading