diff --git a/b2/_internal/b2v3/registry.py b/b2/_internal/b2v3/registry.py index 3017f2370..c099bfba2 100644 --- a/b2/_internal/b2v3/registry.py +++ b/b2/_internal/b2v3/registry.py @@ -26,6 +26,24 @@ def _initialize_b2_api(cls, args: argparse.Namespace, kwargs: dict) -> B2Api: return _get_b2api_for_profile(profile=args.profile, **kwargs) +def main() -> None: + # this is a copy of v4 `main()` but with custom console tool class + + ct = ConsoleTool(stdout=sys.stdout, stderr=sys.stderr) + exit_status = ct.run_command(sys.argv) + logger.info('\\\\ %s %s %s //', SEPARATOR, ('exit=%s' % exit_status).center(8), SEPARATOR) + + # I haven't tracked down the root cause yet, but in Python 2.7, the futures + # packages is hanging on exit sometimes, waiting for a thread to finish. + # This happens when using sync to upload files. + sys.stdout.flush() + sys.stderr.flush() + + logging.shutdown() + + os._exit(exit_status) + + class Ls(B2URIBucketNFolderNameArgMixin, BaseLs): """ {BASELS} diff --git a/b2/_internal/console_tool.py b/b2/_internal/console_tool.py index f01145a8b..48b0edb12 100644 --- a/b2/_internal/console_tool.py +++ b/b2/_internal/console_tool.py @@ -4265,7 +4265,9 @@ def _initialize_b2_api(cls, args: argparse.Namespace, kwargs: dict) -> B2Api: # here we initialize regular b2 api on disk, and check whether it matches # the keys from env vars; if they indeed match then there's no need to - # initialize in-memory account info cause it's already stored on disk + # initialize in-memory account info cause it's already stored on disk; + # beware that this has side effect of creating an empty account info file + # if it didn't exist before b2_api = _get_b2api_for_profile(profile=args.profile, **kwargs) key_id, key = get_keyid_and_key_from_env_vars() diff --git a/test/integration/conftest.py b/test/integration/conftest.py index e4d070996..4ad692871 100755 --- a/test/integration/conftest.py +++ b/test/integration/conftest.py @@ -100,13 +100,18 @@ def get_raw_cli_int_version(config) -> int | None: return None +def get_cli_int_version(config) -> int: + return get_raw_cli_int_version(config) or get_int_version(LATEST_STABLE_VERSION) + + @pytest.fixture(scope='session') -def apiver(request): - return f"v{get_cli_int_version(request.config)}" +def apiver_int(request): + return get_cli_int_version(request.config) -def get_cli_int_version(config) -> int: - return get_raw_cli_int_version(config) or get_int_version(LATEST_STABLE_VERSION) +@pytest.fixture(scope='session') +def apiver(apiver_int): + return f"v{apiver_int}" @pytest.hookimpl diff --git a/test/integration/test_b2_command_line.py b/test/integration/test_b2_command_line.py index 2a7b72dc5..0872c15f2 100755 --- a/test/integration/test_b2_command_line.py +++ b/test/integration/test_b2_command_line.py @@ -595,7 +595,7 @@ def test_rapid_bucket_operations(b2_tool): b2_tool.should_succeed(['delete-bucket', new_bucket_name]) -def test_account(b2_tool, cli_version): +def test_account(b2_tool, cli_version, apiver_int): with b2_tool.env_var_test_context: b2_tool.should_succeed(['clear-account']) bad_application_key = random_hex(len(b2_tool.application_key)) @@ -637,7 +637,17 @@ def test_account(b2_tool, cli_version): ['create-bucket', bucket_name, 'allPrivate', *b2_tool.get_bucket_info_args()] ) b2_tool.should_succeed(['delete-bucket', bucket_name]) - assert not os.path.exists(new_creds), 'sqlite file was created' + + assert os.path.exists(new_creds), 'sqlite file was not created' + account_info = SqliteAccountInfo(new_creds) + if apiver_int >= 4: + with pytest.raises(MissingAccountData): + account_info.get_application_key_id() + with pytest.raises(MissingAccountData): + account_info.get_application_key() + else: + assert account_info.get_application_key_id() == os.environ['B2_TEST_APPLICATION_KEY_ID'] + assert account_info.get_application_key() == os.environ['B2_TEST_APPLICATION_KEY'] os.environ.pop('B2_APPLICATION_KEY') os.environ.pop('B2_APPLICATION_KEY_ID')