Skip to content

Commit e749332

Browse files
authored
chore(*): Remove Python 3.7 support and add Python 3.12 support (#37)
1 parent 4903857 commit e749332

9 files changed

Lines changed: 66 additions & 60 deletions

File tree

.github/workflows/cd.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- uses: actions/checkout@v3
1919
- uses: actions/setup-python@v4
2020
with:
21-
python-version: '3.11'
21+
python-version: '3.12'
2222
- name: version
2323
run: sed -i "s/__version__ = '.*'/__version__ = '$VERSION'/g" aiocli/__init__.py
2424
- name: deps

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
strategy:
1515
matrix:
1616
os: [ ubuntu-latest ]
17-
python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11.0' ]
17+
python-version: [ '3.8', '3.9', '3.10', '3.11', '3.12' ]
1818
steps:
1919
- uses: actions/checkout@v3
2020
- uses: actions/setup-python@v4

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM docker.io/library/python:3.7-slim AS base
1+
FROM docker.io/library/python:3.8-slim AS base
22

33
RUN apt update -y && python3 -m pip install --upgrade pip
44

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 - 2022 aiopy
3+
Copyright (c) 2020 - 2023 aiopy
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

aiocli/commander.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import asyncio
22
import signal
33
import sys
4-
from asyncio import gather, get_event_loop
4+
from asyncio import all_tasks, gather, get_event_loop
55
from asyncio.events import AbstractEventLoop
66
from typing import Any, Callable, List, Optional, Set, Union
77

@@ -27,8 +27,6 @@
2727
'ApplicationParser',
2828
)
2929

30-
from aiocli.helpers import all_tasks
31-
3230

3331
class GracefulExit(SystemExit):
3432
code = 0

aiocli/commander_app.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from abc import ABC, abstractmethod
22
from argparse import Action, ArgumentParser, RawTextHelpFormatter
3+
from asyncio import iscoroutinefunction
34
from dataclasses import dataclass, field
45
from inspect import signature
56
from typing import (
@@ -31,7 +32,7 @@
3132
'InternalCommandHook',
3233
)
3334

34-
from .helpers import iscoroutinefunction, resolve_coroutine, resolve_function
35+
from .helpers import resolve_coroutine, resolve_function
3536
from .logger import logger
3637

3738
CommandHandler = Callable[
@@ -519,7 +520,7 @@ def _resolve_state(cls, state: ArgumentState) -> State:
519520
if isinstance(state, Dict):
520521
return State(state)
521522
if iscoroutinefunction(state):
522-
return cls._resolve_state(resolve_coroutine(state)) # type: ignore
523+
return cls._resolve_state(resolve_coroutine(state))
523524
if callable(state):
524525
return cls._resolve_state(state()) # type: ignore
525526
return State()

aiocli/helpers.py

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,13 @@
1-
import asyncio
2-
from asyncio import get_event_loop_policy
3-
from functools import partial
4-
from sys import version_info
5-
from typing import Any, Callable, Coroutine, Optional, Set
1+
from asyncio import get_event_loop_policy, iscoroutinefunction
2+
from typing import Any, Callable, Coroutine
63

74
__all__ = (
85
# helpers
9-
'all_tasks',
10-
'iscoroutinefunction',
116
'resolve_function',
127
'resolve_coroutine',
138
)
149

1510

16-
def all_tasks(loop: Optional[asyncio.AbstractEventLoop] = None) -> Set["asyncio.Task[Any]"]:
17-
tasks = list(getattr(asyncio.Task, 'all_tasks')(loop))
18-
return {t for t in tasks if not t.done()}
19-
20-
21-
if version_info >= (3, 7):
22-
all_tasks = getattr(asyncio, 'all_tasks')
23-
24-
25-
def iscoroutinefunction(func: Callable[..., Any]) -> bool:
26-
while isinstance(func, partial):
27-
func = func.func
28-
return asyncio.iscoroutinefunction(func)
29-
30-
31-
if version_info >= (3, 8):
32-
iscoroutinefunction = asyncio.iscoroutinefunction
33-
34-
3511
async def resolve_function(func: Callable[..., Any], *args, **kwargs) -> Any: # type: ignore
3612
if iscoroutinefunction(func):
3713
return await func(*args, **kwargs)

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ services:
88
volumes:
99
- .:/app
1010

11-
version: "3.7"
11+
version: "3.8"

pyproject.toml

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ classifiers = [
2424
"Intended Audience :: Developers",
2525
"License :: OSI Approved :: MIT License",
2626
"Programming Language :: Python :: 3 :: Only",
27-
"Programming Language :: Python :: 3.7",
2827
"Programming Language :: Python :: 3.8",
2928
"Programming Language :: Python :: 3.9",
3029
"Programming Language :: Python :: 3.10",
3130
"Programming Language :: Python :: 3.11",
31+
"Programming Language :: Python :: 3.12",
3232
]
3333
dependencies = []
3434
description = "Simple and lightweight async console runner."
@@ -37,42 +37,42 @@ keywords = ["asyncio", "async", "aio", "cli", "console"]
3737
license = { text = "MIT" }
3838
name = "aiocli"
3939
readme = "README.md"
40-
requires-python = ">=3.7"
40+
requires-python = ">=3.8"
4141

4242
[project.optional-dependencies]
4343
dev = [
44-
"pre-commit==2.20.0",
45-
'tomli==2.0.1; python_version<"3.11"',
46-
'types-toml==0.10.8.1; python_version<"3.11"',
44+
'pre-commit>=3.3.3',
45+
'tomli>=2.0.1; python_version<"3.11"',
46+
'types-toml>=0.10.8.7; python_version<"3.11"',
4747
]
4848
deploy = [
49-
"build==0.9.0",
50-
"setuptools==65.6.0",
51-
"twine==4.0.1",
52-
"wheel==0.38.4",
49+
"build>=0.10.0",
50+
'setuptools>=68.1.2',
51+
"twine>=4.0.2",
52+
"wheel>=0.41.1",
5353
]
5454
docs = [
55-
"mkdocs==1.4.2",
56-
"mkdocs-material==8.5.10",
55+
"mkdocs>=1.5.2",
56+
"mkdocs-material>=9.1.21",
5757
]
5858
fmt = [
59-
"black==22.10.0",
60-
"isort==5.10.1",
59+
'black>=23.7.0',
60+
'isort>=5.12.0',
6161
]
6262
security-analysis = [
63-
"bandit==1.7.4",
64-
"liccheck==0.7.3",
63+
"bandit>=1.7.5",
64+
"liccheck>=0.9.1",
6565
]
6666
static-analysis = [
67-
"mypy==0.991",
68-
"pylint==2.15.6",
67+
'mypy>=1.5.1',
68+
"pylint>=2.17.5",
6969
]
7070
test = [
71-
"psutil==5.9.4",
72-
"pytest==7.2.0",
73-
"pytest-asyncio==0.20.2",
74-
"pytest-cov==4.0.0",
75-
"pytest-xdist==3.0.2",
71+
"psutil>=5.9.5",
72+
"pytest>=7.4.0",
73+
"pytest-asyncio>=0.21.1",
74+
"pytest-cov>=4.1.0",
75+
"pytest-xdist>=3.3.1",
7676
]
7777

7878
[project.urls]
@@ -152,23 +152,54 @@ for pathname in ['./build', './*.egg-info', './dist', './var', '**/__pycache__']
152152
for path in iglob(pathname, recursive=True):
153153
rmtree(path, ignore_errors=True)
154154
\""""
155+
dev-server = """python3 -c \"
156+
from asyncio import CancelledError, TimeoutError as AsyncTimeoutError, get_event_loop, sleep, wait_for
157+
from contextlib import suppress
158+
from signal import SIGHUP, SIGINT, SIGTERM
159+
160+
async def development_server(timeout: int) -> None:
161+
retry = True
162+
async def _check() -> None:
163+
if not retry:
164+
return
165+
while retry:
166+
await sleep(1)
167+
try:
168+
print('Development server running...', '')
169+
await wait_for(fut=_check(), timeout=timeout)
170+
except (TimeoutError, AsyncTimeoutError):
171+
pass
172+
finally:
173+
retry = False
174+
175+
async def run_development_server(timeout: int) -> None:
176+
loop = get_event_loop() # lazy
177+
coro = development_server(timeout)
178+
task = loop.create_task(coro)
179+
_ = [loop.add_signal_handler(sig, task.cancel) for sig in (SIGHUP, SIGTERM, SIGINT)]
180+
with suppress(CancelledError):
181+
await task
182+
183+
if __name__ >= '__main__':
184+
get_event_loop().run_until_complete(run_development_server(timeout=3600)) # 1h
185+
\""""
155186

156187
[tool.tox]
157188
legacy_tox_ini = """
158189
[tox]
159-
envlist = py37, py38, py39, py310, py311
190+
envlist = py38, py39, py310, py311, py312
160191
isolated_build = True
161192
skipsdist = True
162193
skip_missing_interpreters = True
163194
toxworkdir = var/tox
164195
165196
[gh-actions]
166197
python =
167-
3.7: py37
168198
3.8: py38
169199
3.9: py39
170200
3.10: py310
171201
3.11: py311
202+
3.12: py312
172203
173204
[testenv]
174205
deps = .[dev,deploy,docs,fmt,security-analysis,static-analysis,test]

0 commit comments

Comments
 (0)