diff --git a/b2sdk/_internal/account_info/stub.py b/b2sdk/_internal/account_info/stub.py index 925f05ec..c052ed3e 100644 --- a/b2sdk/_internal/account_info/stub.py +++ b/b2sdk/_internal/account_info/stub.py @@ -77,10 +77,10 @@ def get_bucket_name_or_none_from_bucket_id(self, bucket_id: str) -> str | None: return None def list_bucket_names_ids(self) -> list[tuple[str, str]]: - return list((bucket.bucket_name, bucket.bucket_id) for bucket in self.buckets.values()) + return list((bucket.bucket_name, bucket.id_) for bucket in self.buckets.values()) def save_bucket(self, bucket): - self.buckets[bucket.bucket_id] = bucket + self.buckets[bucket.id_] = bucket def remove_bucket_name(self, bucket_name): pass diff --git a/b2sdk/_internal/session.py b/b2sdk/_internal/session.py index a2a97d64..c05f0e04 100644 --- a/b2sdk/_internal/session.py +++ b/b2sdk/_internal/session.py @@ -73,10 +73,11 @@ def __init__( self.raw_api = api_config.raw_api_class(self.B2HTTP_CLASS(api_config)) if account_info is None: account_info = self.SQLITE_ACCOUNT_INFO_CLASS() - if cache is None: - cache = AuthInfoCache(account_info) if cache is None: - cache = DummyCache() + if account_info: + cache = AuthInfoCache(account_info) + else: + cache = DummyCache() self.account_info = account_info self.cache = cache diff --git a/b2sdk/v2/session.py b/b2sdk/v2/session.py index 0b90bcbd..137b7df8 100644 --- a/b2sdk/v2/session.py +++ b/b2sdk/v2/session.py @@ -13,12 +13,26 @@ from .b2http import B2Http from ._compat import _file_infos_rename +from .._internal import api_config as _api_config +from .._internal import cache as _cache +from .._internal.account_info import abstract as _abstract # Override to use legacy B2Http class B2Session(v3.B2Session): B2HTTP_CLASS = staticmethod(B2Http) + def __init__( + self, + account_info: _abstract.AbstractAccountInfo | None = None, + cache: _cache.AbstractCache | None = None, + api_config: _api_config.B2HttpApiConfig = _api_config.DEFAULT_HTTP_API_CONFIG + ): + if account_info is not None and cache is None: + # preserve legacy behavior https://github.com/Backblaze/b2-sdk-python/issues/497#issuecomment-2147461352 + cache = _cache.DummyCache() + super().__init__(account_info, cache, api_config) + @_file_infos_rename def upload_file( self, diff --git a/changelog.d/+stub_acct_info.fixed.md b/changelog.d/+stub_acct_info.fixed.md new file mode 100644 index 00000000..9540f904 --- /dev/null +++ b/changelog.d/+stub_acct_info.fixed.md @@ -0,0 +1 @@ +Fix bucket caching erroring out when using `StubAccountInfo`. diff --git a/changelog.d/497.changed.md b/changelog.d/497.changed.md new file mode 100644 index 00000000..0d70b788 --- /dev/null +++ b/changelog.d/497.changed.md @@ -0,0 +1,3 @@ +In `b2sdk.v3` the `B2Api` will always create `cache` from `AccountInfo` object, unless `cache` is provided explicitly. +The current stable `b2sdk.v2` remains unchanged, i.e. `DummyCache` is created by default if `account_info` was provided, but not `cache`. +Documentation for `b2sdk.v2` was updated with the new recommended usage, e.g. `B2Api(info, cache=AuthInfoCache(info))`, to achieve the same behavior as `b2sdk.v3`. diff --git a/doc/source/quick_start.rst b/doc/source/quick_start.rst index b3b296db..8c2fe592 100644 --- a/doc/source/quick_start.rst +++ b/doc/source/quick_start.rst @@ -12,7 +12,7 @@ Prepare b2sdk >>> from b2sdk.v2 import * >>> info = InMemoryAccountInfo() - >>> b2_api = B2Api(info) + >>> b2_api = B2Api(info, cache=AuthInfoCache(info)) >>> application_key_id = '4a5b6c7d8e9f' >>> application_key = '001b8e23c26ff6efb941e237deb182b9599a84bef7' >>> b2_api.authorize_account("production", application_key_id, application_key) diff --git a/test/unit/test_session.py b/test/unit/test_session.py index 0c26da93..1a1adabd 100644 --- a/test/unit/test_session.py +++ b/test/unit/test_session.py @@ -11,6 +11,8 @@ from unittest import mock +from apiver_deps import AuthInfoCache, B2Session, DummyCache, InMemoryAccountInfo + from .account_info.fixtures import * # noqa from .fixtures import * # noqa @@ -71,3 +73,16 @@ def test_clear_cache(self): self.b2_session.authorize_account('dev', '123', '456') assert self.b2_session.cache.clear.called is True + + +def test_session__with_in_memory_account_info(apiver_int): + memory_info = InMemoryAccountInfo() + b2_session = B2Session(account_info=memory_info,) + + assert b2_session.account_info is memory_info + + if apiver_int < 3: + assert isinstance(b2_session.cache, DummyCache) + else: + assert isinstance(b2_session.cache, AuthInfoCache) + assert b2_session.cache.info is memory_info