@property@functools.lru_cache()defusername(self)->Optional[str]:ifcast(str,self.config["repository"]).startswith((utils.DEFAULT_REPOSITORY,utils.TEST_REPOSITORY)):# As of 2024-01-01, PyPI requires API tokens for uploads, meaning# that the username is invariant.return"__token__"returnutils.get_userpass_value(self.input.username,self.config,key="username",prompt_strategy=self.username_from_keyring_or_prompt,)@property@functools.lru_cache()defpassword(self)->Optional[str]:returnutils.get_userpass_value(self.input.password,self.config,key="password",prompt_strategy=self.password_from_keyring_or_prompt,)@propertydefsystem(self)->Optional[str]:returnself.config["repository"]
[docs]defget_username_from_keyring(self)->Optional[str]:try:system=cast(str,self.system)logger.info("Querying keyring for username")creds=keyring.get_credential(system,None)ifcreds:returncast(str,creds.username)exceptAttributeError:# To support keyring prior to 15.2passexceptExceptionasexc:logger.warning("Error getting username from keyring",exc_info=exc)returnNone
[docs]defget_password_from_keyring(self)->Optional[str]:try:system=cast(str,self.system)username=cast(str,self.username)logger.info("Querying keyring for password")returncast(str,keyring.get_password(system,username))exceptExceptionasexc:logger.warning("Error getting password from keyring",exc_info=exc)returnNone
[docs]defusername_from_keyring_or_prompt(self)->str:username=self.get_username_from_keyring()ifusername:logger.info("username set from keyring")returnusernamereturnself.prompt("username",input)
[docs]defpassword_from_keyring_or_prompt(self)->str:password=self.get_password_from_keyring()ifpassword:logger.info("password set from keyring")returnpassword# As of 2024-01-01, PyPI requires API tokens for uploads;# specialize the prompt to clarify that an API token must be provided.ifcast(str,self.config["repository"]).startswith((utils.DEFAULT_REPOSITORY,utils.TEST_REPOSITORY)):prompt="API token"else:prompt="password"returnself.prompt(prompt,getpass.getpass)
[docs]defprompt(self,what:str,how:Callable[...,str])->str:returnhow(f"Enter your {what}: ")