Skip to content

Commit

Permalink
💥 remove Python 3.7 support (#1148)
Browse files Browse the repository at this point in the history
  • Loading branch information
yanyongyu authored Aug 14, 2022
1 parent 0620bec commit 4974c59
Show file tree
Hide file tree
Showing 26 changed files with 261 additions and 317 deletions.
2 changes: 1 addition & 1 deletion .github/actions/setup-python/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ inputs:
python-version:
description: Python version
required: false
default: "3.9"
default: "3.10"

runs:
using: "composite"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
cancel-in-progress: true
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]
python-version: ["3.8", "3.9", "3.10"]
os: [ubuntu-latest, windows-latest, macos-latest]
fail-fast: false
env:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ _✨ 跨平台 Python 异步机器人框架 ✨_
<a href="https://pypi.python.org/pypi/nonebot2">
<img src="https://img.shields.io/pypi/v/nonebot2" alt="pypi">
</a>
<img src="https://img.shields.io/badge/python-3.7.3+-blue" alt="python">
<img src="https://img.shields.io/badge/python-3.8+-blue" alt="python">
<a href="https://codecov.io/gh/nonebot/nonebot2">
<img src="https://codecov.io/gh/nonebot/nonebot2/branch/master/graph/badge.svg?token=2P0G0VS7N4" alt="codecov"/>
</a>
Expand Down
5 changes: 2 additions & 3 deletions nonebot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,7 @@ def get_bots() -> Dict[str, Bot]:
bots = nonebot.get_bots()
```
"""
driver = get_driver()
return driver.bots
return get_driver().bots


def _resolve_dot_notation(
Expand Down Expand Up @@ -240,7 +239,7 @@ def init(*, _env_file: Optional[str] = None, **kwargs: Any) -> None:
f"Loaded <y><b>Config</b></y>: {escape_tag(str(config.dict()))}"
)

DriverClass: Type[Driver] = _resolve_combine_expr(config.driver)
DriverClass = _resolve_combine_expr(config.driver)
_driver = DriverClass(env, config)


Expand Down
2 changes: 1 addition & 1 deletion nonebot/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
sidebar_position: 9
description: nonebot.consts 模块
"""
from typing_extensions import Literal
from typing import Literal

# used by Matcher
RECEIVE_KEY: Literal["_receive_{id}"] = "_receive_{id}"
Expand Down
50 changes: 29 additions & 21 deletions nonebot/dependencies/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,26 @@

import abc
import inspect
from typing import Any, Dict, List, Type, Generic, TypeVar, Callable, Optional
from typing import (
Any,
Dict,
List,
Type,
Generic,
TypeVar,
Callable,
Optional,
Awaitable,
cast,
)

from pydantic import BaseConfig
from pydantic.schema import get_annotation_from_field_info
from pydantic.fields import Required, FieldInfo, Undefined, ModelField

from nonebot.log import logger
from nonebot.exception import TypeMisMatch
from nonebot.typing import _DependentCallable
from nonebot.utils import run_sync, is_coroutine_callable

from .utils import check_field_type, get_typed_signature
Expand Down Expand Up @@ -64,7 +76,7 @@ class Dependent(Generic[R]):
def __init__(
self,
*,
call: Callable[..., Any],
call: _DependentCallable[R],
pre_checkers: Optional[List[Param]] = None,
params: Optional[List[ModelField]] = None,
parameterless: Optional[List[Param]] = None,
Expand All @@ -89,29 +101,25 @@ async def __call__(self, **kwargs: Any) -> R:
values = await self.solve(**kwargs)

if is_coroutine_callable(self.call):
return await self.call(**values)
return await cast(Callable[..., Awaitable[R]], self.call)(**values)
else:
return await run_sync(self.call)(**values)
return await run_sync(cast(Callable[..., R], self.call))(**values)

def parse_param(self, name: str, param: inspect.Parameter) -> Param:
for allow_type in self.allow_types:
field_info = allow_type._check_param(self, name, param)
if field_info:
if field_info := allow_type._check_param(self, name, param):
return field_info
else:
raise ValueError(
f"Unknown parameter {name} for function {self.call} with type {param.annotation}"
)
raise ValueError(
f"Unknown parameter {name} for function {self.call} with type {param.annotation}"
)

def parse_parameterless(self, value: Any) -> Param:
for allow_type in self.allow_types:
field_info = allow_type._check_parameterless(self, value)
if field_info:
if field_info := allow_type._check_parameterless(self, value):
return field_info
else:
raise ValueError(
f"Unknown parameterless {value} for function {self.call} with type {type(value)}"
)
raise ValueError(
f"Unknown parameterless {value} for function {self.call} with type {type(value)}"
)

def prepend_parameterless(self, value: Any) -> None:
self.parameterless.insert(0, self.parse_parameterless(value))
Expand All @@ -121,12 +129,12 @@ def append_parameterless(self, value: Any) -> None:

@classmethod
def parse(
cls: Type[T],
cls,
*,
call: Callable[..., Any],
call: _DependentCallable[R],
parameterless: Optional[List[Any]] = None,
allow_types: Optional[List[Type[Param]]] = None,
) -> T:
) -> "Dependent[R]":
signature = get_typed_signature(call)
params = signature.parameters
dependent = cls(
Expand All @@ -141,10 +149,10 @@ def parse(

if isinstance(default_value, Param):
field_info = default_value
default_value = field_info.default
else:
field_info = dependent.parse_param(param_name, param)
default_value = field_info.default

default_value = field_info.default

annotation: Any = Any
required = default_value == Required
Expand Down
3 changes: 1 addition & 2 deletions nonebot/dependencies/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
)
for param in signature.parameters.values()
]
typed_signature = inspect.Signature(typed_params)
return typed_signature
return inspect.Signature(typed_params)


def get_typed_annotation(param: inspect.Parameter, globalns: Dict[str, Any]) -> Any:
Expand Down
21 changes: 12 additions & 9 deletions nonebot/drivers/_block_driver.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import signal
import asyncio
import threading
from typing import Set, Union, Callable, Awaitable
from typing import Set, Union, Callable, Awaitable, cast

from nonebot.log import logger
from nonebot.drivers import Driver
from nonebot.typing import overrides
from nonebot.config import Env, Config
from nonebot.utils import run_sync, is_coroutine_callable

STARTUP_FUNC = Callable[[], Union[None, Awaitable[None]]]
SHUTDOWN_FUNC = Callable[[], Union[None, Awaitable[None]]]
HOOK_FUNC = Union[Callable[[], None], Callable[[], Awaitable[None]]]
HANDLED_SIGNALS = (
signal.SIGINT, # Unix signal 2. Sent by Ctrl+C.
signal.SIGTERM, # Unix signal 15. Sent by `kill <pid>`.
Expand All @@ -20,8 +19,8 @@
class BlockDriver(Driver):
def __init__(self, env: Env, config: Config):
super().__init__(env, config)
self.startup_funcs: Set[STARTUP_FUNC] = set()
self.shutdown_funcs: Set[SHUTDOWN_FUNC] = set()
self.startup_funcs: Set[HOOK_FUNC] = set()
self.shutdown_funcs: Set[HOOK_FUNC] = set()
self.should_exit: asyncio.Event = asyncio.Event()
self.force_exit: bool = False

Expand All @@ -38,15 +37,15 @@ def logger(self):
return logger

@overrides(Driver)
def on_startup(self, func: STARTUP_FUNC) -> STARTUP_FUNC:
def on_startup(self, func: HOOK_FUNC) -> HOOK_FUNC:
"""
注册一个启动时执行的函数
"""
self.startup_funcs.add(func)
return func

@overrides(Driver)
def on_shutdown(self, func: SHUTDOWN_FUNC) -> SHUTDOWN_FUNC:
def on_shutdown(self, func: HOOK_FUNC) -> HOOK_FUNC:
"""
注册一个停止时执行的函数
"""
Expand All @@ -71,7 +70,9 @@ async def serve(self):
async def startup(self):
# run startup
cors = [
startup() if is_coroutine_callable(startup) else run_sync(startup)()
cast(Callable[..., Awaitable[None]], startup)()
if is_coroutine_callable(startup)
else run_sync(startup)()
for startup in self.startup_funcs
]
if cors:
Expand All @@ -94,7 +95,9 @@ async def shutdown(self):
logger.info("Waiting for application shutdown.")
# run shutdown
cors = [
shutdown() if is_coroutine_callable(shutdown) else run_sync(shutdown)()
cast(Callable[..., Awaitable[None]], shutdown)()
if is_coroutine_callable(shutdown)
else run_sync(shutdown)()
for shutdown in self.shutdown_funcs
]
if cors:
Expand Down
15 changes: 8 additions & 7 deletions nonebot/drivers/fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
description: nonebot.drivers.fastapi 模块
"""


import logging
import contextlib
from functools import wraps
from typing import Any, List, Tuple, Union, Callable, Optional

Expand Down Expand Up @@ -186,14 +188,12 @@ async def _handle_http(
setup: HTTPServerSetup,
) -> Response:
json: Any = None
try:
with contextlib.suppress(Exception):
json = await request.json()
except Exception:
pass

data: Optional[dict] = None
files: Optional[List[Tuple[str, FileTypes]]] = None
try:
with contextlib.suppress(Exception):
form = await request.form()
data = {}
files = []
Expand All @@ -204,8 +204,7 @@ async def _handle_http(
)
else:
data[key] = value
except Exception:
pass

http_request = BaseRequest(
request.method,
str(request.url),
Expand All @@ -219,7 +218,9 @@ async def _handle_http(
)

response = await setup.handle_func(http_request)
return Response(response.content, response.status_code, dict(response.headers))
return Response(
response.content, response.status_code, dict(response.headers.items())
)

async def _handle_ws(self, websocket: WebSocket, setup: WebSocketServerSetup):
request = BaseRequest(
Expand Down
13 changes: 5 additions & 8 deletions nonebot/internal/adapter/bot.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import abc
import asyncio
from functools import partial
from typing_extensions import Protocol
from typing import TYPE_CHECKING, Any, Set, Union, Optional
from typing import TYPE_CHECKING, Any, Set, Union, Optional, Protocol

from nonebot.log import logger
from nonebot.config import Config
Expand Down Expand Up @@ -72,8 +71,7 @@ async def call_api(self, api: str, **data: Any) -> Any:
skip_calling_api: bool = False
exception: Optional[Exception] = None

coros = list(map(lambda x: x(self, api, data), self._calling_api_hook))
if coros:
if coros := [hook(self, api, data) for hook in self._calling_api_hook]:
try:
logger.debug("Running CallingAPI hooks...")
await asyncio.gather(*coros)
Expand All @@ -95,10 +93,9 @@ async def call_api(self, api: str, **data: Any) -> Any:
except Exception as e:
exception = e

coros = list(
map(lambda x: x(self, exception, api, data, result), self._called_api_hook)
)
if coros:
if coros := [
hook(self, exception, api, data, result) for hook in self._called_api_hook
]:
try:
logger.debug("Running CalledAPI hooks...")
await asyncio.gather(*coros)
Expand Down
16 changes: 7 additions & 9 deletions nonebot/internal/driver/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,11 @@ def combine_driver(driver: Type[Driver], *mixins: Type[ForwardMixin]) -> Type[Dr
if not mixins:
return driver

class CombinedDriver(*mixins, driver, ForwardDriver): # type: ignore
@property
def type(self) -> str:
return (
driver.type.__get__(self)
+ "+"
+ "+".join(map(lambda x: x.type.__get__(self), mixins))
)
def type_(self: ForwardDriver) -> str:
return (
driver.type.__get__(self)
+ "+"
+ "+".join(map(lambda x: x.type.__get__(self), mixins))
)

return CombinedDriver
return type("CombinedDriver", (*mixins, driver, ForwardDriver), {"type": property(type_)}) # type: ignore
Loading

0 comments on commit 4974c59

Please sign in to comment.