Commit 679eb6d
Remember which keyring backend was found, instead of searching every run (#37)
Left to itself, keyring works out which backend to use by loading every
backend that every installed package registers and keeping the best of
them. That search runs again on every invocation and is the single most
expensive thing a keycmd run does: measured here it is the difference
between 0.156s and 0.085s, and it grows with the number of packages
installed and with any backend that takes its time deciding it is not
viable.
The answer, though, is the same every time until the packages on the
machine change. So the new backend.py writes it down the first time a
run needs a credential and loads that backend by name afterwards, which
is the shortcut PYTHON_KEYRING_BACKEND buys without anyone having to
know the variable exists. Nothing to read, nothing to set: the second
run is simply faster than the first.
The note goes where the platform keeps files a program can afford to
lose -- %LOCALAPPDATA% on windows, ~/Library/Caches on macOS,
$XDG_CACHE_HOME on linux -- and holds one line, and is trusted only as
far as it can be checked:
- is_backend_name keeps anything that is not a dotted class name from
reaching an import, so a file that has been truncated or scribbled in
is worth no more than a search
- a name that no longer loads sends the run back to searching and is
replaced. load_keyring asks the class for its priority on the way,
which is how keyring itself decides a backend is viable, so an
uninstalled backend and one whose daemon stopped are both caught
- backend_name looks through the chainer, which is not a backend but the
search wearing one's clothes; writing that down would leave the search
in place, so the backend it would have reached first is written instead
- PYTHON_KEYRING_BACKEND outranks the note and is never written over
- a search that found nothing is not an answer, and is not remembered
What keycmd cannot notice by itself is a backend that still loads but is
no longer the one you want, so the two steps are also available on
purpose:
keycmd --detect-backend # search now, and remember what turns up
keycmd --reset-backend # forget it, so the next run searches again
Two ways of ending up with no backend used to reach the user as a
traceback and are now errors that say what to do: keyring settling on
fail.Keyring, which raises on the first lookup and which inside a distro
points at the WSL section of the README, and a PYTHON_KEYRING_BACKEND
that cannot be loaded. logs.error grew the hint lines those need.
keyring stays out of the import path of a run that looks up no
credential: backend.py reaches for it inside the functions that need it,
the way creds.py used to, and its own name only appears at module level
under TYPE_CHECKING.
Claude-Session: https://claude.ai/code/session_01CRYugGcVh3wvC5a5pzwKU3
Co-authored-by: Claude <noreply@anthropic.com>1 parent 479415e commit 679eb6d
10 files changed
Lines changed: 768 additions & 24 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
| 33 | + | |
32 | 34 | | |
33 | 35 | | |
34 | 36 | | |
35 | 37 | | |
36 | | - | |
| 38 | + | |
37 | 39 | | |
38 | 40 | | |
39 | 41 | | |
40 | | - | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
41 | 45 | | |
42 | 46 | | |
43 | 47 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
157 | 157 | | |
158 | 158 | | |
159 | 159 | | |
160 | | - | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
161 | 163 | | |
162 | 164 | | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
167 | | - | |
168 | | - | |
169 | | - | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
170 | 176 | | |
171 | 177 | | |
172 | 178 | | |
| |||
401 | 407 | | |
402 | 408 | | |
403 | 409 | | |
404 | | - | |
| 410 | + | |
405 | 411 | | |
406 | 412 | | |
407 | 413 | | |
| |||
419 | 425 | | |
420 | 426 | | |
421 | 427 | | |
422 | | - | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
423 | 452 | | |
424 | 453 | | |
425 | 454 | | |
426 | 455 | | |
427 | 456 | | |
428 | 457 | | |
429 | | - | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
430 | 472 | | |
431 | 473 | | |
432 | 474 | | |
| |||
0 commit comments