From 442b1124658fcb9d758e12402413b551b5d56c88 Mon Sep 17 00:00:00 2001 From: Denis Navarro Date: Sun, 12 Oct 2025 09:48:59 +0200 Subject: [PATCH] fix: ensure event loop creation for Python 3.14 compatibility --- .github/workflows/cd.yml | 2 +- .github/workflows/ci.yml | 2 +- Containerfile | 8 +- aiocli/commander.py | 20 +- aiocli/commander_app.py | 12 +- compose.yml | 4 +- docs_src/docs/en/release-notes.md | 27 + docs_src/generated/en/404.html | 359 +++++++---- .../en/advanced/exception_handler/index.html | 429 ++++++++----- .../generated/en/advanced/hooks/index.html | 439 ++++++++----- .../en/advanced/middleware/index.html | 433 ++++++++----- .../en/advanced/serverless_support/index.html | 453 +++++++------ .../generated/en/advanced/state/index.html | 425 ++++++++----- .../en/advanced/test_support/index.html | 429 ++++++++----- .../assets/javascripts/bundle.a6c66575.min.js | 29 - .../javascripts/bundle.a6c66575.min.js.map | 8 - .../assets/javascripts/bundle.f55a23d4.min.js | 16 + .../javascripts/bundle.f55a23d4.min.js.map | 7 + .../javascripts/lunr/min/lunr.ar.min.js | 2 +- .../javascripts/lunr/min/lunr.el.min.js | 1 + .../javascripts/lunr/min/lunr.he.min.js | 1 + .../javascripts/lunr/min/lunr.hy.min.js | 1 + .../javascripts/lunr/min/lunr.kn.min.js | 1 + .../javascripts/lunr/min/lunr.ko.min.js | 1 + .../javascripts/lunr/min/lunr.sa.min.js | 1 + .../javascripts/lunr/min/lunr.ta.min.js | 1 + .../javascripts/lunr/min/lunr.te.min.js | 1 + .../javascripts/lunr/min/lunr.zh.min.js | 2 +- .../en/assets/javascripts/lunr/wordcut.js | 4 +- .../workers/search.2a1c317c.min.js.map | 8 - .../workers/search.973d3a69.min.js} | 24 +- .../workers/search.973d3a69.min.js.map | 7 + .../assets/stylesheets/main.2a3383ac.min.css | 1 + .../stylesheets/main.2a3383ac.min.css.map | 1 + .../assets/stylesheets/main.c382b1dc.min.css | 1 - .../stylesheets/main.c382b1dc.min.css.map | 1 - .../stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + .../stylesheets/palette.cc9b2e1e.min.css | 1 - .../stylesheets/palette.cc9b2e1e.min.css.map | 1 - docs_src/generated/en/features/index.html | 493 +++++++++------ docs_src/generated/en/index.html | 464 +++++++++----- .../generated/en/release-notes/index.html | 593 ++++++++++++----- .../generated/en/search/search_index.json | 2 +- docs_src/generated/en/sitemap.xml | 27 +- docs_src/generated/en/sitemap.xml.gz | Bin 298 -> 279 bytes docs_src/generated/es/404.html | 361 +++++++---- .../es/advanced/exception_handler/index.html | 431 ++++++++----- .../generated/es/advanced/hooks/index.html | 441 ++++++++----- .../es/advanced/middleware/index.html | 435 ++++++++----- .../es/advanced/serverless_support/index.html | 455 ++++++++------ .../generated/es/advanced/state/index.html | 427 ++++++++----- .../es/advanced/test_support/index.html | 431 ++++++++----- .../assets/javascripts/bundle.a6c66575.min.js | 29 - .../javascripts/bundle.a6c66575.min.js.map | 8 - .../assets/javascripts/bundle.f55a23d4.min.js | 16 + .../javascripts/bundle.f55a23d4.min.js.map | 7 + .../javascripts/lunr/min/lunr.ar.min.js | 2 +- .../javascripts/lunr/min/lunr.el.min.js | 1 + .../javascripts/lunr/min/lunr.he.min.js | 1 + .../javascripts/lunr/min/lunr.hy.min.js | 1 + .../javascripts/lunr/min/lunr.kn.min.js | 1 + .../javascripts/lunr/min/lunr.ko.min.js | 1 + .../javascripts/lunr/min/lunr.sa.min.js | 1 + .../javascripts/lunr/min/lunr.ta.min.js | 1 + .../javascripts/lunr/min/lunr.te.min.js | 1 + .../javascripts/lunr/min/lunr.zh.min.js | 2 +- .../es/assets/javascripts/lunr/wordcut.js | 4 +- .../workers/search.2a1c317c.min.js.map | 8 - .../workers/search.973d3a69.min.js} | 24 +- .../workers/search.973d3a69.min.js.map | 7 + .../assets/stylesheets/main.2a3383ac.min.css | 1 + .../stylesheets/main.2a3383ac.min.css.map | 1 + .../assets/stylesheets/main.c382b1dc.min.css | 1 - .../stylesheets/main.c382b1dc.min.css.map | 1 - .../stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + .../stylesheets/palette.cc9b2e1e.min.css | 1 - .../stylesheets/palette.cc9b2e1e.min.css.map | 1 - docs_src/generated/es/features/index.html | 495 +++++++++------ docs_src/generated/es/index.html | 468 +++++++++----- .../generated/es/release-notes/index.html | 595 +++++++++++++----- .../generated/es/search/search_index.json | 2 +- docs_src/generated/es/sitemap.xml | 27 +- docs_src/generated/es/sitemap.xml.gz | Bin 298 -> 279 bytes pyproject.toml | 33 +- tests/conftest.py | 2 + 87 files changed, 6017 insertions(+), 3453 deletions(-) delete mode 100644 docs_src/generated/en/assets/javascripts/bundle.a6c66575.min.js delete mode 100644 docs_src/generated/en/assets/javascripts/bundle.a6c66575.min.js.map create mode 100644 docs_src/generated/en/assets/javascripts/bundle.f55a23d4.min.js create mode 100644 docs_src/generated/en/assets/javascripts/bundle.f55a23d4.min.js.map create mode 100644 docs_src/generated/en/assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 docs_src/generated/en/assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 docs_src/generated/en/assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 docs_src/generated/en/assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 docs_src/generated/en/assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 docs_src/generated/en/assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 docs_src/generated/en/assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 docs_src/generated/en/assets/javascripts/lunr/min/lunr.te.min.js delete mode 100644 docs_src/generated/en/assets/javascripts/workers/search.2a1c317c.min.js.map rename docs_src/generated/{es/assets/javascripts/workers/search.2a1c317c.min.js => en/assets/javascripts/workers/search.973d3a69.min.js} (55%) create mode 100644 docs_src/generated/en/assets/javascripts/workers/search.973d3a69.min.js.map create mode 100644 docs_src/generated/en/assets/stylesheets/main.2a3383ac.min.css create mode 100644 docs_src/generated/en/assets/stylesheets/main.2a3383ac.min.css.map delete mode 100644 docs_src/generated/en/assets/stylesheets/main.c382b1dc.min.css delete mode 100644 docs_src/generated/en/assets/stylesheets/main.c382b1dc.min.css.map create mode 100644 docs_src/generated/en/assets/stylesheets/palette.06af60db.min.css create mode 100644 docs_src/generated/en/assets/stylesheets/palette.06af60db.min.css.map delete mode 100644 docs_src/generated/en/assets/stylesheets/palette.cc9b2e1e.min.css delete mode 100644 docs_src/generated/en/assets/stylesheets/palette.cc9b2e1e.min.css.map delete mode 100644 docs_src/generated/es/assets/javascripts/bundle.a6c66575.min.js delete mode 100644 docs_src/generated/es/assets/javascripts/bundle.a6c66575.min.js.map create mode 100644 docs_src/generated/es/assets/javascripts/bundle.f55a23d4.min.js create mode 100644 docs_src/generated/es/assets/javascripts/bundle.f55a23d4.min.js.map create mode 100644 docs_src/generated/es/assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 docs_src/generated/es/assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 docs_src/generated/es/assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 docs_src/generated/es/assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 docs_src/generated/es/assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 docs_src/generated/es/assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 docs_src/generated/es/assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 docs_src/generated/es/assets/javascripts/lunr/min/lunr.te.min.js delete mode 100644 docs_src/generated/es/assets/javascripts/workers/search.2a1c317c.min.js.map rename docs_src/generated/{en/assets/javascripts/workers/search.2a1c317c.min.js => es/assets/javascripts/workers/search.973d3a69.min.js} (55%) create mode 100644 docs_src/generated/es/assets/javascripts/workers/search.973d3a69.min.js.map create mode 100644 docs_src/generated/es/assets/stylesheets/main.2a3383ac.min.css create mode 100644 docs_src/generated/es/assets/stylesheets/main.2a3383ac.min.css.map delete mode 100644 docs_src/generated/es/assets/stylesheets/main.c382b1dc.min.css delete mode 100644 docs_src/generated/es/assets/stylesheets/main.c382b1dc.min.css.map create mode 100644 docs_src/generated/es/assets/stylesheets/palette.06af60db.min.css create mode 100644 docs_src/generated/es/assets/stylesheets/palette.06af60db.min.css.map delete mode 100644 docs_src/generated/es/assets/stylesheets/palette.cc9b2e1e.min.css delete mode 100644 docs_src/generated/es/assets/stylesheets/palette.cc9b2e1e.min.css.map diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 7d72417..90c5b1f 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: - python-version: '3.13' + python-version: '3.14' - name: version run: sed -i "s/__version__ = '.*'/__version__ = '$VERSION'/g" aiocli/__init__.py - name: deps diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db7cb66..26b2853 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: os: [ ubuntu-latest ] - python-version: [ '3.10', '3.11', '3.12', '3.13' ] + python-version: [ '3.10', '3.11', '3.12', '3.13', '3.14' ] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 diff --git a/Containerfile b/Containerfile index b90c085..cd9495b 100644 --- a/Containerfile +++ b/Containerfile @@ -2,7 +2,8 @@ FROM docker.io/continuumio/miniconda3:latest AS miniconda3 WORKDIR /app -RUN conda install -y --download-only "python=3.12" && \ +RUN conda install -y --download-only "python=3.13" && \ + conda install -y --download-only "python=3.12" && \ conda install -y --download-only "python=3.11" && \ conda install -y --download-only "python=3.10" @@ -11,6 +12,11 @@ COPY . ./ ENTRYPOINT ["python3"] CMD ["run-script"] +FROM miniconda3 AS py313 + +RUN conda install -y "python=3.13" +RUN --mount=type=cache,target=/root/.cache/pip python3 run-script dev-install + FROM miniconda3 AS py312 RUN conda install -y "python=3.12" diff --git a/aiocli/commander.py b/aiocli/commander.py index 405b514..81f3aae 100644 --- a/aiocli/commander.py +++ b/aiocli/commander.py @@ -1,7 +1,14 @@ import asyncio import signal import sys -from asyncio import all_tasks, gather, get_event_loop +from asyncio import ( + all_tasks, + gather, + get_event_loop, + get_running_loop, + new_event_loop, + set_event_loop, +) from asyncio.events import AbstractEventLoop from typing import Any, Callable, List, Optional, Set, Union @@ -140,7 +147,16 @@ def run_app( override_return: Optional[bool] = None, ) -> Any: def wrapper(*args, **kwargs) -> Optional[int]: # type: ignore - loop_ = loop or get_event_loop() + try: + # Try to get the currently running event loop (Python ≥3.10 preferred API). + # In Python 3.14+, get_event_loop() no longer creates a default loop automatically. + # If no loop is running yet, this raises RuntimeError — we handle that below. + loop_ = loop or get_running_loop() + except RuntimeError: + # No event loop exists in the current thread (Python 3.14+ behavior). + # Create and set a new loop to preserve backward compatibility with Python ≤3.13. + loop_ = new_event_loop() + set_event_loop(loop_) app_ = app if isinstance(app, Application) else app() diff --git a/aiocli/commander_app.py b/aiocli/commander_app.py index da63735..42ef6be 100644 --- a/aiocli/commander_app.py +++ b/aiocli/commander_app.py @@ -726,11 +726,13 @@ async def _resolve_or_retrieve_from_cache_dependency(self, of: str, annotation: async def _execute_command_handler(self, handler: CommandHandler, kwargs: Dict[str, Any]) -> Any: self._log( - msg='Executing command handler with: {0}.'.format( - ', '.join(['{0}={1}'.format(key, val) for key, val in kwargs.items()]) - ) - if kwargs - else 'Executing command handler.', + msg=( + 'Executing command handler with: {0}.'.format( + ', '.join(['{0}={1}'.format(key, val) for key, val in kwargs.items()]) + ) + if kwargs + else 'Executing command handler.' + ), ) return await resolve_function(handler, **kwargs) diff --git a/compose.yml b/compose.yml index 3289e23..4304458 100644 --- a/compose.yml +++ b/compose.yml @@ -5,9 +5,9 @@ services: dockerfile: Containerfile # target: py310 # target: py311 - target: py312 +# target: py312 # image: ghcr.io/aiopy/python-aiocli:py310-${VERSION:-latest} # image: ghcr.io/aiopy/python-aiocli:py311-${VERSION:-latest} - image: ghcr.io/aiopy/python-aiocli:py312-${VERSION:-latest} + image: ghcr.io/aiopy/python-aiocli:py314-${VERSION:-latest} volumes: - .:/app diff --git a/docs_src/docs/en/release-notes.md b/docs_src/docs/en/release-notes.md index f5d93dc..1a7c8fa 100644 --- a/docs_src/docs/en/release-notes.md +++ b/docs_src/docs/en/release-notes.md @@ -1,5 +1,32 @@ ## CHANGELOG +### **1.11.x** + +* Drop Python 3.9 support. +* Bump dev deps. + +### **1.10.x** + +* Drop Python 3.8 support. +* Add Python 3.13 support. + +### **1.9.x** + +* Drop Python 3.7 support. +* Add Python 3.12 support. + +### **1.8.x** + +* Add more controls over the original input and app output. + +### **1.7.x** + +* Improve commands and app help usage. +* Lazy loading of the App and State instances. +* Improve command hooks. +* Add after middlware hook. +* Colorize help usage. + ### **1.6.x** * Add State. diff --git a/docs_src/generated/en/404.html b/docs_src/generated/en/404.html index 676c7ca..89f7c49 100644 --- a/docs_src/generated/en/404.html +++ b/docs_src/generated/en/404.html @@ -10,8 +10,11 @@ + + + - + @@ -19,13 +22,17 @@ - + - - + + + + + + @@ -37,12 +44,13 @@ - + + @@ -56,9 +64,6 @@ - - - @@ -72,16 +77,19 @@ -
+ + +