From 12cf076118570eebbff08c6b3090e0d4798447a1 Mon Sep 17 00:00:00 2001 From: cyfraeviolae Date: Wed, 3 Apr 2024 03:17:55 -0400 Subject: no venv --- .../setuptools/config/pyprojecttoml.py | 493 --------------------- 1 file changed, 493 deletions(-) delete mode 100644 venv/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py (limited to 'venv/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py') diff --git a/venv/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py b/venv/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py deleted file mode 100644 index d995f0b..0000000 --- a/venv/lib/python3.11/site-packages/setuptools/config/pyprojecttoml.py +++ /dev/null @@ -1,493 +0,0 @@ -""" -Load setuptools configuration from ``pyproject.toml`` files. - -**PRIVATE MODULE**: API reserved for setuptools internal usage only. -""" -import logging -import os -import warnings -from contextlib import contextmanager -from functools import partial -from typing import TYPE_CHECKING, Callable, Dict, Optional, Mapping, Union - -from setuptools.errors import FileError, OptionError - -from . import expand as _expand -from ._apply_pyprojecttoml import apply as _apply -from ._apply_pyprojecttoml import _PREVIOUSLY_DEFINED, _WouldIgnoreField - -if TYPE_CHECKING: - from setuptools.dist import Distribution # noqa - -_Path = Union[str, os.PathLike] -_logger = logging.getLogger(__name__) - - -def load_file(filepath: _Path) -> dict: - from setuptools.extern import tomli # type: ignore - - with open(filepath, "rb") as file: - return tomli.load(file) - - -def validate(config: dict, filepath: _Path) -> bool: - from . import _validate_pyproject as validator - - trove_classifier = validator.FORMAT_FUNCTIONS.get("trove-classifier") - if hasattr(trove_classifier, "_disable_download"): - # Improve reproducibility by default. See issue 31 for validate-pyproject. - trove_classifier._disable_download() # type: ignore - - try: - return validator.validate(config) - except validator.ValidationError as ex: - summary = f"configuration error: {ex.summary}" - if ex.name.strip("`") != "project": - # Probably it is just a field missing/misnamed, not worthy the verbosity... - _logger.debug(summary) - _logger.debug(ex.details) - - error = f"invalid pyproject.toml config: {ex.name}." - raise ValueError(f"{error}\n{summary}") from None - - -def apply_configuration( - dist: "Distribution", - filepath: _Path, - ignore_option_errors=False, -) -> "Distribution": - """Apply the configuration from a ``pyproject.toml`` file into an existing - distribution object. - """ - config = read_configuration(filepath, True, ignore_option_errors, dist) - return _apply(dist, config, filepath) - - -def read_configuration( - filepath: _Path, - expand=True, - ignore_option_errors=False, - dist: Optional["Distribution"] = None, -): - """Read given configuration file and returns options from it as a dict. - - :param str|unicode filepath: Path to configuration file in the ``pyproject.toml`` - format. - - :param bool expand: Whether to expand directives and other computed values - (i.e. post-process the given configuration) - - :param bool ignore_option_errors: Whether to silently ignore - options, values of which could not be resolved (e.g. due to exceptions - in directives such as file:, attr:, etc.). - If False exceptions are propagated as expected. - - :param Distribution|None: Distribution object to which the configuration refers. - If not given a dummy object will be created and discarded after the - configuration is read. This is used for auto-discovery of packages in the case - a dynamic configuration (e.g. ``attr`` or ``cmdclass``) is expanded. - When ``expand=False`` this object is simply ignored. - - :rtype: dict - """ - filepath = os.path.abspath(filepath) - - if not os.path.isfile(filepath): - raise FileError(f"Configuration file {filepath!r} does not exist.") - - asdict = load_file(filepath) or {} - project_table = asdict.get("project", {}) - tool_table = asdict.get("tool", {}) - setuptools_table = tool_table.get("setuptools", {}) - if not asdict or not (project_table or setuptools_table): - return {} # User is not using pyproject to configure setuptools - - if setuptools_table: - # TODO: Remove the following once the feature stabilizes: - msg = "Support for `[tool.setuptools]` in `pyproject.toml` is still *beta*." - warnings.warn(msg, _BetaConfiguration) - - # There is an overall sense in the community that making include_package_data=True - # the default would be an improvement. - # `ini2toml` backfills include_package_data=False when nothing is explicitly given, - # therefore setting a default here is backwards compatible. - orig_setuptools_table = setuptools_table.copy() - if dist and getattr(dist, "include_package_data") is not None: - setuptools_table.setdefault("include-package-data", dist.include_package_data) - else: - setuptools_table.setdefault("include-package-data", True) - # Persist changes: - asdict["tool"] = tool_table - tool_table["setuptools"] = setuptools_table - - try: - # Don't complain about unrelated errors (e.g. tools not using the "tool" table) - subset = {"project": project_table, "tool": {"setuptools": setuptools_table}} - validate(subset, filepath) - except Exception as ex: - # TODO: Remove the following once the feature stabilizes: - if _skip_bad_config(project_table, orig_setuptools_table, dist): - return {} - # TODO: After the previous statement is removed the try/except can be replaced - # by the _ignore_errors context manager. - if ignore_option_errors: - _logger.debug(f"ignored error: {ex.__class__.__name__} - {ex}") - else: - raise # re-raise exception - - if expand: - root_dir = os.path.dirname(filepath) - return expand_configuration(asdict, root_dir, ignore_option_errors, dist) - - return asdict - - -def _skip_bad_config( - project_cfg: dict, setuptools_cfg: dict, dist: Optional["Distribution"] -) -> bool: - """Be temporarily forgiving with invalid ``pyproject.toml``""" - # See pypa/setuptools#3199 and pypa/cibuildwheel#1064 - - if dist is None or ( - dist.metadata.name is None - and dist.metadata.version is None - and dist.install_requires is None - ): - # It seems that the build is not getting any configuration from other places - return False - - if setuptools_cfg: - # If `[tool.setuptools]` is set, then `pyproject.toml` config is intentional - return False - - given_config = set(project_cfg.keys()) - popular_subset = {"name", "version", "python_requires", "requires-python"} - if given_config <= popular_subset: - # It seems that the docs in cibuildtool has been inadvertently encouraging users - # to create `pyproject.toml` files that are not compliant with the standards. - # Let's be forgiving for the time being. - warnings.warn(_InvalidFile.message(), _InvalidFile, stacklevel=2) - return True - - return False - - -def expand_configuration( - config: dict, - root_dir: Optional[_Path] = None, - ignore_option_errors: bool = False, - dist: Optional["Distribution"] = None, -) -> dict: - """Given a configuration with unresolved fields (e.g. dynamic, cmdclass, ...) - find their final values. - - :param dict config: Dict containing the configuration for the distribution - :param str root_dir: Top-level directory for the distribution/project - (the same directory where ``pyproject.toml`` is place) - :param bool ignore_option_errors: see :func:`read_configuration` - :param Distribution|None: Distribution object to which the configuration refers. - If not given a dummy object will be created and discarded after the - configuration is read. Used in the case a dynamic configuration - (e.g. ``attr`` or ``cmdclass``). - - :rtype: dict - """ - return _ConfigExpander(config, root_dir, ignore_option_errors, dist).expand() - - -class _ConfigExpander: - def __init__( - self, - config: dict, - root_dir: Optional[_Path] = None, - ignore_option_errors: bool = False, - dist: Optional["Distribution"] = None, - ): - self.config = config - self.root_dir = root_dir or os.getcwd() - self.project_cfg = config.get("project", {}) - self.dynamic = self.project_cfg.get("dynamic", []) - self.setuptools_cfg = config.get("tool", {}).get("setuptools", {}) - self.dynamic_cfg = self.setuptools_cfg.get("dynamic", {}) - self.ignore_option_errors = ignore_option_errors - self._dist = dist - - def _ensure_dist(self) -> "Distribution": - from setuptools.dist import Distribution - - attrs = {"src_root": self.root_dir, "name": self.project_cfg.get("name", None)} - return self._dist or Distribution(attrs) - - def _process_field(self, container: dict, field: str, fn: Callable): - if field in container: - with _ignore_errors(self.ignore_option_errors): - container[field] = fn(container[field]) - - def _canonic_package_data(self, field="package-data"): - package_data = self.setuptools_cfg.get(field, {}) - return _expand.canonic_package_data(package_data) - - def expand(self): - self._expand_packages() - self._canonic_package_data() - self._canonic_package_data("exclude-package-data") - - # A distribution object is required for discovering the correct package_dir - dist = self._ensure_dist() - ctx = _EnsurePackagesDiscovered(dist, self.project_cfg, self.setuptools_cfg) - with ctx as ensure_discovered: - package_dir = ensure_discovered.package_dir - self._expand_data_files() - self._expand_cmdclass(package_dir) - self._expand_all_dynamic(dist, package_dir) - - return self.config - - def _expand_packages(self): - packages = self.setuptools_cfg.get("packages") - if packages is None or isinstance(packages, (list, tuple)): - return - - find = packages.get("find") - if isinstance(find, dict): - find["root_dir"] = self.root_dir - find["fill_package_dir"] = self.setuptools_cfg.setdefault("package-dir", {}) - with _ignore_errors(self.ignore_option_errors): - self.setuptools_cfg["packages"] = _expand.find_packages(**find) - - def _expand_data_files(self): - data_files = partial(_expand.canonic_data_files, root_dir=self.root_dir) - self._process_field(self.setuptools_cfg, "data-files", data_files) - - def _expand_cmdclass(self, package_dir: Mapping[str, str]): - root_dir = self.root_dir - cmdclass = partial(_expand.cmdclass, package_dir=package_dir, root_dir=root_dir) - self._process_field(self.setuptools_cfg, "cmdclass", cmdclass) - - def _expand_all_dynamic(self, dist: "Distribution", package_dir: Mapping[str, str]): - special = ( # need special handling - "version", - "readme", - "entry-points", - "scripts", - "gui-scripts", - "classifiers", - "dependencies", - "optional-dependencies", - ) - # `_obtain` functions are assumed to raise appropriate exceptions/warnings. - obtained_dynamic = { - field: self._obtain(dist, field, package_dir) - for field in self.dynamic - if field not in special - } - obtained_dynamic.update( - self._obtain_entry_points(dist, package_dir) or {}, - version=self._obtain_version(dist, package_dir), - readme=self._obtain_readme(dist), - classifiers=self._obtain_classifiers(dist), - dependencies=self._obtain_dependencies(dist), - optional_dependencies=self._obtain_optional_dependencies(dist), - ) - # `None` indicates there is nothing in `tool.setuptools.dynamic` but the value - # might have already been set by setup.py/extensions, so avoid overwriting. - updates = {k: v for k, v in obtained_dynamic.items() if v is not None} - self.project_cfg.update(updates) - - def _ensure_previously_set(self, dist: "Distribution", field: str): - previous = _PREVIOUSLY_DEFINED[field](dist) - if previous is None and not self.ignore_option_errors: - msg = ( - f"No configuration found for dynamic {field!r}.\n" - "Some dynamic fields need to be specified via `tool.setuptools.dynamic`" - "\nothers must be specified via the equivalent attribute in `setup.py`." - ) - raise OptionError(msg) - - def _expand_directive( - self, specifier: str, directive, package_dir: Mapping[str, str] - ): - with _ignore_errors(self.ignore_option_errors): - root_dir = self.root_dir - if "file" in directive: - return _expand.read_files(directive["file"], root_dir) - if "attr" in directive: - return _expand.read_attr(directive["attr"], package_dir, root_dir) - raise ValueError(f"invalid `{specifier}`: {directive!r}") - return None - - def _obtain(self, dist: "Distribution", field: str, package_dir: Mapping[str, str]): - if field in self.dynamic_cfg: - return self._expand_directive( - f"tool.setuptools.dynamic.{field}", - self.dynamic_cfg[field], - package_dir, - ) - self._ensure_previously_set(dist, field) - return None - - def _obtain_version(self, dist: "Distribution", package_dir: Mapping[str, str]): - # Since plugins can set version, let's silently skip if it cannot be obtained - if "version" in self.dynamic and "version" in self.dynamic_cfg: - return _expand.version(self._obtain(dist, "version", package_dir)) - return None - - def _obtain_readme(self, dist: "Distribution") -> Optional[Dict[str, str]]: - if "readme" not in self.dynamic: - return None - - dynamic_cfg = self.dynamic_cfg - if "readme" in dynamic_cfg: - return { - "text": self._obtain(dist, "readme", {}), - "content-type": dynamic_cfg["readme"].get("content-type", "text/x-rst"), - } - - self._ensure_previously_set(dist, "readme") - return None - - def _obtain_entry_points( - self, dist: "Distribution", package_dir: Mapping[str, str] - ) -> Optional[Dict[str, dict]]: - fields = ("entry-points", "scripts", "gui-scripts") - if not any(field in self.dynamic for field in fields): - return None - - text = self._obtain(dist, "entry-points", package_dir) - if text is None: - return None - - groups = _expand.entry_points(text) - expanded = {"entry-points": groups} - - def _set_scripts(field: str, group: str): - if group in groups: - value = groups.pop(group) - if field not in self.dynamic: - msg = _WouldIgnoreField.message(field, value) - warnings.warn(msg, _WouldIgnoreField) - # TODO: Don't set field when support for pyproject.toml stabilizes - # instead raise an error as specified in PEP 621 - expanded[field] = value - - _set_scripts("scripts", "console_scripts") - _set_scripts("gui-scripts", "gui_scripts") - - return expanded - - def _obtain_classifiers(self, dist: "Distribution"): - if "classifiers" in self.dynamic: - value = self._obtain(dist, "classifiers", {}) - if value: - return value.splitlines() - return None - - def _obtain_dependencies(self, dist: "Distribution"): - if "dependencies" in self.dynamic: - value = self._obtain(dist, "dependencies", {}) - if value: - return _parse_requirements_list(value) - return None - - def _obtain_optional_dependencies(self, dist: "Distribution"): - if "optional-dependencies" not in self.dynamic: - return None - if "optional-dependencies" in self.dynamic_cfg: - optional_dependencies_map = self.dynamic_cfg["optional-dependencies"] - assert isinstance(optional_dependencies_map, dict) - return { - group: _parse_requirements_list(self._expand_directive( - f"tool.setuptools.dynamic.optional-dependencies.{group}", - directive, - {}, - )) - for group, directive in optional_dependencies_map.items() - } - self._ensure_previously_set(dist, "optional-dependencies") - return None - - -def _parse_requirements_list(value): - return [ - line - for line in value.splitlines() - if line.strip() and not line.strip().startswith("#") - ] - - -@contextmanager -def _ignore_errors(ignore_option_errors: bool): - if not ignore_option_errors: - yield - return - - try: - yield - except Exception as ex: - _logger.debug(f"ignored error: {ex.__class__.__name__} - {ex}") - - -class _EnsurePackagesDiscovered(_expand.EnsurePackagesDiscovered): - def __init__( - self, distribution: "Distribution", project_cfg: dict, setuptools_cfg: dict - ): - super().__init__(distribution) - self._project_cfg = project_cfg - self._setuptools_cfg = setuptools_cfg - - def __enter__(self): - """When entering the context, the values of ``packages``, ``py_modules`` and - ``package_dir`` that are missing in ``dist`` are copied from ``setuptools_cfg``. - """ - dist, cfg = self._dist, self._setuptools_cfg - package_dir: Dict[str, str] = cfg.setdefault("package-dir", {}) - package_dir.update(dist.package_dir or {}) - dist.package_dir = package_dir # needs to be the same object - - dist.set_defaults._ignore_ext_modules() # pyproject.toml-specific behaviour - - # Set `name`, `py_modules` and `packages` in dist to short-circuit - # auto-discovery, but avoid overwriting empty lists purposefully set by users. - if dist.metadata.name is None: - dist.metadata.name = self._project_cfg.get("name") - if dist.py_modules is None: - dist.py_modules = cfg.get("py-modules") - if dist.packages is None: - dist.packages = cfg.get("packages") - - return super().__enter__() - - def __exit__(self, exc_type, exc_value, traceback): - """When exiting the context, if values of ``packages``, ``py_modules`` and - ``package_dir`` are missing in ``setuptools_cfg``, copy from ``dist``. - """ - # If anything was discovered set them back, so they count in the final config. - self._setuptools_cfg.setdefault("packages", self._dist.packages) - self._setuptools_cfg.setdefault("py-modules", self._dist.py_modules) - return super().__exit__(exc_type, exc_value, traceback) - - -class _BetaConfiguration(UserWarning): - """Explicitly inform users that some `pyproject.toml` configuration is *beta*""" - - -class _InvalidFile(UserWarning): - """The given `pyproject.toml` file is invalid and would be ignored. - !!\n\n - ############################ - # Invalid `pyproject.toml` # - ############################ - - Any configurations in `pyproject.toml` will be ignored. - Please note that future releases of setuptools will halt the build process - if an invalid file is given. - - To prevent setuptools from considering `pyproject.toml` please - DO NOT include the `[project]` or `[tool.setuptools]` tables in your file. - \n\n!! - """ - - @classmethod - def message(cls): - from inspect import cleandoc - return cleandoc(cls.__doc__) -- cgit v1.2.3