mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-11-04 22:36:34 +08:00
fix(types): type messaging template and queue boundaries
This commit is contained in:
@@ -11,7 +11,7 @@ import time
|
||||
from contextvars import Context, copy_context
|
||||
from datetime import datetime
|
||||
from functools import partial
|
||||
from typing import Any, Callable, Dict, List, Literal, Optional, Protocol, Union
|
||||
from typing import Any, Callable, Dict, List, Literal, Optional, Protocol, Union, cast
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
@@ -123,7 +123,7 @@ class TemplateContextBuilder:
|
||||
episodes_info: Optional[List[TmdbEpisode]] = None,
|
||||
include_raw_objects: bool = True,
|
||||
aggregate_music_album: bool = False,
|
||||
**kwargs
|
||||
**kwargs: Any,
|
||||
) -> Dict[str, Any]:
|
||||
"""
|
||||
构建一次性渲染上下文字典。
|
||||
@@ -343,9 +343,9 @@ class TemplateContextBuilder:
|
||||
"artist": cls.__convert_invalid_characters(meta.artist),
|
||||
# 标签专辑名常自带尾部年份,与模板独立追加的年份去重(issue #6355)
|
||||
"album": cls.__strip_album_trailing_year(
|
||||
cls.__convert_invalid_characters(meta.album), meta.year
|
||||
cls.__convert_invalid_characters(meta.album or ""), meta.year
|
||||
),
|
||||
"album_artist": cls.__convert_invalid_characters(meta.album_artist),
|
||||
"album_artist": cls.__convert_invalid_characters(meta.album_artist or ""),
|
||||
"year": meta.year,
|
||||
"disc_number": meta.disc_number,
|
||||
"track_number": meta.track_number,
|
||||
@@ -367,12 +367,12 @@ class TemplateContextBuilder:
|
||||
})
|
||||
return
|
||||
|
||||
episode_data = {"episode_title": None, "episode_date": None}
|
||||
episode_data: Dict[str, Optional[str]] = {"episode_title": None, "episode_date": None}
|
||||
if meta.begin_episode and episodes:
|
||||
for episode in episodes:
|
||||
if episode.episode_number == meta.begin_episode:
|
||||
episode_data.update({
|
||||
"episode_title": cls.__convert_invalid_characters(episode.name),
|
||||
"episode_title": cls.__convert_invalid_characters(episode.name or ""),
|
||||
"episode_date": episode.air_date if episode.air_date else None
|
||||
})
|
||||
break
|
||||
@@ -442,11 +442,12 @@ class TemplateContextBuilder:
|
||||
"""
|
||||
if not torrentinfo:
|
||||
return
|
||||
size: Union[str, int] = 0
|
||||
if torrentinfo.size:
|
||||
if str(torrentinfo.size).replace(".", "").isdigit():
|
||||
size = size_tools.format_compact_size(torrentinfo.size)
|
||||
else:
|
||||
size = torrentinfo.size
|
||||
size = str(torrentinfo.size)
|
||||
else:
|
||||
size = 0
|
||||
|
||||
@@ -489,7 +490,7 @@ class TemplateContextBuilder:
|
||||
ctx = {
|
||||
"transfer_type": transferinfo.transfer_type,
|
||||
"file_count": transferinfo.file_count,
|
||||
"total_size": size_tools.format_compact_size(transferinfo.total_size),
|
||||
"total_size": size_tools.format_compact_size(transferinfo.total_size or 0),
|
||||
"err_msg": transferinfo.message,
|
||||
}
|
||||
context.update(ctx)
|
||||
@@ -536,7 +537,7 @@ class TemplateContextBuilder:
|
||||
context.update(raw_objects)
|
||||
|
||||
@staticmethod
|
||||
def __convert_invalid_characters(filename: str):
|
||||
def __convert_invalid_characters(filename: str) -> str:
|
||||
"""
|
||||
将不支持的字符转换为全角字符
|
||||
"""
|
||||
@@ -554,7 +555,7 @@ class TemplateContextBuilder:
|
||||
|
||||
@staticmethod
|
||||
def __strip_album_trailing_year(
|
||||
album: Optional[str], year: Optional[int]
|
||||
album: Optional[str], year: Optional[Union[int, str]]
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
去除专辑名尾部的括号年份标记(如 ``欲望反光 (2018)`` -> ``欲望反光``)。
|
||||
@@ -573,13 +574,13 @@ class TemplateHelper(metaclass=SingletonClass):
|
||||
模板格式渲染帮助类
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self) -> None:
|
||||
"""初始化模板上下文构建器和短期渲染缓存。"""
|
||||
self.builder = TemplateContextBuilder()
|
||||
self.cache = TTLCache(region="notification", maxsize=100, ttl=600)
|
||||
|
||||
@staticmethod
|
||||
def _generate_cache_key(cuntent: Union[str, dict]) -> str:
|
||||
def _generate_cache_key(cuntent: Union[str, Dict[str, Any]]) -> str:
|
||||
"""
|
||||
生成缓存键
|
||||
"""
|
||||
@@ -589,14 +590,14 @@ class TemplateHelper(metaclass=SingletonClass):
|
||||
|
||||
return HashUtils.md5(cuntent)
|
||||
|
||||
def get_cache_context(self, cuntent: Union[str, dict]) -> Optional[dict]:
|
||||
def get_cache_context(self, cuntent: Union[str, Dict[str, Any]]) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
获取缓存上下文
|
||||
"""
|
||||
cache_key = self._generate_cache_key(cuntent)
|
||||
return self.cache.get(cache_key)
|
||||
return cast(Optional[Dict[str, Any]], self.cache.get(cache_key))
|
||||
|
||||
def set_cache_context(self, cuntent: Union[str, dict], context: dict) -> None:
|
||||
def set_cache_context(self, cuntent: Union[str, Dict[str, Any]], context: Dict[str, Any]) -> None:
|
||||
"""
|
||||
设置缓存上下文
|
||||
"""
|
||||
@@ -606,7 +607,7 @@ class TemplateHelper(metaclass=SingletonClass):
|
||||
def render(self,
|
||||
template_content: str,
|
||||
template_type: Literal['string', 'dict', 'literal'] = "literal",
|
||||
**kwargs) -> Optional[Union[str, dict]]:
|
||||
**kwargs: Any) -> Optional[Union[str, Dict[str, Any]]]:
|
||||
"""
|
||||
根据模板格式渲染内容
|
||||
:param template_content: 模板字符串
|
||||
@@ -655,7 +656,7 @@ class TemplateHelper(metaclass=SingletonClass):
|
||||
raise ValueError(f"模板处理失败: {str(e)}") from e
|
||||
|
||||
@staticmethod
|
||||
def render_with_context(template_content: str, context: dict) -> str:
|
||||
def render_with_context(template_content: str, context: Dict[str, Any]) -> str:
|
||||
"""
|
||||
使用指定上下文渲染 Jinja2 模板字符串
|
||||
template_content: Jinja2 模板字符串
|
||||
@@ -663,18 +664,18 @@ class TemplateHelper(metaclass=SingletonClass):
|
||||
"""
|
||||
# 渲染模板
|
||||
template = Template(template_content)
|
||||
return template.render(context)
|
||||
return cast(str, template.render(context))
|
||||
|
||||
@staticmethod
|
||||
def parse_template_content(template_content: Union[str, dict],
|
||||
template_type: Literal['string', 'dict', 'literal'] = None) -> Optional[Union[str, dict]]:
|
||||
def parse_template_content(template_content: Union[str, Dict[str, Any]],
|
||||
template_type: Optional[Literal['string', 'dict', 'literal']] = None) -> Optional[Union[str, Dict[str, Any]]]:
|
||||
"""
|
||||
解析模板字符
|
||||
:param template_content 模板格式字符
|
||||
:param template_type 模板字符类型
|
||||
"""
|
||||
|
||||
def parse_literal(_template_content: str) -> Union[dict, str]:
|
||||
def parse_literal(_template_content: str) -> Union[Dict[str, Any], str]:
|
||||
"""
|
||||
解析Python字面量
|
||||
"""
|
||||
@@ -694,7 +695,7 @@ class TemplateHelper(metaclass=SingletonClass):
|
||||
'dict': lambda x: x,
|
||||
'literal': parse_literal
|
||||
}
|
||||
return parse_map[template_type](template_content)
|
||||
return cast(Optional[Union[str, Dict[str, Any]]], parse_map[template_type](template_content))
|
||||
|
||||
# 自动判断模板类型
|
||||
if isinstance(template_content, dict):
|
||||
@@ -716,7 +717,7 @@ class TemplateHelper(metaclass=SingletonClass):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def __process_formatted_string(rendered: str) -> Optional[Union[dict, str]]:
|
||||
def __process_formatted_string(rendered: str) -> Optional[Union[Dict[str, Any], str]]:
|
||||
"""
|
||||
处理格式化字符串
|
||||
保留转义字符
|
||||
@@ -751,11 +752,11 @@ class TemplateHelper(metaclass=SingletonClass):
|
||||
# 尝试解析为JSON
|
||||
try:
|
||||
rendered_dict = json.loads(processed)
|
||||
return restore_chars(rendered_dict)
|
||||
return cast(Optional[Union[Dict[str, Any], str]], restore_chars(rendered_dict))
|
||||
except json.JSONDecodeError:
|
||||
return rendered
|
||||
|
||||
def close(self):
|
||||
def close(self) -> None:
|
||||
"""
|
||||
清理资源
|
||||
"""
|
||||
@@ -769,7 +770,7 @@ class MessageTemplateHelper:
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def render(message: Message, *args, **kwargs) -> Optional[Message]:
|
||||
def render(message: Message, *args: Any, **kwargs: Any) -> Optional[Message]:
|
||||
"""
|
||||
渲染消息模板
|
||||
"""
|
||||
@@ -789,7 +790,7 @@ class MessageTemplateHelper:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def meets_update_conditions(message: Message, *args, **kwargs) -> bool:
|
||||
def meets_update_conditions(message: Message, *args: Any, **kwargs: Any) -> bool:
|
||||
"""
|
||||
判断是否满足消息实例更新条件
|
||||
|
||||
@@ -803,19 +804,17 @@ class MessageTemplateHelper:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _apply_template_data(message: Message, *args, **kwargs) -> Optional[Message]:
|
||||
def _apply_template_data(message: Message, *args: Any, **kwargs: Any) -> Optional[Message]:
|
||||
"""
|
||||
更新消息实例
|
||||
"""
|
||||
try:
|
||||
if template := MessageTemplateHelper._get_template(message):
|
||||
try:
|
||||
rendered = TemplateHelper().render(
|
||||
template_content=template, *args, **kwargs
|
||||
)
|
||||
rendered = TemplateHelper().render(template, *args, **kwargs)
|
||||
except ValueError as err:
|
||||
logger.warning(
|
||||
f"通知模板 {message.ctype.value} 渲染失败,消息保持原样:{str(err)}"
|
||||
f"通知模板 {message.ctype.value if message.ctype else 'unknown'} 渲染失败,消息保持原样:{str(err)}"
|
||||
)
|
||||
return message
|
||||
if not isinstance(rendered, dict):
|
||||
@@ -836,7 +835,7 @@ class MessageTemplateHelper:
|
||||
try:
|
||||
template_dict = get_configured_system_config().get(SystemConfigKey.NotificationTemplates) or {}
|
||||
if isinstance(template_dict, dict):
|
||||
configured = template_dict.get(message.ctype.value)
|
||||
configured = template_dict.get(message.ctype.value) if message.ctype else None
|
||||
if str(configured or "").strip() not in {"", "{}", "{ }"}:
|
||||
return configured
|
||||
except Exception as err:
|
||||
@@ -876,7 +875,7 @@ class MessageQueueManager(metaclass=SingletonClass):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
send_callback: Optional[Callable] = None,
|
||||
send_callback: Optional[Callable[..., Any]] = None,
|
||||
check_interval: Optional[int] = 10,
|
||||
auto_start: bool = True,
|
||||
) -> None:
|
||||
@@ -934,12 +933,12 @@ class MessageQueueManager(metaclass=SingletonClass):
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _parse_schedule(periods: Union[list, dict]) -> List[tuple[int, int, int, int]]:
|
||||
def _parse_schedule(periods: Union[List[Dict[str, Any]], Dict[str, Any], None]) -> List[tuple[int, int, int, int]]:
|
||||
"""
|
||||
将字符串时间格式转换为分钟数元组
|
||||
支持格式为 'HH:MM' 或 'HH:MM:SS' 的时间字符串
|
||||
"""
|
||||
parsed = []
|
||||
parsed: List[tuple[int, int, int, int]] = []
|
||||
if not periods:
|
||||
return parsed
|
||||
if not isinstance(periods, list):
|
||||
@@ -1004,7 +1003,7 @@ class MessageQueueManager(metaclass=SingletonClass):
|
||||
return True
|
||||
return False
|
||||
|
||||
def send_message(self, *args, **kwargs) -> None:
|
||||
def send_message(self, *args: Any, **kwargs: Any) -> None:
|
||||
"""
|
||||
发送消息(立即发送或加入队列)
|
||||
"""
|
||||
@@ -1019,7 +1018,7 @@ class MessageQueueManager(metaclass=SingletonClass):
|
||||
"""使用显式调用方回调立即发送或排队,避免共享队列绑定首个 Chain。"""
|
||||
self._dispatch_message(send_callback, True, *args, **kwargs)
|
||||
|
||||
async def async_send_message(self, *args, **kwargs) -> None:
|
||||
async def async_send_message(self, *args: Any, **kwargs: Any) -> None:
|
||||
"""
|
||||
异步发送消息:``immediately=True`` 立即发送,否则按调度时段入队。
|
||||
|
||||
@@ -1129,7 +1128,7 @@ class MessageQueueManager(metaclass=SingletonClass):
|
||||
self.queue.put(message)
|
||||
logger.info(f"消息已加入队列,当前队列长度:{self.queue.qsize()}")
|
||||
|
||||
def _send(self, *args, **kwargs) -> None:
|
||||
def _send(self, *args: Any, **kwargs: Any) -> None:
|
||||
"""
|
||||
实际发送消息(可通过回调函数自定义)
|
||||
"""
|
||||
@@ -1229,7 +1228,7 @@ class MessageHelper(metaclass=Singleton):
|
||||
|
||||
@staticmethod
|
||||
def _build_system_notification_key(
|
||||
message: Any, role: str, title: str = None, note: Union[list, dict] = None
|
||||
message: Any, role: str, title: Optional[str] = None, note: Optional[Union[List[Any], Dict[str, Any]]] = None
|
||||
) -> str:
|
||||
"""
|
||||
构建系统通知短期去重键。
|
||||
@@ -1247,7 +1246,7 @@ class MessageHelper(metaclass=Singleton):
|
||||
)
|
||||
|
||||
def _is_recent_system_notification(
|
||||
self, message: Any, role: str, title: str = None, note: Union[list, dict] = None
|
||||
self, message: Any, role: str, title: Optional[str] = None, note: Optional[Union[List[Any], Dict[str, Any]]] = None
|
||||
) -> bool:
|
||||
"""
|
||||
判断系统通知是否在短时间内重复。
|
||||
@@ -1262,11 +1261,11 @@ class MessageHelper(metaclass=Singleton):
|
||||
self,
|
||||
message: Any,
|
||||
role: str = "plugin",
|
||||
title: str = None,
|
||||
note: Union[list, dict] = None,
|
||||
title: Optional[str] = None,
|
||||
note: Optional[Union[List[Any], Dict[str, Any]]] = None,
|
||||
mtype: Optional[MessageType] = None,
|
||||
level: Optional[NotificationLevel] = None,
|
||||
):
|
||||
) -> None:
|
||||
"""
|
||||
存消息
|
||||
:param message: 消息
|
||||
|
||||
@@ -108,7 +108,7 @@ ARCH-201 至 ARCH-204 均达到实现、验证、提交、推送和远端门禁
|
||||
| Event Contract | 53 | 均已有 payload model,但当前全部是 diagnostic enforcement |
|
||||
| Python 源码量 | 373,625 行 | 本次重新扫描物理行数,排除 `app/plugins/**`;74 个文件超过 1,000 行,12 个超过 2,000 行;源码尺寸仅作观察 |
|
||||
| 长方法 | 309 个超过 80 行 | 本次 AST 扫描排除 `app/plugins/**`;61 个超过 150 行,17 个超过 250 行;新增函数仍受 C901/嵌套深度门禁约束 |
|
||||
| 全量 mypy 历史债务 | 4,625 / 255 文件 | 本轮在消息、站点、诊断、备份、用户配置、订阅、AcoustID、TMDB、仪表板和命令生命周期边界补齐类型,历史债务再减少 53 项;TMDB v3 API 显式导出并保留集合 parts 的列表合同,逐文件逐错误码无增长;此前工作流筛选、动态插件路由和 stdio 流补齐边界类型,历史债务减少 3 项;Bitpt 与 CookieCloud 补齐边界类型,历史债务减少 16 项;知行站点解析器补齐数值属性与基类合同,历史债务减少 18 项;通知排版补齐 Slack 消息块类型,历史债务减少 2 项;工作流资源过滤改用领域对象调用过滤链,恢复的节点输出在消费前归一化,并收紧可空资源列表的类型低水位;消息媒体交互类型债务已清零,canonical Facade 与 endpoint 类型边界已补齐,低水位只允许继续下降;微信 ClawBot 入站 item_list 媒体解析改为按子项键名分派后,类型错误减少 4 项;站点解析器分享率改用浮点初值,类型错误减少 20 项;本次下载与文件安全修复再减少 3 项;Transmission 进度回退值归一化再减少 2 项;本批清理 Servarr、认证、存储、订阅策略和搜索/规则/通知 Schema 的 18 项类型错误,并修复系统配置中的 Python 2 异常语法;本批再清理订阅元数据、订阅写入、交互宿主、整理路径、删除统计和工作流动作的 14 项类型错误,逐文件逐错误码无增长;本批补齐 OCR 请求参数、工具 Schema 摘要和宿主模块配置快照的 5 项边界类型,逐文件逐错误码无增长;本批为 Rousi 用户消息分页解析补齐返回类型与数据结构兜底,减少 2 项类型错误;本批优先处理 TMDB v3 电影与电视剧对象模型,补齐 98 个同步/异步方法注解并减少 122 项历史类型错误;随后补齐剧集、季度、人物、搜索和趋势对象的 142 个方法注解,再减少 142 项类型错误;绿联 API 响应边界补齐具体泛型与运行时字典收窄,减少 31 项类型错误;运行时限流器补齐状态方法、装饰器边界和时间队列类型,减少 31 项类型错误;QQ Bot API 响应边界补齐具体泛型与 JSON 形状校验,减少 17 项类型错误;rTorrent 客户端清理 182 项错误,调用端同步明确字典合同,累计再减少 190 项错误;豆瓣 API、中心服务接口及订阅消费端补齐返回边界和参数收窄,结合 Context 方法签名与缓存代理类型清理,累计再减少 455 项错误;共享 HTTP 客户端清理 110 项错误,TMDB API 清理 84 项错误,索引器爬虫清理 87 项错误,并补充 U115、AliPan、OpenList 对可空流响应的防守;U115 其余存储基类契约债务暂留待测试完备后处理;缓存同步/异步继承冲突保留为设计债务,未纳入严格门禁 |
|
||||
| 全量 mypy 历史债务 | 4,448 / 252 文件 | 本轮在消息、站点、诊断、备份、用户配置、订阅、AcoustID、TMDB、仪表板和命令生命周期边界补齐类型,历史债务再减少 53 项;TMDB v3 API 显式导出并保留集合 parts 的列表合同,逐文件逐错误码无增长;此前工作流筛选、动态插件路由和 stdio 流补齐边界类型,历史债务减少 3 项;Bitpt 与 CookieCloud 补齐边界类型,历史债务减少 16 项;知行站点解析器补齐数值属性与基类合同,历史债务减少 18 项;通知排版补齐 Slack 消息块类型,历史债务减少 2 项;工作流资源过滤改用领域对象调用过滤链,恢复的节点输出在消费前归一化,并收紧可空资源列表的类型低水位;消息媒体交互类型债务已清零,canonical Facade 与 endpoint 类型边界已补齐,低水位只允许继续下降;微信 ClawBot 入站 item_list 媒体解析改为按子项键名分派后,类型错误减少 4 项;站点解析器分享率改用浮点初值,类型错误减少 20 项;本次下载与文件安全修复再减少 3 项;Transmission 进度回退值归一化再减少 2 项;本批清理 Servarr、认证、存储、订阅策略和搜索/规则/通知 Schema 的 18 项类型错误,并修复系统配置中的 Python 2 异常语法;本批再清理订阅元数据、订阅写入、交互宿主、整理路径、删除统计和工作流动作的 14 项类型错误,逐文件逐错误码无增长;本批补齐 OCR 请求参数、工具 Schema 摘要和宿主模块配置快照的 5 项边界类型,逐文件逐错误码无增长;本批为 Rousi 用户消息分页解析补齐返回类型与数据结构兜底,减少 2 项类型错误;本批优先处理 TMDB v3 电影与电视剧对象模型,补齐 98 个同步/异步方法注解并减少 122 项历史类型错误;随后补齐剧集、季度、人物、搜索和趋势对象的 142 个方法注解,再减少 142 项类型错误;绿联 API 响应边界补齐具体泛型与运行时字典收窄,减少 31 项类型错误;运行时限流器补齐状态方法、装饰器边界和时间队列类型,减少 31 项类型错误;QQ Bot API 响应边界补齐具体泛型与 JSON 形状校验,减少 17 项类型错误;rTorrent 客户端清理 182 项错误,调用端同步明确字典合同,累计再减少 190 项错误;豆瓣 API、中心服务接口及订阅消费端补齐返回边界和参数收窄,结合 Context 方法签名与缓存代理类型清理,累计再减少 455 项错误;共享 HTTP 客户端清理 110 项错误,TMDB API 清理 84 项错误,索引器爬虫清理 87 项错误,并补充 U115、AliPan、OpenList 对可空流响应的防守;U115 其余存储基类契约债务暂留待测试完备后处理;缓存同步/异步继承冲突保留为设计债务,未纳入严格门禁;本批并行清理消息模板与队列、TMDB 模块和飞牛媒体客户端,累计减少 177 项类型错误,新增严格门禁文件 3 个 |
|
||||
| Ruff 历史诊断 | 73 | 低水位门禁通过,但规则集只覆盖 `E4/E7/E9/F/I` |
|
||||
| 覆盖率逐文件低水位 | 全 app(排除 app/plugins)当前聚合 77.68% | 存量文件低水位只增不减,新文件至少 80% |
|
||||
|
||||
|
||||
3
mypy.ini
3
mypy.ini
@@ -25,6 +25,7 @@ files =
|
||||
app/modules/_base/downloader.py,
|
||||
app/monitor/dispatcher.py,
|
||||
app/application/messaging/skill.py,
|
||||
app/application/messaging/message.py,
|
||||
app/workflow/actions/add_subscribe.py,
|
||||
app/workflow/actions/scan_file.py,
|
||||
app/workflow/actions/transfer_file.py,
|
||||
@@ -44,6 +45,8 @@ files =
|
||||
app/modules/dingtalk/__init__.py,
|
||||
app/modules/synologychat/synologychat.py,
|
||||
app/modules/__init__.py,
|
||||
app/modules/trimemedia/trimemedia.py,
|
||||
app/modules/themoviedb/__init__.py,
|
||||
app/runtime/debounce.py,
|
||||
app/modules/vocechat/vocechat.py,
|
||||
app/chain/system.py,
|
||||
|
||||
45
tests/fixtures/architecture/mypy-baseline.json
vendored
45
tests/fixtures/architecture/mypy-baseline.json
vendored
@@ -419,18 +419,6 @@
|
||||
"no-untyped-def": 1,
|
||||
"type-arg": 2
|
||||
},
|
||||
"app/application/messaging/message.py": {
|
||||
"arg-type": 5,
|
||||
"assignment": 9,
|
||||
"dict-item": 1,
|
||||
"misc": 1,
|
||||
"no-any-return": 4,
|
||||
"no-untyped-call": 2,
|
||||
"no-untyped-def": 12,
|
||||
"type-arg": 18,
|
||||
"union-attr": 2,
|
||||
"var-annotated": 1
|
||||
},
|
||||
"app/application/messaging/plugin.py": {
|
||||
"arg-type": 5,
|
||||
"no-untyped-call": 1,
|
||||
@@ -977,7 +965,6 @@
|
||||
"assignment": 2,
|
||||
"attr-defined": 1,
|
||||
"no-redef": 1,
|
||||
"no-untyped-call": 1,
|
||||
"no-untyped-def": 3,
|
||||
"operator": 6,
|
||||
"type-arg": 2,
|
||||
@@ -1222,22 +1209,10 @@
|
||||
"misc": 2,
|
||||
"no-untyped-def": 2
|
||||
},
|
||||
"app/modules/themoviedb/__init__.py": {
|
||||
"arg-type": 5,
|
||||
"assignment": 11,
|
||||
"empty-body": 1,
|
||||
"index": 2,
|
||||
"no-any-return": 2,
|
||||
"no-untyped-call": 3,
|
||||
"no-untyped-def": 3,
|
||||
"return-value": 2,
|
||||
"type-arg": 19,
|
||||
"union-attr": 2
|
||||
},
|
||||
"app/modules/themoviedb/cache.py": {
|
||||
"no-any-return": 3,
|
||||
"no-untyped-def": 4,
|
||||
"type-arg": 5,
|
||||
"no-untyped-def": 2,
|
||||
"type-arg": 4,
|
||||
"union-attr": 5
|
||||
},
|
||||
"app/modules/themoviedb/scraper.py": {
|
||||
@@ -1261,29 +1236,17 @@
|
||||
},
|
||||
"app/modules/trimemedia/api.py": {
|
||||
"misc": 2,
|
||||
"no-untyped-def": 11,
|
||||
"no-untyped-def": 9,
|
||||
"type-arg": 6
|
||||
},
|
||||
"app/modules/trimemedia/module.py": {
|
||||
"assignment": 1,
|
||||
"empty-body": 1,
|
||||
"no-any-return": 3,
|
||||
"no-untyped-call": 1,
|
||||
"no-any-return": 1,
|
||||
"no-untyped-def": 7,
|
||||
"return": 1,
|
||||
"type-arg": 2
|
||||
},
|
||||
"app/modules/trimemedia/trimemedia.py": {
|
||||
"arg-type": 5,
|
||||
"no-any-return": 1,
|
||||
"no-untyped-call": 8,
|
||||
"no-untyped-def": 9,
|
||||
"operator": 1,
|
||||
"return": 1,
|
||||
"type-arg": 2,
|
||||
"union-attr": 32,
|
||||
"var-annotated": 4
|
||||
},
|
||||
"app/modules/ugreen/module.py": {
|
||||
"arg-type": 3,
|
||||
"assignment": 1,
|
||||
|
||||
Reference in New Issue
Block a user