diff --git a/core/builtins/message/__init__.py b/core/builtins/message/__init__.py index ce1a693c5e..b7c2fee627 100644 --- a/core/builtins/message/__init__.py +++ b/core/builtins/message/__init__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import asyncio from datetime import datetime, UTC as datetimeUTC from typing import Any, Coroutine, Dict, List, Optional, Union @@ -22,18 +24,18 @@ class ExecutionLockList: _list = set() @staticmethod - def add(msg: 'MessageSession'): + def add(msg: MessageSession): target_id = msg.target.sender_id ExecutionLockList._list.add(target_id) @staticmethod - def remove(msg: 'MessageSession'): + def remove(msg: MessageSession): target_id = msg.target.sender_id if target_id in ExecutionLockList._list: ExecutionLockList._list.remove(target_id) @staticmethod - def check(msg: 'MessageSession'): + def check(msg: MessageSession): target_id = msg.target.sender_id return target_id in ExecutionLockList._list @@ -49,7 +51,7 @@ class MessageTaskManager: @classmethod def add_task( cls, - session: 'MessageSession', + session: MessageSession, flag: asyncio.Event, all_: bool = False, reply: Optional[Union[List[int], List[str], int, str]] = None, @@ -73,7 +75,7 @@ def add_callback(cls, message_id: Union[List[int], List[str], int, str], callbac cls._callback_list[message_id] = {'callback': callback, 'ts': datetime.now().timestamp()} @classmethod - def get_result(cls, session: 'MessageSession'): + def get_result(cls, session: MessageSession): if 'result' in cls._task_list[session.target.target_id][session.target.sender_id][session]: return cls._task_list[session.target.target_id][session.target.sender_id][session]['result'] else: @@ -98,7 +100,7 @@ async def bg_check(cls): del cls._callback_list[message_id] @classmethod - async def check(cls, session: 'MessageSession'): + async def check(cls, session: MessageSession): if session.target.target_id in cls._task_list: senders = [] if session.target.sender_id in cls._task_list[session.target.target_id]: @@ -284,7 +286,7 @@ async def get_text_channel_list(self) -> List[str]: raise NotImplementedError class Typing: - def __init__(self, msg: 'MessageSession'): + def __init__(self, msg: MessageSession): """ :param msg: 本条消息,由于此class需要被一同传入下游方便调用,所以作为子class存在,将来可能会有其他的解决办法。 """ @@ -346,7 +348,7 @@ async def wait_next_message(self, quote: bool = True, delete: bool = False, timeout: Optional[float] = 120, - append_instruction: bool = True) -> 'MessageSession': + append_instruction: bool = True) -> MessageSession: """ 一次性模板,用于等待对象的下一条消息。 @@ -386,7 +388,7 @@ async def wait_reply(self, delete: bool = False, timeout: Optional[float] = 120, all_: bool = False, - append_instruction: bool = True) -> 'MessageSession': + append_instruction: bool = True) -> MessageSession: """ 一次性模板,用于等待触发对象回复消息。 @@ -425,7 +427,7 @@ async def wait_anyone(self, message_chain: Optional[Union[MessageChain, str, list, MessageElement]] = None, quote: bool = False, delete: bool = False, - timeout: Optional[float] = 120) -> 'MessageSession': + timeout: Optional[float] = 120) -> MessageSession: """ 一次性模板,用于等待触发对象所属对话内任意成员确认。 diff --git a/core/builtins/message/chain.py b/core/builtins/message/chain.py index 5a1d00f56e..00be41f803 100644 --- a/core/builtins/message/chain.py +++ b/core/builtins/message/chain.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import base64 import re from typing import List, Optional, Tuple, Union, Any @@ -32,7 +34,7 @@ def __init__( List[MessageElement], Tuple[MessageElement], MessageElement, - 'MessageChain' + MessageChain ]] = None, ): """ @@ -146,7 +148,7 @@ def unsafeprompt(name, secret, text): return False return True - def as_sendable(self, msg: 'MessageSession' = None, embed: bool = True) -> list: + def as_sendable(self, msg: MessageSession = None, embed: bool = True) -> list: """ 将消息链转换为可发送的格式。 """ diff --git a/core/builtins/message/elements.py b/core/builtins/message/elements.py index 8c6977edcb..56c70a5b3d 100644 --- a/core/builtins/message/elements.py +++ b/core/builtins/message/elements.py @@ -1,9 +1,11 @@ +from __future__ import annotations + import base64 import os import random import re from datetime import datetime, timezone -from typing import Tuple, Optional, TYPE_CHECKING, Dict, Any, Union, List +from typing import Optional, TYPE_CHECKING, Dict, Any, Union, List from urllib import parse import aiohttp @@ -19,6 +21,8 @@ from core.utils.cache import random_cache_path from core.utils.i18n import Locale +from copy import deepcopy + if TYPE_CHECKING: from core.builtins import MessageSession @@ -50,7 +54,7 @@ def assign(cls, text = ''.join([str(x) for x in texts]) if not disable_joke: text = joke(text) - return cls(text=text) + return deepcopy(cls(text=text)) @define @@ -76,7 +80,7 @@ def assign(cls, url: str, use_mm: bool = False): "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM") url = mm_url % parse.quote(parse.unquote(url).translate(rot13)) - return cls(url=url) + return deepcopy(cls(url=url)) def __str__(self): if self.md_format: @@ -98,7 +102,7 @@ class FormattedTimeElement(MessageElement): seconds: bool = True timezone: bool = True - def to_str(self, msg: Optional['MessageSession'] = None): + def to_str(self, msg: Optional[MessageSession] = None): ftime_template = [] if msg: if self.date: @@ -145,7 +149,7 @@ def assign(cls, timestamp: float, :param seconds: 是否显示秒。(默认为True) :param timezone: 是否显示时区。(默认为True) """ - return cls(timestamp=timestamp, date=date, iso=iso, time=time, seconds=seconds, timezone=timezone) + return deepcopy(cls(timestamp=timestamp, date=date, iso=iso, time=time, seconds=seconds, timezone=timezone)) @define @@ -164,7 +168,7 @@ def assign(cls, :param key: 多语言的键名。 :param kwargs: 多语言中的变量。 """ - return cls(key=key, kwargs=kwargs) + return deepcopy(cls(key=key, kwargs=kwargs)) @define @@ -203,7 +207,7 @@ def assign(cls, error_message += '\n' + \ locale.t('error.prompt.address', url=str(report_url)) - return cls(error_message) + return deepcopy(cls(error_message)) def __str__(self): return self.error_message @@ -234,7 +238,7 @@ def assign(cls, path: Union[str, PILImage.Image], path = save elif re.match('^https?://.*', path): need_get = True - return cls(path, need_get, headers) + return deepcopy(cls(path, need_get, headers)) async def get(self): """ @@ -294,7 +298,7 @@ def assign(cls, path: str): """ :param path: 语音路径。 """ - return cls(path) + return deepcopy(cls(path)) @define @@ -317,7 +321,7 @@ def assign(cls, name: str, value: str, inline: bool = False): :param value: 字段值。 :param inline: 是否内联。(默认为False) """ - return cls(name=name, value=value, inline=inline) + return deepcopy(cls(name=name, value=value, inline=inline)) @define @@ -355,7 +359,7 @@ def assign(cls, title: Optional[str] = None, author: Optional[str] = None, footer: Optional[str] = None, fields: Optional[List[EmbedFieldElement]] = None): - return cls( + return deepcopy(cls( title=title, description=description, url=url, @@ -365,9 +369,9 @@ def assign(cls, title: Optional[str] = None, thumbnail=thumbnail, author=author, footer=footer, - fields=fields) + fields=fields)) - def to_message_chain(self, msg: Optional['MessageSession'] = None): + def to_message_chain(self, msg: Optional[MessageSession] = None): """ 将Embed转换为消息链。 """ diff --git a/core/component.py b/core/component.py index f80551cc0e..7098c5f03d 100644 --- a/core/component.py +++ b/core/component.py @@ -184,22 +184,22 @@ def module( :param exclude_from: 此命令排除的平台列表。 :param support_languages: 此命令支持的语言列表。 """ - module = Module(alias=alias, - bind_prefix=bind_prefix, - desc=desc, - recommend_modules=recommend_modules, - developers=developers, - base=base, - doc=doc, - hidden=hidden, - load=load, - rss=rss, - required_admin=required_admin, - required_superuser=required_superuser, - required_base_superuser=required_base_superuser, - available_for=available_for, - exclude_from=exclude_from, - support_languages=support_languages) + module = Module.assign(alias=alias, + bind_prefix=bind_prefix, + desc=desc, + recommend_modules=recommend_modules, + developers=developers, + base=base, + doc=doc, + hidden=hidden, + load=load, + rss=rss, + required_admin=required_admin, + required_superuser=required_superuser, + required_base_superuser=required_base_superuser, + available_for=available_for, + exclude_from=exclude_from, + support_languages=support_languages) frame = inspect.currentframe() ModulesManager.add_module(module, frame.f_back.f_globals["__name__"]) return Bind.Module(bind_prefix) diff --git a/core/parser/message.py b/core/parser/message.py index 66fc2878d9..c4b99dd91e 100644 --- a/core/parser/message.py +++ b/core/parser/message.py @@ -489,10 +489,10 @@ async def execute_submodule(msg: Bot.MessageSession, command_first_word, command if Config('bug_report_url', bug_report_url_default, cfg_type=str): errmsg += '\n' + msg.locale.t('error.prompt.address', - url=str(Url(Config('bug_report_url', - bug_report_url_default, - cfg_type=str), - use_mm=False))) + url=Url(Config('bug_report_url', + bug_report_url_default, + cfg_type=str), + use_mm=False)) await msg.send_message(errmsg) if not timeout and report_targets: diff --git a/core/types/message/__init__.py b/core/types/message/__init__.py index c6268c1df6..f9542bdd5e 100644 --- a/core/types/message/__init__.py +++ b/core/types/message/__init__.py @@ -7,8 +7,8 @@ @define class MsgInfo: - target_id: Union[int, str] - sender_id: Union[int, str] + target_id: str + sender_id: str sender_prefix: str target_from: str sender_from: str diff --git a/core/types/module/__init__.py b/core/types/module/__init__.py index 69538759dd..bfe21f07f0 100644 --- a/core/types/module/__init__.py +++ b/core/types/module/__init__.py @@ -7,57 +7,47 @@ from .component_matches import * +from .utils import convert2lst -def convert2lst(elements: Union[str, list, tuple]) -> list: - if isinstance(elements, str): - return [elements] - elif isinstance(elements, tuple): - return list(elements) - return elements +from attrs import define, field, Converter +from copy import deepcopy + +def alias_converter(value, _self) -> dict: + if isinstance(value, str): + return {value: _self.bind_prefix} + elif isinstance(value, (tuple, list)): + return {x: _self.bind_prefix for x in value} + return value + + +@define class Module: - def __init__(self, - bind_prefix: str, - alias: Union[str, list, tuple, dict, None] = None, - desc: str = None, - recommend_modules: Union[str, list, tuple, None] = None, - developers: Union[str, list, tuple, None] = None, - required_admin: bool = False, - base: bool = False, - doc: bool = False, - hidden: bool = False, - load: bool = True, - rss: bool = False, - required_superuser: bool = False, - required_base_superuser: bool = False, - available_for: Union[str, list, tuple, None] = '*', - exclude_from: Union[str, list, tuple, None] = '', - support_languages: Union[str, list, tuple, None] = None): - self.bind_prefix: str = bind_prefix - if isinstance(alias, str): - alias = {alias: bind_prefix} - elif isinstance(alias, (tuple, list)): - alias = {x: bind_prefix for x in alias} - self.alias: Dict[str, str] = alias - self.desc: str = desc - self.recommend_modules: List[str] = convert2lst(recommend_modules) - self.developers: List[str] = convert2lst(developers) - self.required_admin: bool = required_admin - self.base: bool = base - self.doc: bool = doc - self.hidden: bool = hidden - self.load: bool = load - self.rss: bool = rss - self.required_superuser: bool = required_superuser - self.required_base_superuser: bool = required_base_superuser - self.available_for: List[str] = convert2lst(available_for) - self.exclude_from: List[str] = convert2lst(exclude_from) - self.support_languages: List[str] = convert2lst(support_languages) - self.command_list = CommandMatches() - self.regex_list = RegexMatches() - self.schedule_list = ScheduleMatches() - self.hooks_list = HookMatches() + bind_prefix: str + alias: dict = field(converter=Converter(alias_converter, takes_self=True)) + recommend_modules: list = field(converter=convert2lst) + developers: list = field(converter=convert2lst) + available_for: list = field(default=['*'], converter=convert2lst) + exclude_from: list = field(default=[], converter=convert2lst) + support_languages: list = field(default=None, converter=convert2lst) + desc: Union[str] = '' + required_admin: bool = False + base: bool = False + doc: bool = False + hidden: bool = False + load: bool = True + rss: bool = False + required_superuser: bool = False + required_base_superuser: bool = False + command_list: CommandMatches = CommandMatches.init() + regex_list: RegexMatches = RegexMatches.init() + schedule_list: ScheduleMatches = ScheduleMatches.init() + hooks_list: HookMatches = HookMatches.init() + + @classmethod + def assign(cls, **kwargs): + return deepcopy(cls(**kwargs)) __all__ = ["Module", "AndTrigger", "OrTrigger", "DateTrigger", diff --git a/core/types/module/component_matches.py b/core/types/module/component_matches.py index d272904449..11c1bfca41 100644 --- a/core/types/module/component_matches.py +++ b/core/types/module/component_matches.py @@ -2,15 +2,27 @@ from .component_meta import * +from attrs import define, field +from copy import deepcopy -class CommandMatches: - def __init__(self): - self.set: List[CommandMeta] = [] + +@define +class BaseMatches: + set: List[ModuleMeta] = [] def add(self, meta): self.set.append(meta) return self.set + @classmethod + def init(cls): + return deepcopy(cls()) + + +@define +class CommandMatches(BaseMatches): + set: List[CommandMeta] = [] + def get(self, target_from: str, show_required_superuser: bool = False, show_required_base_superuser: bool = False) -> List[CommandMeta]: metas = [] @@ -28,13 +40,9 @@ def get(self, target_from: str, show_required_superuser: bool = False, return metas -class RegexMatches: - def __init__(self): - self.set: List[RegexMeta] = [] - - def add(self, meta): - self.set.append(meta) - return self.set +@define +class RegexMatches(BaseMatches): + set: List[RegexMeta] = [] def get(self, target_from: str, show_required_superuser: bool = False, show_required_base_superuser: bool = False) -> List[RegexMeta]: @@ -53,22 +61,14 @@ def get(self, target_from: str, show_required_superuser: bool = False, return metas -class ScheduleMatches: - def __init__(self): - self.set: List[ScheduleMeta] = [] - - def add(self, meta): - self.set.append(meta) - return self.set +@define +class ScheduleMatches(BaseMatches): + set: List[ScheduleMeta] = [] -class HookMatches: - def __init__(self): - self.set: List[HookMeta] = [] - - def add(self, meta): - self.set.append(meta) - return self.set +@define +class HookMatches(BaseMatches): + set: List[HookMeta] = [] __all__ = ["CommandMatches", "RegexMatches", "ScheduleMatches", "HookMatches"] diff --git a/core/types/module/component_meta.py b/core/types/module/component_meta.py index a35d8cc469..36f5678a8b 100644 --- a/core/types/module/component_meta.py +++ b/core/types/module/component_meta.py @@ -8,100 +8,55 @@ from core.parser.args import Template - -class Meta: - def __init__(self, **kwargs): - raise NotImplementedError - - -class CommandMeta: - def __init__(self, - function: Callable = None, - help_doc: List[Template] = None, - options_desc: dict = None, - required_admin: bool = False, - required_superuser: bool = False, - required_base_superuser: bool = False, - available_for: Union[str, list, tuple] = '*', - exclude_from: Union[str, list, tuple] = '', - load: bool = True, - priority: int = 1 - ): - self.function = function - if isinstance(help_doc, str): - help_doc = [help_doc] - elif isinstance(help_doc, tuple): - help_doc = list(help_doc) - self.help_doc: List[Template] = help_doc - self.options_desc = options_desc - self.required_admin = required_admin - self.required_superuser = required_superuser - self.required_base_superuser = required_base_superuser - if isinstance(available_for, str): - available_for = [available_for] - elif isinstance(available_for, tuple): - available_for = list(available_for) - if isinstance(exclude_from, str): - exclude_from = [exclude_from] - elif isinstance(exclude_from, tuple): - exclude_from = list(exclude_from) - self.available_for = available_for - self.exclude_from = exclude_from - self.load = load - self.priority = priority - - -class RegexMeta: - def __init__(self, - function: Callable = None, - pattern: Union[str, re.Pattern] = None, - mode: str = None, - desc: str = None, - required_admin: bool = False, - required_superuser: bool = False, - required_base_superuser: bool = False, - available_for: Union[str, list, tuple] = '*', - exclude_from: Union[str, list, tuple] = '', - flags: re.RegexFlag = 0, - load: bool = True, - show_typing: bool = True, - logging: bool = True - ): - self.function = function - self.pattern = pattern - self.mode = mode - self.flags = flags - self.desc = desc - self.required_admin = required_admin - self.required_superuser = required_superuser - self.required_base_superuser = required_base_superuser - if isinstance(available_for, str): - available_for = [available_for] - elif isinstance(available_for, tuple): - available_for = list(available_for) - if isinstance(exclude_from, str): - exclude_from = [exclude_from] - elif isinstance(exclude_from, tuple): - exclude_from = list(exclude_from) - self.available_for = available_for - self.exclude_from = exclude_from - self.load = load - self.show_typing = show_typing - self.logging = logging - - -class ScheduleMeta: - def __init__(self, trigger: Union[AndTrigger, OrTrigger, DateTrigger, CronTrigger, IntervalTrigger], - function: Callable = None - ): - self.trigger = trigger - self.function = function - - -class HookMeta: - def __init__(self, function: Callable, name: str = None): - self.function = function - self.name = name - - -__all__ = ["Meta", "CommandMeta", "RegexMeta", "ScheduleMeta", "HookMeta"] +from attrs import define, field +from .utils import convert2lst + + +class ModuleMeta: + pass + + +@define +class CommandMeta(ModuleMeta): + function: Callable = None + help_doc: List[Template] = field(default=[], converter=convert2lst) + options_desc: dict = None + required_admin: bool = False + required_superuser: bool = False + required_base_superuser: bool = False + available_for: list = field(default=['*'], converter=convert2lst) + exclude_from: list = field(default=[], converter=convert2lst) + load: bool = True + priority: int = 1 + + +@define +class RegexMeta(ModuleMeta): + function: Callable = None + pattern: Union[str, re.Pattern] = None + mode: str = None + desc: str = None + required_admin: bool = False + required_superuser: bool = False + required_base_superuser: bool = False + available_for: list = field(default=['*'], converter=convert2lst) + exclude_from: list = field(default=[], converter=convert2lst) + flags: re.RegexFlag = 0 + load: bool = True + show_typing: bool = True + logging: bool = True + + +@define +class ScheduleMeta(ModuleMeta): + trigger: Union[AndTrigger, OrTrigger, DateTrigger, CronTrigger, IntervalTrigger] + function: Callable = None + + +@define +class HookMeta(ModuleMeta): + function: Callable = None + name: str = None + + +__all__ = ["ModuleMeta", "CommandMeta", "RegexMeta", "ScheduleMeta", "HookMeta"] diff --git a/core/types/module/utils.py b/core/types/module/utils.py new file mode 100644 index 0000000000..e3696498b0 --- /dev/null +++ b/core/types/module/utils.py @@ -0,0 +1,9 @@ +from typing import Union + + +def convert2lst(elements: Union[str, list, tuple]) -> list: + if isinstance(elements, str): + return [elements] + elif isinstance(elements, tuple): + return list(elements) + return elements diff --git a/poetry.lock b/poetry.lock index 244b7d0f4c..eb399fb1be 100644 --- a/poetry.lock +++ b/poetry.lock @@ -312,22 +312,22 @@ test = ["black (>=20.8b1)", "flake8 (>=3.8.3)", "mypy (>=0.812)", "mypy-extensio [[package]] name = "attrs" -version = "23.2.0" +version = "24.2.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.7" files = [ - {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, - {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, ] [package.extras] -cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] -dev = ["attrs[tests]", "pre-commit"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs[tests-no-zope]", "zope-interface"] -tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] -tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "autopep8" @@ -1989,15 +1989,19 @@ name = "langconv" version = "0.3.0" description = "A Python library for conversion between Traditional and Simplified Chinese, inspired by MediaWiki's LanguageConverter." optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "langconv-0.3.0-py3-none-any.whl", hash = "sha256:dfd3484e0373a07ed8271ab60293648e9d216ef460c58ff7dda80315292d0566"}, - {file = "langconv-0.3.0.tar.gz", hash = "sha256:816bedf81db368a410959293a31aeebe4cd75de516427b50370727003f3bd3ce"}, -] +python-versions = ">=3.9" +files = [] +develop = false [package.dependencies] -attrs = ">=23.2.0,<24.0.0" -iso639-lang = ">=2.2.3,<3.0.0" +attrs = "^24.2.0" +iso639-lang = "^2.2.3" + +[package.source] +type = "git" +url = "https://github.com/OasisAkari/langconv.py.git" +reference = "HEAD" +resolved_reference = "975ee0896096b63148f0930db762607a5a2113df" [[package]] name = "langsmith" @@ -4533,4 +4537,4 @@ propcache = ">=0.2.0" [metadata] lock-version = "2.0" python-versions = "^3.12.0" -content-hash = "da8ebfb92146be8808b96bfbf4e259908ebfdd98702bac00070595d29010fda3" +content-hash = "78bd3610a1b3fc1005ea68cf7bf4f181df6a14bc9cfacef8ede379835fc559c5" diff --git a/pyproject.toml b/pyproject.toml index c5cd672fda..c3ea64953e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ tiktoken = "^0.8.0" pycryptodome = "^3.18.0" khl-py = "^0.3.16" matrix-nio = "^0.25.0" -attrs = "^23.1.0" +attrs = "^24.2.0" uvicorn = {extras = ["standard"], version = "^0.32.0"} pyjwt = {extras = ["crypto"], version = "^2.8.0"} python-whois = "^0.9.0" @@ -61,7 +61,7 @@ fastapi = "^0.115.0" inputimeout = "^1.0.4" prompt-toolkit = "^3.0.47" emoji = "^2.12.1" -langconv = "0.3.0" +langconv = {git = "https://github.com/OasisAkari/langconv.py.git"} ff3 = "^1.0.2" orjson = "^3.10.9" jinja2 = "^3.1.4" diff --git a/requirements.txt b/requirements.txt index c498ddd4c5..e79799b3a2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ anyio==4.6.2.post1 ; python_full_version >= "3.12.0" and python_version < "4.0" appdirs==1.4.4 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" apscheduler==3.10.4 ; python_version >= "3.12" and python_version < "4.0" asyncio-dgram==2.2.0 ; python_full_version >= "3.12.0" and python_version < "4" -attrs==23.2.0 ; python_version >= "3.12" and python_version < "4.0" +attrs==24.2.0 ; python_version >= "3.12" and python_version < "4.0" backoff==2.2.1 ; python_full_version >= "3.12.0" and python_version < "4.0" beautifulsoup4==4.12.3 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" blinker==1.8.2 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" @@ -59,7 +59,7 @@ hyperframe==6.0.1 ; python_full_version >= "3.12.0" and python_full_version < "4 identify==2.6.1 ; python_version >= "3.12" and python_version < "4.0" idna==3.10 ; python_version >= "3.12" and python_version < "4.0" inputimeout==1.0.4 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" -iso639-lang==2.5.0 ; python_full_version >= "3.12.0" and python_version < "4.0" +iso639-lang==2.5.0 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" itsdangerous==2.2.0 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" jaraco-context==6.0.1 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" jinja2==3.1.4 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" @@ -73,7 +73,7 @@ kiwisolver==1.4.7 ; python_full_version >= "3.12.0" and python_full_version < "4 langchain-core==0.3.15 ; python_full_version >= "3.12.0" and python_version < "4.0" langchain-text-splitters==0.3.2 ; python_full_version >= "3.12.0" and python_version < "4.0" langchain==0.3.7 ; python_full_version >= "3.12.0" and python_version < "4.0" -langconv==0.3.0 ; python_full_version >= "3.12.0" and python_version < "4.0" +langconv @ git+https://github.com/OasisAkari/langconv.py.git@975ee0896096b63148f0930db762607a5a2113df ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" langsmith==0.1.139 ; python_full_version >= "3.12.0" and python_version < "4.0" loguru==0.7.2 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" magic-filter==1.0.12 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0"