Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion keyring/backends/Windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def priority(cls) -> float:
return 5

@staticmethod
def _compound_name(username, service):
def _compound_name(username: str | None, service: str) -> str:
return f'{username}@{service}'

def get_password(self, service, username):
Expand Down
20 changes: 13 additions & 7 deletions keyring/backends/chainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
discover passwords in each.
"""

from .. import backend
from .. import backend, credentials
from ..compat import properties
from . import fail

Expand All @@ -28,12 +28,12 @@ def priority(cls) -> float:
return 10 if len(cls.backends) > 1 else (fail.Keyring.priority - 1)

@properties.classproperty
def backends(cls):
def backends(cls) -> list[backend.KeyringBackend]:
"""
Discover all keyrings for chaining.
"""

def allow(keyring):
def allow(keyring: backend.KeyringBackend) -> bool:
limit = backend._limit or bool
return (
not isinstance(keyring, ChainerBackend)
Expand All @@ -44,28 +44,34 @@ def allow(keyring):
allowed = filter(allow, backend.get_all_keyring())
return sorted(allowed, key=backend.by_priority, reverse=True)

def get_password(self, service, username):
def get_password(self, service: str, username: str) -> str | None:
for keyring in self.backends:
password = keyring.get_password(service, username)
if password is not None:
return password
return None

def set_password(self, service, username, password):
def set_password(self, service: str, username: str, password: str) -> None:
for keyring in self.backends:
try:
return keyring.set_password(service, username, password)
except NotImplementedError:
pass

def delete_password(self, service, username):
def delete_password(self, service: str, username: str) -> None:
for keyring in self.backends:
try:
return keyring.delete_password(service, username)
except NotImplementedError:
pass

def get_credential(self, service, username):
def get_credential(
self,
service: str,
username: str | None,
) -> credentials.Credential | None:
for keyring in self.backends:
credential = keyring.get_credential(service, username)
if credential is not None:
return credential
return None
6 changes: 3 additions & 3 deletions keyring/testing/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
assert min(ord(char) for char in UNICODE_CHARS) > 127


def is_ascii_printable(s):
def is_ascii_printable(s: str) -> bool:
return all(32 <= ord(c) < 127 for c in s)


Expand All @@ -44,13 +44,13 @@ def cleanup(self):
for item in self.credentials_created:
self.keyring.delete_password(*item)

def set_password(self, service, username, password):
def set_password(self, service: str, username: str, password: str) -> None:
# set the password and save the result so the test runner can clean
# up after if necessary.
self.keyring.set_password(service, username, password)
self.credentials_created.add((service, username))

def check_set_get(self, service, username, password):
def check_set_get(self, service: str, username: str, password: str) -> None:
keyring = self.keyring

# for the non-existent password
Expand Down
2 changes: 1 addition & 1 deletion keyring/testing/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@ def Environ(**changes):
ALPHABET = string.ascii_letters + string.digits


def random_string(k, source=ALPHABET):
def random_string(k: int, source: str=ALPHABET) -> str:
"""Generate a random string with length <i>k</i>"""
return ''.join(random.choice(source) for _unused in range(k))