From f9837aacdac417bff97fbc808d640916329b02fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=B8ldrup?= <14809761+martinmoldrup@users.noreply.github.com> Date: Sat, 20 Dec 2025 21:43:04 +0100 Subject: [PATCH 1/7] Abanddon python 3.9 which is deprecated --- .github/workflows/continuous_integration.yaml | 9 +- CHANGELOG.md | 3 + pyproject.toml | 7 +- ruff.toml | 4 +- uv.lock | 126 ++++++------------ 5 files changed, 55 insertions(+), 94 deletions(-) diff --git a/.github/workflows/continuous_integration.yaml b/.github/workflows/continuous_integration.yaml index 4e026e3..a0bb0aa 100644 --- a/.github/workflows/continuous_integration.yaml +++ b/.github/workflows/continuous_integration.yaml @@ -15,6 +15,11 @@ jobs: lint_and_type_check: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.10", "3.14"] + steps: - name: Checkout repository uses: actions/checkout@v2 @@ -39,10 +44,10 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.10", "3.13"] + python-version: ["3.10", "3.14"] include-extras: [true] include: - - python-version: "3.9" + - python-version: "3.10" include-extras: false steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 44fd4fe..907a1e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. *NOTE:* Version 0.X.X might have breaking changes in bumps of the minor version number. This is because the project is still in early development and the API is not yet stable. It will still be marked clearly in the release notes. +## [0.6.0] - 20-12-2025 +- Abanddon python 3.9 which is deprecated. Now only support python 3.10 and higher. + ## [0.5.0] - 24-09-2025 - Improvements to the plugin system. Plugins can choose their own names and the plugins is show in a seperate section in the rich help panel. diff --git a/pyproject.toml b/pyproject.toml index cc57ec8..bd87b80 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,9 +1,9 @@ [project] name = "toolit" -version = "0.5.0" +version = "0.6.0" description = "MCP Server, Typer CLI and vscode tasks in one, provides an easy way to configure your own DevTools and python scripts in a project." readme = "README.md" -requires-python = ">=3.9" # mcp[cli] requires Python 3.10+ +requires-python = ">=3.10" dependencies = [ "toml", "typer", @@ -15,7 +15,6 @@ classifiers = [ "Topic :: Software Development :: Testing", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -49,7 +48,7 @@ dev = [ ] [project.optional-dependencies] -mcp = ["mcp[cli]; python_version >= '3.10'"] +mcp = ["mcp[cli]"] [project.scripts] toolit = "toolit.cli:app" diff --git a/ruff.toml b/ruff.toml index fb32259..2dfb3a0 100644 --- a/ruff.toml +++ b/ruff.toml @@ -2,8 +2,8 @@ line-length = 120 indent-width = 4 -# Assume Python 3.9 -target-version = "py39" +# Assume Python 3.10+ codebase +target-version = "py310" output-format = "concise" [lint] diff --git a/uv.lock b/uv.lock index 54eca9b..f674a09 100644 --- a/uv.lock +++ b/uv.lock @@ -1,10 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.9" -resolution-markers = [ - "python_full_version >= '3.10'", - "python_full_version < '3.10'", -] +requires-python = ">=3.10" [[package]] name = "annotated-types" @@ -20,10 +16,10 @@ name = "anyio" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "exceptiongroup", marker = "python_full_version == '3.10.*'" }, - { name = "idna", marker = "python_full_version >= '3.10'" }, - { name = "sniffio", marker = "python_full_version >= '3.10'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.10' and python_full_version < '3.13'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" } wheels = [ @@ -97,19 +93,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166, upload-time = "2025-05-02T08:33:15.458Z" }, { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064, upload-time = "2025-05-02T08:33:17.06Z" }, { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641, upload-time = "2025-05-02T08:33:18.753Z" }, - { url = "https://files.pythonhosted.org/packages/28/f8/dfb01ff6cc9af38552c69c9027501ff5a5117c4cc18dcd27cb5259fa1888/charset_normalizer-3.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4", size = 201671, upload-time = "2025-05-02T08:34:12.696Z" }, - { url = "https://files.pythonhosted.org/packages/32/fb/74e26ee556a9dbfe3bd264289b67be1e6d616329403036f6507bb9f3f29c/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7", size = 144744, upload-time = "2025-05-02T08:34:14.665Z" }, - { url = "https://files.pythonhosted.org/packages/ad/06/8499ee5aa7addc6f6d72e068691826ff093329fe59891e83b092ae4c851c/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836", size = 154993, upload-time = "2025-05-02T08:34:17.134Z" }, - { url = "https://files.pythonhosted.org/packages/f1/a2/5e4c187680728219254ef107a6949c60ee0e9a916a5dadb148c7ae82459c/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597", size = 147382, upload-time = "2025-05-02T08:34:19.081Z" }, - { url = "https://files.pythonhosted.org/packages/4c/fe/56aca740dda674f0cc1ba1418c4d84534be51f639b5f98f538b332dc9a95/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7", size = 149536, upload-time = "2025-05-02T08:34:21.073Z" }, - { url = "https://files.pythonhosted.org/packages/53/13/db2e7779f892386b589173dd689c1b1e304621c5792046edd8a978cbf9e0/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f", size = 151349, upload-time = "2025-05-02T08:34:23.193Z" }, - { url = "https://files.pythonhosted.org/packages/69/35/e52ab9a276186f729bce7a0638585d2982f50402046e4b0faa5d2c3ef2da/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba", size = 146365, upload-time = "2025-05-02T08:34:25.187Z" }, - { url = "https://files.pythonhosted.org/packages/a6/d8/af7333f732fc2e7635867d56cb7c349c28c7094910c72267586947561b4b/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12", size = 154499, upload-time = "2025-05-02T08:34:27.359Z" }, - { url = "https://files.pythonhosted.org/packages/7a/3d/a5b2e48acef264d71e036ff30bcc49e51bde80219bb628ba3e00cf59baac/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518", size = 157735, upload-time = "2025-05-02T08:34:29.798Z" }, - { url = "https://files.pythonhosted.org/packages/85/d8/23e2c112532a29f3eef374375a8684a4f3b8e784f62b01da931186f43494/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5", size = 154786, upload-time = "2025-05-02T08:34:31.858Z" }, - { url = "https://files.pythonhosted.org/packages/c7/57/93e0169f08ecc20fe82d12254a200dfaceddc1c12a4077bf454ecc597e33/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3", size = 150203, upload-time = "2025-05-02T08:34:33.88Z" }, - { url = "https://files.pythonhosted.org/packages/2c/9d/9bf2b005138e7e060d7ebdec7503d0ef3240141587651f4b445bdf7286c2/charset_normalizer-3.4.2-cp39-cp39-win32.whl", hash = "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471", size = 98436, upload-time = "2025-05-02T08:34:35.907Z" }, - { url = "https://files.pythonhosted.org/packages/6d/24/5849d46cf4311bbf21b424c443b09b459f5b436b1558c04e45dbb7cc478b/charset_normalizer-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e", size = 105772, upload-time = "2025-05-02T08:34:37.935Z" }, { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" }, ] @@ -160,8 +143,8 @@ name = "httpcore" version = "1.0.9" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "certifi", marker = "python_full_version >= '3.10'" }, - { name = "h11", marker = "python_full_version >= '3.10'" }, + { name = "certifi" }, + { name = "h11" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } wheels = [ @@ -173,10 +156,10 @@ name = "httpx" version = "0.28.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio", marker = "python_full_version >= '3.10'" }, - { name = "certifi", marker = "python_full_version >= '3.10'" }, - { name = "httpcore", marker = "python_full_version >= '3.10'" }, - { name = "idna", marker = "python_full_version >= '3.10'" }, + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } wheels = [ @@ -227,15 +210,15 @@ name = "mcp" version = "1.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio", marker = "python_full_version >= '3.10'" }, - { name = "httpx", marker = "python_full_version >= '3.10'" }, - { name = "httpx-sse", marker = "python_full_version >= '3.10'" }, - { name = "pydantic", marker = "python_full_version >= '3.10'" }, - { name = "pydantic-settings", marker = "python_full_version >= '3.10'" }, - { name = "python-multipart", marker = "python_full_version >= '3.10'" }, - { name = "sse-starlette", marker = "python_full_version >= '3.10'" }, - { name = "starlette", marker = "python_full_version >= '3.10'" }, - { name = "uvicorn", marker = "python_full_version >= '3.10' and sys_platform != 'emscripten'" }, + { name = "anyio" }, + { name = "httpx" }, + { name = "httpx-sse" }, + { name = "pydantic" }, + { name = "pydantic-settings" }, + { name = "python-multipart" }, + { name = "sse-starlette" }, + { name = "starlette" }, + { name = "uvicorn", marker = "sys_platform != 'emscripten'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e7/bc/54aec2c334698cc575ca3b3481eed627125fb66544152fa1af927b1a495c/mcp-1.9.1.tar.gz", hash = "sha256:19879cd6dde3d763297617242888c2f695a95dfa854386a6a68676a646ce75e4", size = 316247, upload-time = "2025-05-22T15:52:21.26Z" } wheels = [ @@ -244,8 +227,8 @@ wheels = [ [package.optional-dependencies] cli = [ - { name = "python-dotenv", marker = "python_full_version >= '3.10'" }, - { name = "typer", marker = "python_full_version >= '3.10'" }, + { name = "python-dotenv" }, + { name = "typer" }, ] [[package]] @@ -293,12 +276,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/64/ff75e71c65a0cb6ee737287c7913ea155845a556c64144c65b811afdb9c7/mypy-1.16.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7e32297a437cc915599e0578fa6bc68ae6a8dc059c9e009c628e1c47f91495d", size = 12701356, upload-time = "2025-05-29T13:35:13.553Z" }, { url = "https://files.pythonhosted.org/packages/0a/ad/0e93c18987a1182c350f7a5fab70550852f9fabe30ecb63bfbe51b602074/mypy-1.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:afe420c9380ccec31e744e8baff0d406c846683681025db3531b32db56962d52", size = 12900745, upload-time = "2025-05-29T13:17:24.409Z" }, { url = "https://files.pythonhosted.org/packages/28/5d/036c278d7a013e97e33f08c047fe5583ab4f1fc47c9a49f985f1cdd2a2d7/mypy-1.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:55f9076c6ce55dd3f8cd0c6fff26a008ca8e5131b89d5ba6d86bd3f47e736eeb", size = 9572200, upload-time = "2025-05-29T13:33:44.92Z" }, - { url = "https://files.pythonhosted.org/packages/bd/eb/c0759617fe2159aee7a653f13cceafbf7f0b6323b4197403f2e587ca947d/mypy-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f56236114c425620875c7cf71700e3d60004858da856c6fc78998ffe767b73d3", size = 10956081, upload-time = "2025-05-29T13:19:32.264Z" }, - { url = "https://files.pythonhosted.org/packages/70/35/df3c74a2967bdf86edea58b265feeec181d693432faed1c3b688b7c231e3/mypy-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:15486beea80be24ff067d7d0ede673b001d0d684d0095803b3e6e17a886a2a92", size = 10084422, upload-time = "2025-05-29T13:18:01.437Z" }, - { url = "https://files.pythonhosted.org/packages/b3/07/145ffe29f4b577219943b7b1dc0a71df7ead3c5bed4898686bd87c5b5cc2/mypy-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f2ed0e0847a80655afa2c121835b848ed101cc7b8d8d6ecc5205aedc732b1436", size = 11879670, upload-time = "2025-05-29T13:17:45.971Z" }, - { url = "https://files.pythonhosted.org/packages/c6/94/0421562d6b046e22986758c9ae31865d10ea0ba607ae99b32c9d18b16f66/mypy-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eb5fbc8063cb4fde7787e4c0406aa63094a34a2daf4673f359a1fb64050e9cb2", size = 12610528, upload-time = "2025-05-29T13:34:36.983Z" }, - { url = "https://files.pythonhosted.org/packages/1a/f1/39a22985b78c766a594ae1e0bbb6f8bdf5f31ea8d0c52291a3c211fd3cd5/mypy-1.16.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a5fcfdb7318c6a8dd127b14b1052743b83e97a970f0edb6c913211507a255e20", size = 12871923, upload-time = "2025-05-29T13:32:21.823Z" }, - { url = "https://files.pythonhosted.org/packages/f3/8e/84db4fb0d01f43d2c82fa9072ca72a42c49e52d58f44307bbd747c977bc2/mypy-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:2e7e0ad35275e02797323a5aa1be0b14a4d03ffdb2e5f2b0489fa07b89c67b21", size = 9482931, upload-time = "2025-05-29T13:21:32.326Z" }, { url = "https://files.pythonhosted.org/packages/99/a3/6ed10530dec8e0fdc890d81361260c9ef1f5e5c217ad8c9b21ecb2b8366b/mypy-1.16.0-py3-none-any.whl", hash = "sha256:29e1499864a3888bca5c1542f2d7232c6e586295183320caa95758fc84034031", size = 2265773, upload-time = "2025-05-29T13:35:18.762Z" }, ] @@ -343,10 +320,10 @@ name = "pydantic" version = "2.11.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "annotated-types", marker = "python_full_version >= '3.10'" }, - { name = "pydantic-core", marker = "python_full_version >= '3.10'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.10'" }, - { name = "typing-inspection", marker = "python_full_version >= '3.10'" }, + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f0/86/8ce9040065e8f924d642c58e4a344e33163a07f6b57f836d0d734e0ad3fb/pydantic-2.11.5.tar.gz", hash = "sha256:7f853db3d0ce78ce8bbb148c401c2cdd6431b3473c0cdff2755c7690952a7b7a", size = 787102, upload-time = "2025-05-22T21:18:08.761Z" } wheels = [ @@ -358,7 +335,7 @@ name = "pydantic-core" version = "2.33.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version >= '3.10'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } wheels = [ @@ -420,19 +397,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, - { url = "https://files.pythonhosted.org/packages/53/ea/bbe9095cdd771987d13c82d104a9c8559ae9aec1e29f139e286fd2e9256e/pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d", size = 2028677, upload-time = "2025-04-23T18:32:27.227Z" }, - { url = "https://files.pythonhosted.org/packages/49/1d/4ac5ed228078737d457a609013e8f7edc64adc37b91d619ea965758369e5/pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954", size = 1864735, upload-time = "2025-04-23T18:32:29.019Z" }, - { url = "https://files.pythonhosted.org/packages/23/9a/2e70d6388d7cda488ae38f57bc2f7b03ee442fbcf0d75d848304ac7e405b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb", size = 1898467, upload-time = "2025-04-23T18:32:31.119Z" }, - { url = "https://files.pythonhosted.org/packages/ff/2e/1568934feb43370c1ffb78a77f0baaa5a8b6897513e7a91051af707ffdc4/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7", size = 1983041, upload-time = "2025-04-23T18:32:33.655Z" }, - { url = "https://files.pythonhosted.org/packages/01/1a/1a1118f38ab64eac2f6269eb8c120ab915be30e387bb561e3af904b12499/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4", size = 2136503, upload-time = "2025-04-23T18:32:35.519Z" }, - { url = "https://files.pythonhosted.org/packages/5c/da/44754d1d7ae0f22d6d3ce6c6b1486fc07ac2c524ed8f6eca636e2e1ee49b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b", size = 2736079, upload-time = "2025-04-23T18:32:37.659Z" }, - { url = "https://files.pythonhosted.org/packages/4d/98/f43cd89172220ec5aa86654967b22d862146bc4d736b1350b4c41e7c9c03/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3", size = 2006508, upload-time = "2025-04-23T18:32:39.637Z" }, - { url = "https://files.pythonhosted.org/packages/2b/cc/f77e8e242171d2158309f830f7d5d07e0531b756106f36bc18712dc439df/pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a", size = 2113693, upload-time = "2025-04-23T18:32:41.818Z" }, - { url = "https://files.pythonhosted.org/packages/54/7a/7be6a7bd43e0a47c147ba7fbf124fe8aaf1200bc587da925509641113b2d/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782", size = 2074224, upload-time = "2025-04-23T18:32:44.033Z" }, - { url = "https://files.pythonhosted.org/packages/2a/07/31cf8fadffbb03be1cb520850e00a8490c0927ec456e8293cafda0726184/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9", size = 2245403, upload-time = "2025-04-23T18:32:45.836Z" }, - { url = "https://files.pythonhosted.org/packages/b6/8d/bbaf4c6721b668d44f01861f297eb01c9b35f612f6b8e14173cb204e6240/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e", size = 2242331, upload-time = "2025-04-23T18:32:47.618Z" }, - { url = "https://files.pythonhosted.org/packages/bb/93/3cc157026bca8f5006250e74515119fcaa6d6858aceee8f67ab6dc548c16/pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9", size = 1910571, upload-time = "2025-04-23T18:32:49.401Z" }, - { url = "https://files.pythonhosted.org/packages/5b/90/7edc3b2a0d9f0dda8806c04e511a67b0b7a41d2187e2003673a996fb4310/pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3", size = 1956504, upload-time = "2025-04-23T18:32:51.287Z" }, { url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982, upload-time = "2025-04-23T18:32:53.14Z" }, { url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412, upload-time = "2025-04-23T18:32:55.52Z" }, { url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749, upload-time = "2025-04-23T18:32:57.546Z" }, @@ -451,15 +415,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" }, { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" }, { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" }, - { url = "https://files.pythonhosted.org/packages/08/98/dbf3fdfabaf81cda5622154fda78ea9965ac467e3239078e0dcd6df159e7/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101", size = 2024034, upload-time = "2025-04-23T18:33:32.843Z" }, - { url = "https://files.pythonhosted.org/packages/8d/99/7810aa9256e7f2ccd492590f86b79d370df1e9292f1f80b000b6a75bd2fb/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64", size = 1858578, upload-time = "2025-04-23T18:33:34.912Z" }, - { url = "https://files.pythonhosted.org/packages/d8/60/bc06fa9027c7006cc6dd21e48dbf39076dc39d9abbaf718a1604973a9670/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d", size = 1892858, upload-time = "2025-04-23T18:33:36.933Z" }, - { url = "https://files.pythonhosted.org/packages/f2/40/9d03997d9518816c68b4dfccb88969756b9146031b61cd37f781c74c9b6a/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535", size = 2068498, upload-time = "2025-04-23T18:33:38.997Z" }, - { url = "https://files.pythonhosted.org/packages/d8/62/d490198d05d2d86672dc269f52579cad7261ced64c2df213d5c16e0aecb1/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d", size = 2108428, upload-time = "2025-04-23T18:33:41.18Z" }, - { url = "https://files.pythonhosted.org/packages/9a/ec/4cd215534fd10b8549015f12ea650a1a973da20ce46430b68fc3185573e8/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6", size = 2069854, upload-time = "2025-04-23T18:33:43.446Z" }, - { url = "https://files.pythonhosted.org/packages/1a/1a/abbd63d47e1d9b0d632fee6bb15785d0889c8a6e0a6c3b5a8e28ac1ec5d2/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca", size = 2237859, upload-time = "2025-04-23T18:33:45.56Z" }, - { url = "https://files.pythonhosted.org/packages/80/1c/fa883643429908b1c90598fd2642af8839efd1d835b65af1f75fba4d94fe/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039", size = 2239059, upload-time = "2025-04-23T18:33:47.735Z" }, - { url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" }, ] [[package]] @@ -467,9 +422,9 @@ name = "pydantic-settings" version = "2.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pydantic", marker = "python_full_version >= '3.10'" }, - { name = "python-dotenv", marker = "python_full_version >= '3.10'" }, - { name = "typing-inspection", marker = "python_full_version >= '3.10'" }, + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "typing-inspection" }, ] sdist = { url = "https://files.pythonhosted.org/packages/67/1d/42628a2c33e93f8e9acbde0d5d735fa0850f3e6a2f8cb1eb6c40b9a732ac/pydantic_settings-2.9.1.tar.gz", hash = "sha256:c509bf79d27563add44e8446233359004ed85066cd096d8b510f715e6ef5d268", size = 163234, upload-time = "2025-04-18T16:44:48.265Z" } wheels = [ @@ -508,7 +463,6 @@ version = "0.26.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, - { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156, upload-time = "2025-03-25T06:22:28.883Z" } wheels = [ @@ -610,8 +564,8 @@ name = "sse-starlette" version = "2.3.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio", marker = "python_full_version >= '3.10'" }, - { name = "starlette", marker = "python_full_version >= '3.10'" }, + { name = "anyio" }, + { name = "starlette" }, ] sdist = { url = "https://files.pythonhosted.org/packages/10/5f/28f45b1ff14bee871bacafd0a97213f7ec70e389939a80c60c0fb72a9fc9/sse_starlette-2.3.5.tar.gz", hash = "sha256:228357b6e42dcc73a427990e2b4a03c023e2495ecee82e14f07ba15077e334b2", size = 17511, upload-time = "2025-05-12T18:23:52.601Z" } wheels = [ @@ -623,7 +577,7 @@ name = "starlette" version = "0.46.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio", marker = "python_full_version >= '3.10'" }, + { name = "anyio" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" } wheels = [ @@ -680,7 +634,7 @@ wheels = [ [[package]] name = "toolit" -version = "0.4.0" +version = "0.6.0" source = { editable = "." } dependencies = [ { name = "toml" }, @@ -689,7 +643,7 @@ dependencies = [ [package.optional-dependencies] mcp = [ - { name = "mcp", extra = ["cli"], marker = "python_full_version >= '3.10'" }, + { name = "mcp", extra = ["cli"] }, ] [package.dev-dependencies] @@ -704,7 +658,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "mcp", extras = ["cli"], marker = "python_full_version >= '3.10' and extra == 'mcp'" }, + { name = "mcp", extras = ["cli"], marker = "extra == 'mcp'" }, { name = "toml" }, { name = "typer" }, ] @@ -758,7 +712,7 @@ name = "typing-inspection" version = "0.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version >= '3.10'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } wheels = [ @@ -779,9 +733,9 @@ name = "uvicorn" version = "0.34.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click", marker = "python_full_version >= '3.10'" }, - { name = "h11", marker = "python_full_version >= '3.10'" }, - { name = "typing-extensions", marker = "python_full_version == '3.10.*'" }, + { name = "click" }, + { name = "h11" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload-time = "2025-04-19T06:02:50.101Z" } wheels = [ From ecb2948db49c20fc915a75739a4fdad35c97c5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=B8ldrup?= <14809761+martinmoldrup@users.noreply.github.com> Date: Sat, 20 Dec 2025 21:44:31 +0100 Subject: [PATCH 2/7] Fix compatibility issues with newer Python versions and refactor CLI initialization --- CHANGELOG.md | 1 + tests/cli_test.py | 17 +++++++++++++++++ toolit/auto_loader.py | 14 ++++++++++++-- toolit/cli.py | 10 ++++++---- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 907a1e5..9ab085d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ## [0.6.0] - 20-12-2025 - Abanddon python 3.9 which is deprecated. Now only support python 3.10 and higher. +- Fix bug with plugin system, in newer python version, where it would raise an exception when loading plugins. ## [0.5.0] - 24-09-2025 - Improvements to the plugin system. Plugins can choose their own names and the plugins is show in a seperate section in the rich help panel. diff --git a/tests/cli_test.py b/tests/cli_test.py index f18718b..b059d93 100644 --- a/tests/cli_test.py +++ b/tests/cli_test.py @@ -2,6 +2,21 @@ from typer.testing import CliRunner +def test_cli_run_with_no_tools() -> None: + # Get the commands from the typer cli app + runner = CliRunner() + result = runner.invoke(create_apps_and_register.app, ["--help"]) + assert result.exit_code == 0 + print(result.stdout) + + +def test_cli_loads_tools_and_plugins_without_plugins() -> None: + from toolit.cli import initialize_cli + initialize_cli() + runner = CliRunner() + result = runner.invoke(create_apps_and_register.app, ["--help"]) + assert result.exit_code == 0 + def a_new_command_registered() -> None: """Test a new command is registered.""" print("This is a new command registered.") @@ -14,3 +29,5 @@ def test_cli_command_is_registered() -> None: result = runner.invoke(create_apps_and_register.app, ["--help"]) assert result.exit_code == 0 assert "a-new-command-registered" in result.stdout + + diff --git a/toolit/auto_loader.py b/toolit/auto_loader.py index f6b14e8..215a81a 100644 --- a/toolit/auto_loader.py +++ b/toolit/auto_loader.py @@ -4,6 +4,7 @@ A folder is defined. Everything that has the @decorators.tool decorator will be loaded and added as CLI and MCP commands. """ + from __future__ import annotations import os @@ -119,10 +120,19 @@ def import_module(file: pathlib.Path) -> ModuleType: return module +def get_entry_point(name: str) -> importlib.metadata.EntryPoints | None: + """Get entry points by group name.""" + entry_points = importlib.metadata.entry_points() + return entry_points.select(group=name) + + def get_plugin_tools() -> list[FunctionType]: """Discover and return plugin commands via entry points.""" - plugins = [] - for entry_point in importlib.metadata.entry_points().get("toolit_plugins", []): + plugins: list[FunctionType] = [] + entry_point_group = get_entry_point("toolit_plugins") + if entry_point_group is None: + return plugins + for entry_point in entry_point_group: plugin_func: Any = entry_point.load() plugin_func.__name__ = entry_point.name plugins.append(plugin_func) diff --git a/toolit/cli.py b/toolit/cli.py index c21b83e..5f98caa 100644 --- a/toolit/cli.py +++ b/toolit/cli.py @@ -5,11 +5,13 @@ from toolit.create_apps_and_register import app from toolit.create_tasks_json import create_vscode_tasks_json -load_tools_from_folder(load_devtools_folder()) -load_tools_from_plugins() -register_command(create_vscode_tasks_json, rich_help_panel=RichHelpPanelNames.PLUGINS_COMMANDS_PANEL) - +def initialize_cli() -> None: + """Initialize the CLI by loading tools and plugins.""" + load_tools_from_folder(load_devtools_folder()) + load_tools_from_plugins() + register_command(create_vscode_tasks_json, rich_help_panel=RichHelpPanelNames.PLUGINS_COMMANDS_PANEL) if __name__ == "__main__": + initialize_cli() # Run the typer app app() From dbd6190a18e9d7efc39a1c1942d11bdf0731bb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=B8ldrup?= <14809761+martinmoldrup@users.noreply.github.com> Date: Sat, 20 Dec 2025 21:58:08 +0100 Subject: [PATCH 3/7] Fixes --- CHANGELOG.md | 2 +- tests/cli_test.py | 4 ++-- toolit/auto_loader.py | 12 +++++++++++- toolit/cli.py | 12 ++---------- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ab085d..6e7e670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. *NOTE:* Version 0.X.X might have breaking changes in bumps of the minor version number. This is because the project is still in early development and the API is not yet stable. It will still be marked clearly in the release notes. ## [0.6.0] - 20-12-2025 -- Abanddon python 3.9 which is deprecated. Now only support python 3.10 and higher. +- Abandon python 3.9 which is deprecated. Now only support python 3.10 and higher. - Fix bug with plugin system, in newer python version, where it would raise an exception when loading plugins. ## [0.5.0] - 24-09-2025 diff --git a/tests/cli_test.py b/tests/cli_test.py index b059d93..c7d485f 100644 --- a/tests/cli_test.py +++ b/tests/cli_test.py @@ -11,8 +11,8 @@ def test_cli_run_with_no_tools() -> None: def test_cli_loads_tools_and_plugins_without_plugins() -> None: - from toolit.cli import initialize_cli - initialize_cli() + from toolit.auto_loader import register_all_tools_from_folder_and_plugin + register_all_tools_from_folder_and_plugin() runner = CliRunner() result = runner.invoke(create_apps_and_register.app, ["--help"]) assert result.exit_code == 0 diff --git a/toolit/auto_loader.py b/toolit/auto_loader.py index 215a81a..c301227 100644 --- a/toolit/auto_loader.py +++ b/toolit/auto_loader.py @@ -14,10 +14,13 @@ import pathlib import importlib import importlib.metadata +from collections.abc import Callable +from toolit.config import load_devtools_folder from toolit.constants import MARKER_TOOL, RichHelpPanelNames, ToolitTypesEnum from toolit.create_apps_and_register import register_command +from toolit.create_tasks_json import create_vscode_tasks_json from types import FunctionType, ModuleType -from typing import Any, Callable +from typing import Any def get_items_from_folder( @@ -137,3 +140,10 @@ def get_plugin_tools() -> list[FunctionType]: plugin_func.__name__ = entry_point.name plugins.append(plugin_func) return plugins + + +def register_all_tools_from_folder_and_plugin() -> None: + """Load and register all tools that will be used by default.""" + load_tools_from_folder(load_devtools_folder()) + load_tools_from_plugins() + register_command(create_vscode_tasks_json, rich_help_panel=RichHelpPanelNames.PLUGINS_COMMANDS_PANEL) diff --git a/toolit/cli.py b/toolit/cli.py index 5f98caa..0ccc3f8 100644 --- a/toolit/cli.py +++ b/toolit/cli.py @@ -1,17 +1,9 @@ """CLI entry point for the toolit package.""" -from toolit.auto_loader import load_tools_from_folder, load_tools_from_plugins, register_command -from toolit.config import load_devtools_folder -from toolit.constants import RichHelpPanelNames +from toolit.auto_loader import register_all_tools_from_folder_and_plugin from toolit.create_apps_and_register import app -from toolit.create_tasks_json import create_vscode_tasks_json -def initialize_cli() -> None: - """Initialize the CLI by loading tools and plugins.""" - load_tools_from_folder(load_devtools_folder()) - load_tools_from_plugins() - register_command(create_vscode_tasks_json, rich_help_panel=RichHelpPanelNames.PLUGINS_COMMANDS_PANEL) +register_all_tools_from_folder_and_plugin() if __name__ == "__main__": - initialize_cli() # Run the typer app app() From a1b166b0733c8d516582b31c787c831949f63f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=B8ldrup?= <14809761+martinmoldrup@users.noreply.github.com> Date: Sat, 20 Dec 2025 22:03:11 +0100 Subject: [PATCH 4/7] Small fixes --- toolit/auto_loader.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/toolit/auto_loader.py b/toolit/auto_loader.py index c301227..cd40702 100644 --- a/toolit/auto_loader.py +++ b/toolit/auto_loader.py @@ -100,7 +100,7 @@ def get_toolit_type(tool: FunctionType) -> ToolitTypesEnum | None: def load_tools_from_file(module: ModuleType, tool_type: ToolitTypesEnum) -> list[FunctionType]: """Load a tool from a given file and register it as a command.""" - tools = [] + tools: list[FunctionType] = [] for _name, obj in inspect.getmembers(module): is_tool: bool = get_toolit_type(obj) == tool_type if inspect.isfunction(obj) and is_tool: @@ -123,7 +123,7 @@ def import_module(file: pathlib.Path) -> ModuleType: return module -def get_entry_point(name: str) -> importlib.metadata.EntryPoints | None: +def get_entry_point(name: str) -> importlib.metadata.EntryPoints: """Get entry points by group name.""" entry_points = importlib.metadata.entry_points() return entry_points.select(group=name) @@ -133,8 +133,6 @@ def get_plugin_tools() -> list[FunctionType]: """Discover and return plugin commands via entry points.""" plugins: list[FunctionType] = [] entry_point_group = get_entry_point("toolit_plugins") - if entry_point_group is None: - return plugins for entry_point in entry_point_group: plugin_func: Any = entry_point.load() plugin_func.__name__ = entry_point.name From b624d8c411a8d79fe8cf17dd71c8cf2976f803d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=B8ldrup?= <14809761+martinmoldrup@users.noreply.github.com> Date: Sat, 20 Dec 2025 22:05:50 +0100 Subject: [PATCH 5/7] Small name refactoring --- toolit/auto_loader.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toolit/auto_loader.py b/toolit/auto_loader.py index cd40702..c2ae960 100644 --- a/toolit/auto_loader.py +++ b/toolit/auto_loader.py @@ -123,7 +123,7 @@ def import_module(file: pathlib.Path) -> ModuleType: return module -def get_entry_point(name: str) -> importlib.metadata.EntryPoints: +def get_entry_points(name: str) -> importlib.metadata.EntryPoints: """Get entry points by group name.""" entry_points = importlib.metadata.entry_points() return entry_points.select(group=name) @@ -132,8 +132,8 @@ def get_entry_point(name: str) -> importlib.metadata.EntryPoints: def get_plugin_tools() -> list[FunctionType]: """Discover and return plugin commands via entry points.""" plugins: list[FunctionType] = [] - entry_point_group = get_entry_point("toolit_plugins") - for entry_point in entry_point_group: + entry_points = get_entry_points("toolit_plugins") + for entry_point in entry_points: plugin_func: Any = entry_point.load() plugin_func.__name__ = entry_point.name plugins.append(plugin_func) From 1e2d96c68a80558f77bc724aff81ad4f59a95e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=B8ldrup?= <14809761+martinmoldrup@users.noreply.github.com> Date: Sat, 20 Dec 2025 22:13:33 +0100 Subject: [PATCH 6/7] Refactor CLI initialization and register tools from new module to improve compatibility with newer Python versions --- tests/cli_test.py | 2 +- toolit/auto_loader.py | 8 -------- toolit/cli.py | 2 +- toolit/config.py | 3 ++- toolit/decorators.py | 3 ++- toolit/register_all_tool_and_plugins.py | 13 +++++++++++++ 6 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 toolit/register_all_tool_and_plugins.py diff --git a/tests/cli_test.py b/tests/cli_test.py index c7d485f..af70d6b 100644 --- a/tests/cli_test.py +++ b/tests/cli_test.py @@ -11,7 +11,7 @@ def test_cli_run_with_no_tools() -> None: def test_cli_loads_tools_and_plugins_without_plugins() -> None: - from toolit.auto_loader import register_all_tools_from_folder_and_plugin + from toolit.register_all_tool_and_plugins import register_all_tools_from_folder_and_plugin register_all_tools_from_folder_and_plugin() runner = CliRunner() result = runner.invoke(create_apps_and_register.app, ["--help"]) diff --git a/toolit/auto_loader.py b/toolit/auto_loader.py index c2ae960..b012c69 100644 --- a/toolit/auto_loader.py +++ b/toolit/auto_loader.py @@ -15,10 +15,8 @@ import importlib import importlib.metadata from collections.abc import Callable -from toolit.config import load_devtools_folder from toolit.constants import MARKER_TOOL, RichHelpPanelNames, ToolitTypesEnum from toolit.create_apps_and_register import register_command -from toolit.create_tasks_json import create_vscode_tasks_json from types import FunctionType, ModuleType from typing import Any @@ -139,9 +137,3 @@ def get_plugin_tools() -> list[FunctionType]: plugins.append(plugin_func) return plugins - -def register_all_tools_from_folder_and_plugin() -> None: - """Load and register all tools that will be used by default.""" - load_tools_from_folder(load_devtools_folder()) - load_tools_from_plugins() - register_command(create_vscode_tasks_json, rich_help_panel=RichHelpPanelNames.PLUGINS_COMMANDS_PANEL) diff --git a/toolit/cli.py b/toolit/cli.py index 0ccc3f8..12bb43e 100644 --- a/toolit/cli.py +++ b/toolit/cli.py @@ -1,6 +1,6 @@ """CLI entry point for the toolit package.""" -from toolit.auto_loader import register_all_tools_from_folder_and_plugin from toolit.create_apps_and_register import app +from toolit.register_all_tool_and_plugins import register_all_tools_from_folder_and_plugin register_all_tools_from_folder_and_plugin() diff --git a/toolit/config.py b/toolit/config.py index f4c3771..ed13087 100644 --- a/toolit/config.py +++ b/toolit/config.py @@ -10,9 +10,10 @@ import toml import pathlib +from collections.abc import Callable from functools import lru_cache from toolit.constants import ConfigFileKeys -from typing import Callable, overload +from typing import overload def load_ini_config(file_path: pathlib.Path) -> dict[str, str]: diff --git a/toolit/decorators.py b/toolit/decorators.py index 45ca993..38955c7 100644 --- a/toolit/decorators.py +++ b/toolit/decorators.py @@ -1,7 +1,8 @@ """Decorator to tell if a function is a tool.""" +from collections.abc import Callable from toolit.constants import MARKER_TOOL, ToolitTypesEnum -from typing import Any, Callable, TypeVar +from typing import Any, TypeVar T = TypeVar("T", bound=Callable[..., Any]) diff --git a/toolit/register_all_tool_and_plugins.py b/toolit/register_all_tool_and_plugins.py new file mode 100644 index 0000000..8e8bc71 --- /dev/null +++ b/toolit/register_all_tool_and_plugins.py @@ -0,0 +1,13 @@ +"""Register all tools and plugins to be used by default.""" +from toolit.auto_loader import load_tools_from_folder, load_tools_from_plugins +from toolit.config import load_devtools_folder +from toolit.constants import RichHelpPanelNames +from toolit.create_apps_and_register import register_command +from toolit.create_tasks_json import create_vscode_tasks_json + + +def register_all_tools_from_folder_and_plugin() -> None: + """Load and register all tools that will be used by default.""" + load_tools_from_folder(load_devtools_folder()) + load_tools_from_plugins() + register_command(create_vscode_tasks_json, rich_help_panel=RichHelpPanelNames.PLUGINS_COMMANDS_PANEL) From 62db07ebd284bc962e90f040392b9cb7dfb5069c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=B8ldrup?= <14809761+martinmoldrup@users.noreply.github.com> Date: Sun, 21 Dec 2025 22:31:27 +0100 Subject: [PATCH 7/7] fix testing issue in CI --- .github/workflows/continuous_integration.yaml | 4 +++- toolit/auto_loader.py | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous_integration.yaml b/.github/workflows/continuous_integration.yaml index a0bb0aa..0ad4c16 100644 --- a/.github/workflows/continuous_integration.yaml +++ b/.github/workflows/continuous_integration.yaml @@ -44,11 +44,13 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.10", "3.14"] + python-version: ["3.10", "3.13"] include-extras: [true] include: - python-version: "3.10" include-extras: false + - python-version: "3.14" + include-extras: false steps: - name: Checkout repository diff --git a/toolit/auto_loader.py b/toolit/auto_loader.py index b012c69..75de33f 100644 --- a/toolit/auto_loader.py +++ b/toolit/auto_loader.py @@ -136,4 +136,3 @@ def get_plugin_tools() -> list[FunctionType]: plugin_func.__name__ = entry_point.name plugins.append(plugin_func) return plugins -