Skip to content

Commit c954b49

Browse files
doc cleanup and test fixes
1 parent 9e3daa7 commit c954b49

File tree

5 files changed

+55
-21
lines changed

5 files changed

+55
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2525
### Added
2626
* Add `__slots__` and `__eq__` to `FileVersionInfo` for memory usage optimization and ease of testing
2727
* Add support for SSE-C server-side encryption mode
28+
* Add support for `XDG_CONFIG_HOME` for determining the location of `SqliteAccountInfo` db file
2829

2930
### Changed
3031
* `BasicSyncEncryptionSettingsProvider` supports different settings sets for reading and writing

b2sdk/_v2/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from b2sdk.account_info.abstract import AbstractAccountInfo
3535
from b2sdk.account_info.in_memory import InMemoryAccountInfo
3636
from b2sdk.account_info.sqlite_account_info import SqliteAccountInfo
37-
from b2sdk.account_info.sqlite_account_info import B2_ACCOUNT_INFO_ENV_VAR, B2_ACCOUNT_INFO_DEFAULT_FILE
37+
from b2sdk.account_info.sqlite_account_info import B2_ACCOUNT_INFO_ENV_VAR, B2_ACCOUNT_INFO_DEFAULT_FILE, XDG_CONFIG_HOME_ENV_VAR
3838
from b2sdk.account_info.stub import StubAccountInfo
3939
from b2sdk.account_info.upload_url_pool import UploadUrlPool
4040
from b2sdk.account_info.upload_url_pool import UrlPoolAccountInfo

b2sdk/account_info/sqlite_account_info.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
B2_ACCOUNT_INFO_ENV_VAR = 'B2_ACCOUNT_INFO'
2626
B2_ACCOUNT_INFO_DEFAULT_FILE = '~/.b2_account_info'
27+
XDG_CONFIG_HOME_ENV_VAR = 'XDG_CONFIG_HOME'
2728

2829

2930
class SqliteAccountInfo(UrlPoolAccountInfo):
@@ -44,13 +45,14 @@ def __init__(self, file_name=None, last_upgrade_to_run=None):
4445
instead, use ``self.filename`` to get the actual resolved location.
4546
4647
SqliteAccountInfo currently checks locations in the following order:
48+
4749
* ``file_name``, if truthy
48-
* ``B2_ACCOUNT_INFO_ENV_VAR``'s value, if set
49-
* ``~/.b2_account_info``, if it exists
50-
* ``$XDG_CONFIG_HOME/b2/account_info``, if XDG_CONFIG_HOME is set
51-
* ``~/.b2_account_info``, as default
50+
* ``{B2_ACCOUNT_INFO_ENV_VAR}`` env var's value, if set
51+
* ``{B2_ACCOUNT_INFO_DEFAULT_FILE}``, if it exists
52+
* ``{XDG_CONFIG_HOME_ENV_VAR}/b2/account_info``, if ``{XDG_CONFIG_HOME_ENV_VAR}`` env var is set
53+
* ``{B2_ACCOUNT_INFO_DEFAULT_FILE}``, as default
5254
53-
If the directory ``$XDG_CONFIG_HOME/b2`` does not exist, it is created.
55+
If the directory ``{XDG_CONFIG_HOME_ENV_VAR}/b2`` does not exist (and is needed), it is created.
5456
5557
:param str file_name: The sqlite file to use; overrides the default.
5658
:param int last_upgrade_to_run: For testing only, override the auto-update on the db.
@@ -63,8 +65,8 @@ def __init__(self, file_name=None, last_upgrade_to_run=None):
6365
user_account_info_path = os.environ[B2_ACCOUNT_INFO_ENV_VAR]
6466
elif os.path.exists(os.path.expanduser(B2_ACCOUNT_INFO_DEFAULT_FILE)):
6567
user_account_info_path = B2_ACCOUNT_INFO_DEFAULT_FILE
66-
elif 'XDG_CONFIG_HOME' in os.environ:
67-
config_home = os.environ['XDG_CONFIG_HOME']
68+
elif XDG_CONFIG_HOME_ENV_VAR in os.environ:
69+
config_home = os.environ[XDG_CONFIG_HOME_ENV_VAR]
6870
user_account_info_path = os.path.join(config_home, 'b2', 'account_info')
6971
if not os.path.exists(os.path.join(config_home, 'b2')):
7072
os.makedirs(os.path.join(config_home, 'b2'), mode=0o755)
@@ -79,6 +81,16 @@ def __init__(self, file_name=None, last_upgrade_to_run=None):
7981
self._create_tables(conn, last_upgrade_to_run)
8082
super(SqliteAccountInfo, self).__init__()
8183

84+
# dirty trick to use parameters in the docstring
85+
if getattr(__init__, '__doc__', None): # don't break when using `python -oo`
86+
__init__.__doc__ = __init__.__doc__.format(
87+
**dict(
88+
B2_ACCOUNT_INFO_ENV_VAR=B2_ACCOUNT_INFO_ENV_VAR,
89+
B2_ACCOUNT_INFO_DEFAULT_FILE=B2_ACCOUNT_INFO_DEFAULT_FILE,
90+
XDG_CONFIG_HOME_ENV_VAR=XDG_CONFIG_HOME_ENV_VAR,
91+
)
92+
)
93+
8294
def _validate_database(self, last_upgrade_to_run=None):
8395
"""
8496
Make sure that the database is openable. Removes the file if it's not.

b2sdk/v1/account_info.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
logger = logging.getLogger(__name__)
1919

20+
2021
class OldAccountInfoMethods:
2122
def set_auth_data(
2223
self,

test/unit/account_info/test_account_info.py

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,28 @@
1818

1919
import pytest
2020

21-
from apiver_deps import AbstractAccountInfo, InMemoryAccountInfo, UploadUrlPool, SqliteAccountInfo, TempDir, B2_ACCOUNT_INFO_ENV_VAR
21+
from apiver_deps import (
22+
AbstractAccountInfo,
23+
InMemoryAccountInfo,
24+
UploadUrlPool,
25+
SqliteAccountInfo,
26+
TempDir,
27+
B2_ACCOUNT_INFO_ENV_VAR,
28+
XDG_CONFIG_HOME_ENV_VAR,
29+
)
2230
from apiver_deps_exception import CorruptAccountInfo, MissingAccountData
2331

2432
from .fixtures import *
2533

2634

35+
class WindowsSafeTempDir(TempDir):
36+
def __exit__(self, exc_type, exc_val, exc_tb):
37+
try:
38+
super().__exit__(exc_type, exc_val, exc_tb)
39+
except OSError:
40+
pass
41+
42+
2743
class TestAccountInfo:
2844
@pytest.fixture(autouse=True)
2945
def setup(self, account_info_factory, account_info_default_data):
@@ -292,11 +308,11 @@ def setUp(self, request):
292308
self.home = tempfile.mkdtemp()
293309

294310
yield
295-
try:
296-
os.unlink(self.db_path)
297-
except OSError:
298-
pass
299-
shutil.rmtree(self.home)
311+
for cleanup_method in [lambda: os.unlink(self.db_path), lambda: shutil.rmtree(self.home)]:
312+
try:
313+
cleanup_method
314+
except OSError:
315+
pass
300316

301317
def test_corrupted(self):
302318
"""
@@ -351,17 +367,19 @@ def test_uses_default(self):
351367
account_info = self._make_sqlite_account_info(
352368
env={
353369
'HOME': self.home,
370+
'USERPROFILE': self.home,
354371
}
355372
)
356373
actual_path = os.path.abspath(account_info.filename)
357374
assert os.path.join(self.home, '.b2_account_info') == actual_path
358375

359376
def test_uses_xdg_config_home(self, apiver):
360-
with TempDir() as d:
377+
with WindowsSafeTempDir() as d:
361378
account_info = self._make_sqlite_account_info(
362379
env={
363380
'HOME': self.home,
364-
'XDG_CONFIG_HOME': d,
381+
'USERPROFILE': self.home,
382+
XDG_CONFIG_HOME_ENV_VAR: d,
365383
}
366384
)
367385
if apiver in ['v0', 'v1']:
@@ -373,25 +391,27 @@ def test_uses_xdg_config_home(self, apiver):
373391
assert expected_path == actual_path
374392

375393
def test_uses_existing_file_and_ignores_xdg(self):
376-
with TempDir() as d:
394+
with WindowsSafeTempDir() as d:
377395
default_db_file_location = os.path.join(self.home, '.b2_account_info')
378396
open(default_db_file_location, 'a').close()
379397
account_info = self._make_sqlite_account_info(
380398
env={
381399
'HOME': self.home,
382-
'XDG_CONFIG_HOME': d,
400+
'USERPROFILE': self.home,
401+
XDG_CONFIG_HOME_ENV_VAR: d,
383402
}
384403
)
385-
assert not os.path.exists(os.path.join(d, 'b2'))
386404
actual_path = os.path.abspath(account_info.filename)
387405
assert default_db_file_location == actual_path
406+
assert not os.path.exists(os.path.join(d, 'b2'))
388407

389408
def test_account_info_env_var_overrides_xdg_config_home(self):
390-
with TempDir() as d:
409+
with WindowsSafeTempDir() as d:
391410
account_info = self._make_sqlite_account_info(
392411
env={
393412
'HOME': self.home,
394-
'XDG_CONFIG_HOME': d,
413+
'USERPROFILE': self.home,
414+
XDG_CONFIG_HOME_ENV_VAR: d,
395415
B2_ACCOUNT_INFO_ENV_VAR: os.path.join(d, 'b2_account_info'),
396416
}
397417
)

0 commit comments

Comments
 (0)