Repository: jaraco/keyring

Issue:
Should third party keyring backends use keyringrc.cfg, or use their own config file?
I'm using the `keyrings.codeartifact` backend, which expects its configuration to be stored in keyring's `keyringrc.cfg` file:

- Code: https://github.com/jmkeyes/keyrings.codeartifact/blob/1.2.0/keyrings/codeartifact.py#L30
- Documentation: https://github.com/jmkeyes/keyrings.codeartifact/tree/1.2.0?tab=readme-ov-file#config

Is this supported? Or should `keyrings.codeartifact` look for its own config file? Reusing the config file feels a little odd to me, as there's potential for naming conflicts, but maybe that's unlikely if folks are reasonable about naming.

If this *is* supported, then I think keyring is overly strict in how it parses its config file:

- If the config file doesn't exist, then it [silently does nothing](https://github.com/jaraco/keyring/blob/v25.2.1/keyring/core.py#L166). Great.
- If the config file does exist, but there isn't a `backend.default-keyring` setting, then [it raises `configparser.NoOptionError`](https://github.com/jaraco/keyring/blob/v25.2.1/keyring/core.py#L174C19-L174C45), which gets [logged as a "Keyring config file contains incorrect values" warning](https://github.com/jaraco/keyring/blob/v25.2.1/keyring/core.py#L178-L181).

I can work around this by explicitly setting the `backend.default-keyring` setting, but I'd rather not set a configuration option that I don't have to just to avoid a warning.

Discussion:
@jaraco: To my recollection, it hasn't been explicitly supported or not supported. I suspect other backends like keyrings.alt re-use the same `platform` module for configuration, so I'm not surprised that other backends are using it. I'm inclined to say it should be supported.

And I agree with your assessment - adding unrelated config shouldn't break the behavior compared to an empty config.

Are you willing/interested to work on a fix?@jfly: > Are you willing/interested to work on a fix?

Sure! How does this look? https://github.com/jaraco/keyring/pull/702

Solution patch:
diff --git a/keyring/core.py b/keyring/core.py
index bbdb3e47..da47e02e 100644
--- a/keyring/core.py
+++ b/keyring/core.py
@@ -178,7 +178,7 @@ def load_config() -> typing.Optional[backend.KeyringBackend]:
         if config.has_section("backend"):
             keyring_name = config.get("backend", "default-keyring").strip()
         else:
-            raise configparser.NoOptionError('backend', 'default-keyring')
+            return None
 
     except (configparser.NoOptionError, ImportError):
         logger = logging.getLogger('keyring')
diff --git a/newsfragments/682.feature.rst b/newsfragments/682.feature.rst
new file mode 100644
index 00000000..3ed61640
--- /dev/null
+++ b/newsfragments/682.feature.rst
@@ -0,0 +1 @@
+Avoid logging a warning when config does not specify a backend.


Test patch:
diff --git a/tests/test_core.py b/tests/test_core.py
index 083bcfd5..eb29a4b0 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -25,6 +25,12 @@ def test_load_config_missing(caplog, config_path):
     assert not caplog.records
 
 
+def test_load_empty_config(caplog, config_path):
+    config_path.write_text("", encoding='utf-8')
+    assert keyring.core.load_config() is None
+    assert not caplog.records
+
+
 fail_config = textwrap.dedent(
     """
     [backend]