Voice et bot modif
This commit is contained in:
parent
189d56026b
commit
7333a22bcd
10774 changed files with 634644 additions and 933308 deletions
|
|
@ -1,7 +1,7 @@
|
|||
The code contained in this directory was automatically generated using the
|
||||
following command:
|
||||
|
||||
python -m validate_pyproject.pre_compile --output-dir=setuptools/config/_validate_pyproject --enable-plugins setuptools distutils --very-verbose -t setuptools=setuptools/config/setuptools.schema.json -t distutils=setuptools/config/distutils.schema.json
|
||||
python -m validate_pyproject.pre_compile --output-dir=setuptools/config/_validate_pyproject --enable-plugins setuptools distutils --very-verbose -t distutils=setuptools/config/distutils.schema.json -t setuptools=setuptools/config/setuptools.schema.json
|
||||
|
||||
Please avoid changing it manually.
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
|
|
@ -6,7 +8,7 @@ import re
|
|||
import typing
|
||||
from contextlib import contextmanager
|
||||
from textwrap import indent, wrap
|
||||
from typing import Any, Dict, Generator, Iterator, List, Optional, Sequence, Union
|
||||
from typing import Any, Generator, Iterator, Sequence
|
||||
|
||||
from .fastjsonschema_exceptions import JsonSchemaValueException
|
||||
|
||||
|
|
@ -36,7 +38,7 @@ _SKIP_DETAILS = (
|
|||
_NEED_DETAILS = {"anyOf", "oneOf", "allOf", "contains", "propertyNames", "not", "items"}
|
||||
|
||||
_CAMEL_CASE_SPLITTER = re.compile(r"\W+|([A-Z][^A-Z\W]*)")
|
||||
_IDENTIFIER = re.compile(r"^[\w_]+$", re.I)
|
||||
_IDENTIFIER = re.compile(r"^[\w_]+$", re.IGNORECASE)
|
||||
|
||||
_TOML_JARGON = {
|
||||
"object": "table",
|
||||
|
|
@ -73,7 +75,7 @@ class ValidationError(JsonSchemaValueException):
|
|||
_original_message = ""
|
||||
|
||||
@classmethod
|
||||
def _from_jsonschema(cls, ex: JsonSchemaValueException) -> "Self":
|
||||
def _from_jsonschema(cls, ex: JsonSchemaValueException) -> Self:
|
||||
formatter = _ErrorFormatting(ex)
|
||||
obj = cls(str(formatter), ex.value, formatter.name, ex.definition, ex.rule)
|
||||
debug_code = os.getenv("JSONSCHEMA_DEBUG_CODE_GENERATION", "false").lower()
|
||||
|
|
@ -173,8 +175,8 @@ class _ErrorFormatting:
|
|||
class _SummaryWriter:
|
||||
_IGNORE = frozenset(("description", "default", "title", "examples"))
|
||||
|
||||
def __init__(self, jargon: Optional[Dict[str, str]] = None):
|
||||
self.jargon: Dict[str, str] = jargon or {}
|
||||
def __init__(self, jargon: dict[str, str] | None = None):
|
||||
self.jargon: dict[str, str] = jargon or {}
|
||||
# Clarify confusing terms
|
||||
self._terms = {
|
||||
"anyOf": "at least one of the following",
|
||||
|
|
@ -207,14 +209,14 @@ class _SummaryWriter:
|
|||
"multipleOf",
|
||||
]
|
||||
|
||||
def _jargon(self, term: Union[str, List[str]]) -> Union[str, List[str]]:
|
||||
def _jargon(self, term: str | list[str]) -> str | list[str]:
|
||||
if isinstance(term, list):
|
||||
return [self.jargon.get(t, t) for t in term]
|
||||
return self.jargon.get(term, term)
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
schema: Union[dict, List[dict]],
|
||||
schema: dict | list[dict],
|
||||
prefix: str = "",
|
||||
*,
|
||||
_path: Sequence[str] = (),
|
||||
|
|
@ -261,15 +263,15 @@ class _SummaryWriter:
|
|||
return any(key.startswith(k) for k in "$_") or key in self._IGNORE
|
||||
|
||||
def _filter_unecessary(
|
||||
self, schema: Dict[str, Any], path: Sequence[str]
|
||||
) -> Dict[str, Any]:
|
||||
self, schema: dict[str, Any], path: Sequence[str]
|
||||
) -> dict[str, Any]:
|
||||
return {
|
||||
key: value
|
||||
for key, value in schema.items()
|
||||
if not self._is_unecessary([*path, key])
|
||||
}
|
||||
|
||||
def _handle_simple_dict(self, value: dict, path: Sequence[str]) -> Optional[str]:
|
||||
def _handle_simple_dict(self, value: dict, path: Sequence[str]) -> str | None:
|
||||
inline = any(p in value for p in self._guess_inline_defs)
|
||||
simple = not any(isinstance(v, (list, dict)) for v in value.values())
|
||||
if inline or simple:
|
||||
|
|
@ -328,7 +330,7 @@ class _SummaryWriter:
|
|||
return len(parent_prefix) * " " + child_prefix
|
||||
|
||||
|
||||
def _separate_terms(word: str) -> List[str]:
|
||||
def _separate_terms(word: str) -> list[str]:
|
||||
"""
|
||||
>>> _separate_terms("FooBar-foo")
|
||||
['foo', 'bar', 'foo']
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ difficult to express as a JSON Schema (or that are not supported by the current
|
|||
JSON Schema library).
|
||||
"""
|
||||
|
||||
import collections
|
||||
import itertools
|
||||
from inspect import cleandoc
|
||||
from typing import Mapping, TypeVar
|
||||
from typing import Generator, Iterable, Mapping, TypeVar
|
||||
|
||||
from .error_reporting import ValidationError
|
||||
|
||||
|
|
@ -19,8 +21,7 @@ class RedefiningStaticFieldAsDynamic(ValidationError):
|
|||
"""
|
||||
__doc__ = _DESC
|
||||
_URL = (
|
||||
"https://packaging.python.org/en/latest/specifications/"
|
||||
"pyproject-toml/#dynamic"
|
||||
"https://packaging.python.org/en/latest/specifications/pyproject-toml/#dynamic"
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -31,6 +32,24 @@ class IncludedDependencyGroupMustExist(ValidationError):
|
|||
_URL = "https://peps.python.org/pep-0735/"
|
||||
|
||||
|
||||
class ImportNameCollision(ValidationError):
|
||||
_DESC = """According to PEP 794:
|
||||
|
||||
All import-names and import-namespaces items must be unique.
|
||||
"""
|
||||
__doc__ = _DESC
|
||||
_URL = "https://peps.python.org/pep-0794/"
|
||||
|
||||
|
||||
class ImportNameMissing(ValidationError):
|
||||
_DESC = """According to PEP 794:
|
||||
|
||||
An import name must have all parents listed.
|
||||
"""
|
||||
__doc__ = _DESC
|
||||
_URL = "https://peps.python.org/pep-0794/"
|
||||
|
||||
|
||||
def validate_project_dynamic(pyproject: T) -> T:
|
||||
project_table = pyproject.get("project", {})
|
||||
dynamic = project_table.get("dynamic", [])
|
||||
|
|
@ -79,4 +98,54 @@ def validate_include_depenency(pyproject: T) -> T:
|
|||
return pyproject
|
||||
|
||||
|
||||
EXTRA_VALIDATIONS = (validate_project_dynamic, validate_include_depenency)
|
||||
def _remove_private(items: Iterable[str]) -> Generator[str, None, None]:
|
||||
for item in items:
|
||||
yield item.partition(";")[0].rstrip()
|
||||
|
||||
|
||||
def validate_import_name_issues(pyproject: T) -> T:
|
||||
project = pyproject.get("project", {})
|
||||
import_names = collections.Counter(_remove_private(project.get("import-names", [])))
|
||||
import_namespaces = collections.Counter(
|
||||
_remove_private(project.get("import-namespaces", []))
|
||||
)
|
||||
|
||||
duplicated = [k for k, v in (import_names + import_namespaces).items() if v > 1]
|
||||
|
||||
if duplicated:
|
||||
raise ImportNameCollision(
|
||||
message="Duplicated names are not allowed in import-names/import-namespaces",
|
||||
value=duplicated,
|
||||
name="data.project.importnames(paces)",
|
||||
definition={
|
||||
"description": cleandoc(ImportNameCollision._DESC),
|
||||
"see": ImportNameCollision._URL,
|
||||
},
|
||||
rule="PEP 794",
|
||||
)
|
||||
|
||||
names = frozenset(import_names + import_namespaces)
|
||||
for name in names:
|
||||
for parent in itertools.accumulate(
|
||||
name.split(".")[:-1], lambda a, b: f"{a}.{b}"
|
||||
):
|
||||
if parent not in names:
|
||||
raise ImportNameMissing(
|
||||
message="All parents of an import name must also be listed in import-namespace/import-names",
|
||||
value=name,
|
||||
name="data.project.importnames(paces)",
|
||||
definition={
|
||||
"description": cleandoc(ImportNameMissing._DESC),
|
||||
"see": ImportNameMissing._URL,
|
||||
},
|
||||
rule="PEP 794",
|
||||
)
|
||||
|
||||
return pyproject
|
||||
|
||||
|
||||
EXTRA_VALIDATIONS = (
|
||||
validate_project_dynamic,
|
||||
validate_include_depenency,
|
||||
validate_import_name_issues,
|
||||
)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -7,7 +7,9 @@ The correspondence is given by replacing the ``_`` character in the name of the
|
|||
function with a ``-`` to obtain the format name and vice versa.
|
||||
"""
|
||||
|
||||
import builtins
|
||||
from __future__ import annotations
|
||||
|
||||
import keyword
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
|
@ -16,6 +18,8 @@ import typing
|
|||
from itertools import chain as _chain
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
import builtins
|
||||
|
||||
from typing_extensions import Literal
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
|
@ -54,7 +58,9 @@ VERSION_PATTERN = r"""
|
|||
(?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
|
||||
"""
|
||||
|
||||
VERSION_REGEX = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.X | re.I)
|
||||
VERSION_REGEX = re.compile(
|
||||
r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE
|
||||
)
|
||||
|
||||
|
||||
def pep440(version: str) -> bool:
|
||||
|
|
@ -68,7 +74,7 @@ def pep440(version: str) -> bool:
|
|||
# PEP 508
|
||||
|
||||
PEP508_IDENTIFIER_PATTERN = r"([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])"
|
||||
PEP508_IDENTIFIER_REGEX = re.compile(f"^{PEP508_IDENTIFIER_PATTERN}$", re.I)
|
||||
PEP508_IDENTIFIER_REGEX = re.compile(f"^{PEP508_IDENTIFIER_PATTERN}$", re.IGNORECASE)
|
||||
|
||||
|
||||
def pep508_identifier(name: str) -> bool:
|
||||
|
|
@ -93,9 +99,9 @@ try:
|
|||
"""
|
||||
try:
|
||||
_req.Requirement(value)
|
||||
return True
|
||||
except _req.InvalidRequirement:
|
||||
return False
|
||||
return True
|
||||
|
||||
except ImportError: # pragma: no cover
|
||||
_logger.warning(
|
||||
|
|
@ -104,7 +110,7 @@ except ImportError: # pragma: no cover
|
|||
"To enforce validation, please install `packaging`."
|
||||
)
|
||||
|
||||
def pep508(value: str) -> bool:
|
||||
def pep508(value: str) -> bool: # noqa: ARG001
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -163,7 +169,7 @@ class _TroveClassifier:
|
|||
option (classifiers will be validated anyway during the upload to PyPI).
|
||||
"""
|
||||
|
||||
downloaded: typing.Union[None, "Literal[False]", typing.Set[str]]
|
||||
downloaded: None | Literal[False] | set[str]
|
||||
"""
|
||||
None => not cached yet
|
||||
False => unavailable
|
||||
|
|
@ -200,7 +206,7 @@ class _TroveClassifier:
|
|||
_logger.debug(msg)
|
||||
try:
|
||||
self.downloaded = set(_download_classifiers().splitlines())
|
||||
except Exception:
|
||||
except Exception: # noqa: BLE001
|
||||
self.downloaded = False
|
||||
_logger.debug("Problem with download, skipping validation")
|
||||
return True
|
||||
|
|
@ -253,21 +259,23 @@ def url(value: str) -> bool:
|
|||
"`scheme` prefix in your URL (e.g. 'http://'). "
|
||||
f"Given value: {value}"
|
||||
)
|
||||
if not (value.startswith("/") or value.startswith("\\") or "@" in value):
|
||||
if not (value.startswith(("/", "\\")) or "@" in value):
|
||||
parts = urlparse(f"http://{value}")
|
||||
|
||||
return bool(parts.scheme and parts.netloc)
|
||||
except Exception:
|
||||
except Exception: # noqa: BLE001
|
||||
return False
|
||||
|
||||
|
||||
# https://packaging.python.org/specifications/entry-points/
|
||||
ENTRYPOINT_PATTERN = r"[^\[\s=]([^=]*[^\s=])?"
|
||||
ENTRYPOINT_REGEX = re.compile(f"^{ENTRYPOINT_PATTERN}$", re.I)
|
||||
ENTRYPOINT_REGEX = re.compile(f"^{ENTRYPOINT_PATTERN}$", re.IGNORECASE)
|
||||
RECOMMEDED_ENTRYPOINT_PATTERN = r"[\w.-]+"
|
||||
RECOMMEDED_ENTRYPOINT_REGEX = re.compile(f"^{RECOMMEDED_ENTRYPOINT_PATTERN}$", re.I)
|
||||
RECOMMEDED_ENTRYPOINT_REGEX = re.compile(
|
||||
f"^{RECOMMEDED_ENTRYPOINT_PATTERN}$", re.IGNORECASE
|
||||
)
|
||||
ENTRYPOINT_GROUP_PATTERN = r"\w+(\.\w+)*"
|
||||
ENTRYPOINT_GROUP_REGEX = re.compile(f"^{ENTRYPOINT_GROUP_PATTERN}$", re.I)
|
||||
ENTRYPOINT_GROUP_REGEX = re.compile(f"^{ENTRYPOINT_GROUP_PATTERN}$", re.IGNORECASE)
|
||||
|
||||
|
||||
def python_identifier(value: str) -> bool:
|
||||
|
|
@ -368,11 +376,41 @@ def uint16(value: builtins.int) -> bool:
|
|||
return 0 <= value < 2**16
|
||||
|
||||
|
||||
def uint(value: builtins.int) -> bool:
|
||||
def uint32(value: builtins.int) -> bool:
|
||||
r"""Unsigned 32-bit integer (:math:`0 \leq x < 2^{32}`)"""
|
||||
return 0 <= value < 2**32
|
||||
|
||||
|
||||
def uint64(value: builtins.int) -> bool:
|
||||
r"""Unsigned 64-bit integer (:math:`0 \leq x < 2^{64}`)"""
|
||||
return 0 <= value < 2**64
|
||||
|
||||
|
||||
def uint(value: builtins.int) -> bool:
|
||||
r"""Signed 64-bit integer (:math:`0 \leq x < 2^{64}`)"""
|
||||
return 0 <= value < 2**64
|
||||
|
||||
|
||||
def int8(value: builtins.int) -> bool:
|
||||
r"""Signed 8-bit integer (:math:`-2^{7} \leq x < 2^{7}`)"""
|
||||
return -(2**7) <= value < 2**7
|
||||
|
||||
|
||||
def int16(value: builtins.int) -> bool:
|
||||
r"""Signed 16-bit integer (:math:`-2^{15} \leq x < 2^{15}`)"""
|
||||
return -(2**15) <= value < 2**15
|
||||
|
||||
|
||||
def int32(value: builtins.int) -> bool:
|
||||
r"""Signed 32-bit integer (:math:`-2^{31} \leq x < 2^{31}`)"""
|
||||
return -(2**31) <= value < 2**31
|
||||
|
||||
|
||||
def int64(value: builtins.int) -> bool:
|
||||
r"""Signed 64-bit integer (:math:`-2^{63} \leq x < 2^{63}`)"""
|
||||
return -(2**63) <= value < 2**63
|
||||
|
||||
|
||||
def int(value: builtins.int) -> bool:
|
||||
r"""Signed 64-bit integer (:math:`-2^{63} \leq x < 2^{63}`)"""
|
||||
return -(2**63) <= value < 2**63
|
||||
|
|
@ -387,9 +425,9 @@ try:
|
|||
"""
|
||||
try:
|
||||
_licenses.canonicalize_license_expression(value)
|
||||
return True
|
||||
except _licenses.InvalidLicenseExpression:
|
||||
return False
|
||||
return True
|
||||
|
||||
except ImportError: # pragma: no cover
|
||||
_logger.warning(
|
||||
|
|
@ -398,5 +436,29 @@ except ImportError: # pragma: no cover
|
|||
"To enforce validation, please install `packaging>=24.2`."
|
||||
)
|
||||
|
||||
def SPDX(value: str) -> bool:
|
||||
def SPDX(value: str) -> bool: # noqa: ARG001
|
||||
return True
|
||||
|
||||
|
||||
VALID_IMPORT_NAME = re.compile(
|
||||
r"""
|
||||
^ # start of string
|
||||
[A-Za-z_][A-Za-z_0-9]+ # a valid Python identifier
|
||||
(?:\.[A-Za-z_][A-Za-z_0-9]*)* # optionally followed by .identifier's
|
||||
(?:\s*;\s*private)? # optionally followed by ; private
|
||||
$ # end of string
|
||||
""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
|
||||
def import_name(value: str) -> bool:
|
||||
"""This is a valid import name. It has to be series of python identifiers
|
||||
(not keywords), separated by dots, optionally followed by a semicolon and
|
||||
the keyword "private".
|
||||
"""
|
||||
if VALID_IMPORT_NAME.match(value) is None:
|
||||
return False
|
||||
|
||||
idents, _, _ = value.partition(";")
|
||||
return all(not keyword.iskeyword(ident) for ident in idents.rstrip().split("."))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue