We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
fix: remove exception when keyring is locked 
# Pull Request Check List

Resolves: #1917

<!-- This is just a reminder about the most common mistakes. Please make sure that you tick all *appropriate* boxes.  But please read our [contribution guide](https://python-poetry.org/docs/contributing/) at least once, it will save you unnecessary review cycles! -->

- [ ] Added **tests** for changed code.
- [ ] Updated **documentation** for changed code.

<!-- If you have *any* questions to *any* of the points above, just **submit and ask**!  This checklist is here to *help* you, not to deter you from contributing! -->


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/poetry/utils/password_manager.py`
Content:
```
1 from __future__ import annotations
2 
3 import dataclasses
4 import logging
5 
6 from contextlib import suppress
7 from typing import TYPE_CHECKING
8 
9 
10 if TYPE_CHECKING:
11     from poetry.config.config import Config
12 
13 logger = logging.getLogger(__name__)
14 
15 
16 class PasswordManagerError(Exception):
17     pass
18 
19 
20 class PoetryKeyringError(Exception):
21     pass
22 
23 
24 @dataclasses.dataclass
25 class HTTPAuthCredential:
26     username: str | None = dataclasses.field(default=None)
27     password: str | None = dataclasses.field(default=None)
28 
29 
30 class PoetryKeyring:
31     def __init__(self, namespace: str) -> None:
32         self._namespace = namespace
33         self._is_available = True
34 
35         self._check()
36 
37     def is_available(self) -> bool:
38         return self._is_available
39 
40     def get_credential(
41         self, *names: str, username: str | None = None
42     ) -> HTTPAuthCredential:
43         default = HTTPAuthCredential(username=username, password=None)
44 
45         if not self.is_available():
46             return default
47 
48         import keyring
49 
50         for name in names:
51             credential = keyring.get_credential(name, username)
52             if credential:
53                 return HTTPAuthCredential(
54                     username=credential.username, password=credential.password
55                 )
56 
57         return default
58 
59     def get_password(self, name: str, username: str) -> str | None:
60         if not self.is_available():
61             return None
62 
63         import keyring
64         import keyring.errors
65 
66         name = self.get_entry_name(name)
67 
68         try:
69             return keyring.get_password(name, username)
70         except (RuntimeError, keyring.errors.KeyringError):
71             raise PoetryKeyringError(
72                 f"Unable to retrieve the password for {name} from the key ring"
73             )
74 
75     def set_password(self, name: str, username: str, password: str) -> None:
76         if not self.is_available():
77             return
78 
79         import keyring
80         import keyring.errors
81 
82         name = self.get_entry_name(name)
83 
84         try:
85             keyring.set_password(name, username, password)
86         except (RuntimeError, keyring.errors.KeyringError) as e:
87             raise PoetryKeyringError(
88                 f"Unable to store the password for {name} in the key ring: {e}"
89             )
90 
91     def delete_password(self, name: str, username: str) -> None:
92         if not self.is_available():
93             return
94 
95         import keyring.errors
96 
97         name = self.get_entry_name(name)
98 
99         try:
100             keyring.delete_password(name, username)
101         except (RuntimeError, keyring.errors.KeyringError):
102             raise PoetryKeyringError(
103                 f"Unable to delete the password for {name} from the key ring"
104             )
105 
106     def get_entry_name(self, name: str) -> str:
107         return f"{self._namespace}-{name}"
108 
109     def _check(self) -> None:
110         try:
111             import keyring
112         except ImportError as e:
113             logger.debug("An error occurred while importing keyring: %s", e)
114             self._is_available = False
115 
116             return
117 
118         backend = keyring.get_keyring()
119         name = backend.name.split(" ")[0]
120         if name in ("fail", "null"):
121             logger.debug("No suitable keyring backend found")
122             self._is_available = False
123         elif "plaintext" in backend.name.lower():
124             logger.debug("Only a plaintext keyring backend is available. Not using it.")
125             self._is_available = False
126         elif name == "chainer":
127             try:
128                 import keyring.backend
129 
130                 backends = keyring.backend.get_all_keyring()
131 
132                 self._is_available = any(
133                     b.name.split(" ")[0] not in ["chainer", "fail", "null"]
134                     and "plaintext" not in b.name.lower()
135                     for b in backends
136                 )
137             except ImportError:
138                 self._is_available = False
139 
140         if not self._is_available:
141             logger.debug("No suitable keyring backends were found")
142 
143 
144 class PasswordManager:
145     def __init__(self, config: Config) -> None:
146         self._config = config
147         self._keyring: PoetryKeyring | None = None
148 
149     @property
150     def keyring(self) -> PoetryKeyring:
151         if self._keyring is None:
152             self._keyring = PoetryKeyring("poetry-repository")
153 
154             if not self._keyring.is_available():
155                 logger.debug(
156                     "<warning>Keyring is not available, credentials will be stored and "
157                     "retrieved from configuration files as plaintext.</>"
158                 )
159 
160         return self._keyring
161 
162     @staticmethod
163     def warn_plaintext_credentials_stored() -> None:
164         logger.warning("Using a plaintext file to store credentials")
165 
166     def set_pypi_token(self, name: str, token: str) -> None:
167         if not self.keyring.is_available():
168             self.warn_plaintext_credentials_stored()
169             self._config.auth_config_source.add_property(f"pypi-token.{name}", token)
170         else:
171             self.keyring.set_password(name, "__token__", token)
172 
173     def get_pypi_token(self, repo_name: str) -> str | None:
174         """Get PyPi token.
175 
176         First checks the environment variables for a token,
177         then the configured username/password and the
178         available keyring.
179 
180         :param repo_name:  Name of repository.
181         :return: Returns a token as a string if found, otherwise None.
182         """
183         token: str | None = self._config.get(f"pypi-token.{repo_name}")
184         if token:
185             return token
186 
187         return self.keyring.get_password(repo_name, "__token__")
188 
189     def delete_pypi_token(self, name: str) -> None:
190         if not self.keyring.is_available():
191             return self._config.auth_config_source.remove_property(f"pypi-token.{name}")
192 
193         self.keyring.delete_password(name, "__token__")
194 
195     def get_http_auth(self, name: str) -> dict[str, str | None] | None:
196         username = self._config.get(f"http-basic.{name}.username")
197         password = self._config.get(f"http-basic.{name}.password")
198         if not username and not password:
199             return None
200 
201         if not password:
202             password = self.keyring.get_password(name, username)
203 
204         return {
205             "username": username,
206             "password": password,
207         }
208 
209     def set_http_password(self, name: str, username: str, password: str) -> None:
210         auth = {"username": username}
211 
212         if not self.keyring.is_available():
213             self.warn_plaintext_credentials_stored()
214             auth["password"] = password
215         else:
216             self.keyring.set_password(name, username, password)
217 
218         self._config.auth_config_source.add_property(f"http-basic.{name}", auth)
219 
220     def delete_http_password(self, name: str) -> None:
221         auth = self.get_http_auth(name)
222         if not auth:
223             return
224 
225         username = auth.get("username")
226         if username is None:
227             return
228 
229         with suppress(PoetryKeyringError):
230             self.keyring.delete_password(name, username)
231 
232         self._config.auth_config_source.remove_property(f"http-basic.{name}")
233
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/poetry/utils/password_manager.py b/src/poetry/utils/password_manager.py
--- a/src/poetry/utils/password_manager.py
+++ b/src/poetry/utils/password_manager.py
@@ -47,8 +47,18 @@
 
         import keyring
 
+        from keyring.errors import KeyringError
+        from keyring.errors import KeyringLocked
+
         for name in names:
-            credential = keyring.get_credential(name, username)
+            credential = None
+            try:
+                credential = keyring.get_credential(name, username)
+            except KeyringLocked:
+                logger.debug("Keyring %s is locked", name)
+            except (KeyringError, RuntimeError):
+                logger.debug("Accessing keyring %s failed", name, exc_info=True)
+
             if credential:
                 return HTTPAuthCredential(
                     username=credential.username, password=credential.password

{"golden_diff": "diff --git a/src/poetry/utils/password_manager.py b/src/poetry/utils/password_manager.py\n--- a/src/poetry/utils/password_manager.py\n+++ b/src/poetry/utils/password_manager.py\n@@ -47,8 +47,18 @@\n \n         import keyring\n \n+        from keyring.errors import KeyringError\n+        from keyring.errors import KeyringLocked\n+\n         for name in names:\n-            credential = keyring.get_credential(name, username)\n+            credential = None\n+            try:\n+                credential = keyring.get_credential(name, username)\n+            except KeyringLocked:\n+                logger.debug(\"Keyring %s is locked\", name)\n+            except (KeyringError, RuntimeError):\n+                logger.debug(\"Accessing keyring %s failed\", name, exc_info=True)\n+\n             if credential:\n                 return HTTPAuthCredential(\n                     username=credential.username, password=credential.password\n", "issue": "fix: remove exception when keyring is locked \n# Pull Request Check List\r\n\r\nResolves: #1917\r\n\r\n<!-- This is just a reminder about the most common mistakes. Please make sure that you tick all *appropriate* boxes.  But please read our [contribution guide](https://python-poetry.org/docs/contributing/) at least once, it will save you unnecessary review cycles! -->\r\n\r\n- [ ] Added **tests** for changed code.\r\n- [ ] Updated **documentation** for changed code.\r\n\r\n<!-- If you have *any* questions to *any* of the points above, just **submit and ask**!  This checklist is here to *help* you, not to deter you from contributing! -->\r\n\n", "before_files": [{"content": "from __future__ import annotations\n\nimport dataclasses\nimport logging\n\nfrom contextlib import suppress\nfrom typing import TYPE_CHECKING\n\n\nif TYPE_CHECKING:\n    from poetry.config.config import Config\n\nlogger = logging.getLogger(__name__)\n\n\nclass PasswordManagerError(Exception):\n    pass\n\n\nclass PoetryKeyringError(Exception):\n    pass\n\n\n@dataclasses.dataclass\nclass HTTPAuthCredential:\n    username: str | None = dataclasses.field(default=None)\n    password: str | None = dataclasses.field(default=None)\n\n\nclass PoetryKeyring:\n    def __init__(self, namespace: str) -> None:\n        self._namespace = namespace\n        self._is_available = True\n\n        self._check()\n\n    def is_available(self) -> bool:\n        return self._is_available\n\n    def get_credential(\n        self, *names: str, username: str | None = None\n    ) -> HTTPAuthCredential:\n        default = HTTPAuthCredential(username=username, password=None)\n\n        if not self.is_available():\n            return default\n\n        import keyring\n\n        for name in names:\n            credential = keyring.get_credential(name, username)\n            if credential:\n                return HTTPAuthCredential(\n                    username=credential.username, password=credential.password\n                )\n\n        return default\n\n    def get_password(self, name: str, username: str) -> str | None:\n        if not self.is_available():\n            return None\n\n        import keyring\n        import keyring.errors\n\n        name = self.get_entry_name(name)\n\n        try:\n            return keyring.get_password(name, username)\n        except (RuntimeError, keyring.errors.KeyringError):\n            raise PoetryKeyringError(\n                f\"Unable to retrieve the password for {name} from the key ring\"\n            )\n\n    def set_password(self, name: str, username: str, password: str) -> None:\n        if not self.is_available():\n            return\n\n        import keyring\n        import keyring.errors\n\n        name = self.get_entry_name(name)\n\n        try:\n            keyring.set_password(name, username, password)\n        except (RuntimeError, keyring.errors.KeyringError) as e:\n            raise PoetryKeyringError(\n                f\"Unable to store the password for {name} in the key ring: {e}\"\n            )\n\n    def delete_password(self, name: str, username: str) -> None:\n        if not self.is_available():\n            return\n\n        import keyring.errors\n\n        name = self.get_entry_name(name)\n\n        try:\n            keyring.delete_password(name, username)\n        except (RuntimeError, keyring.errors.KeyringError):\n            raise PoetryKeyringError(\n                f\"Unable to delete the password for {name} from the key ring\"\n            )\n\n    def get_entry_name(self, name: str) -> str:\n        return f\"{self._namespace}-{name}\"\n\n    def _check(self) -> None:\n        try:\n            import keyring\n        except ImportError as e:\n            logger.debug(\"An error occurred while importing keyring: %s\", e)\n            self._is_available = False\n\n            return\n\n        backend = keyring.get_keyring()\n        name = backend.name.split(\" \")[0]\n        if name in (\"fail\", \"null\"):\n            logger.debug(\"No suitable keyring backend found\")\n            self._is_available = False\n        elif \"plaintext\" in backend.name.lower():\n            logger.debug(\"Only a plaintext keyring backend is available. Not using it.\")\n            self._is_available = False\n        elif name == \"chainer\":\n            try:\n                import keyring.backend\n\n                backends = keyring.backend.get_all_keyring()\n\n                self._is_available = any(\n                    b.name.split(\" \")[0] not in [\"chainer\", \"fail\", \"null\"]\n                    and \"plaintext\" not in b.name.lower()\n                    for b in backends\n                )\n            except ImportError:\n                self._is_available = False\n\n        if not self._is_available:\n            logger.debug(\"No suitable keyring backends were found\")\n\n\nclass PasswordManager:\n    def __init__(self, config: Config) -> None:\n        self._config = config\n        self._keyring: PoetryKeyring | None = None\n\n    @property\n    def keyring(self) -> PoetryKeyring:\n        if self._keyring is None:\n            self._keyring = PoetryKeyring(\"poetry-repository\")\n\n            if not self._keyring.is_available():\n                logger.debug(\n                    \"<warning>Keyring is not available, credentials will be stored and \"\n                    \"retrieved from configuration files as plaintext.</>\"\n                )\n\n        return self._keyring\n\n    @staticmethod\n    def warn_plaintext_credentials_stored() -> None:\n        logger.warning(\"Using a plaintext file to store credentials\")\n\n    def set_pypi_token(self, name: str, token: str) -> None:\n        if not self.keyring.is_available():\n            self.warn_plaintext_credentials_stored()\n            self._config.auth_config_source.add_property(f\"pypi-token.{name}\", token)\n        else:\n            self.keyring.set_password(name, \"__token__\", token)\n\n    def get_pypi_token(self, repo_name: str) -> str | None:\n        \"\"\"Get PyPi token.\n\n        First checks the environment variables for a token,\n        then the configured username/password and the\n        available keyring.\n\n        :param repo_name:  Name of repository.\n        :return: Returns a token as a string if found, otherwise None.\n        \"\"\"\n        token: str | None = self._config.get(f\"pypi-token.{repo_name}\")\n        if token:\n            return token\n\n        return self.keyring.get_password(repo_name, \"__token__\")\n\n    def delete_pypi_token(self, name: str) -> None:\n        if not self.keyring.is_available():\n            return self._config.auth_config_source.remove_property(f\"pypi-token.{name}\")\n\n        self.keyring.delete_password(name, \"__token__\")\n\n    def get_http_auth(self, name: str) -> dict[str, str | None] | None:\n        username = self._config.get(f\"http-basic.{name}.username\")\n        password = self._config.get(f\"http-basic.{name}.password\")\n        if not username and not password:\n            return None\n\n        if not password:\n            password = self.keyring.get_password(name, username)\n\n        return {\n            \"username\": username,\n            \"password\": password,\n        }\n\n    def set_http_password(self, name: str, username: str, password: str) -> None:\n        auth = {\"username\": username}\n\n        if not self.keyring.is_available():\n            self.warn_plaintext_credentials_stored()\n            auth[\"password\"] = password\n        else:\n            self.keyring.set_password(name, username, password)\n\n        self._config.auth_config_source.add_property(f\"http-basic.{name}\", auth)\n\n    def delete_http_password(self, name: str) -> None:\n        auth = self.get_http_auth(name)\n        if not auth:\n            return\n\n        username = auth.get(\"username\")\n        if username is None:\n            return\n\n        with suppress(PoetryKeyringError):\n            self.keyring.delete_password(name, username)\n\n        self._config.auth_config_source.remove_property(f\"http-basic.{name}\")\n", "path": "src/poetry/utils/password_manager.py"}], "after_files": [{"content": "from __future__ import annotations\n\nimport dataclasses\nimport logging\n\nfrom contextlib import suppress\nfrom typing import TYPE_CHECKING\n\n\nif TYPE_CHECKING:\n    from poetry.config.config import Config\n\nlogger = logging.getLogger(__name__)\n\n\nclass PasswordManagerError(Exception):\n    pass\n\n\nclass PoetryKeyringError(Exception):\n    pass\n\n\n@dataclasses.dataclass\nclass HTTPAuthCredential:\n    username: str | None = dataclasses.field(default=None)\n    password: str | None = dataclasses.field(default=None)\n\n\nclass PoetryKeyring:\n    def __init__(self, namespace: str) -> None:\n        self._namespace = namespace\n        self._is_available = True\n\n        self._check()\n\n    def is_available(self) -> bool:\n        return self._is_available\n\n    def get_credential(\n        self, *names: str, username: str | None = None\n    ) -> HTTPAuthCredential:\n        default = HTTPAuthCredential(username=username, password=None)\n\n        if not self.is_available():\n            return default\n\n        import keyring\n\n        from keyring.errors import KeyringError\n        from keyring.errors import KeyringLocked\n\n        for name in names:\n            credential = None\n            try:\n                credential = keyring.get_credential(name, username)\n            except KeyringLocked:\n                logger.debug(\"Keyring %s is locked\", name)\n            except (KeyringError, RuntimeError):\n                logger.debug(\"Accessing keyring %s failed\", name, exc_info=True)\n\n            if credential:\n                return HTTPAuthCredential(\n                    username=credential.username, password=credential.password\n                )\n\n        return default\n\n    def get_password(self, name: str, username: str) -> str | None:\n        if not self.is_available():\n            return None\n\n        import keyring\n        import keyring.errors\n\n        name = self.get_entry_name(name)\n\n        try:\n            return keyring.get_password(name, username)\n        except (RuntimeError, keyring.errors.KeyringError):\n            raise PoetryKeyringError(\n                f\"Unable to retrieve the password for {name} from the key ring\"\n            )\n\n    def set_password(self, name: str, username: str, password: str) -> None:\n        if not self.is_available():\n            return\n\n        import keyring\n        import keyring.errors\n\n        name = self.get_entry_name(name)\n\n        try:\n            keyring.set_password(name, username, password)\n        except (RuntimeError, keyring.errors.KeyringError) as e:\n            raise PoetryKeyringError(\n                f\"Unable to store the password for {name} in the key ring: {e}\"\n            )\n\n    def delete_password(self, name: str, username: str) -> None:\n        if not self.is_available():\n            return\n\n        import keyring.errors\n\n        name = self.get_entry_name(name)\n\n        try:\n            keyring.delete_password(name, username)\n        except (RuntimeError, keyring.errors.KeyringError):\n            raise PoetryKeyringError(\n                f\"Unable to delete the password for {name} from the key ring\"\n            )\n\n    def get_entry_name(self, name: str) -> str:\n        return f\"{self._namespace}-{name}\"\n\n    def _check(self) -> None:\n        try:\n            import keyring\n        except ImportError as e:\n            logger.debug(\"An error occurred while importing keyring: %s\", e)\n            self._is_available = False\n\n            return\n\n        backend = keyring.get_keyring()\n        name = backend.name.split(\" \")[0]\n        if name in (\"fail\", \"null\"):\n            logger.debug(\"No suitable keyring backend found\")\n            self._is_available = False\n        elif \"plaintext\" in backend.name.lower():\n            logger.debug(\"Only a plaintext keyring backend is available. Not using it.\")\n            self._is_available = False\n        elif name == \"chainer\":\n            try:\n                import keyring.backend\n\n                backends = keyring.backend.get_all_keyring()\n\n                self._is_available = any(\n                    b.name.split(\" \")[0] not in [\"chainer\", \"fail\", \"null\"]\n                    and \"plaintext\" not in b.name.lower()\n                    for b in backends\n                )\n            except ImportError:\n                self._is_available = False\n\n        if not self._is_available:\n            logger.debug(\"No suitable keyring backends were found\")\n\n\nclass PasswordManager:\n    def __init__(self, config: Config) -> None:\n        self._config = config\n        self._keyring: PoetryKeyring | None = None\n\n    @property\n    def keyring(self) -> PoetryKeyring:\n        if self._keyring is None:\n            self._keyring = PoetryKeyring(\"poetry-repository\")\n\n            if not self._keyring.is_available():\n                logger.debug(\n                    \"<warning>Keyring is not available, credentials will be stored and \"\n                    \"retrieved from configuration files as plaintext.</>\"\n                )\n\n        return self._keyring\n\n    @staticmethod\n    def warn_plaintext_credentials_stored() -> None:\n        logger.warning(\"Using a plaintext file to store credentials\")\n\n    def set_pypi_token(self, name: str, token: str) -> None:\n        if not self.keyring.is_available():\n            self.warn_plaintext_credentials_stored()\n            self._config.auth_config_source.add_property(f\"pypi-token.{name}\", token)\n        else:\n            self.keyring.set_password(name, \"__token__\", token)\n\n    def get_pypi_token(self, repo_name: str) -> str | None:\n        \"\"\"Get PyPi token.\n\n        First checks the environment variables for a token,\n        then the configured username/password and the\n        available keyring.\n\n        :param repo_name:  Name of repository.\n        :return: Returns a token as a string if found, otherwise None.\n        \"\"\"\n        token: str | None = self._config.get(f\"pypi-token.{repo_name}\")\n        if token:\n            return token\n\n        return self.keyring.get_password(repo_name, \"__token__\")\n\n    def delete_pypi_token(self, name: str) -> None:\n        if not self.keyring.is_available():\n            return self._config.auth_config_source.remove_property(f\"pypi-token.{name}\")\n\n        self.keyring.delete_password(name, \"__token__\")\n\n    def get_http_auth(self, name: str) -> dict[str, str | None] | None:\n        username = self._config.get(f\"http-basic.{name}.username\")\n        password = self._config.get(f\"http-basic.{name}.password\")\n        if not username and not password:\n            return None\n\n        if not password:\n            password = self.keyring.get_password(name, username)\n\n        return {\n            \"username\": username,\n            \"password\": password,\n        }\n\n    def set_http_password(self, name: str, username: str, password: str) -> None:\n        auth = {\"username\": username}\n\n        if not self.keyring.is_available():\n            self.warn_plaintext_credentials_stored()\n            auth[\"password\"] = password\n        else:\n            self.keyring.set_password(name, username, password)\n\n        self._config.auth_config_source.add_property(f\"http-basic.{name}\", auth)\n\n    def delete_http_password(self, name: str) -> None:\n        auth = self.get_http_auth(name)\n        if not auth:\n            return\n\n        username = auth.get(\"username\")\n        if username is None:\n            return\n\n        with suppress(PoetryKeyringError):\n            self.keyring.delete_password(name, username)\n\n        self._config.auth_config_source.remove_property(f\"http-basic.{name}\")\n", "path": "src/poetry/utils/password_manager.py"}]}