/
niceSOFT
/
python3-hatchling
Обзор
Документация
Войти
/
niceSOFT
/
python3-hatchling
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/hatch/publish/auth.py
116 строк
4 KB
Valentin Oliver Melberg Loftsson
Pass repo URL to `keyring` instead of repo name (#2146)
09 янв 2026, 01:55
Не верифицирован
09 янв 2026, 01:55
8783049
Код
Авторство
О чём код?
from __future__ import annotations from hatch.utils.fs import Path class AuthenticationCredentials: def __init__( self, app, cache_dir: Path, options: dict, repo: str, repo_config: dict[str, str], ): self._app = app self._pwu_path = cache_dir / "previous_working_users.json" self._options = options self._repo = repo self._repo_config = repo_config self.__username: str | None = None self.__password: str | None = None self.__username_was_read = False self.__password_was_read = False self.__pwu_data: dict[str, str] = {} @property def password(self) -> str: if self.__password is None: self.__password = self.__get_password() return self.__password @property def username(self) -> str: if self.__username is None: self.__username = self.__get_username() return self.__username def __get_password(self) -> str: # this method doesn't consider .pypirc as the __password attribute would have # been set when it was looked up during username retrieval password = self._options.get("auth") or self._repo_config.get("auth") if password is not None: return password import keyring keyring_service = self._repo_config["url"] password = keyring.get_password(keyring_service, self.username) if password is not None: return password if self._options["no_prompt"]: self._app.abort("Missing required option: auth") self.__password_was_read = True return self._app.prompt("Password / Token", hide_input=True) def __get_username(self) -> str: username = ( self._options.get("user") or self._repo_config.get("user") or self._read_pypirc() or self._read_previous_working_user_data() ) if username is not None: return username if self._options["no_prompt"]: self._app.abort("Missing required option: user") self.__username_was_read = True return self._app.prompt(f"Username for '{self._repo_config['url']}' [__token__]") or "__token__" def _read_previous_working_user_data(self) -> str | None: if self._pwu_path.is_file(): contents = self._pwu_path.read_text() if contents: import json self.__pwu_data = json.loads(contents) return self.__pwu_data.get(self._repo) def _read_pypirc(self) -> str | None: import configparser pypirc = configparser.ConfigParser() pypirc.read(Path.home() / ".pypirc") repo = self._repo or "pypi" if pypirc.has_section(repo): self.__password = pypirc.get(section=repo, option="password", fallback=None) return pypirc.get(section=repo, option="username", fallback=None) repo_url = self._repo_config["url"] for section in pypirc.sections(): if pypirc.get(section=section, option="repository", fallback=None) == repo_url: self.__password = pypirc.get(section=section, option="password", fallback=None) return pypirc.get(section=section, option="username", fallback=None) return None def write_updated_data(self): if self.__username_was_read: import json self.__pwu_data[self._repo] = self.__username self._pwu_path.ensure_parent_dir_exists() self._pwu_path.write_text(json.dumps(self.__pwu_data)) if self.__password_was_read: import keyring keyring_service = self._repo_config["url"] keyring.set_password(keyring_service, self.__username, self.__password)