aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-08-09 14:09:23 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-08-09 14:18:03 +0300
commitfc4431b2298b392e5ab598032f69123586c808e1 (patch)
treec9f8f753f0726a88d40bedd49a7da4e5f05f9adb
parent65146091795a50027474976479e03e0b64f9dbda (diff)
downloadydb-fc4431b2298b392e5ab598032f69123586c808e1.tar.gz
Intermediate changes
-rw-r--r--contrib/python/incremental/py3/.dist-info/METADATA126
-rw-r--r--contrib/python/incremental/py3/.dist-info/entry_points.txt8
-rw-r--r--contrib/python/incremental/py3/README.rst91
-rw-r--r--contrib/python/incremental/py3/incremental/__init__.py322
-rw-r--r--contrib/python/incremental/py3/incremental/_hatch.py37
-rw-r--r--contrib/python/incremental/py3/incremental/_version.py2
-rw-r--r--contrib/python/incremental/py3/incremental/update.py156
-rw-r--r--contrib/python/incremental/py3/ya.make8
8 files changed, 509 insertions, 241 deletions
diff --git a/contrib/python/incremental/py3/.dist-info/METADATA b/contrib/python/incremental/py3/.dist-info/METADATA
index c4a9409082..2bbcbfdc36 100644
--- a/contrib/python/incremental/py3/.dist-info/METADATA
+++ b/contrib/python/incremental/py3/.dist-info/METADATA
@@ -1,30 +1,29 @@
Metadata-Version: 2.1
Name: incremental
-Version: 22.10.0
-Summary: "A small library that versions your Python projects."
-Home-page: https://github.com/twisted/incremental
-Maintainer: Amber Brown
-Maintainer-email: hawkowl@twistedmatrix.com
-License: MIT
+Version: 24.7.0
+Summary: A small library that versions your Python projects.
+Maintainer-email: Amber Brown <hawkowl@twistedmatrix.com>
+Project-URL: Homepage, https://github.com/twisted/incremental
+Project-URL: Documentation, https://twisted.org/incremental/docs/
+Project-URL: Issues, https://github.com/twisted/incremental/issues
+Project-URL: Changelog, https://github.com/twisted/incremental/blob/trunk/NEWS.rst
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
+Classifier: Framework :: Hatch
+Classifier: Framework :: Setuptools Plugin
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Requires-Python: >=3.8
+Description-Content-Type: text/x-rst
License-File: LICENSE
-Provides-Extra: mypy
-Requires-Dist: click (>=6.0) ; extra == 'mypy'
-Requires-Dist: twisted (>=16.4.0) ; extra == 'mypy'
-Requires-Dist: mypy (==0.812) ; extra == 'mypy'
+Requires-Dist: setuptools >=61.0
+Requires-Dist: tomli ; python_version < "3.11"
Provides-Extra: scripts
-Requires-Dist: click (>=6.0) ; extra == 'scripts'
-Requires-Dist: twisted (>=16.4.0) ; extra == 'scripts'
+Requires-Dist: click >=6.0 ; extra == 'scripts'
Incremental
===========
@@ -35,15 +34,84 @@ Incremental
Incremental is a small library that versions your Python projects.
-API documentation can be found `here <https://twisted.github.io/incremental/docs/>`_.
+API documentation can be found `here <https://twisted.org/incremental/docs/>`_.
+.. contents::
Quick Start
-----------
-Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versioning arguments:
+Using setuptools
+~~~~~~~~~~~~~~~~
-.. code::
+Add Incremental to your ``pyproject.toml``:
+
+.. code-block:: toml
+
+ [build-system]
+ requires = [
+ "setuptools",
+ "incremental>=24.7.0", # ← Add incremental as a build dependency
+ ]
+ build-backend = "setuptools.build_meta"
+
+ [project]
+ name = "<projectname>"
+ dynamic = ["version"] # ← Mark the version dynamic
+ dependencies = [
+ "incremental>=24.7.0", # ← Depend on incremental at runtime
+ ]
+ # ...
+
+ [tool.incremental] # ← Activate Incremental's setuptools plugin
+
+It's fine if the ``[tool.incremental]`` table is empty, but it must be present.
+
+Remove any ``[project] version =`` entry and any ``[tool.setuptools.dynamic] version =`` entry.
+
+Next, `initialize the project`_.
+
+Using Hatchling
+~~~~~~~~~~~~~~~
+
+If you're using `Hatchling <https://hatch.pypa.io/>`_ to package your project,
+activate Incremental's Hatchling plugin by altering your ``pyproject.toml``:
+
+.. code:: toml
+
+ [build-system]
+ requires = [
+ "hatchling",
+ "incremental>=24.7.0", # ← Add incremental as a build dependency
+ ]
+ build-backend = "hatchling.build"
+
+ [project]
+ name = "<projectname>"
+ dynamic = ["version"] # ← Mark the version dynamic
+ dependencies = [
+ "incremental>=24.7.0", # ← Depend on incremental at runtime
+ ]
+ # ...
+
+ [tool.hatch.version]
+ source = "incremental" # ← Activate Incremental's Hatchling plugin
+
+Incremental can be configured as usual in an optional ``[tool.incremental]`` table.
+
+The ``hatch version`` command will report the Incremental-managed version.
+Use the ``python -m incremental.update`` command to change the version (setting it with ``hatch version`` is not supported).
+
+Next, `initialize the project`_.
+
+
+Using ``setup.py``
+~~~~~~~~~~~~~~~~~~
+
+Incremental may be used from ``setup.py`` instead of ``pyproject.toml``.
+Add this to your ``setup()`` call, removing any other versioning arguments:
+
+.. code:: python
setup(
use_incremental=True,
@@ -52,22 +120,27 @@ Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versionin
...
}
+Then `initialize the project`_.
+
+
+Initialize the project
+~~~~~~~~~~~~~~~~~~~~~~
Install Incremental to your local environment with ``pip install incremental[scripts]``.
Then run ``python -m incremental.update <projectname> --create``.
-It will create a file in your package named ``_version.py`` and look like this:
+It will create a file in your package named ``_version.py`` like this:
-.. code::
+.. code:: python
from incremental import Version
- __version__ = Version("widgetbox", 17, 1, 0)
+ __version__ = Version("<projectname>", 24, 1, 0)
__all__ = ["__version__"]
Then, so users of your project can find your version, in your root package's ``__init__.py`` add:
-.. code::
+.. code:: python
from ._version import __version__
@@ -75,6 +148,7 @@ Then, so users of your project can find your version, in your root package's ``_
Subsequent installations of your project will then use Incremental for versioning.
+
Incremental Versions
--------------------
@@ -89,7 +163,7 @@ It is made up of the following elements (which are given during instantiation):
You can extract a PEP-440 compatible version string by using the ``.public()`` method, which returns a ``str`` containing the full version. This is the version you should provide to users, or publicly use. An example output would be ``"13.2.0"``, ``"17.1.2dev1"``, or ``"18.8.0rc2"``.
-Calling ``repr()`` with a ``Version`` will give a Python-source-code representation of it, and calling ``str()`` with a ``Version`` will provide a string similar to ``'[Incremental, version 16.10.1]'``.
+Calling ``repr()`` with a ``Version`` will give a Python-source-code representation of it, and calling ``str()`` on a ``Version`` produces a string like ``'[Incremental, version 16.10.1]'``.
Updating
diff --git a/contrib/python/incremental/py3/.dist-info/entry_points.txt b/contrib/python/incremental/py3/.dist-info/entry_points.txt
index 1c7b4877c1..5e1e6d9974 100644
--- a/contrib/python/incremental/py3/.dist-info/entry_points.txt
+++ b/contrib/python/incremental/py3/.dist-info/entry_points.txt
@@ -1,2 +1,8 @@
[distutils.setup_keywords]
-use_incremental = incremental:_get_version
+use_incremental = incremental:_get_distutils_version
+
+[hatch]
+incremental = incremental._hatch
+
+[setuptools.finalize_distribution_options]
+incremental = incremental:_get_setuptools_version
diff --git a/contrib/python/incremental/py3/README.rst b/contrib/python/incremental/py3/README.rst
index 7a20d077af..56baba2fca 100644
--- a/contrib/python/incremental/py3/README.rst
+++ b/contrib/python/incremental/py3/README.rst
@@ -7,15 +7,84 @@ Incremental
Incremental is a small library that versions your Python projects.
-API documentation can be found `here <https://twisted.github.io/incremental/docs/>`_.
+API documentation can be found `here <https://twisted.org/incremental/docs/>`_.
+.. contents::
Quick Start
-----------
-Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versioning arguments:
+Using setuptools
+~~~~~~~~~~~~~~~~
-.. code::
+Add Incremental to your ``pyproject.toml``:
+
+.. code-block:: toml
+
+ [build-system]
+ requires = [
+ "setuptools",
+ "incremental>=24.7.0", # ← Add incremental as a build dependency
+ ]
+ build-backend = "setuptools.build_meta"
+
+ [project]
+ name = "<projectname>"
+ dynamic = ["version"] # ← Mark the version dynamic
+ dependencies = [
+ "incremental>=24.7.0", # ← Depend on incremental at runtime
+ ]
+ # ...
+
+ [tool.incremental] # ← Activate Incremental's setuptools plugin
+
+It's fine if the ``[tool.incremental]`` table is empty, but it must be present.
+
+Remove any ``[project] version =`` entry and any ``[tool.setuptools.dynamic] version =`` entry.
+
+Next, `initialize the project`_.
+
+Using Hatchling
+~~~~~~~~~~~~~~~
+
+If you're using `Hatchling <https://hatch.pypa.io/>`_ to package your project,
+activate Incremental's Hatchling plugin by altering your ``pyproject.toml``:
+
+.. code:: toml
+
+ [build-system]
+ requires = [
+ "hatchling",
+ "incremental>=24.7.0", # ← Add incremental as a build dependency
+ ]
+ build-backend = "hatchling.build"
+
+ [project]
+ name = "<projectname>"
+ dynamic = ["version"] # ← Mark the version dynamic
+ dependencies = [
+ "incremental>=24.7.0", # ← Depend on incremental at runtime
+ ]
+ # ...
+
+ [tool.hatch.version]
+ source = "incremental" # ← Activate Incremental's Hatchling plugin
+
+Incremental can be configured as usual in an optional ``[tool.incremental]`` table.
+
+The ``hatch version`` command will report the Incremental-managed version.
+Use the ``python -m incremental.update`` command to change the version (setting it with ``hatch version`` is not supported).
+
+Next, `initialize the project`_.
+
+
+Using ``setup.py``
+~~~~~~~~~~~~~~~~~~
+
+Incremental may be used from ``setup.py`` instead of ``pyproject.toml``.
+Add this to your ``setup()`` call, removing any other versioning arguments:
+
+.. code:: python
setup(
use_incremental=True,
@@ -24,22 +93,27 @@ Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versionin
...
}
+Then `initialize the project`_.
+
+
+Initialize the project
+~~~~~~~~~~~~~~~~~~~~~~
Install Incremental to your local environment with ``pip install incremental[scripts]``.
Then run ``python -m incremental.update <projectname> --create``.
-It will create a file in your package named ``_version.py`` and look like this:
+It will create a file in your package named ``_version.py`` like this:
-.. code::
+.. code:: python
from incremental import Version
- __version__ = Version("widgetbox", 17, 1, 0)
+ __version__ = Version("<projectname>", 24, 1, 0)
__all__ = ["__version__"]
Then, so users of your project can find your version, in your root package's ``__init__.py`` add:
-.. code::
+.. code:: python
from ._version import __version__
@@ -47,6 +121,7 @@ Then, so users of your project can find your version, in your root package's ``_
Subsequent installations of your project will then use Incremental for versioning.
+
Incremental Versions
--------------------
@@ -61,7 +136,7 @@ It is made up of the following elements (which are given during instantiation):
You can extract a PEP-440 compatible version string by using the ``.public()`` method, which returns a ``str`` containing the full version. This is the version you should provide to users, or publicly use. An example output would be ``"13.2.0"``, ``"17.1.2dev1"``, or ``"18.8.0rc2"``.
-Calling ``repr()`` with a ``Version`` will give a Python-source-code representation of it, and calling ``str()`` with a ``Version`` will provide a string similar to ``'[Incremental, version 16.10.1]'``.
+Calling ``repr()`` with a ``Version`` will give a Python-source-code representation of it, and calling ``str()`` on a ``Version`` produces a string like ``'[Incremental, version 16.10.1]'``.
Updating
diff --git a/contrib/python/incremental/py3/incremental/__init__.py b/contrib/python/incremental/py3/incremental/__init__.py
index c0c06c0ae1..b10d5be033 100644
--- a/contrib/python/incremental/py3/incremental/__init__.py
+++ b/contrib/python/incremental/py3/incremental/__init__.py
@@ -9,44 +9,37 @@ 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
-
-#
-# Compat functions
-#
-
-_T = TypeVar("_T", contravariant=True)
+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
-else:
- _Distribution = object
-
-if sys.version_info > (3,):
-
- def _cmp(a, b): # type: (Any, Any) -> int
- """
- Compare two objects.
+#
+# Compat functions
+#
- 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
+def _cmp(a, b): # type: (Any, Any) -> int
+ """
+ Compare two objects.
-else:
- _cmp = cmp # noqa: F821
+ 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
#
@@ -71,19 +64,17 @@ class _Inf(object):
return 0
return 1
- if sys.version_info >= (3,):
-
- def __lt__(self, other): # type: (object) -> bool
- return self.__cmp__(other) < 0
+ 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 __le__(self, other): # type: (object) -> bool
+ return self.__cmp__(other) <= 0
- def __gt__(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
+ def __ge__(self, other): # type: (object) -> bool
+ return self.__cmp__(other) >= 0
_inf = _Inf()
@@ -167,7 +158,7 @@ class Version(object):
"Version.release_candidate instead.",
DeprecationWarning,
stacklevel=2,
- ),
+ )
return self.release_candidate
def public(self): # type: () -> str
@@ -187,7 +178,7 @@ class Version(object):
if self.release_candidate is None:
rc = ""
else:
- rc = ".rc%s" % (self.release_candidate,)
+ rc = "rc%s" % (self.release_candidate,)
if self.post is None:
post = ""
@@ -206,7 +197,6 @@ class Version(object):
local = public
def __repr__(self): # type: () -> str
-
if self.release_candidate is None:
release_candidate = ""
else:
@@ -236,7 +226,7 @@ class Version(object):
def __str__(self): # type: () -> str
return "[%s, version %s]" % (self.package, self.short())
- def __cmp__(self, other): # type: (Version) -> int
+ def __cmp__(self, other): # type: (object) -> int
"""
Compare two versions, considering major versions, minor versions, micro
versions, then release candidates, then postreleases, then dev
@@ -310,43 +300,41 @@ class Version(object):
)
return x
- if sys.version_info >= (3,):
-
- def __eq__(self, other): # type: (Any) -> bool
- c = self.__cmp__(other)
- if c is NotImplemented:
- return c # type: ignore[return-value]
- return c == 0
-
- def __ne__(self, other): # type: (Any) -> bool
- c = self.__cmp__(other)
- if c is NotImplemented:
- return c # type: ignore[return-value]
- return c != 0
-
- def __lt__(self, other): # type: (Version) -> bool
- c = self.__cmp__(other)
- if c is NotImplemented:
- return c # type: ignore[return-value]
- return c < 0
-
- def __le__(self, other): # type: (Version) -> bool
- c = self.__cmp__(other)
- if c is NotImplemented:
- return c # type: ignore[return-value]
- return c <= 0
-
- def __gt__(self, other): # type: (Version) -> bool
- c = self.__cmp__(other)
- if c is NotImplemented:
- return c # type: ignore[return-value]
- return c > 0
-
- def __ge__(self, other): # type: (Version) -> bool
- c = self.__cmp__(other)
- if c is NotImplemented:
- return c # type: ignore[return-value]
- return c >= 0
+ 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
@@ -360,36 +348,192 @@ def getVersionString(version): # type: (Version) -> str
return result
-def _get_version(dist, keyword, value): # type: (_Distribution, object, object) -> None
+def _findPath(path, package): # type: (str, str) -> str
"""
- Get the version from the package listed in the Distribution.
+ 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 package {}: I looked in {} and {}".format(
+ package, src_dir, current_dir
+ )
+ )
+
+
+def _existing_version(path): # type: (str) -> Version
+ """
+ Load the current version from {path}/_version.py.
+ """
+ version_info = {} # type: Dict[str, Version]
+
+ versionpath = os.path.join(path, "_version.py")
+ with open(versionpath, "r") as f:
+ exec(f.read(), version_info)
+
+ return version_info["__version__"]
+
+
+def _get_setuptools_version(dist): # type: (_Distribution) -> None
"""
- if not value:
+ Setuptools integration: load the version from the working directory
+
+ This function is registered as a setuptools.finalize_distribution_options
+ entry point [1]. It is a no-op unless there is a pyproject.toml containing
+ an empty [tool.incremental] section.
+
+ @param dist: An empty C{setuptools.Distribution} instance to mutate.
+
+ [1]: https://setuptools.pypa.io/en/latest/userguide/extension.html#customizing-distribution-options
+ """
+ config = _load_pyproject_toml("./pyproject.toml")
+ if not config or not config.has_tool_incremental:
return
- from distutils.command import build_py
+ dist.metadata.version = _existing_version(config.path).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(): # type: ignore[attr-defined]
+ for item in sp_command.find_all_modules():
if item[1] == "_version":
- version_file = {} # type: Dict[str, Version]
+ package_path = os.path.dirname(item[2])
+ dist.metadata.version = _existing_version(package_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.
+ """
+
+ has_tool_incremental: 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 package name, capitalized as in the package metadata."""
+
+ path: str
+ """Path to the package root"""
+
+
+def _load_pyproject_toml(toml_path): # type: (str) -> Optional[_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.
+ """
+ try:
+ with open(toml_path, "rb") as f:
+ data = _load_toml(f)
+ except FileNotFoundError:
+ return None
+
+ tool_incremental = _extract_tool_incremental(data)
+
+ if tool_incremental is None or tool_incremental == {}:
+ try:
+ package = data["project"]["name"]
+ except KeyError:
+ raise ValueError("""\
+Couldn't extract the package name from pyproject.toml. Specify it like:
+
+ [project]
+ name = "Foo"
+
+Or:
+
+ [tool.incremental]
+ name = "Foo"
+""")
+ elif tool_incremental.keys() == {"name"}:
+ package = tool_incremental["name"]
+ else:
+ raise ValueError("Unexpected key(s) in [tool.incremental]")
+
+ if not isinstance(package, str):
+ raise TypeError(
+ "Package name must be a string, but found {}".format(type(package))
+ )
+
+ return _IncrementalConfig(
+ has_tool_incremental=tool_incremental is not None,
+ package=package,
+ path=_findPath(os.path.dirname(toml_path), package),
+ )
+
- with open(item[2]) as f:
- exec(f.read(), version_file)
+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
- dist.metadata.version = version_file["__version__"].public()
- return None
+ tool_incremental = data["tool"]["incremental"]
+ if not isinstance(tool_incremental, dict):
+ raise ValueError("[tool.incremental] must be a table")
- raise Exception("No _version.py found.")
+ return tool_incremental
from ._version import __version__ # noqa: E402
def _setuptools_version(): # type: () -> str
- return __version__.public()
+ return __version__.public() # pragma: no cover
__all__ = ["__version__", "Version", "getVersionString"]
diff --git a/contrib/python/incremental/py3/incremental/_hatch.py b/contrib/python/incremental/py3/incremental/_hatch.py
new file mode 100644
index 0000000000..8d677c4b9d
--- /dev/null
+++ b/contrib/python/incremental/py3/incremental/_hatch.py
@@ -0,0 +1,37 @@
+# Copyright (c) Twisted Matrix Laboratories.
+# See LICENSE for details.
+
+import os
+import shlex
+from typing import Any, Dict, List, Type, TypedDict
+
+from hatchling.version.source.plugin.interface import VersionSourceInterface
+from hatchling.plugin import hookimpl
+
+from incremental import _load_pyproject_toml, _existing_version
+
+
+class _VersionData(TypedDict):
+ version: str
+
+
+class IncrementalVersionSource(VersionSourceInterface):
+ PLUGIN_NAME = "incremental"
+
+ def get_version_data(self) -> _VersionData: # type: ignore[override]
+ path = os.path.join(self.root, "./pyproject.toml")
+ config = _load_pyproject_toml(path)
+ assert config is not None, "Failed to read {}".format(path)
+ return {"version": _existing_version(config.path).public()}
+
+ def set_version(self, version: str, version_data: Dict[Any, Any]) -> None:
+ raise NotImplementedError(
+ f"Run `python -m incremental.version --newversion"
+ f" {shlex.quote(version)}` to set the version.\n\n"
+ f" See `python -m incremental.version --help` for more options."
+ )
+
+
+@hookimpl
+def hatch_register_version_source() -> List[Type[VersionSourceInterface]]:
+ return [IncrementalVersionSource]
diff --git a/contrib/python/incremental/py3/incremental/_version.py b/contrib/python/incremental/py3/incremental/_version.py
index 12cb1b8151..672cfb7961 100644
--- a/contrib/python/incremental/py3/incremental/_version.py
+++ b/contrib/python/incremental/py3/incremental/_version.py
@@ -7,5 +7,5 @@ Provides Incremental version information.
from incremental import Version
-__version__ = Version("Incremental", 22, 10, 0)
+__version__ = Version("Incremental", 24, 7, 0)
__all__ = ["__version__"]
diff --git a/contrib/python/incremental/py3/incremental/update.py b/contrib/python/incremental/py3/incremental/update.py
index 64a5cc84e7..f3e33ee003 100644
--- a/contrib/python/incremental/py3/incremental/update.py
+++ b/contrib/python/incremental/py3/incremental/update.py
@@ -6,53 +6,9 @@ from __future__ import absolute_import, division, print_function
import click
import os
import datetime
-from typing import TYPE_CHECKING, Dict, Optional, Callable, Iterable
+from typing import Dict, Optional, Callable
-from incremental import Version
-
-if TYPE_CHECKING:
- from typing_extensions import Protocol
-
- class _ReadableWritable(Protocol):
- def read(self): # type: () -> bytes
- pass
-
- def write(self, v): # type: (bytes) -> object
- pass
-
- def __enter__(self): # type: () -> _ReadableWritable
- pass
-
- def __exit__(self, *args, **kwargs): # type: (object, object) -> Optional[bool]
- pass
-
- # FilePath is missing type annotations
- # https://twistedmatrix.com/trac/ticket/10148
- class FilePath(object):
- def __init__(self, path): # type: (str) -> None
- self.path = path
-
- def child(self, v): # type: (str) -> FilePath
- pass
-
- def isdir(self): # type: () -> bool
- pass
-
- def isfile(self): # type: () -> bool
- pass
-
- def getContent(self): # type: () -> bytes
- pass
-
- def open(self, mode): # type: (str) -> _ReadableWritable
- pass
-
- def walk(self): # type: () -> Iterable[FilePath]
- pass
-
-
-else:
- from twisted.python.filepath import FilePath
+from incremental import Version, _findPath, _existing_version
_VERSIONPY_TEMPLATE = '''"""
Provides {package} version information.
@@ -70,35 +26,6 @@ __all__ = ["__version__"]
_YEAR_START = 2000
-def _findPath(path, package): # type: (str, str) -> FilePath
-
- cwd = FilePath(path)
-
- src_dir = cwd.child("src").child(package.lower())
- current_dir = cwd.child(package.lower())
-
- if src_dir.isdir():
- return src_dir
- elif current_dir.isdir():
- return current_dir
- else:
- raise ValueError(
- "Can't find under `./src` or `./`. Check the "
- "package name is right (note that we expect your "
- "package name to be lower cased), or pass it using "
- "'--path'."
- )
-
-
-def _existing_version(path): # type: (FilePath) -> Version
- version_info = {} # type: Dict[str, Version]
-
- with path.child("_version.py").open("r") as f:
- exec(f.read(), version_info)
-
- return version_info["__version__"]
-
-
def _run(
package, # type: str
path, # type: Optional[str]
@@ -112,17 +39,14 @@ def _run(
_getcwd=None, # type: Optional[Callable[[], str]]
_print=print, # type: Callable[[object], object]
): # type: (...) -> None
-
if not _getcwd:
_getcwd = os.getcwd
if not _date:
_date = datetime.date.today()
- if type(package) != str:
- package = package.encode("utf8") # type: ignore[assignment]
-
- _path = FilePath(path) if path else _findPath(_getcwd(), package)
+ if not path:
+ path = _findPath(_getcwd(), package)
if (
newversion
@@ -156,7 +80,7 @@ def _run(
if newversion:
from pkg_resources import parse_version
- existing = _existing_version(_path)
+ existing = _existing_version(path)
st_version = parse_version(newversion)._version # type: ignore[attr-defined]
release = list(st_version.release)
@@ -185,7 +109,7 @@ def _run(
existing = v
elif rc and not patch:
- existing = _existing_version(_path)
+ existing = _existing_version(path)
if existing.release_candidate:
v = Version(
@@ -199,7 +123,7 @@ def _run(
v = Version(package, _date.year - _YEAR_START, _date.month, 0, 1)
elif patch:
- existing = _existing_version(_path)
+ existing = _existing_version(path)
v = Version(
package,
existing.major,
@@ -209,7 +133,7 @@ def _run(
)
elif post:
- existing = _existing_version(_path)
+ existing = _existing_version(path)
if existing.post is None:
_post = 0
@@ -219,7 +143,7 @@ def _run(
v = Version(package, existing.major, existing.minor, existing.micro, post=_post)
elif dev:
- existing = _existing_version(_path)
+ existing = _existing_version(path)
if existing.dev is None:
_dev = 0
@@ -236,7 +160,7 @@ def _run(
)
else:
- existing = _existing_version(_path)
+ existing = _existing_version(path)
if existing.release_candidate:
v = Version(package, existing.major, existing.minor, existing.micro)
@@ -254,41 +178,43 @@ def _run(
_print("Updating codebase to %s" % (v.public()))
- for x in _path.walk():
-
- if not x.isfile():
- continue
-
- original_content = x.getContent()
- content = original_content
+ for dirpath, dirnames, filenames in os.walk(path):
+ for filename in filenames:
+ filepath = os.path.join(dirpath, filename)
+ with open(filepath, "rb") as f:
+ original_content = f.read()
+ content = original_content
+
+ # Replace previous release_candidate calls to the new one
+ if existing.release_candidate:
+ content = content.replace(
+ existing_version_repr_bytes, version_repr_bytes
+ )
+ content = content.replace(
+ (package.encode("utf8") + b" " + existing.public().encode("utf8")),
+ (package.encode("utf8") + b" " + v.public().encode("utf8")),
+ )
+
+ # Replace NEXT Version calls with the new one
+ content = content.replace(NEXT_repr_bytes, version_repr_bytes)
+ content = content.replace(
+ NEXT_repr_bytes.replace(b"'", b'"'), version_repr_bytes
+ )
- # Replace previous release_candidate calls to the new one
- if existing.release_candidate:
- content = content.replace(existing_version_repr_bytes, version_repr_bytes)
+ # Replace <package> NEXT with <package> <public>
content = content.replace(
- (package.encode("utf8") + b" " + existing.public().encode("utf8")),
+ package.encode("utf8") + b" NEXT",
(package.encode("utf8") + b" " + v.public().encode("utf8")),
)
- # Replace NEXT Version calls with the new one
- content = content.replace(NEXT_repr_bytes, version_repr_bytes)
- content = content.replace(
- NEXT_repr_bytes.replace(b"'", b'"'), version_repr_bytes
- )
-
- # Replace <package> NEXT with <package> <public>
- content = content.replace(
- package.encode("utf8") + b" NEXT",
- (package.encode("utf8") + b" " + v.public().encode("utf8")),
- )
-
- if content != original_content:
- _print("Updating %s" % (x.path,))
- with x.open("w") as f:
- f.write(content)
+ if content != original_content:
+ _print("Updating %s" % (filepath,))
+ with open(filepath, "wb") as f:
+ f.write(content)
- _print("Updating %s/_version.py" % (_path.path))
- with _path.child("_version.py").open("w") as f:
+ versionpath = os.path.join(path, "_version.py")
+ _print("Updating %s" % (versionpath,))
+ with open(versionpath, "wb") as f:
f.write(
(
_VERSIONPY_TEMPLATE.format(package=package, version_repr=version_repr)
diff --git a/contrib/python/incremental/py3/ya.make b/contrib/python/incremental/py3/ya.make
index 57846dd33a..66ee789b70 100644
--- a/contrib/python/incremental/py3/ya.make
+++ b/contrib/python/incremental/py3/ya.make
@@ -2,19 +2,25 @@
PY3_LIBRARY()
-VERSION(22.10.0)
+VERSION(24.7.0)
LICENSE(MIT)
+PEERDIR(
+ contrib/python/setuptools
+)
+
NO_LINT()
NO_CHECK_IMPORTS(
+ incremental._hatch
incremental.update
)
PY_SRCS(
TOP_LEVEL
incremental/__init__.py
+ incremental/_hatch.py
incremental/_version.py
incremental/update.py
)