"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "poetry/console/commands/config.py" between
poetry-1.1.15.tar.gz and poetry-1.2.0.tar.gz

About: Poetry is a tool for dependency management and packaging in Python.

config.py  (poetry-1.1.15):config.py  (poetry-1.2.0)
from __future__ import annotations
import json import json
import re import re
from cleo import argument from pathlib import Path
from cleo import option from typing import TYPE_CHECKING
from typing import Any
from poetry.core.pyproject import PyProjectException from typing import cast
from poetry.core.toml.file import TOMLFile
from poetry.factory import Factory from cleo.helpers import argument
from cleo.helpers import option
from poetry.config.config import PackageFilterPolicy
from poetry.config.config import boolean_normalizer
from poetry.config.config import boolean_validator
from poetry.config.config import int_normalizer
from poetry.console.commands.command import Command
from poetry.locations import DEFAULT_CACHE_DIR
from .command import Command if TYPE_CHECKING:
from poetry.config.config_source import ConfigSource
class ConfigCommand(Command): class ConfigCommand(Command):
name = "config" name = "config"
description = "Manages configuration settings." description = "Manages configuration settings."
arguments = [ arguments = [
argument("key", "Setting key.", optional=True), argument("key", "Setting key.", optional=True),
argument("value", "Setting value.", optional=True, multiple=True), argument("value", "Setting value.", optional=True, multiple=True),
] ]
options = [ options = [
option("list", None, "List configuration settings."), option("list", None, "List configuration settings."),
option("unset", None, "Unset configuration setting."), option("unset", None, "Unset configuration setting."),
option("local", None, "Set/Get from the project's local configuration.") , option("local", None, "Set/Get from the project's local configuration.") ,
] ]
help = """This command allows you to edit the poetry config settings and rep help = """\
ositories. This command allows you to edit the poetry config settings and repositories.
To add a repository: To add a repository:
<comment>poetry config repositories.foo https://bar.com/simple/</comment> <comment>poetry config repositories.foo https://bar.com/simple/</comment>
To remove a repository (repo is a short alias for repositories): To remove a repository (repo is a short alias for repositories):
<comment>poetry config --unset repo.foo</comment>""" <comment>poetry config --unset repo.foo</comment>"""
LIST_PROHIBITED_SETTINGS = {"http-basic", "pypi-token"} LIST_PROHIBITED_SETTINGS = {"http-basic", "pypi-token"}
@property @property
def unique_config_values(self): def unique_config_values(self) -> dict[str, tuple[Any, Any, Any]]:
from poetry.config.config import boolean_normalizer
from poetry.config.config import boolean_validator
from poetry.locations import CACHE_DIR
from poetry.utils._compat import Path
unique_config_values = { unique_config_values = {
"cache-dir": ( "cache-dir": (
str, str,
lambda val: str(Path(val)), lambda val: str(Path(val)),
str(Path(CACHE_DIR) / "virtualenvs"), str(DEFAULT_CACHE_DIR / "virtualenvs"),
), ),
"virtualenvs.create": (boolean_validator, boolean_normalizer, True), "virtualenvs.create": (boolean_validator, boolean_normalizer, True),
"virtualenvs.in-project": (boolean_validator, boolean_normalizer, Fa lse), "virtualenvs.in-project": (boolean_validator, boolean_normalizer, Fa lse),
"virtualenvs.options.always-copy": (
boolean_validator,
boolean_normalizer,
False,
),
"virtualenvs.options.system-site-packages": (
boolean_validator,
boolean_normalizer,
False,
),
"virtualenvs.options.no-pip": (
boolean_validator,
boolean_normalizer,
False,
),
"virtualenvs.options.no-setuptools": (
boolean_validator,
boolean_normalizer,
False,
),
"virtualenvs.path": ( "virtualenvs.path": (
str, str,
lambda val: str(Path(val)), lambda val: str(Path(val)),
str(Path(CACHE_DIR) / "virtualenvs"), str(DEFAULT_CACHE_DIR / "virtualenvs"),
),
"virtualenvs.prefer-active-python": (
boolean_validator,
boolean_normalizer,
False,
), ),
"experimental.new-installer": ( "experimental.new-installer": (
boolean_validator, boolean_validator,
boolean_normalizer, boolean_normalizer,
True, True,
), ),
"installer.parallel": (boolean_validator, boolean_normalizer, True,) "experimental.system-git-client": (
, boolean_validator,
boolean_normalizer,
False,
),
"installer.parallel": (
boolean_validator,
boolean_normalizer,
True,
),
"installer.max-workers": (
lambda val: int(val) > 0,
int_normalizer,
None,
),
"virtualenvs.prompt": (
str,
lambda val: str(val),
"{project_name}-py{python_version}",
),
"installer.no-binary": (
PackageFilterPolicy.validator,
PackageFilterPolicy.normalize,
None,
),
} }
return unique_config_values return unique_config_values
def handle(self): def handle(self) -> int:
from pathlib import Path
from poetry.core.pyproject.exceptions import PyProjectException
from poetry.core.toml.file import TOMLFile
from poetry.config.config import Config
from poetry.config.file_config_source import FileConfigSource from poetry.config.file_config_source import FileConfigSource
from poetry.locations import CONFIG_DIR from poetry.locations import CONFIG_DIR
from poetry.utils._compat import Path
from poetry.utils._compat import basestring
config = Factory.create_config(self.io) config = Config.create()
config_file = TOMLFile(Path(CONFIG_DIR) / "config.toml") config_file = TOMLFile(CONFIG_DIR / "config.toml")
try: try:
local_config_file = TOMLFile(self.poetry.file.parent / "poetry.toml" ) local_config_file = TOMLFile(self.poetry.file.parent / "poetry.toml" )
if local_config_file.exists(): if local_config_file.exists():
config.merge(local_config_file.read()) config.merge(local_config_file.read())
except (RuntimeError, PyProjectException): except (RuntimeError, PyProjectException):
local_config_file = TOMLFile(Path.cwd() / "poetry.toml") local_config_file = TOMLFile(Path.cwd() / "poetry.toml")
if self.option("local"): if self.option("local"):
config.set_config_source(FileConfigSource(local_config_file)) config.set_config_source(FileConfigSource(local_config_file))
skipping to change at line 109 skipping to change at line 168
setting_key = self.argument("key") setting_key = self.argument("key")
if not setting_key: if not setting_key:
return 0 return 0
if self.argument("value") and self.option("unset"): if self.argument("value") and self.option("unset"):
raise RuntimeError("You can not combine a setting value with --unset ") raise RuntimeError("You can not combine a setting value with --unset ")
# show the value if no value is provided # show the value if no value is provided
if not self.argument("value") and not self.option("unset"): if not self.argument("value") and not self.option("unset"):
m = re.match(r"^repos?(?:itories)?(?:\.(.+))?", self.argument("key") ) m = re.match(r"^repos?(?:itories)?(?:\.(.+))?", self.argument("key") )
value: str | dict[str, Any]
if m: if m:
if not m.group(1): if not m.group(1):
value = {} value = {}
if config.get("repositories") is not None: if config.get("repositories") is not None:
value = config.get("repositories") value = config.get("repositories")
else: else:
repo = config.get("repositories.{}".format(m.group(1))) repo = config.get(f"repositories.{m.group(1)}")
if repo is None: if repo is None:
raise ValueError( raise ValueError(f"There is no {m.group(1)} repository d
"There is no {} repository defined".format(m.group(1 efined")
))
)
value = repo value = repo
self.line(str(value)) self.line(str(value))
else: else:
values = self.unique_config_values if setting_key not in self.unique_config_values:
if setting_key not in values: raise ValueError(f"There is no {setting_key} setting.")
raise ValueError("There is no {} setting.".format(setting_ke
y))
value = config.get(setting_key) value = config.get(setting_key)
if not isinstance(value, basestring): if not isinstance(value, str):
value = json.dumps(value) value = json.dumps(value)
self.line(value) self.line(value)
return 0 return 0
values = self.argument("value") values: list[str] = self.argument("value")
unique_config_values = self.unique_config_values unique_config_values = self.unique_config_values
if setting_key in unique_config_values: if setting_key in unique_config_values:
if self.option("unset"): if self.option("unset"):
return config.config_source.remove_property(setting_key) config.config_source.remove_property(setting_key)
return 0
return self._handle_single_value( return self._handle_single_value(
config.config_source, config.config_source,
setting_key, setting_key,
unique_config_values[setting_key], unique_config_values[setting_key],
values, values,
) )
# handle repositories # handle repositories
m = re.match(r"^repos?(?:itories)?(?:\.(.+))?", self.argument("key")) m = re.match(r"^repos?(?:itories)?(?:\.(.+))?", self.argument("key"))
if m: if m:
if not m.group(1): if not m.group(1):
raise ValueError("You cannot remove the [repositories] section") raise ValueError("You cannot remove the [repositories] section")
if self.option("unset"): if self.option("unset"):
repo = config.get("repositories.{}".format(m.group(1))) repo = config.get(f"repositories.{m.group(1)}")
if repo is None: if repo is None:
raise ValueError( raise ValueError(f"There is no {m.group(1)} repository defin
"There is no {} repository defined".format(m.group(1)) ed")
)
config.config_source.remove_property( config.config_source.remove_property(f"repositories.{m.group(1)}
"repositories.{}".format(m.group(1)) ")
)
return 0 return 0
if len(values) == 1: if len(values) == 1:
url = values[0] url = values[0]
config.config_source.add_property( config.config_source.add_property(f"repositories.{m.group(1)}.ur
"repositories.{}.url".format(m.group(1)), url l", url)
)
return 0 return 0
raise ValueError( raise ValueError(
"You must pass the url. " "You must pass the url. "
"Example: poetry config repositories.foo https://bar.com" "Example: poetry config repositories.foo https://bar.com"
) )
# handle auth # handle auth
m = re.match(r"^(http-basic|pypi-token)\.(.+)", self.argument("key")) m = re.match(r"^(http-basic|pypi-token)\.(.+)", self.argument("key"))
skipping to change at line 207 skipping to change at line 259
return 0 return 0
if m.group(1) == "http-basic": if m.group(1) == "http-basic":
if len(values) == 1: if len(values) == 1:
username = values[0] username = values[0]
# Only username, so we prompt for password # Only username, so we prompt for password
password = self.secret("Password:") password = self.secret("Password:")
elif len(values) != 2: elif len(values) != 2:
raise ValueError( raise ValueError(
"Expected one or two arguments " "Expected one or two arguments "
"(username, password), got {}".format(len(values)) f"(username, password), got {len(values)}"
) )
else: else:
username = values[0] username = values[0]
password = values[1] password = values[1]
password_manager.set_http_password(m.group(2), username, passwor d) password_manager.set_http_password(m.group(2), username, passwor d)
elif m.group(1) == "pypi-token": elif m.group(1) == "pypi-token":
if len(values) != 1: if len(values) != 1:
raise ValueError( raise ValueError(
"Expected only one argument (token), got {}".format(len( values)) f"Expected only one argument (token), got {len(values)}"
) )
token = values[0] token = values[0]
password_manager.set_pypi_token(m.group(2), token) password_manager.set_pypi_token(m.group(2), token)
return 0 return 0
# handle certs # handle certs
m = re.match( m = re.match(r"certificates\.([^.]+)\.(cert|client-cert)", self.argument
r"(?:certificates)\.([^.]+)\.(cert|client-cert)", self.argument("key ("key"))
")
)
if m: if m:
repository = m.group(1)
key = m.group(2)
if self.option("unset"): if self.option("unset"):
config.auth_config_source.remove_property( config.auth_config_source.remove_property(
"certificates.{}.{}".format(m.group(1), m.group(2)) f"certificates.{repository}.{key}"
) )
return 0 return 0
if len(values) == 1: if len(values) == 1:
new_value: str | bool = values[0]
if key == "cert" and boolean_validator(values[0]):
new_value = boolean_normalizer(values[0])
config.auth_config_source.add_property( config.auth_config_source.add_property(
"certificates.{}.{}".format(m.group(1), m.group(2)), values[ 0] f"certificates.{repository}.{key}", new_value
) )
else: else:
raise ValueError("You must pass exactly 1 value") raise ValueError("You must pass exactly 1 value")
return 0 return 0
raise ValueError("Setting {} does not exist".format(self.argument("key") )) raise ValueError(f"Setting {self.argument('key')} does not exist")
def _handle_single_value(self, source, key, callbacks, values): def _handle_single_value(
self,
source: ConfigSource,
key: str,
callbacks: tuple[Any, Any, Any],
values: list[Any],
) -> int:
validator, normalizer, _ = callbacks validator, normalizer, _ = callbacks
if len(values) > 1: if len(values) > 1:
raise RuntimeError("You can only pass one value.") raise RuntimeError("You can only pass one value.")
value = values[0] value = values[0]
if not validator(value): if not validator(value):
raise RuntimeError('"{}" is an invalid value for {}'.format(value, k ey)) raise RuntimeError(f'"{value}" is an invalid value for {key}')
source.add_property(key, normalizer(value)) source.add_property(key, normalizer(value))
return 0 return 0
def _list_configuration(self, config, raw, k=""): def _list_configuration(
from poetry.utils._compat import basestring self, config: dict[str, Any], raw: dict[str, Any], k: str = ""
) -> None:
orig_k = k orig_k = k
for key, value in sorted(config.items()): for key, value in sorted(config.items()):
if k + key in self.LIST_PROHIBITED_SETTINGS: if k + key in self.LIST_PROHIBITED_SETTINGS:
continue continue
raw_val = raw.get(key) raw_val = raw.get(key)
if isinstance(value, dict): if isinstance(value, dict):
k += "{}.".format(key) k += f"{key}."
raw_val = cast("dict[str, Any]", raw_val)
self._list_configuration(value, raw_val, k=k) self._list_configuration(value, raw_val, k=k)
k = orig_k k = orig_k
continue continue
elif isinstance(value, list): elif isinstance(value, list):
value = [ value = ", ".join(
json.dumps(val) if isinstance(val, list) else val for val in value json.dumps(val) if isinstance(val, list) else val for val in value
] )
value = f"[{value}]"
value = "[{}]".format(", ".join(value))
if k.startswith("repositories."): if k.startswith("repositories."):
message = "<c1>{}</c1> = <c2>{}</c2>".format( message = f"<c1>{k + key}</c1> = <c2>{json.dumps(raw_val)}</c2>"
k + key, json.dumps(raw_val) elif isinstance(raw_val, str) and raw_val != value:
) message = (
elif isinstance(raw_val, basestring) and raw_val != value: f"<c1>{k + key}</c1> = <c2>{json.dumps(raw_val)}</c2> # {va
message = "<c1>{}</c1> = <c2>{}</c2> # {}".format( lue}"
k + key, json.dumps(raw_val), value
) )
else: else:
message = "<c1>{}</c1> = <c2>{}</c2>".format(k + key, json.dumps (value)) message = f"<c1>{k + key}</c1> = <c2>{json.dumps(value)}</c2>"
self.line(message) self.line(message)
def _list_setting(self, contents, setting=None, k=None, default=None):
values = self._get_setting(contents, setting, k, default)
for value in values:
self.line(
"<comment>{}</comment> = <info>{}</info>".format(value[0], value
[1])
)
def _get_setting(self, contents, setting=None, k=None, default=None):
orig_k = k
if setting and setting.split(".")[0] not in contents:
value = json.dumps(default)
return [((k or "") + setting, value)]
else:
values = []
for key, value in contents.items():
if setting and key != setting.split(".")[0]:
continue
if isinstance(value, dict) or key == "repositories" and k is Non
e:
if k is None:
k = ""
k += re.sub(r"^config\.", "", key + ".")
if setting and len(setting) > 1:
setting = ".".join(setting.split(".")[1:])
values += self._get_setting(
value, k=k, setting=setting, default=default
)
k = orig_k
continue
if isinstance(value, list):
value = [
json.dumps(val) if isinstance(val, list) else val
for val in value
]
value = "[{}]".format(", ".join(value))
value = json.dumps(value)
values.append(((k or "") + key, value))
return values
def _get_formatted_value(self, value):
if isinstance(value, list):
value = [json.dumps(val) if isinstance(val, list) else val for val i
n value]
value = "[{}]".format(", ".join(value))
return json.dumps(value)
 End of changes. 41 change blocks. 
73 lines changed or deleted 136 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)