RAHHH
This commit is contained in:
565
backend/lib/python3.12/site-packages/incremental/__init__.py
Normal file
565
backend/lib/python3.12/site-packages/incremental/__init__.py
Normal file
@@ -0,0 +1,565 @@
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Versions for Python packages.
|
||||
|
||||
See L{Version}.
|
||||
"""
|
||||
|
||||
from __future__ import division, absolute_import
|
||||
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
from typing import TYPE_CHECKING, Any, TypeVar, Union, Optional, Dict, BinaryIO
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import io
|
||||
from typing_extensions import Literal
|
||||
from distutils.dist import Distribution as _Distribution
|
||||
|
||||
|
||||
#
|
||||
# Compat functions
|
||||
#
|
||||
|
||||
|
||||
def _cmp(a, b): # type: (Any, Any) -> int
|
||||
"""
|
||||
Compare two objects.
|
||||
|
||||
Returns a negative number if C{a < b}, zero if they are equal, and a
|
||||
positive number if C{a > b}.
|
||||
"""
|
||||
if a < b:
|
||||
return -1
|
||||
elif a == b:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
|
||||
#
|
||||
# Versioning
|
||||
#
|
||||
|
||||
|
||||
class _Inf(object):
|
||||
"""
|
||||
An object that is bigger than all other objects.
|
||||
"""
|
||||
|
||||
def __cmp__(self, other): # type: (object) -> int
|
||||
"""
|
||||
@param other: Another object.
|
||||
@type other: any
|
||||
|
||||
@return: 0 if other is inf, 1 otherwise.
|
||||
@rtype: C{int}
|
||||
"""
|
||||
if other is _inf:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def __lt__(self, other): # type: (object) -> bool
|
||||
return self.__cmp__(other) < 0
|
||||
|
||||
def __le__(self, other): # type: (object) -> bool
|
||||
return self.__cmp__(other) <= 0
|
||||
|
||||
def __gt__(self, other): # type: (object) -> bool
|
||||
return self.__cmp__(other) > 0
|
||||
|
||||
def __ge__(self, other): # type: (object) -> bool
|
||||
return self.__cmp__(other) >= 0
|
||||
|
||||
|
||||
_inf = _Inf()
|
||||
|
||||
|
||||
class IncomparableVersions(TypeError):
|
||||
"""
|
||||
Two versions could not be compared.
|
||||
"""
|
||||
|
||||
|
||||
class Version(object):
|
||||
"""
|
||||
An encapsulation of a version for a project, with support for outputting
|
||||
PEP-440 compatible version strings.
|
||||
|
||||
This class supports the standard major.minor.micro[rcN] scheme of
|
||||
versioning.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
package, # type: str
|
||||
major, # type: Union[Literal["NEXT"], int]
|
||||
minor, # type: int
|
||||
micro, # type: int
|
||||
release_candidate=None, # type: Optional[int]
|
||||
prerelease=None, # type: Optional[int]
|
||||
post=None, # type: Optional[int]
|
||||
dev=None, # type: Optional[int]
|
||||
):
|
||||
"""
|
||||
@param package: Name of the package that this is a version of.
|
||||
@type package: C{str}
|
||||
@param major: The major version number.
|
||||
@type major: C{int} or C{str} (for the "NEXT" symbol)
|
||||
@param minor: The minor version number.
|
||||
@type minor: C{int}
|
||||
@param micro: The micro version number.
|
||||
@type micro: C{int}
|
||||
@param release_candidate: The release candidate number.
|
||||
@type release_candidate: C{int}
|
||||
@param prerelease: The prerelease number. (Deprecated)
|
||||
@type prerelease: C{int}
|
||||
@param post: The postrelease number.
|
||||
@type post: C{int}
|
||||
@param dev: The development release number.
|
||||
@type dev: C{int}
|
||||
"""
|
||||
if release_candidate and prerelease:
|
||||
raise ValueError("Please only return one of these.")
|
||||
elif prerelease and not release_candidate:
|
||||
release_candidate = prerelease
|
||||
warnings.warn(
|
||||
"Passing prerelease to incremental.Version was "
|
||||
"deprecated in Incremental 16.9.0. Please pass "
|
||||
"release_candidate instead.",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
if major == "NEXT":
|
||||
if minor or micro or release_candidate or post or dev:
|
||||
raise ValueError(
|
||||
"When using NEXT, all other values except Package must be 0."
|
||||
)
|
||||
|
||||
self.package = package
|
||||
self.major = major
|
||||
self.minor = minor
|
||||
self.micro = micro
|
||||
self.release_candidate = release_candidate
|
||||
self.post = post
|
||||
self.dev = dev
|
||||
|
||||
@property
|
||||
def prerelease(self): # type: () -> Optional[int]
|
||||
warnings.warn(
|
||||
"Accessing incremental.Version.prerelease was "
|
||||
"deprecated in Incremental 16.9.0. Use "
|
||||
"Version.release_candidate instead.",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return self.release_candidate
|
||||
|
||||
def public(self): # type: () -> str
|
||||
"""
|
||||
Return a PEP440-compatible "public" representation of this L{Version}.
|
||||
|
||||
Examples:
|
||||
|
||||
- 14.4.0
|
||||
- 1.2.3rc1
|
||||
- 14.2.1rc1dev9
|
||||
- 16.04.0dev0
|
||||
"""
|
||||
if self.major == "NEXT":
|
||||
return self.major
|
||||
|
||||
if self.release_candidate is None:
|
||||
rc = ""
|
||||
else:
|
||||
rc = "rc%s" % (self.release_candidate,)
|
||||
|
||||
if self.post is None:
|
||||
post = ""
|
||||
else:
|
||||
post = ".post%s" % (self.post,)
|
||||
|
||||
if self.dev is None:
|
||||
dev = ""
|
||||
else:
|
||||
dev = ".dev%s" % (self.dev,)
|
||||
|
||||
return "%r.%d.%d%s%s%s" % (self.major, self.minor, self.micro, rc, post, dev)
|
||||
|
||||
base = public
|
||||
short = public
|
||||
local = public
|
||||
|
||||
def __repr__(self): # type: () -> str
|
||||
if self.release_candidate is None:
|
||||
release_candidate = ""
|
||||
else:
|
||||
release_candidate = ", release_candidate=%r" % (self.release_candidate,)
|
||||
|
||||
if self.post is None:
|
||||
post = ""
|
||||
else:
|
||||
post = ", post=%r" % (self.post,)
|
||||
|
||||
if self.dev is None:
|
||||
dev = ""
|
||||
else:
|
||||
dev = ", dev=%r" % (self.dev,)
|
||||
|
||||
return "%s(%r, %r, %d, %d%s%s%s)" % (
|
||||
self.__class__.__name__,
|
||||
self.package,
|
||||
self.major,
|
||||
self.minor,
|
||||
self.micro,
|
||||
release_candidate,
|
||||
post,
|
||||
dev,
|
||||
)
|
||||
|
||||
def __str__(self): # type: () -> str
|
||||
return "[%s, version %s]" % (self.package, self.short())
|
||||
|
||||
def __cmp__(self, other): # type: (object) -> int
|
||||
"""
|
||||
Compare two versions, considering major versions, minor versions, micro
|
||||
versions, then release candidates, then postreleases, then dev
|
||||
releases. Package names are case insensitive.
|
||||
|
||||
A version with a release candidate is always less than a version
|
||||
without a release candidate. If both versions have release candidates,
|
||||
they will be included in the comparison.
|
||||
|
||||
Likewise, a version with a dev release is always less than a version
|
||||
without a dev release. If both versions have dev releases, they will
|
||||
be included in the comparison.
|
||||
|
||||
@param other: Another version.
|
||||
@type other: L{Version}
|
||||
|
||||
@return: NotImplemented when the other object is not a Version, or one
|
||||
of -1, 0, or 1.
|
||||
|
||||
@raise IncomparableVersions: when the package names of the versions
|
||||
differ.
|
||||
"""
|
||||
if not isinstance(other, self.__class__):
|
||||
return NotImplemented
|
||||
if self.package.lower() != other.package.lower():
|
||||
raise IncomparableVersions("%r != %r" % (self.package, other.package))
|
||||
|
||||
if self.major == "NEXT":
|
||||
major = _inf # type: Union[int, _Inf]
|
||||
else:
|
||||
major = self.major
|
||||
|
||||
if self.release_candidate is None:
|
||||
release_candidate = _inf # type: Union[int, _Inf]
|
||||
else:
|
||||
release_candidate = self.release_candidate
|
||||
|
||||
if self.post is None:
|
||||
post = -1
|
||||
else:
|
||||
post = self.post
|
||||
|
||||
if self.dev is None:
|
||||
dev = _inf # type: Union[int, _Inf]
|
||||
else:
|
||||
dev = self.dev
|
||||
|
||||
if other.major == "NEXT":
|
||||
othermajor = _inf # type: Union[int, _Inf]
|
||||
else:
|
||||
othermajor = other.major
|
||||
|
||||
if other.release_candidate is None:
|
||||
otherrc = _inf # type: Union[int, _Inf]
|
||||
else:
|
||||
otherrc = other.release_candidate
|
||||
|
||||
if other.post is None:
|
||||
otherpost = -1
|
||||
else:
|
||||
otherpost = other.post
|
||||
|
||||
if other.dev is None:
|
||||
otherdev = _inf # type: Union[int, _Inf]
|
||||
else:
|
||||
otherdev = other.dev
|
||||
|
||||
x = _cmp(
|
||||
(major, self.minor, self.micro, release_candidate, post, dev),
|
||||
(othermajor, other.minor, other.micro, otherrc, otherpost, otherdev),
|
||||
)
|
||||
return x
|
||||
|
||||
def __eq__(self, other): # type: (object) -> bool
|
||||
c = self.__cmp__(other)
|
||||
if c is NotImplemented:
|
||||
return c # type: ignore[return-value]
|
||||
return c == 0
|
||||
|
||||
def __ne__(self, other): # type: (object) -> bool
|
||||
c = self.__cmp__(other)
|
||||
if c is NotImplemented:
|
||||
return c # type: ignore[return-value]
|
||||
return c != 0
|
||||
|
||||
def __lt__(self, other): # type: (object) -> bool
|
||||
c = self.__cmp__(other)
|
||||
if c is NotImplemented:
|
||||
return c # type: ignore[return-value]
|
||||
return c < 0
|
||||
|
||||
def __le__(self, other): # type: (object) -> bool
|
||||
c = self.__cmp__(other)
|
||||
if c is NotImplemented:
|
||||
return c # type: ignore[return-value]
|
||||
return c <= 0
|
||||
|
||||
def __gt__(self, other): # type: (object) -> bool
|
||||
c = self.__cmp__(other)
|
||||
if c is NotImplemented:
|
||||
return c # type: ignore[return-value]
|
||||
return c > 0
|
||||
|
||||
def __ge__(self, other): # type: (object) -> bool
|
||||
c = self.__cmp__(other)
|
||||
if c is NotImplemented:
|
||||
return c # type: ignore[return-value]
|
||||
return c >= 0
|
||||
|
||||
|
||||
def getVersionString(version): # type: (Version) -> str
|
||||
"""
|
||||
Get a friendly string for the given version object.
|
||||
|
||||
@param version: A L{Version} object.
|
||||
@return: A string containing the package and short version number.
|
||||
"""
|
||||
result = "%s %s" % (version.package, version.short())
|
||||
return result
|
||||
|
||||
|
||||
def _findPath(path, package): # type: (str, str) -> str
|
||||
"""
|
||||
Determine the package root directory.
|
||||
|
||||
The result is one of:
|
||||
|
||||
- src/{package}
|
||||
- {package}
|
||||
|
||||
Where {package} is downcased.
|
||||
"""
|
||||
src_dir = os.path.join(path, "src", package.lower())
|
||||
current_dir = os.path.join(path, package.lower())
|
||||
|
||||
if os.path.isdir(src_dir):
|
||||
return src_dir
|
||||
elif os.path.isdir(current_dir):
|
||||
return current_dir
|
||||
else:
|
||||
raise ValueError(
|
||||
"Can't find the directory of project {}: I looked in {} and {}".format(
|
||||
package, src_dir, current_dir
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _existing_version(version_path): # type: (str) -> Version
|
||||
"""
|
||||
Load the current version from a ``_version.py`` file.
|
||||
"""
|
||||
version_info = {} # type: Dict[str, Version]
|
||||
|
||||
with open(version_path, "r") as f:
|
||||
exec(f.read(), version_info)
|
||||
|
||||
return version_info["__version__"]
|
||||
|
||||
|
||||
def _get_setuptools_version(dist): # type: (_Distribution) -> None
|
||||
"""
|
||||
Setuptools integration: load the version from the working directory
|
||||
|
||||
This function is registered as a setuptools.finalize_distribution_options
|
||||
entry point [1]. Consequently, it is called in all sorts of weird
|
||||
contexts. In setuptools, silent failure is the law.
|
||||
|
||||
[1]: https://setuptools.pypa.io/en/latest/userguide/extension.html#customizing-distribution-options
|
||||
|
||||
@param dist:
|
||||
A (possibly) empty C{setuptools.Distribution} instance to mutate.
|
||||
There may be some metadata here if a `setup.py` called `setup()`,
|
||||
but this hook is always called before setuptools loads anything
|
||||
from ``pyproject.toml``.
|
||||
"""
|
||||
try:
|
||||
# When operating in a packaging context (i.e. building an sdist or
|
||||
# wheel) pyproject.toml will always be found in the current working
|
||||
# directory.
|
||||
config = _load_pyproject_toml("./pyproject.toml")
|
||||
except Exception:
|
||||
return
|
||||
|
||||
if not config.opt_in:
|
||||
return
|
||||
|
||||
try:
|
||||
version = _existing_version(config.version_path)
|
||||
except FileNotFoundError:
|
||||
return
|
||||
|
||||
dist.metadata.version = version.public()
|
||||
|
||||
|
||||
def _get_distutils_version(dist, keyword, value): # type: (_Distribution, object, object) -> None
|
||||
"""
|
||||
Distutils integration: get the version from the package listed in the Distribution.
|
||||
|
||||
This function is invoked when a C{setup.py} calls C{setup(use_incremental=True)}.
|
||||
|
||||
@see: https://setuptools.pypa.io/en/latest/userguide/extension.html#adding-arguments
|
||||
"""
|
||||
if not value: # use_incremental=False
|
||||
return # pragma: no cover
|
||||
|
||||
from setuptools.command import build_py # type: ignore
|
||||
|
||||
sp_command = build_py.build_py(dist)
|
||||
sp_command.finalize_options()
|
||||
|
||||
for item in sp_command.find_all_modules():
|
||||
if item[1] == "_version":
|
||||
version_path = os.path.join(os.path.dirname(item[2]), "_version.py")
|
||||
dist.metadata.version = _existing_version(version_path).public()
|
||||
return
|
||||
|
||||
raise Exception("No _version.py found.") # pragma: no cover
|
||||
|
||||
|
||||
def _load_toml(f): # type: (BinaryIO) -> Any
|
||||
"""
|
||||
Read the content of a TOML file.
|
||||
"""
|
||||
# This import is deferred to avoid a hard dependency on tomli
|
||||
# when no pyproject.toml is present.
|
||||
if sys.version_info > (3, 11):
|
||||
import tomllib
|
||||
else:
|
||||
import tomli as tomllib
|
||||
|
||||
return tomllib.load(f)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class _IncrementalConfig:
|
||||
"""
|
||||
Configuration loaded from a ``pyproject.toml`` file.
|
||||
"""
|
||||
|
||||
opt_in: bool
|
||||
"""
|
||||
Does the pyproject.toml file contain a [tool.incremental]
|
||||
section? This indicates that the package has explicitly
|
||||
opted-in to Incremental versioning.
|
||||
"""
|
||||
|
||||
package: str
|
||||
"""The project name, capitalized as in the project metadata."""
|
||||
|
||||
path: str
|
||||
"""Path to the package root"""
|
||||
|
||||
@property
|
||||
def version_path(self): # type: () -> str
|
||||
"""Path of the ``_version.py`` file. May not exist."""
|
||||
return os.path.join(self.path, "_version.py")
|
||||
|
||||
|
||||
def _load_pyproject_toml(toml_path): # type: (str) -> _IncrementalConfig
|
||||
"""
|
||||
Load Incremental configuration from a ``pyproject.toml``
|
||||
|
||||
If the [tool.incremental] section is empty we take the project name
|
||||
from the [project] section. Otherwise we require only a C{name} key
|
||||
specifying the project name. Other keys are forbidden to allow future
|
||||
extension and catch typos.
|
||||
|
||||
@param toml_path:
|
||||
Path to the ``pyproject.toml`` to load.
|
||||
"""
|
||||
with open(toml_path, "rb") as f:
|
||||
data = _load_toml(f)
|
||||
|
||||
tool_incremental = _extract_tool_incremental(data)
|
||||
|
||||
# Extract the project name
|
||||
package = None
|
||||
if tool_incremental is not None and "name" in tool_incremental:
|
||||
package = tool_incremental["name"]
|
||||
if package is None:
|
||||
# Try to fall back to [project]
|
||||
try:
|
||||
package = data["project"]["name"]
|
||||
except KeyError:
|
||||
pass
|
||||
if package is None:
|
||||
# We can't proceed without a project name.
|
||||
raise ValueError("""\
|
||||
Incremental failed to extract the project name from pyproject.toml. Specify it like:
|
||||
|
||||
[project]
|
||||
name = "Foo"
|
||||
|
||||
Or:
|
||||
|
||||
[tool.incremental]
|
||||
name = "Foo"
|
||||
|
||||
""")
|
||||
if not isinstance(package, str):
|
||||
raise TypeError(
|
||||
"The project name must be a string, but found {}".format(type(package))
|
||||
)
|
||||
|
||||
return _IncrementalConfig(
|
||||
opt_in=tool_incremental is not None,
|
||||
package=package,
|
||||
path=_findPath(os.path.dirname(toml_path), package),
|
||||
)
|
||||
|
||||
|
||||
def _extract_tool_incremental(data): # type: (Dict[str, object]) -> Optional[Dict[str, object]]
|
||||
if "tool" not in data:
|
||||
return None
|
||||
if not isinstance(data["tool"], dict):
|
||||
raise ValueError("[tool] must be a table")
|
||||
if "incremental" not in data["tool"]:
|
||||
return None
|
||||
|
||||
tool_incremental = data["tool"]["incremental"]
|
||||
if not isinstance(tool_incremental, dict):
|
||||
raise ValueError("[tool.incremental] must be a table")
|
||||
|
||||
if not {"name"}.issuperset(tool_incremental.keys()):
|
||||
raise ValueError("Unexpected key(s) in [tool.incremental]")
|
||||
return tool_incremental
|
||||
|
||||
|
||||
from ._version import __version__ # noqa: E402
|
||||
|
||||
|
||||
def _setuptools_version(): # type: () -> str
|
||||
return __version__.public() # pragma: no cover
|
||||
|
||||
|
||||
__all__ = ["__version__", "Version", "getVersionString"]
|
||||
Reference in New Issue
Block a user