From b6e68730b7a013a575b1be1208f906d8425384a1 Mon Sep 17 00:00:00 2001 From: uy/sun Date: Thu, 29 Feb 2024 19:21:25 +0800 Subject: [PATCH] =?UTF-8?q?:arrow=5Fup:=20=E9=80=82=E9=85=8D=20Pydantic=20?= =?UTF-8?q?V2=20(#484)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :arrow_up: 适配 Pydantic V2 * :bug: 修复测试报错 * :bug: 适配忘记的 from_orm * :bug: 忘记的 class-based `config` * :bug: 更新 red 适配器版本 --- nonebot_bison/compat.py | 28 +++ nonebot_bison/config/db_config.py | 11 +- nonebot_bison/config/db_migration.py | 3 +- nonebot_bison/config/db_model.py | 9 +- .../config/subs_io/nbesf_model/base.py | 9 +- .../config/subs_io/nbesf_model/v1.py | 36 ++- .../config/subs_io/nbesf_model/v2.py | 25 +- nonebot_bison/config/subs_io/subs_io.py | 3 +- nonebot_bison/platform/arknights.py | 8 +- nonebot_bison/platform/bilibili.py | 7 +- nonebot_bison/plugin_config.py | 12 +- nonebot_bison/script/cli.py | 5 +- .../theme/themes/ceobe_canteen/build.py | 5 +- poetry.lock | 224 ++++++++++++------ pyproject.toml | 20 +- tests/subs_io/test_subs_io.py | 5 +- tests/utils.py | 18 +- 17 files changed, 300 insertions(+), 128 deletions(-) create mode 100644 nonebot_bison/compat.py diff --git a/nonebot_bison/compat.py b/nonebot_bison/compat.py new file mode 100644 index 0000000..d4a65a5 --- /dev/null +++ b/nonebot_bison/compat.py @@ -0,0 +1,28 @@ +from typing import Literal, overload + +from pydantic import BaseModel +from nonebot.compat import PYDANTIC_V2 + +__all__ = ("model_validator", "model_rebuild") + + +if PYDANTIC_V2: + from pydantic import model_validator as model_validator + + def model_rebuild(model: type[BaseModel]): + return model.model_rebuild() + +else: + from pydantic import root_validator + + @overload + def model_validator(*, mode: Literal["before"]): ... + + @overload + def model_validator(*, mode: Literal["after"]): ... + + def model_validator(*, mode: Literal["before", "after"]): + return root_validator(pre=mode == "before", allow_reuse=True) + + def model_rebuild(model: type[BaseModel]): + return model.update_forward_refs() diff --git a/nonebot_bison/config/db_config.py b/nonebot_bison/config/db_config.py index f72a572..157b1ef 100644 --- a/nonebot_bison/config/db_config.py +++ b/nonebot_bison/config/db_config.py @@ -3,6 +3,7 @@ from collections import defaultdict from datetime import time, datetime from collections.abc import Callable, Sequence, Awaitable +from nonebot.compat import model_dump from sqlalchemy.orm import selectinload from sqlalchemy.exc import IntegrityError from sqlalchemy import func, delete, select @@ -46,10 +47,10 @@ class DBConfig: tags: list[Tag], ): async with create_session() as session: - db_user_stmt = select(User).where(User.user_target == user.dict()) + db_user_stmt = select(User).where(User.user_target == model_dump(user)) db_user: User | None = await session.scalar(db_user_stmt) if not db_user: - db_user = User(user_target=user.dict()) + db_user = User(user_target=model_dump(user)) session.add(db_user) db_target_stmt = select(Target).where(Target.platform_name == platform_name).where(Target.target == target) db_target: Target | None = await session.scalar(db_target_stmt) @@ -76,7 +77,7 @@ class DBConfig: async with create_session() as session: query_stmt = ( select(Subscribe) - .where(User.user_target == user.dict()) + .where(User.user_target == model_dump(user)) .join(User) .options(selectinload(Subscribe.target)) ) @@ -95,7 +96,7 @@ class DBConfig: async def del_subscribe(self, user: PlatformTarget, target: str, platform_name: str): async with create_session() as session: - user_obj = await session.scalar(select(User).where(User.user_target == user.dict())) + user_obj = await session.scalar(select(User).where(User.user_target == model_dump(user))) target_obj = await session.scalar( select(Target).where(Target.platform_name == platform_name, Target.target == target) ) @@ -121,7 +122,7 @@ class DBConfig: subscribe_obj: Subscribe = await sess.scalar( select(Subscribe) .where( - User.user_target == user.dict(), + User.user_target == model_dump(user), Target.target == target, Target.platform_name == platform_name, ) diff --git a/nonebot_bison/config/db_migration.py b/nonebot_bison/config/db_migration.py index d9775ff..75080ad 100644 --- a/nonebot_bison/config/db_migration.py +++ b/nonebot_bison/config/db_migration.py @@ -1,4 +1,5 @@ from nonebot.log import logger +from nonebot.compat import model_dump from nonebot_plugin_datastore.db import get_engine from sqlalchemy.ext.asyncio.session import AsyncSession from nonebot_plugin_saa import TargetQQGroup, TargetQQPrivate @@ -21,7 +22,7 @@ async def data_migrate(): user_target = TargetQQGroup(group_id=user["user"]) else: user_target = TargetQQPrivate(user_id=user["user"]) - db_user = User(user_target=user_target.dict()) + db_user = User(user_target=model_dump(user_target)) user_to_create.append(db_user) user_sub_set = set() for sub in user["subs"]: diff --git a/nonebot_bison/config/db_model.py b/nonebot_bison/config/db_model.py index 8a093d7..849094d 100644 --- a/nonebot_bison/config/db_model.py +++ b/nonebot_bison/config/db_model.py @@ -3,6 +3,7 @@ from pathlib import Path from nonebot_plugin_saa import PlatformTarget from sqlalchemy.dialects.postgresql import JSONB +from nonebot.compat import PYDANTIC_V2, ConfigDict from nonebot_plugin_datastore import get_plugin_data from sqlalchemy.orm import Mapped, relationship, mapped_column from sqlalchemy import JSON, String, ForeignKey, UniqueConstraint @@ -46,8 +47,12 @@ class ScheduleTimeWeight(Model): target: Mapped[Target] = relationship(back_populates="time_weight") - class Config: - arbitrary_types_allowed = True + if PYDANTIC_V2: + model_config = ConfigDict(arbitrary_types_allowed=True) + else: + + class Config: + arbitrary_types_allowed = True class Subscribe(Model): diff --git a/nonebot_bison/config/subs_io/nbesf_model/base.py b/nonebot_bison/config/subs_io/nbesf_model/base.py index 9f7291f..426c819 100644 --- a/nonebot_bison/config/subs_io/nbesf_model/base.py +++ b/nonebot_bison/config/subs_io/nbesf_model/base.py @@ -1,6 +1,7 @@ from abc import ABC from pydantic import BaseModel +from nonebot.compat import PYDANTIC_V2, ConfigDict from nonebot_plugin_saa.registries import AllSupportedPlatformTarget as UserInfo from ....types import Tag, Category @@ -10,8 +11,12 @@ class NBESFBase(BaseModel, ABC): version: int # 表示nbesf格式版本,有效版本从1开始 groups: list = [] - class Config: - orm_mode = True + if PYDANTIC_V2: + model_config = ConfigDict(from_attributes=True) + else: + + class Config: + orm_mode = True class SubReceipt(BaseModel): diff --git a/nonebot_bison/config/subs_io/nbesf_model/v1.py b/nonebot_bison/config/subs_io/nbesf_model/v1.py index cf198c2..972dd3e 100644 --- a/nonebot_bison/config/subs_io/nbesf_model/v1.py +++ b/nonebot_bison/config/subs_io/nbesf_model/v1.py @@ -6,6 +6,7 @@ from functools import partial from nonebot.log import logger from pydantic import BaseModel from nonebot_plugin_saa import TargetQQGroup, TargetQQPrivate +from nonebot.compat import PYDANTIC_V2, ConfigDict, model_dump, type_validate_json, type_validate_python from ..utils import NBESFParseErr from ....types import Tag, Category @@ -16,14 +17,21 @@ from ...db_config import SubscribeDupException, config NBESF_VERSION = 1 -class UserHead(BaseModel, orm_mode=True): +class UserHead(BaseModel): """Bison快递包收货信息""" type: str uid: int + if PYDANTIC_V2: + model_config = ConfigDict(from_attributes=True) + else: -class Target(BaseModel, orm_mode=True): + class Config: + orm_mode = True + + +class Target(BaseModel): """Bsion快递包发货信息""" target_name: str @@ -31,14 +39,28 @@ class Target(BaseModel, orm_mode=True): platform_name: str default_schedule_weight: int + if PYDANTIC_V2: + model_config = ConfigDict(from_attributes=True) + else: -class SubPayload(BaseModel, orm_mode=True): + class Config: + orm_mode = True + + +class SubPayload(BaseModel): """Bison快递包里的单件货物""" categories: list[Category] tags: list[Tag] target: Target + if PYDANTIC_V2: + model_config = ConfigDict(from_attributes=True) + else: + + class Config: + orm_mode = True + class SubPack(BaseModel): """Bison给指定用户派送的快递包""" @@ -56,7 +78,7 @@ class SubGroup( 结构参见`nbesf_model`下的对应版本 """ - version = NBESF_VERSION + version: int = NBESF_VERSION groups: list[SubPack] @@ -84,7 +106,7 @@ async def subs_receipt_gen(nbesf_data: SubGroup): tags=sub.tags, ) try: - await config.add_subscribe(receipt.user, **receipt.dict(exclude={"user"})) + await config.add_subscribe(receipt.user, **model_dump(receipt, exclude={"user"})) except SubscribeDupException: logger.warning(f"!添加订阅条目 {repr(receipt)} 失败: 相同的订阅已存在") except Exception as e: @@ -96,9 +118,9 @@ async def subs_receipt_gen(nbesf_data: SubGroup): def nbesf_parser(raw_data: Any) -> SubGroup: try: if isinstance(raw_data, str): - nbesf_data = SubGroup.parse_raw(raw_data) + nbesf_data = type_validate_json(SubGroup, raw_data) else: - nbesf_data = SubGroup.parse_obj(raw_data) + nbesf_data = type_validate_python(SubGroup, raw_data) except Exception as e: logger.error("数据解析失败,该数据格式可能不满足NBESF格式标准!") diff --git a/nonebot_bison/config/subs_io/nbesf_model/v2.py b/nonebot_bison/config/subs_io/nbesf_model/v2.py index 5dc5f37..d72b170 100644 --- a/nonebot_bison/config/subs_io/nbesf_model/v2.py +++ b/nonebot_bison/config/subs_io/nbesf_model/v2.py @@ -6,6 +6,7 @@ from functools import partial from nonebot.log import logger from pydantic import BaseModel from nonebot_plugin_saa.registries import AllSupportedPlatformTarget +from nonebot.compat import PYDANTIC_V2, ConfigDict, model_dump, type_validate_json, type_validate_python from ..utils import NBESFParseErr from ....types import Tag, Category @@ -16,7 +17,7 @@ from ...db_config import SubscribeDupException, config NBESF_VERSION = 2 -class Target(BaseModel, orm_mode=True): +class Target(BaseModel): """Bsion快递包发货信息""" target_name: str @@ -24,14 +25,28 @@ class Target(BaseModel, orm_mode=True): platform_name: str default_schedule_weight: int + if PYDANTIC_V2: + model_config = ConfigDict(from_attributes=True) + else: -class SubPayload(BaseModel, orm_mode=True): + class Config: + orm_mode = True + + +class SubPayload(BaseModel): """Bison快递包里的单件货物""" categories: list[Category] tags: list[Tag] target: Target + if PYDANTIC_V2: + model_config = ConfigDict(from_attributes=True) + else: + + class Config: + orm_mode = True + class SubPack(BaseModel): """Bison给指定用户派送的快递包""" @@ -68,7 +83,7 @@ async def subs_receipt_gen(nbesf_data: SubGroup): tags=sub.tags, ) try: - await config.add_subscribe(receipt.user, **receipt.dict(exclude={"user"})) + await config.add_subscribe(receipt.user, **model_dump(receipt, exclude={"user"})) except SubscribeDupException: logger.warning(f"!添加订阅条目 {repr(receipt)} 失败: 相同的订阅已存在") except Exception as e: @@ -80,9 +95,9 @@ async def subs_receipt_gen(nbesf_data: SubGroup): def nbesf_parser(raw_data: Any) -> SubGroup: try: if isinstance(raw_data, str): - nbesf_data = SubGroup.parse_raw(raw_data) + nbesf_data = type_validate_json(SubGroup, raw_data) else: - nbesf_data = SubGroup.parse_obj(raw_data) + nbesf_data = type_validate_python(SubGroup, raw_data) except Exception as e: logger.error("数据解析失败,该数据格式可能不满足NBESF格式标准!") diff --git a/nonebot_bison/config/subs_io/subs_io.py b/nonebot_bison/config/subs_io/subs_io.py index 21c1310..ec82695 100644 --- a/nonebot_bison/config/subs_io/subs_io.py +++ b/nonebot_bison/config/subs_io/subs_io.py @@ -6,6 +6,7 @@ from sqlalchemy import select from nonebot.log import logger from sqlalchemy.sql.selectable import Select from nonebot_plugin_saa import PlatformTarget +from nonebot.compat import type_validate_python from nonebot_plugin_datastore.db import create_session from sqlalchemy.orm.strategy_options import selectinload @@ -37,7 +38,7 @@ async def subscribes_export(selector: Callable[[Select], Select]) -> v2.SubGroup user_id_sub_dict: dict[int, list[v2.SubPayload]] = defaultdict(list) for sub in sub_data: - sub_paylaod = v2.SubPayload.from_orm(sub) + sub_paylaod = type_validate_python(v2.SubPayload, sub) user_id_sub_dict[sub.user_id].append(sub_paylaod) for user in user_data: diff --git a/nonebot_bison/platform/arknights.py b/nonebot_bison/platform/arknights.py index 6f51709..c0b2f56 100644 --- a/nonebot_bison/platform/arknights.py +++ b/nonebot_bison/platform/arknights.py @@ -4,6 +4,7 @@ from functools import partial from httpx import AsyncClient from bs4 import BeautifulSoup as bs from pydantic import Field, BaseModel +from nonebot.compat import type_validate_python from ..post import Post from ..types import Target, RawPost, Category @@ -28,9 +29,6 @@ class BulletinListItem(BaseModel): class BulletinList(BaseModel): list: list[BulletinListItem] - class Config: - extra = "ignore" - class BulletinData(BaseModel): cid: str @@ -76,7 +74,7 @@ class Arknights(NewMessage): async def get_sub_list(self, _) -> list[BulletinListItem]: raw_data = await self.client.get("https://ak-webview.hypergryph.com/api/game/bulletinList?target=IOS") - return ArkBulletinListResponse.parse_obj(raw_data.json()).data.list + return type_validate_python(ArkBulletinListResponse, raw_data.json()).data.list def get_id(self, post: BulletinListItem) -> Any: return post.cid @@ -95,7 +93,7 @@ class Arknights(NewMessage): raw_data = await self.client.get( f"https://ak-webview.hypergryph.com/api/game/bulletin/{self.get_id(post=raw_post)}" ) - data = ArkBulletinResponse.parse_obj(raw_data.json()).data + data = type_validate_python(ArkBulletinResponse, raw_data.json()).data def title_escape(text: str) -> str: return text.replace("\\n", " - ") diff --git a/nonebot_bison/platform/bilibili.py b/nonebot_bison/platform/bilibili.py index 17b724f..90d9178 100644 --- a/nonebot_bison/platform/bilibili.py +++ b/nonebot_bison/platform/bilibili.py @@ -9,6 +9,9 @@ from datetime import datetime, timedelta from httpx import AsyncClient from nonebot.log import logger from pydantic import Field, BaseModel +from nonebot.compat import type_validate_python + +from nonebot_bison.compat import model_rebuild from ..post import Post from ..utils import SchedulerConfig, text_similarity @@ -303,7 +306,7 @@ class Bilibililive(StatusChange): infos = [] for target in targets: if target in data.keys(): - infos.append(self.Info.parse_obj(data[target])) + infos.append(type_validate_python(self.Info, data[target])) else: infos.append(self._gen_empty_info(int(target))) return infos @@ -428,4 +431,4 @@ class BilibiliBangumi(StatusChange): ) -Bilibililive.Info.update_forward_refs() +model_rebuild(Bilibililive.Info) diff --git a/nonebot_bison/plugin_config.py b/nonebot_bison/plugin_config.py index 429069f..60b179b 100644 --- a/nonebot_bison/plugin_config.py +++ b/nonebot_bison/plugin_config.py @@ -1,12 +1,13 @@ import nonebot -from pydantic import Field, BaseSettings +from nonebot import get_plugin_config +from pydantic import Field, BaseModel global_config = nonebot.get_driver().config PlatformName = str ThemeName = str -class PlugConfig(BaseSettings): +class PlugConfig(BaseModel): bison_config_path: str = "" bison_use_pic: bool = Field( default=False, @@ -22,7 +23,7 @@ class PlugConfig(BaseSettings): bison_use_pic_merge: int = 0 # 多图片时启用图片合并转发(仅限群) # 0:不启用;1:首条消息单独发送,剩余照片合并转发;2以及以上:所有消息全部合并转发 bison_resend_times: int = 0 - bison_proxy: str | None + bison_proxy: str | None = None bison_ua: str = Field( "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36", description="默认UA", @@ -34,8 +35,5 @@ class PlugConfig(BaseSettings): def outer_url(self) -> str: return self.bison_outer_url or f"http://localhost:{global_config.port}/bison/" - class Config: - extra = "ignore" - -plugin_config = PlugConfig(**global_config.dict()) +plugin_config = get_plugin_config(PlugConfig) diff --git a/nonebot_bison/script/cli.py b/nonebot_bison/script/cli.py index 1f416c5..291c102 100644 --- a/nonebot_bison/script/cli.py +++ b/nonebot_bison/script/cli.py @@ -8,6 +8,7 @@ from functools import wraps, partial from collections.abc import Callable, Coroutine from nonebot.log import logger +from nonebot.compat import model_dump from ..scheduler.manager import init_scheduler from ..config.subs_io.nbesf_model import v1, v2 @@ -95,14 +96,14 @@ async def subs_export(path: Path, format: str): # If stream is None, it returns the produced stream. # safe_dump produces only standard YAML tags and cannot represent an arbitrary Python object. # 进行以下曲线救国方案 - json_data = json.dumps(export_data.dict(), ensure_ascii=False) + json_data = json.dumps(model_dump(export_data), ensure_ascii=False) yaml_data = pyyaml.safe_load(json_data) pyyaml.safe_dump(yaml_data, f, sort_keys=False) case "json": logger.info("正在导出为json...") - json.dump(export_data.dict(), f, indent=4, ensure_ascii=False) + json.dump(model_dump(export_data), f, indent=4, ensure_ascii=False) case _: raise click.BadParameter(message=f"不支持的导出格式: {format}") diff --git a/nonebot_bison/theme/themes/ceobe_canteen/build.py b/nonebot_bison/theme/themes/ceobe_canteen/build.py index 2dfdf59..7e66374 100644 --- a/nonebot_bison/theme/themes/ceobe_canteen/build.py +++ b/nonebot_bison/theme/themes/ceobe_canteen/build.py @@ -3,9 +3,10 @@ from datetime import datetime from typing import TYPE_CHECKING, Literal import jinja2 -from pydantic import BaseModel, root_validator +from pydantic import BaseModel from nonebot_plugin_saa import Text, Image, MessageSegmentFactory +from nonebot_bison.compat import model_validator from nonebot_bison.theme.utils import convert_to_qr from nonebot_bison.theme import Theme, ThemeRenderError, ThemeRenderUnsupportError @@ -35,7 +36,7 @@ class CeoboContent(BaseModel): image: str | None text: str | None - @root_validator + @model_validator(mode="before") def check(cls, values): if values["image"] is None and values["text"] is None: raise ValueError("image and text cannot be both None") diff --git a/poetry.lock b/poetry.lock index d2370cb..fee0756 100644 --- a/poetry.lock +++ b/poetry.lock @@ -205,6 +205,22 @@ type = "legacy" url = "https://pypi.org/simple" reference = "offical-source" +[[package]] +name = "annotated-types" +version = "0.6.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "offical-source" + [[package]] name = "anyio" version = "3.7.1" @@ -2130,13 +2146,13 @@ reference = "offical-source" [[package]] name = "nb-cli" -version = "1.3.1" +version = "1.4.0" description = "CLI for nonebot2" optional = false python-versions = "<4.0,>=3.9" files = [ - {file = "nb_cli-1.3.1-py3-none-any.whl", hash = "sha256:fa95e1549d87a1f7fbac5df52532f7ca02c2c871b645b9b69290e35c31d73136"}, - {file = "nb_cli-1.3.1.tar.gz", hash = "sha256:9b4dbbd83b9a8b70ba889f143ad303735528727c253c969e0c9935bc879a9051"}, + {file = "nb_cli-1.4.0-py3-none-any.whl", hash = "sha256:9b75d8ba5861493d266b6a5bd7d609b715e4f95ee3c37e1c91e2ece4ae821c0a"}, + {file = "nb_cli-1.4.0.tar.gz", hash = "sha256:8077bd1f44a6f8ea48f434e19dd942a8843d5b8cf909ab2f1c2a75f8cb4ff938"}, ] [package.dependencies] @@ -2147,7 +2163,7 @@ cookiecutter = ">=2.2,<3.0" httpx = ">=0.18,<1.0" jinja2 = ">=3.0,<4.0" noneprompt = ">=0.1.9,<1.0.0" -pydantic = ">=1.9,<2.0" +pydantic = ">=1.10.0,<2.5.0 || >2.5.0,<2.5.1 || >2.5.1,<3.0.0" pyfiglet = ">=1.0.1,<2.0.0" tomlkit = ">=0.10,<1.0" typing-extensions = ">=4.4,<5.0" @@ -2203,13 +2219,13 @@ reference = "offical-source" [[package]] name = "nonebot-adapter-qq" -version = "1.4.1" +version = "1.4.2" description = "QQ adapter for nonebot2" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "nonebot_adapter_qq-1.4.1-py3-none-any.whl", hash = "sha256:dbe59b9559943cb7940f0ff9190ec7428db75be9bc4ba1dbe2cba7ff6e249c23"}, - {file = "nonebot_adapter_qq-1.4.1.tar.gz", hash = "sha256:45e99d8caaf7e52857cbd2661d07fd1451bf56d63ef49e80b833933a222dcb26"}, + {file = "nonebot_adapter_qq-1.4.2-py3-none-any.whl", hash = "sha256:1bae0016420140841baad81365a8226f448d89ce8bd375f9ec5dd030e244e1da"}, + {file = "nonebot_adapter_qq-1.4.2.tar.gz", hash = "sha256:69331998182ecbeec2efa3dee89c63a0d359b93936afa39f158224d96e087c3a"}, ] [package.dependencies] @@ -2225,17 +2241,17 @@ reference = "offical-source" [[package]] name = "nonebot-adapter-red" -version = "0.8.0" +version = "0.9.0" description = "Red Protocol Adapter for Nonebot2" optional = false python-versions = ">=3.8" files = [ - {file = "nonebot_adapter_red-0.8.0-py3-none-any.whl", hash = "sha256:9bce0810e67a2754ba68d8c942bec12deeacb55459329f8e7a4f0b6416641180"}, - {file = "nonebot_adapter_red-0.8.0.tar.gz", hash = "sha256:577c0a286ed1f924339eb398ce1c5efd2cf727029116aff176b8715ab463c234"}, + {file = "nonebot_adapter_red-0.9.0-py3-none-any.whl", hash = "sha256:8dd5cd0a5d964faa23823b7c37fa8c64fa3ed8f67fa66515fe44a2708ee438ec"}, + {file = "nonebot_adapter_red-0.9.0.tar.gz", hash = "sha256:a657c5ffb071c91deb4109bb94ac8046dcbea5cbb584437995c30ffb2d184954"}, ] [package.dependencies] -nonebot2 = ">=2.0.1" +nonebot2 = ">=2.2.0" packaging = ">=23.1" [package.extras] @@ -2268,18 +2284,19 @@ reference = "offical-source" [[package]] name = "nonebot-plugin-apscheduler" -version = "0.3.0" +version = "0.4.0" description = "APScheduler Support for NoneBot2" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "nonebot_plugin_apscheduler-0.3.0-py3-none-any.whl", hash = "sha256:ec5e0267293fc9803e543c6086d3e109ac87bf6dccea5473d219cad826238aae"}, - {file = "nonebot_plugin_apscheduler-0.3.0.tar.gz", hash = "sha256:7c41cc1d49ea6af7c4518c72cd15f8c2f549071b8bc8bfc4b21fbdd0a4875cfd"}, + {file = "nonebot_plugin_apscheduler-0.4.0-py3-none-any.whl", hash = "sha256:f01bb418a5ecf9f04dcadbbc2ff5ba565a48177eb0a758c8c46b13048ac5680c"}, + {file = "nonebot_plugin_apscheduler-0.4.0.tar.gz", hash = "sha256:ba91e68809a38e6dbe28906366d47f37f754ded360944b938cd5ac62029a0eb6"}, ] [package.dependencies] apscheduler = ">=3.7.0,<4.0.0" -nonebot2 = ">=2.0.0,<3.0.0" +nonebot2 = ">=2.2.0,<3.0.0" +pydantic = ">=1.10.0,<2.5.0 || >2.5.0,<2.5.1 || >2.5.1,<3.0.0" [package.source] type = "legacy" @@ -2288,19 +2305,19 @@ reference = "offical-source" [[package]] name = "nonebot-plugin-datastore" -version = "1.1.2" +version = "1.2.0" description = "适用于 Nonebot2 的数据存储插件" optional = false -python-versions = ">=3.8,<4.0" +python-versions = ">=3.9,<4.0" files = [ - {file = "nonebot_plugin_datastore-1.1.2-py3-none-any.whl", hash = "sha256:e61044e018c6b60701b38a078b5d0c1ff87e924ee1722675a14006cc32039b05"}, - {file = "nonebot_plugin_datastore-1.1.2.tar.gz", hash = "sha256:32d06d0b06b32d2c02fb3f206820e0da64e0dde542cff3b8aa44abd93b3aeada"}, + {file = "nonebot_plugin_datastore-1.2.0-py3-none-any.whl", hash = "sha256:22d9bfc948506eda78b010254da6f437c595d0c1878f8852cd92f84a935d204c"}, + {file = "nonebot_plugin_datastore-1.2.0.tar.gz", hash = "sha256:34c6c3c19fc0da6808c6f73e931bacb931d7274ab376f23bdf1b352a760799ed"}, ] [package.dependencies] alembic = ">=1.9.1,<2.0.0" -nonebot-plugin-localstore = ">=0.2.0,<0.3.0 || >0.3.0,<0.4.0 || >0.4.0" -nonebot2 = {version = ">=2.0.0,<3.0.0", extras = ["httpx"]} +nonebot-plugin-localstore = ">=0.6.0" +nonebot2 = {version = ">=2.2.0,<3.0.0", extras = ["httpx"]} sqlalchemy = {version = ">=2.0.0,<3.0.0", extras = ["aiosqlite"]} [package.extras] @@ -2363,19 +2380,19 @@ reference = "offical-source" [[package]] name = "nonebot-plugin-send-anything-anywhere" -version = "0.5.0" +version = "0.6.0" description = "An adaptor for nonebot2 adaptors" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "nonebot_plugin_send_anything_anywhere-0.5.0-py3-none-any.whl", hash = "sha256:bff64f5f337643ba34b9ea0bdd8d86d3ee6285a29b9083d416a67d4815e83ddf"}, - {file = "nonebot_plugin_send_anything_anywhere-0.5.0.tar.gz", hash = "sha256:0230db94ca5654e2b0462b144db7ea74b763ee04fa7bc53deecacf32362e5268"}, + {file = "nonebot_plugin_send_anything_anywhere-0.6.0-py3-none-any.whl", hash = "sha256:30d328c350bc44c39d0e45b622a843275336b4e25d1d670ae1c76ace400fd3d6"}, + {file = "nonebot_plugin_send_anything_anywhere-0.6.0.tar.gz", hash = "sha256:48196b7fdcb1c6c82ec6d27e225a2f11811aee4393edf86a874985480c4d199d"}, ] [package.dependencies] -anyio = ">=3.6.2,<4.0.0" +anyio = ">=3.3.0,<5.0.0" nonebot2 = ">=2.0.0,<3.0.0" -pydantic = ">=1.10.5,<2.0.0" +pydantic = ">=1.10.0,<2.5.0 || >2.5.0,<2.5.1 || >2.5.1,<3.0.0" strenum = ">=0.4.8,<0.5.0" [package.source] @@ -2943,55 +2960,118 @@ reference = "offical-source" [[package]] name = "pydantic" -version = "1.10.14" -description = "Data validation and settings management using python type hints" +version = "2.6.3" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"}, - {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"}, - {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"}, - {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"}, - {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"}, - {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"}, - {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"}, - {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"}, - {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"}, - {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"}, - {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"}, - {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"}, - {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"}, - {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"}, - {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"}, - {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"}, - {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"}, - {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"}, - {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"}, - {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"}, - {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"}, - {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"}, - {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"}, - {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"}, - {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"}, - {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"}, - {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"}, - {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"}, - {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"}, - {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"}, - {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"}, - {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"}, - {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"}, - {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"}, - {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"}, - {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"}, + {file = "pydantic-2.6.3-py3-none-any.whl", hash = "sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a"}, + {file = "pydantic-2.6.3.tar.gz", hash = "sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.16.3" +typing-extensions = ">=4.6.1" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[package.source] +type = "legacy" +url = "https://pypi.org/simple" +reference = "offical-source" + +[[package]] +name = "pydantic-core" +version = "2.16.3" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"}, + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"}, + {file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"}, + {file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"}, + {file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"}, + {file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"}, + {file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"}, + {file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"}, + {file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"}, + {file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"}, + {file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"}, + {file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"}, + {file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"}, + {file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"}, + {file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [package.source] type = "legacy" @@ -3906,13 +3986,13 @@ reference = "offical-source" [[package]] name = "tomlkit" -version = "0.12.3" +version = "0.12.4" description = "Style preserving TOML library" optional = false python-versions = ">=3.7" files = [ - {file = "tomlkit-0.12.3-py3-none-any.whl", hash = "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba"}, - {file = "tomlkit-0.12.3.tar.gz", hash = "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4"}, + {file = "tomlkit-0.12.4-py3-none-any.whl", hash = "sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b"}, + {file = "tomlkit-0.12.4.tar.gz", hash = "sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3"}, ] [package.source] @@ -4485,4 +4565,4 @@ yaml = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<4.0.0" -content-hash = "5853345e1678e8b581c98e75c55d626888054aee3c65264547c19bbd876840d1" +content-hash = "13ed3c2ef12bf2fec8ea959ad55d9cc6efb6287b0e584f4db0df98efb4418549" diff --git a/pyproject.toml b/pyproject.toml index 13885a1..a7677a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,17 +26,18 @@ beautifulsoup4 = ">=4.12.3" expiringdict = "^1.2.1" feedparser = "^6.0.2" httpx = ">=0.16.1" -nonebot2 = {extras = ["fastapi"], version = "^2.1.3"} +nonebot2 = { extras = ["fastapi"], version = "^2.2.1" } nonebot-adapter-onebot = "^2.0.0" nonebot-plugin-htmlrender = ">=0.2.0" -nonebot-plugin-datastore = ">=0.6.2,<2.0.0" -nonebot-plugin-apscheduler = ">=0.2,<0.4" -nonebot-plugin-send-anything-anywhere = "^0.5.0" +nonebot-plugin-datastore = ">=1.2.0,<2.0.0" +nonebot-plugin-apscheduler = ">=0.4.0" +nonebot-plugin-send-anything-anywhere = ">=0.5.0,<0.7.0" pillow = ">=8.1,<11.0" pyjwt = "^2.1.0" python-socketio = "^5.4.0" tinydb = "^4.3.0" qrcode = "^7.4.2" +pydantic = ">=1.10.0,<3.0.0,!=2.5.0,!=2.5.1" [tool.poetry.group.dev.dependencies] black = ">=23.7,<25.0" @@ -62,10 +63,10 @@ respx = "^0.20.0" optional = true [tool.poetry.group.docker.dependencies] -nb-cli = "^1.2.8" -nonebot2 = {extras = ["fastapi", "aiohttp"], version = "^2.1.3"} -nonebot-adapter-red = ">=0.7.4,<0.9.0" -nonebot-adapter-qq = "^1.3.4" +nb-cli = "^1.4.0" +nonebot2 = { extras = ["fastapi", "aiohttp"], version = "^2.2.1" } +nonebot-adapter-red = "^0.9.0" +nonebot-adapter-qq = "^1.4.2" nonebot-adapter-telegram = "^0.1.0b14" poetry-core = "^1.8.1" @@ -115,7 +116,7 @@ extra_standard_library = ["typing_extensions"] [tool.nonebot] adapters = [ - { name = "OneBot V11", module_name = "nonebot.adapters.onebot.v11" }, + { name = "OneBot V11", module_name = "nonebot.adapters.onebot.v11" }, ] plugins = ["nonebot_bison"] plugin_dirs = ["extra_plugins"] @@ -131,6 +132,7 @@ executionEnvironments = [ ] }, { root = "./" }, ] +defineConstant = { PYDANTIC_V2 = true } [[tool.poetry.source]] name = "offical-source" diff --git a/tests/subs_io/test_subs_io.py b/tests/subs_io/test_subs_io.py index 7681a77..bb89d9a 100644 --- a/tests/subs_io/test_subs_io.py +++ b/tests/subs_io/test_subs_io.py @@ -1,5 +1,6 @@ import pytest from nonebug.app import App +from nonebot.compat import model_dump from .utils import get_json @@ -41,14 +42,14 @@ async def test_subs_export(app: App, init_scheduler): assert len(data) == 3 nbesf_data = await subscribes_export(lambda x: x) - assert nbesf_data.dict() == get_json("v2/subs_export.json") + assert model_dump(nbesf_data) == get_json("v2/subs_export.json") nbesf_data_user_234 = await subscribes_export( lambda stmt: stmt.where(User.user_target == {"platform_type": "QQ Group", "group_id": 2342}) ) assert len(nbesf_data_user_234.groups) == 1 assert len(nbesf_data_user_234.groups[0].subs) == 2 - assert nbesf_data_user_234.groups[0].user_target == { + assert model_dump(nbesf_data_user_234.groups[0].user_target) == { "group_id": 2342, "platform_type": "QQ Group", } diff --git a/tests/utils.py b/tests/utils.py index a6a887d..5ea3440 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,5 +1,7 @@ from typing import TYPE_CHECKING, Literal, TypedDict +from nonebot.compat import PYDANTIC_V2, ConfigDict + if TYPE_CHECKING: from nonebot.adapters.onebot.v11 import GroupMessageEvent, PrivateMessageEvent @@ -35,8 +37,12 @@ def fake_group_message_event(**field) -> "GroupMessageEvent": ) to_me: bool = False - class Config: - extra = "forbid" + if PYDANTIC_V2: + model_config = ConfigDict(extra="forbid") + else: + + class Config: + extra = "forbid" return FakeEvent(**field) @@ -62,8 +68,12 @@ def fake_private_message_event(**field) -> "PrivateMessageEvent": sender: Sender = Sender(nickname="test") to_me: bool = False - class Config: - extra = "forbid" + if PYDANTIC_V2: + model_config = ConfigDict(extra="forbid") + else: + + class Config: + extra = "forbid" return FakeEvent(**field)