From f0d72de63f491822f8abe09205c61683243d1e9a Mon Sep 17 00:00:00 2001 From: Sijis Aviles Date: Fri, 1 May 2026 00:16:15 -0500 Subject: [PATCH 1/4] chore: migrate to pyproject.toml and add PEP 751 lockfile Replace setup.py with a pyproject.toml (setuptools backend) and add a uv-generated pylock.toml so installs are reproducible. Update docs to include contribution and release details. --- docs/contributing.rst | 74 +++++++++++ pylock.toml | 216 +++++++++++++++++++++++++++++++++ pyproject.toml | 88 ++++++++++++++ setup.py | 160 ------------------------ tests/release_metadata_test.py | 38 ++++++ tox.ini | 3 +- 6 files changed, 418 insertions(+), 161 deletions(-) create mode 100644 pylock.toml create mode 100644 pyproject.toml delete mode 100644 setup.py create mode 100644 tests/release_metadata_test.py diff --git a/docs/contributing.rst b/docs/contributing.rst index 43a8d2c22..5b141b6c1 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -27,6 +27,28 @@ Clone you github fork repo locally and install errbot in development mode from t From there, anytime you execute `errbot` it will run from the checked out version of Errbot with all your local changes taken into account. +Updating the dependency lockfile +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Errbot ships a pinned dependency lockfile (``pylock.toml``) in `PEP 751`_ format, +generated by uv_ from the top-level dependencies declared in ``pyproject.toml``. +The lockfile is the source of truth for reproducible installs in CI and for +downstream consumers that want exact versions. + +Regenerate the lockfile any time you change a dependency in ``pyproject.toml`` (or +to refresh the pinned versions). From the root of the repository:: + + # Install uv if you don't have it (https://docs.astral.sh/uv/) + pip install uv + + # Recompile the lockfile from pyproject.toml, pinned to the project's + # minimum supported Python version so the resolution covers 3.9+. + uv pip compile pyproject.toml -o pylock.toml \ + --format pylock.toml --python-version 3.9 + +Commit the resulting ``pylock.toml`` alongside your ``pyproject.toml`` change in +the same pull request so the two stay in sync. + Preparing your pull request ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,6 +64,56 @@ these guidelines as you open a pull request. * If you can, please add tests for your code. We know large parts of our codebase are missing tests, so we won't reject your code if it lacks tests, though. +Releasing Errbot +---------------- + +This section is for maintainers cutting a release. The flow assumes a CHANGES.rst +maintained by hand under a ``v9.9.9 (unreleased)`` heading on master. + +Cutting a release +~~~~~~~~~~~~~~~~~ + +1. **Open a release PR** that does two edits: + + - Bump ``errbot/version.py``:: + + VERSION = "X.Y.Z" + + - Rename the unreleased heading in ``CHANGES.rst`` from ``v9.9.9 (unreleased)`` + to ``vX.Y.Z (YYYY-MM-DD)`` and double-check the entries beneath it. + +2. **Let CI gate the change.** The test ``tests/release_metadata_test.py`` skips on the + ``9.9.9`` sentinel but, once ``version.py`` is bumped, asserts that ``CHANGES.rst`` + contains a section heading for the new version. A release PR that forgets the heading + rename will fail this test before it can merge. + +3. **Merge the release PR**, then run the release tooling from a clean checkout:: + + ./tools/releases.sh + + The script reruns the same pre-release gate, builds the sdist/wheel with + ``python -m build``, and calls ``twine`` to publish to PyPI. + +4. **Tag the commit** and push the tag:: + + git tag vX.Y.Z + git push origin vX.Y.Z + +5. **Return master to dev mode** in a follow-up PR: + + - Reset ``errbot/version.py`` to ``VERSION = "9.9.9"``. + - Add a fresh ``v9.9.9 (unreleased)`` heading at the top of ``CHANGES.rst``. + +After this, the gate test goes back to skipping on master and the next release +cycle starts. + +Refreshing the lockfile for a release +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If dependency pins have changed since the previous release, regenerate +``pylock.toml`` (see `Updating the dependency lockfile`_) and include the result +in the release PR. + Contributing documentation & making changes to the website ---------------------------------------------------------- @@ -94,3 +166,5 @@ to ask your question on Stack Overflow, `tagged errbot .. _repos.py: https://github.com/errbotio/errbot/blob/master/errbot/repos.py .. _`issue tracker`: https://github.com/errbotio/errbot/issues/ .. _Gitter: https://gitter.im/errbotio/errbot +.. _uv: https://docs.astral.sh/uv/ +.. _`PEP 751`: https://peps.python.org/pep-0751/ diff --git a/pylock.toml b/pylock.toml new file mode 100644 index 000000000..c6e392639 --- /dev/null +++ b/pylock.toml @@ -0,0 +1,216 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml -o pylock.toml --format pylock.toml --python-version 3.9 +lock-version = "1.0" +created-by = "uv" +requires-python = ">=3.9" + +[[packages]] +name = "ansi" +version = "0.3.6" +sdist = { url = "https://files.pythonhosted.org/packages/ec/ab/a779658c03d9d6d4e4b9e24e50708fc1d214424829407360bd5a1189b675/ansi-0.3.6.tar.gz", upload-time = 2022-02-08T14:22:06Z, size = 7252, hashes = { sha256 = "10545ce2508e470e9208d0cc200616032fdc81b849678826fb7c81c823fd48b1" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/19/d0/d6bc8e852dd8f7e29d9213820857eb69d057f6171cbefd4c7b26700b8bc5/ansi-0.3.6-py3-none-any.whl", upload-time = 2022-02-08T14:22:05Z, size = 8600, hashes = { sha256 = "a83f7e6e7a9a84f4cc2904e28e575516cf42cf862777649e57615d85ac76e11d" } }] + +[[packages]] +name = "beautifulsoup4" +version = "4.14.3" +sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", upload-time = 2025-11-30T15:08:26Z, size = 627737, hashes = { sha256 = "6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", upload-time = 2025-11-30T15:08:24Z, size = 107721, hashes = { sha256 = "0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb" } }] + +[[packages]] +name = "blinker" +version = "1.9.0" +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", upload-time = 2024-11-08T17:25:47Z, size = 22460, hashes = { sha256 = "b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", upload-time = 2024-11-08T17:25:46Z, size = 8458, hashes = { sha256 = "ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc" } }] + +[[packages]] +name = "certifi" +version = "2026.4.22" +sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", upload-time = 2026-04-22T11:26:11Z, size = 137077, hashes = { sha256 = "8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", upload-time = 2026-04-22T11:26:09Z, size = 135707, hashes = { sha256 = "3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a" } }] + +[[packages]] +name = "cffi" +version = "2.0.0" +marker = "platform_python_implementation != 'PyPy'" +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", upload-time = 2025-09-08T23:24:04Z, size = 523588, hashes = { sha256 = "44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/3d/de/38d9726324e127f727b4ecc376bc85e505bfe61ef130eaf3f290c6847dd4/cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", upload-time = 2025-09-08T23:23:49Z, size = 180509, hashes = { sha256 = "de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7" } }] + +[[packages]] +name = "charset-normalizer" +version = "3.4.7" +sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", upload-time = 2026-04-02T09:28:39Z, size = 144271, hashes = { sha256 = "ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5" } } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/1b/ef725f8eb19b5a261b30f78efa9252ef9d017985cb499102f6f49834cd12/charset_normalizer-3.4.7-cp39-cp39-macosx_10_9_universal2.whl", upload-time = 2026-04-02T09:28:14Z, size = 299121, hashes = { sha256 = "177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217" } }, + { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", upload-time = 2026-04-02T09:28:37Z, size = 61958, hashes = { sha256 = "3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d" } }, +] + +[[packages]] +name = "click" +version = "8.1.8" +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", upload-time = 2024-12-21T18:38:44Z, size = 226593, hashes = { sha256 = "ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", upload-time = 2024-12-21T18:38:41Z, size = 98188, hashes = { sha256 = "63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2" } }] + +[[packages]] +name = "colorlog" +version = "6.7.0" +sdist = { url = "https://files.pythonhosted.org/packages/78/6b/4e5481ddcdb9c255b2715f54c863629f1543e97bc8c309d1c5c131ad14f2/colorlog-6.7.0.tar.gz", upload-time = 2022-08-29T14:51:27Z, size = 29920, hashes = { sha256 = "bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/58/43/a363c213224448f9e194d626221123ce00e3fb3d87c0c22aed52b620bdd1/colorlog-6.7.0-py2.py3-none-any.whl", upload-time = 2022-08-29T14:51:26Z, size = 11286, hashes = { sha256 = "0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662" } }] + +[[packages]] +name = "cryptography" +version = "44.0.3" +sdist = { url = "https://files.pythonhosted.org/packages/53/d6/1411ab4d6108ab167d06254c5be517681f1e331f90edf1379895bcb87020/cryptography-44.0.3.tar.gz", upload-time = 2025-05-02T19:36:04Z, size = 711096, hashes = { sha256 = "fe19d8bc5536a91a24a8133328880a41831b6c5df54599a8417b62fe015d3053" } } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/53/c776d80e9d26441bb3868457909b4e74dd9ccabd182e10b2b0ae7a07e265/cryptography-44.0.3-cp37-abi3-macosx_10_9_universal2.whl", upload-time = 2025-05-02T19:34:50Z, size = 6670281, hashes = { sha256 = "962bc30480a08d133e631e8dfd4783ab71cc9e33d5d7c1e192f0b7c06397bb88" } }, + { url = "https://files.pythonhosted.org/packages/34/a3/ad08e0bcc34ad436013458d7528e83ac29910943cea42ad7dd4141a27bbb/cryptography-44.0.3-cp39-abi3-macosx_10_9_universal2.whl", upload-time = 2025-05-02T19:35:13Z, size = 6673501, hashes = { sha256 = "5639c2b16764c6f76eedf722dbad9a0914960d3489c0cc38694ddf9464f1bb2f" } }, +] + +[[packages]] +name = "daemonize" +version = "2.5.0" +marker = "sys_platform != 'win32'" +sdist = { url = "https://files.pythonhosted.org/packages/8c/20/96f7dbc23812cfe4cf479c87af3e4305d0d115fd1fffec32ddeee7b9c82b/daemonize-2.5.0.tar.gz", upload-time = 2018-12-12T19:47:39Z, size = 8759, hashes = { sha256 = "dd026e4ff8d22cb016ed2130bc738b7d4b1da597ef93c074d2adb9e4dea08bc3" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/45/ad/1b20db02287afd40d3130a218ac5ce2f7d2ab581cfda29bada5e1c4bee17/daemonize-2.5.0-py2.py3-none-any.whl", upload-time = 2018-12-12T19:47:37Z, size = 5231, hashes = { sha256 = "9b6b91311a9d934ff3f5f766666635ca280d3de8e7137e4cd7d3f052543b989f" } }] + +[[packages]] +name = "deepmerge" +version = "1.1.0" +sdist = { url = "https://files.pythonhosted.org/packages/82/d7/75916d41be4c45a8d9b93d1bb089ac46de0212630641972982023d785d1f/deepmerge-1.1.0.tar.gz", upload-time = 2022-10-25T05:24:36Z, size = 17785, hashes = { sha256 = "4c27a0db5de285e1a7ceac7dbc1531deaa556b627dea4900c8244581ecdfea2d" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/59/72/72489ad8d3fe1cf5e5be93bf27ca4b5c792d552a5f667367b32a671a2076/deepmerge-1.1.0-py3-none-any.whl", upload-time = 2022-10-25T05:24:34Z, size = 8501, hashes = { sha256 = "59e6ef80b77dc52af3882a1ea78da22bcfc91ae9cdabc0c80729049fe295ff8b" } }] + +[[packages]] +name = "dulwich" +version = "0.21.5" +sdist = { url = "https://files.pythonhosted.org/packages/8c/6c/57adedfc2e1debb62581e9b413d2be78ea62e1da47d21fdd9d0d10317ebc/dulwich-0.21.5.tar.gz", upload-time = 2023-05-04T02:47:53Z, size = 441948, hashes = { sha256 = "70955e4e249ddda6e34a4636b90f74e931e558f993b17c52570fa6144b993103" } } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/48/4308b462565ed6b52a25535fa4b6ed99de052314c35d2f1214991de8aec4/dulwich-0.21.5-cp39-cp39-macosx_10_9_universal2.whl", upload-time = 2023-05-04T03:20:28Z, size = 470766, hashes = { sha256 = "fd4ad079758514375f11469e081723ba8831ce4eaa1a64b41f06a3a866d5ac34" } }, + { url = "https://files.pythonhosted.org/packages/b7/57/37fd47365baad8da470bbf7569494a2707f4972d79111d20d03df971420b/dulwich-0.21.5-cp39-cp39-macosx_11_0_arm64.whl", upload-time = 2023-05-04T03:20:31Z, size = 470750, hashes = { sha256 = "aae448da7d80306dda4fc46292fed7efaa466294571ab3448be16714305076f1" } }, +] + +[[packages]] +name = "flask" +version = "2.3.3" +sdist = { url = "https://files.pythonhosted.org/packages/46/b7/4ace17e37abd9c21715dea5ee11774a25e404c486a7893fa18e764326ead/flask-2.3.3.tar.gz", upload-time = 2023-08-21T19:52:35Z, size = 672756, hashes = { sha256 = "09c347a92aa7ff4a8e7f3206795f30d826654baf38b873d0744cd571ca609efc" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/fd/56/26f0be8adc2b4257df20c1c4260ddd0aa396cf8e75d90ab2f7ff99bc34f9/flask-2.3.3-py3-none-any.whl", upload-time = 2023-08-21T19:52:33Z, size = 96112, hashes = { sha256 = "f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b" } }] + +[[packages]] +name = "idna" +version = "3.13" +sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", upload-time = 2026-04-22T16:42:42Z, size = 194210, hashes = { sha256 = "585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", upload-time = 2026-04-22T16:42:40Z, size = 68629, hashes = { sha256 = "892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3" } }] + +[[packages]] +name = "importlib-metadata" +version = "8.7.1" +marker = "python_full_version < '3.10'" +sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", upload-time = 2025-12-21T10:00:19Z, size = 57107, hashes = { sha256 = "49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl", upload-time = 2025-12-21T10:00:18Z, size = 27865, hashes = { sha256 = "5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151" } }] + +[[packages]] +name = "itsdangerous" +version = "2.2.0" +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", upload-time = 2024-04-16T21:28:15Z, size = 54410, hashes = { sha256 = "e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", upload-time = 2024-04-16T21:28:14Z, size = 16234, hashes = { sha256 = "c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef" } }] + +[[packages]] +name = "jinja2" +version = "3.1.6" +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", upload-time = 2025-03-05T20:05:02Z, size = 245115, hashes = { sha256 = "0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", upload-time = 2025-03-05T20:05:00Z, size = 134899, hashes = { sha256 = "85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" } }] + +[[packages]] +name = "markdown" +version = "3.4.4" +sdist = { url = "https://files.pythonhosted.org/packages/87/2a/62841f4fb1fef5fa015ded48d02401cd95643ca03b6760b29437b62a04a4/Markdown-3.4.4.tar.gz", upload-time = 2023-07-25T15:13:45Z, size = 324459, hashes = { sha256 = "225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/1a/b5/228c1cdcfe138f1a8e01ab1b54284c8b83735476cb22b6ba251656ed13ad/Markdown-3.4.4-py3-none-any.whl", upload-time = 2023-07-25T15:13:43Z, size = 94174, hashes = { sha256 = "a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941" } }] + +[[packages]] +name = "markupsafe" +version = "3.0.3" +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", upload-time = 2025-09-27T18:37:40Z, size = 80313, hashes = { sha256 = "722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/fd/23/07a2cb9a8045d5f3f0890a8c3bc0859d7a47bfd9a560b563899bec7b72ed/markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", upload-time = 2025-09-27T18:37:30Z, size = 12049, hashes = { sha256 = "f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc" } }] + +[[packages]] +name = "pycparser" +version = "2.23" +marker = "implementation_name != 'PyPy' and platform_python_implementation != 'PyPy'" +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", upload-time = 2025-09-09T13:23:47Z, size = 173734, hashes = { sha256 = "78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", upload-time = 2025-09-09T13:23:46Z, size = 118140, hashes = { sha256 = "e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934" } }] + +[[packages]] +name = "pygments" +version = "2.16.1" +sdist = { url = "https://files.pythonhosted.org/packages/d6/f7/4d461ddf9c2bcd6a4d7b2b139267ca32a69439387cc1f02a924ff8883825/Pygments-2.16.1.tar.gz", upload-time = 2023-08-06T15:14:55Z, size = 4872980, hashes = { sha256 = "1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/43/88/29adf0b44ba6ac85045e63734ae0997d3c58d8b1a91c914d240828d0d73d/Pygments-2.16.1-py3-none-any.whl", upload-time = 2023-08-06T15:14:51Z, size = 1164750, hashes = { sha256 = "13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692" } }] + +[[packages]] +name = "pygments-markdown-lexer" +version = "0.1.0.dev39" +sdist = { url = "https://files.pythonhosted.org/packages/c3/12/674cdee66635d638cedb2c5d9c85ce507b7b2f91bdba29e482f1b1160ff6/pygments-markdown-lexer-0.1.0.dev39.zip", upload-time = 2015-07-06T11:08:10Z, size = 28039, hashes = { sha256 = "4c128c26450b5886521c674d759f95fc3768b8955a7d9c81866ee0213c2febdf" } } + +[[packages]] +name = "pyopenssl" +version = "24.3.0" +sdist = { url = "https://files.pythonhosted.org/packages/c1/d4/1067b82c4fc674d6f6e9e8d26b3dff978da46d351ca3bac171544693e085/pyopenssl-24.3.0.tar.gz", upload-time = 2024-11-27T20:43:12Z, size = 178944, hashes = { sha256 = "49f7a019577d834746bc55c5fce6ecbcec0f2b4ec5ce1cf43a9a173b8138bb36" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/42/22/40f9162e943f86f0fc927ebc648078be87def360d9d8db346619fb97df2b/pyOpenSSL-24.3.0-py3-none-any.whl", upload-time = 2024-11-27T20:43:21Z, size = 56111, hashes = { sha256 = "e474f5a473cd7f92221cc04976e48f4d11502804657a08a989fb3be5514c904a" } }] + +[[packages]] +name = "requests" +version = "2.32.3" +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", upload-time = 2024-05-29T15:37:49Z, size = 131218, hashes = { sha256 = "55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", upload-time = 2024-05-29T15:37:47Z, size = 64928, hashes = { sha256 = "70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" } }] + +[[packages]] +name = "setuptools" +version = "82.0.1" +sdist = { url = "https://files.pythonhosted.org/packages/4f/db/cfac1baf10650ab4d1c111714410d2fbb77ac5a616db26775db562c8fab2/setuptools-82.0.1.tar.gz", upload-time = 2026-03-09T12:47:17Z, size = 1152316, hashes = { sha256 = "7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", upload-time = 2026-03-09T12:47:15Z, size = 1006223, hashes = { sha256 = "a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb" } }] + +[[packages]] +name = "soupsieve" +version = "2.8.3" +sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", upload-time = 2026-01-20T04:27:02Z, size = 118627, hashes = { sha256 = "3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", upload-time = 2026-01-20T04:27:01Z, size = 37016, hashes = { sha256 = "ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95" } }] + +[[packages]] +name = "typing-extensions" +version = "4.15.0" +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", upload-time = 2025-08-25T13:49:26Z, size = 109391, hashes = { sha256 = "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } }] + +[[packages]] +name = "urllib3" +version = "2.6.3" +sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", upload-time = 2026-01-07T16:24:43Z, size = 435556, hashes = { sha256 = "1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", upload-time = 2026-01-07T16:24:42Z, size = 131584, hashes = { sha256 = "bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4" } }] + +[[packages]] +name = "waitress" +version = "3.0.2" +sdist = { url = "https://files.pythonhosted.org/packages/bf/cb/04ddb054f45faa306a230769e868c28b8065ea196891f09004ebace5b184/waitress-3.0.2.tar.gz", upload-time = 2024-11-16T20:02:35Z, size = 179901, hashes = { sha256 = "682aaaf2af0c44ada4abfb70ded36393f0e307f4ab9456a215ce0020baefc31f" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/8d/57/a27182528c90ef38d82b636a11f606b0cbb0e17588ed205435f8affe3368/waitress-3.0.2-py3-none-any.whl", upload-time = 2024-11-16T20:02:33Z, size = 56232, hashes = { sha256 = "c56d67fd6e87c2ee598b76abdd4e96cfad1f24cacdea5078d382b1f9d7b5ed2e" } }] + +[[packages]] +name = "webob" +version = "1.8.9" +sdist = { url = "https://files.pythonhosted.org/packages/85/0b/1732085540b01f65e4e7999e15864fe14cd18b12a95731a43fd6fd11b26a/webob-1.8.9.tar.gz", upload-time = 2024-10-24T03:19:20Z, size = 279775, hashes = { sha256 = "ad6078e2edb6766d1334ec3dee072ac6a7f95b1e32ce10def8ff7f0f02d56589" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/50/bd/c336448be43d40be28e71f2e0f3caf7ccb28e2755c58f4c02c065bfe3e8e/WebOb-1.8.9-py2.py3-none-any.whl", upload-time = 2024-10-24T03:19:18Z, size = 115364, hashes = { sha256 = "45e34c58ed0c7e2ecd238ffd34432487ff13d9ad459ddfd77895e67abba7c1f9" } }] + +[[packages]] +name = "webtest" +version = "3.0.0" +sdist = { url = "https://files.pythonhosted.org/packages/26/c8/8ffba1782700eb06e9b9169156698c6ba95c05b66cda3fc9e025b6b3b649/WebTest-3.0.0.tar.gz", upload-time = 2021-08-19T12:40:07Z, size = 75871, hashes = { sha256 = "54bd969725838d9861a9fa27f8d971f79d275d94ae255f5c501f53bb6d9929eb" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/41/c7/3897bd62366cb4a50bfb411d37efca9fa33bf07a7c1c22fce8f6ad2664ff/WebTest-3.0.0-py3-none-any.whl", upload-time = 2021-08-19T12:40:04Z, size = 31858, hashes = { sha256 = "2a001a9efa40d2a7e5d9cd8d1527c75f41814eb6afce2c3d207402547b1e5ead" } }] + +[[packages]] +name = "werkzeug" +version = "3.1.8" +sdist = { url = "https://files.pythonhosted.org/packages/dd/b2/381be8cfdee792dd117872481b6e378f85c957dd7c5bca38897b08f765fd/werkzeug-3.1.8.tar.gz", upload-time = 2026-04-02T18:49:14Z, size = 875852, hashes = { sha256 = "9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/93/8c/2e650f2afeb7ee576912636c23ddb621c91ac6a98e66dc8d29c3c69446e1/werkzeug-3.1.8-py3-none-any.whl", upload-time = 2026-04-02T18:49:12Z, size = 226459, hashes = { sha256 = "63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50" } }] + +[[packages]] +name = "zipp" +version = "3.23.1" +marker = "python_full_version < '3.10'" +sdist = { url = "https://files.pythonhosted.org/packages/30/21/093488dfc7cc8964ded15ab726fad40f25fd3d788fd741cc1c5a17d78ee8/zipp-3.23.1.tar.gz", upload-time = 2026-04-13T23:21:46Z, size = 25965, hashes = { sha256 = "32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/08/8a/0861bec20485572fbddf3dfba2910e38fe249796cb73ecdeb74e07eeb8d3/zipp-3.23.1-py3-none-any.whl", upload-time = 2026-04-13T23:21:45Z, size = 10378, hashes = { sha256 = "0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc" } }] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..1702d4463 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,88 @@ +[build-system] +requires = ["setuptools>=77"] +build-backend = "setuptools.build_meta" + +[project] +name = "errbot" +dynamic = ["version", "readme"] +description = "Errbot is a chatbot designed to be simple to extend with plugins written in Python." +authors = [{name = "errbot.io", email = "info@errbot.io"}] +license = "GPL-3.0-or-later" +license-files = ["COPYING"] +requires-python = ">=3.9" +keywords = ["xmpp", "irc", "slack", "hipchat", "gitter", "tox", "chatbot", "bot", "plugin", "chatops"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Topic :: Communications :: Chat", + "Topic :: Communications :: Chat :: Internet Relay Chat", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] +dependencies = [ + "webtest==3.0.0", + "setuptools>=78.1.1", + "flask==2.3.3", + "requests==2.32.3", + "jinja2==3.1.6", + "pyOpenSSL==24.3.0", + "colorlog==6.7.0", + "markdown==3.4.4", + "ansi==0.3.6", + "Pygments==2.16.1", + "pygments-markdown-lexer==0.1.0.dev39", + "dulwich==0.21.5", + "deepmerge==1.1.0", + 'legacy-cgi==2.6.3; python_version >= "3.13"', + 'daemonize==2.5.0; sys_platform != "win32"', +] + +[project.optional-dependencies] +slack = ["errbot-backend-slackv3==0.3.2"] +discord = ["err-backend-discord==3.0.1"] +mattermost = ["err-backend-mattermost==3.0.0"] +IRC = ["irc==20.3.0"] +telegram = ["python-telegram-bot==13.15"] +XMPP = [ + "slixmpp==1.8.4", + "pyasn1==0.6.3", + "pyasn1-modules==0.3.0", +] +test = ["pytest", "webtest", "requests"] + +[project.urls] +Homepage = "http://errbot.io/" + +[project.scripts] +errbot = "errbot.cli:main" + +[tool.setuptools.dynamic] +version = {attr = "errbot.version.VERSION"} +readme = {file = ["README.rst", "CHANGES.rst"], content-type = "text/x-rst"} + +[tool.setuptools.packages.find] +include = ["errbot", "errbot.*"] + +[tool.setuptools.package-data] +errbot = [ + "backends/*.plug", + "backends/*.html", + "backends/styles/*.css", + "backends/images/*.svg", + "core_plugins/*.plug", + "core_plugins/*.md", + "core_plugins/templates/*.md", + "storage/*.plug", + "templates/initdir/example.py", + "templates/initdir/example.plug", + "templates/initdir/config.py.tmpl", + "templates/*.md", + "templates/new_plugin.py.tmpl", +] + +[tool.ruff.lint.per-file-ignores] +"tests/borken_plugin/broken.py" = ["F401"] diff --git a/setup.py b/setup.py deleted file mode 100644 index 15fa4ccb8..000000000 --- a/setup.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import os -import sys - -from setuptools import find_packages, setup - -py_version = sys.version_info[:2] - -if py_version < (3, 10): - raise RuntimeError("Errbot requires Python 3.10 or later") - -VERSION_FILE = os.path.join("errbot", "version.py") - -deps = [ - "setuptools>=78.1.1", - "flask==3.1.3", - "requests==2.32.5", - "jinja2==3.1.6", - "pyOpenSSL==26.1.0", - "colorlog==6.10.1", - "markdown==3.10.2", - "ansi==0.3.7", - "Pygments==2.20.0", - "pygments-markdown-lexer==0.1.0.dev39", # syntax coloring to debug md - "dulwich==1.2.1", # python implementation of git - "deepmerge==2.0", -] - -src_root = os.curdir - - -def read_version(): - """ - Read directly the errbot/version.py and gives the version without loading Errbot. - :return: errbot.version.VERSION - """ - - variables = {} - with open(VERSION_FILE) as f: - exec(compile(f.read(), "version.py", "exec"), variables) - return variables["VERSION"] - - -def read(fname, encoding="ascii"): - return open( - os.path.join(os.path.dirname(__file__), fname), "r", encoding=encoding - ).read() - - -if __name__ == "__main__": - VERSION = read_version() - - args = set(sys.argv) - - changes = read("CHANGES.rst", "utf8") - - if changes.find(VERSION) == -1: - raise Exception("You forgot to put a release note in CHANGES.rst ?!") - - if args & {"bdist", "bdist_dumb", "bdist_rpm", "bdist_wininst", "bdist_msi"}: - raise Exception("err doesn't support binary distributions") - - packages = find_packages(src_root, include=["errbot", "errbot.*"]) - - setup( - name="errbot", - version=VERSION, - packages=packages, - entry_points={ - "console_scripts": [ - "errbot = errbot.cli:main", - ] - }, - install_requires=deps, - tests_require=["nose", "requests"], - package_data={ - "errbot": [ - "backends/*.plug", - "backends/*.html", - "backends/styles/*.css", - "backends/images/*.svg", - "core_plugins/*.plug", - "core_plugins/*.md", - "core_plugins/templates/*.md", - "storage/*.plug", - "templates/initdir/example.py", - "templates/initdir/example.plug", - "templates/initdir/config.py.tmpl", - "templates/*.md", - "templates/new_plugin.py.tmpl", - ], - }, - extras_require={ - "slack": [ - "errbot-backend-slackv3==0.3.2", - ], - "discord": [ - # held at 3.0.1: 4.0 is a major bump on external backend; compat unverified - "err-backend-discord==3.0.1", - ], - "mattermost": [ - "err-backend-mattermost==3.0.0", - ], - "IRC": [ - "irc==20.5.0", - ], - "telegram": [ - # held at 13.15: v20+ is fully async; backend would need a rewrite - "python-telegram-bot==13.15", - ], - "XMPP:python_version < '3.11'": [ - "slixmpp==1.12.0", - "pyasn1==0.6.3", - "pyasn1-modules==0.4.2", - ], - "XMPP:python_version >= '3.11'": [ - "slixmpp==1.15.0", - "pyasn1==0.6.3", - "pyasn1-modules==0.4.2", - ], - ':sys_platform!="win32"': ["daemonize==2.5.0"], - }, - author="errbot.io", - author_email="info@errbot.io", - description="Errbot is a chatbot designed to be simple to extend with plugins written in Python.", - long_description_content_type="text/x-rst", - long_description="".join([read("README.rst"), "\n\n", changes]), - license="GPL", - keywords="xmpp irc slack hipchat gitter tox chatbot bot plugin chatops", - url="http://errbot.io/", - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Topic :: Communications :: Chat", - "Topic :: Communications :: Chat :: Internet Relay Chat", - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - ], - src_root=src_root, - platforms="any", - ) diff --git a/tests/release_metadata_test.py b/tests/release_metadata_test.py new file mode 100644 index 000000000..3e27bf080 --- /dev/null +++ b/tests/release_metadata_test.py @@ -0,0 +1,38 @@ +"""Release-time gate. + +When ``errbot/version.py`` has been bumped past the dev sentinel ``9.9.9``, +``CHANGES.rst`` must contain a section heading for that version. On master +the sentinel keeps this test skipped; it only fires once a release is being +prepared (or a release branch is checked out), at which point it forces the +maintainer to update CHANGES.rst before the tag goes out. + +This replaces the install-time check that lived in setup.py. +""" +import re +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parent.parent +DEV_SENTINEL = "9.9.9" + + +def _read_version() -> str: + """Read VERSION from errbot/version.py without importing the package.""" + ns: dict = {} + exec((REPO_ROOT / "errbot" / "version.py").read_text(), ns) + return ns["VERSION"] + + +def test_changes_rst_has_section_for_current_version(): + version = _read_version() + if version == DEV_SENTINEL: + pytest.skip(f"dev sentinel {DEV_SENTINEL} — no CHANGES.rst entry expected") + + changes = (REPO_ROOT / "CHANGES.rst").read_text() + pattern = rf"^v?{re.escape(version)}\b" + assert re.search(pattern, changes, re.MULTILINE), ( + f"CHANGES.rst is missing a section heading for version {version}. " + f"Rename the 'v{DEV_SENTINEL} (unreleased)' heading to the new " + "version, or add a new release section, before tagging." + ) diff --git a/tox.ini b/tox.ini index a4e0e7fe4..d17e4032f 100644 --- a/tox.ini +++ b/tox.ini @@ -17,9 +17,10 @@ commands = [testenv:dist-check] deps = + build twine commands = - python setup.py sdist + python -m build --sdist twine check {toxinidir}/dist/* [testenv:security] From cfb129adc8baf436bcfda54434dd27ec77971d88 Mon Sep 17 00:00:00 2001 From: Sijis Aviles Date: Sat, 27 Jun 2026 01:16:08 -0500 Subject: [PATCH 2/4] fix: add xmpp dependencies on python 3.10 --- pyproject.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 1702d4463..2e1c86f3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,9 +48,10 @@ mattermost = ["err-backend-mattermost==3.0.0"] IRC = ["irc==20.3.0"] telegram = ["python-telegram-bot==13.15"] XMPP = [ - "slixmpp==1.8.4", + "slixmpp==1.12.0; python_version < '3.11'", + "slixmpp==1.15.0; python_version >= '3.11'", "pyasn1==0.6.3", - "pyasn1-modules==0.3.0", + "pyasn1-modules==0.4.2", ] test = ["pytest", "webtest", "requests"] From 8afb41b324ed89b621db5c550de061a5d6ec4444 Mon Sep 17 00:00:00 2001 From: Sijis Aviles Date: Sat, 27 Jun 2026 01:34:53 -0500 Subject: [PATCH 3/4] fix: docs build --- pylock.toml | 124 ++++++++++++++++--------------------------------- pyproject.toml | 27 +++++------ 2 files changed, 51 insertions(+), 100 deletions(-) diff --git a/pylock.toml b/pylock.toml index c6e392639..01859dff9 100644 --- a/pylock.toml +++ b/pylock.toml @@ -1,20 +1,14 @@ # This file was autogenerated by uv via the following command: -# uv pip compile pyproject.toml -o pylock.toml --format pylock.toml --python-version 3.9 +# uv pip compile pyproject.toml -o pylock.toml --format pylock.toml --python-version 3.10 lock-version = "1.0" created-by = "uv" -requires-python = ">=3.9" +requires-python = ">=3.10" [[packages]] name = "ansi" -version = "0.3.6" -sdist = { url = "https://files.pythonhosted.org/packages/ec/ab/a779658c03d9d6d4e4b9e24e50708fc1d214424829407360bd5a1189b675/ansi-0.3.6.tar.gz", upload-time = 2022-02-08T14:22:06Z, size = 7252, hashes = { sha256 = "10545ce2508e470e9208d0cc200616032fdc81b849678826fb7c81c823fd48b1" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/19/d0/d6bc8e852dd8f7e29d9213820857eb69d057f6171cbefd4c7b26700b8bc5/ansi-0.3.6-py3-none-any.whl", upload-time = 2022-02-08T14:22:05Z, size = 8600, hashes = { sha256 = "a83f7e6e7a9a84f4cc2904e28e575516cf42cf862777649e57615d85ac76e11d" } }] - -[[packages]] -name = "beautifulsoup4" -version = "4.14.3" -sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", upload-time = 2025-11-30T15:08:26Z, size = 627737, hashes = { sha256 = "6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", upload-time = 2025-11-30T15:08:24Z, size = 107721, hashes = { sha256 = "0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb" } }] +version = "0.3.7" +sdist = { url = "https://files.pythonhosted.org/packages/ed/58/9444d8e465858ae9cb2096aa48236ab5760ea9dbaac58e609f3b461776de/ansi-0.3.7.tar.gz", upload-time = 2024-01-22T00:52:48Z, size = 7926, hashes = { sha256 = "7e59108922259e03c54e4d93fc611bba0e756513086849708b86b6c80f8d4cd4" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/0e/44/8244b092c39aa39cb61afcb5d64f4a2a22bf9ab291d5f689a9406d158d04/ansi-0.3.7-py3-none-any.whl", upload-time = 2024-01-22T00:52:46Z, size = 9000, hashes = { sha256 = "bdd9e3c2dc3e4c8df8c2b745ca6f07f715aa4edee5ed4a5bcb29065da06a3f71" } }] [[packages]] name = "blinker" @@ -31,16 +25,16 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b86 [[packages]] name = "cffi" version = "2.0.0" -marker = "platform_python_implementation != 'PyPy'" +marker = "python_full_version >= '3.9' and platform_python_implementation != 'PyPy'" sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", upload-time = 2025-09-08T23:24:04Z, size = 523588, hashes = { sha256 = "44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/3d/de/38d9726324e127f727b4ecc376bc85e505bfe61ef130eaf3f290c6847dd4/cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", upload-time = 2025-09-08T23:23:49Z, size = 180509, hashes = { sha256 = "de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7" } }] +wheels = [{ url = "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", upload-time = 2025-09-08T23:22:10Z, size = 180504, hashes = { sha256 = "f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49" } }] [[packages]] name = "charset-normalizer" version = "3.4.7" sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", upload-time = 2026-04-02T09:28:39Z, size = 144271, hashes = { sha256 = "ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5" } } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/1b/ef725f8eb19b5a261b30f78efa9252ef9d017985cb499102f6f49834cd12/charset_normalizer-3.4.7-cp39-cp39-macosx_10_9_universal2.whl", upload-time = 2026-04-02T09:28:14Z, size = 299121, hashes = { sha256 = "177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217" } }, + { url = "https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", upload-time = 2026-04-02T09:25:40Z, size = 315182, hashes = { sha256 = "cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d" } }, { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", upload-time = 2026-04-02T09:28:37Z, size = 61958, hashes = { sha256 = "3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d" } }, ] @@ -52,18 +46,15 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd039706778 [[packages]] name = "colorlog" -version = "6.7.0" -sdist = { url = "https://files.pythonhosted.org/packages/78/6b/4e5481ddcdb9c255b2715f54c863629f1543e97bc8c309d1c5c131ad14f2/colorlog-6.7.0.tar.gz", upload-time = 2022-08-29T14:51:27Z, size = 29920, hashes = { sha256 = "bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/58/43/a363c213224448f9e194d626221123ce00e3fb3d87c0c22aed52b620bdd1/colorlog-6.7.0-py2.py3-none-any.whl", upload-time = 2022-08-29T14:51:26Z, size = 11286, hashes = { sha256 = "0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662" } }] +version = "6.10.1" +sdist = { url = "https://files.pythonhosted.org/packages/a2/61/f083b5ac52e505dfc1c624eafbf8c7589a0d7f32daa398d2e7590efa5fda/colorlog-6.10.1.tar.gz", upload-time = 2025-10-16T16:14:11Z, size = 17162, hashes = { sha256 = "eb4ae5cb65fe7fec7773c2306061a8e63e02efc2c72eba9d27b0fa23c94f1321" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/6d/c1/e419ef3723a074172b68aaa89c9f3de486ed4c2399e2dbd8113a4fdcaf9e/colorlog-6.10.1-py3-none-any.whl", upload-time = 2025-10-16T16:14:10Z, size = 11743, hashes = { sha256 = "2d7e8348291948af66122cff006c9f8da6255d224e7cf8e37d8de2df3bad8c9c" } }] [[packages]] name = "cryptography" -version = "44.0.3" -sdist = { url = "https://files.pythonhosted.org/packages/53/d6/1411ab4d6108ab167d06254c5be517681f1e331f90edf1379895bcb87020/cryptography-44.0.3.tar.gz", upload-time = 2025-05-02T19:36:04Z, size = 711096, hashes = { sha256 = "fe19d8bc5536a91a24a8133328880a41831b6c5df54599a8417b62fe015d3053" } } -wheels = [ - { url = "https://files.pythonhosted.org/packages/08/53/c776d80e9d26441bb3868457909b4e74dd9ccabd182e10b2b0ae7a07e265/cryptography-44.0.3-cp37-abi3-macosx_10_9_universal2.whl", upload-time = 2025-05-02T19:34:50Z, size = 6670281, hashes = { sha256 = "962bc30480a08d133e631e8dfd4783ab71cc9e33d5d7c1e192f0b7c06397bb88" } }, - { url = "https://files.pythonhosted.org/packages/34/a3/ad08e0bcc34ad436013458d7528e83ac29910943cea42ad7dd4141a27bbb/cryptography-44.0.3-cp39-abi3-macosx_10_9_universal2.whl", upload-time = 2025-05-02T19:35:13Z, size = 6673501, hashes = { sha256 = "5639c2b16764c6f76eedf722dbad9a0914960d3489c0cc38694ddf9464f1bb2f" } }, -] +version = "47.0.0" +sdist = { url = "https://files.pythonhosted.org/packages/ef/b2/7ffa7fe8207a8c42147ffe70c3e360b228160c1d85dc3faff16aaa3244c0/cryptography-47.0.0.tar.gz", upload-time = 2026-04-24T19:54:57Z, size = 830863, hashes = { sha256 = "9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/e0/34/a4fae8ae7c3bc227460c9ae43f56abf1b911da0ec29e0ebac53bb0a4b6b7/cryptography-47.0.0-cp38-abi3-macosx_10_9_universal2.whl", upload-time = 2026-04-24T19:54:06Z, size = 7904072, hashes = { sha256 = "14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4" } }] [[packages]] name = "daemonize" @@ -74,24 +65,24 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/45/ad/1b20db02287afd4 [[packages]] name = "deepmerge" -version = "1.1.0" -sdist = { url = "https://files.pythonhosted.org/packages/82/d7/75916d41be4c45a8d9b93d1bb089ac46de0212630641972982023d785d1f/deepmerge-1.1.0.tar.gz", upload-time = 2022-10-25T05:24:36Z, size = 17785, hashes = { sha256 = "4c27a0db5de285e1a7ceac7dbc1531deaa556b627dea4900c8244581ecdfea2d" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/59/72/72489ad8d3fe1cf5e5be93bf27ca4b5c792d552a5f667367b32a671a2076/deepmerge-1.1.0-py3-none-any.whl", upload-time = 2022-10-25T05:24:34Z, size = 8501, hashes = { sha256 = "59e6ef80b77dc52af3882a1ea78da22bcfc91ae9cdabc0c80729049fe295ff8b" } }] +version = "2.0" +sdist = { url = "https://files.pythonhosted.org/packages/a8/3a/b0ba594708f1ad0bc735884b3ad854d3ca3bdc1d741e56e40bbda6263499/deepmerge-2.0.tar.gz", upload-time = 2024-08-30T05:31:50Z, size = 19890, hashes = { sha256 = "5c3d86081fbebd04dd5de03626a0607b809a98fb6ccba5770b62466fe940ff20" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/2d/82/e5d2c1c67d19841e9edc74954c827444ae826978499bde3dfc1d007c8c11/deepmerge-2.0-py3-none-any.whl", upload-time = 2024-08-30T05:31:48Z, size = 13475, hashes = { sha256 = "6de9ce507115cff0bed95ff0ce9ecc31088ef50cbdf09bc90a09349a318b3d00" } }] [[packages]] name = "dulwich" -version = "0.21.5" -sdist = { url = "https://files.pythonhosted.org/packages/8c/6c/57adedfc2e1debb62581e9b413d2be78ea62e1da47d21fdd9d0d10317ebc/dulwich-0.21.5.tar.gz", upload-time = 2023-05-04T02:47:53Z, size = 441948, hashes = { sha256 = "70955e4e249ddda6e34a4636b90f74e931e558f993b17c52570fa6144b993103" } } +version = "1.2.1" +sdist = { url = "https://files.pythonhosted.org/packages/72/0f/46df53e30b03cc8fee9d1bbd7ca624b4d1b579ce2e4efeaa1cb712d119b0/dulwich-1.2.1.tar.gz", upload-time = 2026-04-29T15:12:19Z, size = 1223320, hashes = { sha256 = "ba43bfb3a7cad40d9607170561e8c3be42e7083b4b57af89a5f54e01577ff791" } } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/48/4308b462565ed6b52a25535fa4b6ed99de052314c35d2f1214991de8aec4/dulwich-0.21.5-cp39-cp39-macosx_10_9_universal2.whl", upload-time = 2023-05-04T03:20:28Z, size = 470766, hashes = { sha256 = "fd4ad079758514375f11469e081723ba8831ce4eaa1a64b41f06a3a866d5ac34" } }, - { url = "https://files.pythonhosted.org/packages/b7/57/37fd47365baad8da470bbf7569494a2707f4972d79111d20d03df971420b/dulwich-0.21.5-cp39-cp39-macosx_11_0_arm64.whl", upload-time = 2023-05-04T03:20:31Z, size = 470750, hashes = { sha256 = "aae448da7d80306dda4fc46292fed7efaa466294571ab3448be16714305076f1" } }, + { url = "https://files.pythonhosted.org/packages/0b/4c/4a505c6d0597666e5842d73c4d6b62c4325d47742fc6b881027070394366/dulwich-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", upload-time = 2026-04-29T15:11:09Z, size = 1320113, hashes = { sha256 = "e88fd960a9327d87556a3bad76ad84b6346d3a07409fe8f081877a775977c86b" } }, + { url = "https://files.pythonhosted.org/packages/08/55/f5470846eb8bdbf204f1c1b47c3d25f542fe4a0134f027c672498fb6e0d3/dulwich-1.2.1-py3-none-any.whl", upload-time = 2026-04-29T15:12:18Z, size = 674611, hashes = { sha256 = "1961e0b6c0b1f2920f4ab05821652d8eb12f19ddb5a4c167c385902391c08dd3" } }, ] [[packages]] name = "flask" -version = "2.3.3" -sdist = { url = "https://files.pythonhosted.org/packages/46/b7/4ace17e37abd9c21715dea5ee11774a25e404c486a7893fa18e764326ead/flask-2.3.3.tar.gz", upload-time = 2023-08-21T19:52:35Z, size = 672756, hashes = { sha256 = "09c347a92aa7ff4a8e7f3206795f30d826654baf38b873d0744cd571ca609efc" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/fd/56/26f0be8adc2b4257df20c1c4260ddd0aa396cf8e75d90ab2f7ff99bc34f9/flask-2.3.3-py3-none-any.whl", upload-time = 2023-08-21T19:52:33Z, size = 96112, hashes = { sha256 = "f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b" } }] +version = "3.1.3" +sdist = { url = "https://files.pythonhosted.org/packages/26/00/35d85dcce6c57fdc871f3867d465d780f302a175ea360f62533f12b27e2b/flask-3.1.3.tar.gz", upload-time = 2026-02-19T05:00:57Z, size = 759004, hashes = { sha256 = "0ef0e52b8a9cd932855379197dd8f94047b359ca0a78695144304cb45f87c9eb" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/7f/9c/34f6962f9b9e9c71f6e5ed806e0d0ff03c9d1b0b2340088a0cf4bce09b18/flask-3.1.3-py3-none-any.whl", upload-time = 2026-02-19T05:00:56Z, size = 103424, hashes = { sha256 = "f4bcbefc124291925f1a26446da31a5178f9483862233b23c0c96a20701f670c" } }] [[packages]] name = "idna" @@ -99,13 +90,6 @@ version = "3.13" sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", upload-time = 2026-04-22T16:42:42Z, size = 194210, hashes = { sha256 = "585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242" } } wheels = [{ url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", upload-time = 2026-04-22T16:42:40Z, size = 68629, hashes = { sha256 = "892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3" } }] -[[packages]] -name = "importlib-metadata" -version = "8.7.1" -marker = "python_full_version < '3.10'" -sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", upload-time = 2025-12-21T10:00:19Z, size = 57107, hashes = { sha256 = "49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl", upload-time = 2025-12-21T10:00:18Z, size = 27865, hashes = { sha256 = "5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151" } }] - [[packages]] name = "itsdangerous" version = "2.2.0" @@ -120,28 +104,28 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f [[packages]] name = "markdown" -version = "3.4.4" -sdist = { url = "https://files.pythonhosted.org/packages/87/2a/62841f4fb1fef5fa015ded48d02401cd95643ca03b6760b29437b62a04a4/Markdown-3.4.4.tar.gz", upload-time = 2023-07-25T15:13:45Z, size = 324459, hashes = { sha256 = "225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/1a/b5/228c1cdcfe138f1a8e01ab1b54284c8b83735476cb22b6ba251656ed13ad/Markdown-3.4.4-py3-none-any.whl", upload-time = 2023-07-25T15:13:43Z, size = 94174, hashes = { sha256 = "a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941" } }] +version = "3.10.2" +sdist = { url = "https://files.pythonhosted.org/packages/2b/f4/69fa6ed85ae003c2378ffa8f6d2e3234662abd02c10d216c0ba96081a238/markdown-3.10.2.tar.gz", upload-time = 2026-02-09T14:57:26Z, size = 368805, hashes = { sha256 = "994d51325d25ad8aa7ce4ebaec003febcce822c3f8c911e3b17c52f7f589f950" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/de/1f/77fa3081e4f66ca3576c896ae5d31c3002ac6607f9747d2e3aa49227e464/markdown-3.10.2-py3-none-any.whl", upload-time = 2026-02-09T14:57:25Z, size = 108180, hashes = { sha256 = "e91464b71ae3ee7afd3017d9f358ef0baf158fd9a298db92f1d4761133824c36" } }] [[packages]] name = "markupsafe" version = "3.0.3" sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", upload-time = 2025-09-27T18:37:40Z, size = 80313, hashes = { sha256 = "722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/fd/23/07a2cb9a8045d5f3f0890a8c3bc0859d7a47bfd9a560b563899bec7b72ed/markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", upload-time = 2025-09-27T18:37:30Z, size = 12049, hashes = { sha256 = "f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc" } }] +wheels = [{ url = "https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", upload-time = 2025-09-27T18:36:07Z, size = 12057, hashes = { sha256 = "e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419" } }] [[packages]] name = "pycparser" version = "2.23" -marker = "implementation_name != 'PyPy' and platform_python_implementation != 'PyPy'" +marker = "python_full_version >= '3.9' and implementation_name != 'PyPy' and platform_python_implementation != 'PyPy'" sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", upload-time = 2025-09-09T13:23:47Z, size = 173734, hashes = { sha256 = "78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2" } } wheels = [{ url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", upload-time = 2025-09-09T13:23:46Z, size = 118140, hashes = { sha256 = "e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934" } }] [[packages]] name = "pygments" -version = "2.16.1" -sdist = { url = "https://files.pythonhosted.org/packages/d6/f7/4d461ddf9c2bcd6a4d7b2b139267ca32a69439387cc1f02a924ff8883825/Pygments-2.16.1.tar.gz", upload-time = 2023-08-06T15:14:55Z, size = 4872980, hashes = { sha256 = "1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/43/88/29adf0b44ba6ac85045e63734ae0997d3c58d8b1a91c914d240828d0d73d/Pygments-2.16.1-py3-none-any.whl", upload-time = 2023-08-06T15:14:51Z, size = 1164750, hashes = { sha256 = "13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692" } }] +version = "2.20.0" +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", upload-time = 2026-03-29T13:29:33Z, size = 4955991, hashes = { sha256 = "6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", upload-time = 2026-03-29T13:29:30Z, size = 1231151, hashes = { sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" } }] [[packages]] name = "pygments-markdown-lexer" @@ -150,15 +134,15 @@ sdist = { url = "https://files.pythonhosted.org/packages/c3/12/674cdee66635d638c [[packages]] name = "pyopenssl" -version = "24.3.0" -sdist = { url = "https://files.pythonhosted.org/packages/c1/d4/1067b82c4fc674d6f6e9e8d26b3dff978da46d351ca3bac171544693e085/pyopenssl-24.3.0.tar.gz", upload-time = 2024-11-27T20:43:12Z, size = 178944, hashes = { sha256 = "49f7a019577d834746bc55c5fce6ecbcec0f2b4ec5ce1cf43a9a173b8138bb36" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/42/22/40f9162e943f86f0fc927ebc648078be87def360d9d8db346619fb97df2b/pyOpenSSL-24.3.0-py3-none-any.whl", upload-time = 2024-11-27T20:43:21Z, size = 56111, hashes = { sha256 = "e474f5a473cd7f92221cc04976e48f4d11502804657a08a989fb3be5514c904a" } }] +version = "26.1.0" +sdist = { url = "https://files.pythonhosted.org/packages/8c/a8/26d36401e3ab8eed9030ad33f381da7856fcfad5691780fccd1b019718fc/pyopenssl-26.1.0.tar.gz", upload-time = 2026-04-24T20:23:48Z, size = 186181, hashes = { sha256 = "737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/a8/41/52f3a3e812b816a91e89aa504199d8bf989a1f873192b10762be66cf2009/pyopenssl-26.1.0-py3-none-any.whl", upload-time = 2026-04-24T20:23:46Z, size = 58109, hashes = { sha256 = "115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece" } }] [[packages]] name = "requests" -version = "2.32.3" -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", upload-time = 2024-05-29T15:37:49Z, size = 131218, hashes = { sha256 = "55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", upload-time = 2024-05-29T15:37:47Z, size = 64928, hashes = { sha256 = "70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" } }] +version = "2.32.5" +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", upload-time = 2025-08-18T20:46:02Z, size = 134517, hashes = { sha256 = "dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf" } } +wheels = [{ url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", upload-time = 2025-08-18T20:46:00Z, size = 64738, hashes = { sha256 = "2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6" } }] [[packages]] name = "setuptools" @@ -166,15 +150,10 @@ version = "82.0.1" sdist = { url = "https://files.pythonhosted.org/packages/4f/db/cfac1baf10650ab4d1c111714410d2fbb77ac5a616db26775db562c8fab2/setuptools-82.0.1.tar.gz", upload-time = 2026-03-09T12:47:17Z, size = 1152316, hashes = { sha256 = "7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9" } } wheels = [{ url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", upload-time = 2026-03-09T12:47:15Z, size = 1006223, hashes = { sha256 = "a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb" } }] -[[packages]] -name = "soupsieve" -version = "2.8.3" -sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", upload-time = 2026-01-20T04:27:02Z, size = 118627, hashes = { sha256 = "3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", upload-time = 2026-01-20T04:27:01Z, size = 37016, hashes = { sha256 = "ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95" } }] - [[packages]] name = "typing-extensions" version = "4.15.0" +marker = "python_full_version < '3.13'" sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", upload-time = 2025-08-25T13:49:26Z, size = 109391, hashes = { sha256 = "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } } wheels = [{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } }] @@ -184,33 +163,8 @@ version = "2.6.3" sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", upload-time = 2026-01-07T16:24:43Z, size = 435556, hashes = { sha256 = "1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed" } } wheels = [{ url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", upload-time = 2026-01-07T16:24:42Z, size = 131584, hashes = { sha256 = "bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4" } }] -[[packages]] -name = "waitress" -version = "3.0.2" -sdist = { url = "https://files.pythonhosted.org/packages/bf/cb/04ddb054f45faa306a230769e868c28b8065ea196891f09004ebace5b184/waitress-3.0.2.tar.gz", upload-time = 2024-11-16T20:02:35Z, size = 179901, hashes = { sha256 = "682aaaf2af0c44ada4abfb70ded36393f0e307f4ab9456a215ce0020baefc31f" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/8d/57/a27182528c90ef38d82b636a11f606b0cbb0e17588ed205435f8affe3368/waitress-3.0.2-py3-none-any.whl", upload-time = 2024-11-16T20:02:33Z, size = 56232, hashes = { sha256 = "c56d67fd6e87c2ee598b76abdd4e96cfad1f24cacdea5078d382b1f9d7b5ed2e" } }] - -[[packages]] -name = "webob" -version = "1.8.9" -sdist = { url = "https://files.pythonhosted.org/packages/85/0b/1732085540b01f65e4e7999e15864fe14cd18b12a95731a43fd6fd11b26a/webob-1.8.9.tar.gz", upload-time = 2024-10-24T03:19:20Z, size = 279775, hashes = { sha256 = "ad6078e2edb6766d1334ec3dee072ac6a7f95b1e32ce10def8ff7f0f02d56589" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/50/bd/c336448be43d40be28e71f2e0f3caf7ccb28e2755c58f4c02c065bfe3e8e/WebOb-1.8.9-py2.py3-none-any.whl", upload-time = 2024-10-24T03:19:18Z, size = 115364, hashes = { sha256 = "45e34c58ed0c7e2ecd238ffd34432487ff13d9ad459ddfd77895e67abba7c1f9" } }] - -[[packages]] -name = "webtest" -version = "3.0.0" -sdist = { url = "https://files.pythonhosted.org/packages/26/c8/8ffba1782700eb06e9b9169156698c6ba95c05b66cda3fc9e025b6b3b649/WebTest-3.0.0.tar.gz", upload-time = 2021-08-19T12:40:07Z, size = 75871, hashes = { sha256 = "54bd969725838d9861a9fa27f8d971f79d275d94ae255f5c501f53bb6d9929eb" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/41/c7/3897bd62366cb4a50bfb411d37efca9fa33bf07a7c1c22fce8f6ad2664ff/WebTest-3.0.0-py3-none-any.whl", upload-time = 2021-08-19T12:40:04Z, size = 31858, hashes = { sha256 = "2a001a9efa40d2a7e5d9cd8d1527c75f41814eb6afce2c3d207402547b1e5ead" } }] - [[packages]] name = "werkzeug" version = "3.1.8" sdist = { url = "https://files.pythonhosted.org/packages/dd/b2/381be8cfdee792dd117872481b6e378f85c957dd7c5bca38897b08f765fd/werkzeug-3.1.8.tar.gz", upload-time = 2026-04-02T18:49:14Z, size = 875852, hashes = { sha256 = "9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44" } } wheels = [{ url = "https://files.pythonhosted.org/packages/93/8c/2e650f2afeb7ee576912636c23ddb621c91ac6a98e66dc8d29c3c69446e1/werkzeug-3.1.8-py3-none-any.whl", upload-time = 2026-04-02T18:49:12Z, size = 226459, hashes = { sha256 = "63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50" } }] - -[[packages]] -name = "zipp" -version = "3.23.1" -marker = "python_full_version < '3.10'" -sdist = { url = "https://files.pythonhosted.org/packages/30/21/093488dfc7cc8964ded15ab726fad40f25fd3d788fd741cc1c5a17d78ee8/zipp-3.23.1.tar.gz", upload-time = 2026-04-13T23:21:46Z, size = 25965, hashes = { sha256 = "32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110" } } -wheels = [{ url = "https://files.pythonhosted.org/packages/08/8a/0861bec20485572fbddf3dfba2910e38fe249796cb73ecdeb74e07eeb8d3/zipp-3.23.1-py3-none-any.whl", upload-time = 2026-04-13T23:21:45Z, size = 10378, hashes = { sha256 = "0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc" } }] diff --git a/pyproject.toml b/pyproject.toml index 2e1c86f3b..99fdc834a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ description = "Errbot is a chatbot designed to be simple to extend with plugins authors = [{name = "errbot.io", email = "info@errbot.io"}] license = "GPL-3.0-or-later" license-files = ["COPYING"] -requires-python = ">=3.9" +requires-python = ">=3.10" keywords = ["xmpp", "irc", "slack", "hipchat", "gitter", "tox", "chatbot", "bot", "plugin", "chatops"] classifiers = [ "Development Status :: 5 - Production/Stable", @@ -17,27 +17,24 @@ classifiers = [ "Topic :: Communications :: Chat :: Internet Relay Chat", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", ] dependencies = [ - "webtest==3.0.0", "setuptools>=78.1.1", - "flask==2.3.3", - "requests==2.32.3", + "flask==3.1.3", + "requests==2.32.5", "jinja2==3.1.6", - "pyOpenSSL==24.3.0", - "colorlog==6.7.0", - "markdown==3.4.4", - "ansi==0.3.6", - "Pygments==2.16.1", + "pyOpenSSL==26.1.0", + "colorlog==6.10.1", + "markdown==3.10.2", + "ansi==0.3.7", + "Pygments==2.20.0", "pygments-markdown-lexer==0.1.0.dev39", - "dulwich==0.21.5", - "deepmerge==1.1.0", - 'legacy-cgi==2.6.3; python_version >= "3.13"', + "dulwich==1.2.1", + "deepmerge==2.0", 'daemonize==2.5.0; sys_platform != "win32"', ] @@ -45,7 +42,7 @@ dependencies = [ slack = ["errbot-backend-slackv3==0.3.2"] discord = ["err-backend-discord==3.0.1"] mattermost = ["err-backend-mattermost==3.0.0"] -IRC = ["irc==20.3.0"] +IRC = ["irc==20.5.0"] telegram = ["python-telegram-bot==13.15"] XMPP = [ "slixmpp==1.12.0; python_version < '3.11'", @@ -53,7 +50,7 @@ XMPP = [ "pyasn1==0.6.3", "pyasn1-modules==0.4.2", ] -test = ["pytest", "webtest", "requests"] +test = ["pytest", "requests"] [project.urls] Homepage = "http://errbot.io/" From 4b35d037314f476aba3a55ba53431a6806edfa3e Mon Sep 17 00:00:00 2001 From: Sijis Aviles Date: Sat, 27 Jun 2026 02:19:30 -0500 Subject: [PATCH 4/4] docs: update references to use uv --- docs/contributing.rst | 4 ++-- tools/README.md | 4 ++-- tools/releases.sh | 13 +++++++------ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 5b141b6c1..74462ea49 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -42,9 +42,9 @@ to refresh the pinned versions). From the root of the repository:: pip install uv # Recompile the lockfile from pyproject.toml, pinned to the project's - # minimum supported Python version so the resolution covers 3.9+. + # minimum supported Python version so the resolution covers 3.10+. uv pip compile pyproject.toml -o pylock.toml \ - --format pylock.toml --python-version 3.9 + --format pylock.toml --python-version 3.10 Commit the resulting ``pylock.toml`` alongside your ``pyproject.toml`` change in the same pull request so the two stay in sync. diff --git a/tools/README.md b/tools/README.md index bc201fb15..02a82f810 100644 --- a/tools/README.md +++ b/tools/README.md @@ -18,12 +18,12 @@ These are support tools for the project - creates a temporary directory, clones the repository, builds the python package, and prepares multi-arch docker images. - **Requirements:** - `git` - - `pipenv` + - `uv` - `python 3.12` - `podman` (for docker image builds) - **Execution (macOS):** 1. **Pre-requisite:** Open `tools/releases.sh` and update the `RELEASE`, `BRANCH`, and `PYTHON_VERSION` variables to match the target release. - 2. Ensure you have the requirements installed (e.g., `brew install pipenv podman`). + 2. Ensure you have the requirements installed (e.g., `brew install uv podman`). 3. Make the script executable: `chmod +x tools/releases.sh` 4. Run the script from the project root: `./tools/releases.sh` 5. Follow the manual steps printed at the end of the script to complete the publication. diff --git a/tools/releases.sh b/tools/releases.sh index cbe653964..774e20759 100755 --- a/tools/releases.sh +++ b/tools/releases.sh @@ -36,13 +36,14 @@ pushd errbot git checkout ${BRANCH} header "pypi build" -pipenv --python ${PYTHON_VERSION} -pipenv run pip3 install pytest twine build +uv venv --python ${PYTHON_VERSION} +source .venv/bin/activate +uv pip install pytest twine build #header "pre-release gate (version <-> CHANGES.rst)" -#pipenv run python3 -m pytest tests/release_metadata_test.py -v +#python3 -m pytest tests/release_metadata_test.py -v -pipenv run python3 -m build +python3 -m build header "Building multi-arch docker images..." podman rmi -f errbotio/errbot:test 2>/dev/null || true @@ -50,10 +51,10 @@ podman manifest rm errbotio/errbot:test 2>/dev/null || true podman build --platform linux/amd64,linux/arm64 --manifest errbotio/errbot:test -f Dockerfile . header "Checking and uploading Python package..." -pipenv run twine check dist/* +twine check dist/* header "Manual: publish pypi and docker" -echo pipenv run twine upload dist/* +echo twine upload dist/* echo podman build --platform linux/amd64,linux/arm64 --manifest errbotio/errbot:${RELEASE} -f Dockerfile . echo podman manifest push errbotio/errbot:${RELEASE} docker://docker.io/errbotio/errbot:${RELEASE} echo git tag v${RELEASE}