-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor CacheManager to use generic type T #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,7 @@ | |
| from collections.abc import Hashable | ||
| from dataclasses import dataclass, field | ||
| from functools import lru_cache | ||
| from typing import Any, Generic, TypeVar | ||
| from typing import Generic, TypeVar | ||
|
|
||
| from typing_extensions import Self | ||
|
|
||
|
|
@@ -33,7 +33,7 @@ | |
| max_size: int = 1000 | ||
|
|
||
| # LRU实现 | ||
| _cache: OrderedDict[str, BaseData] = field(default_factory=lambda: OrderedDict()) | ||
| _cache: OrderedDict[str, T] = field(default_factory=lambda: OrderedDict()) | ||
|
|
||
| def __post_init__(self): | ||
| if self.max_size <= 0: | ||
|
|
@@ -48,7 +48,7 @@ | |
| return True | ||
|
|
||
| # 添加新数据 | ||
| self._cache[data_id] = data | ||
|
Check failure on line 51 in nonebot_plugin_value/_cache.py
|
||
| self._cache.move_to_end(data_id) | ||
|
|
||
| # 如果超出最大大小,删除最久未使用的项(第一个) | ||
|
|
@@ -84,9 +84,9 @@ | |
| return Lock() | ||
|
|
||
|
|
||
| class CacheManager: | ||
| class CacheManager(Generic[T]): | ||
| _instance = None | ||
| _cached: dict[CacheCategoryEnum, Cache[Any]] | ||
| _cached: dict[CacheCategoryEnum, Cache[T]] | ||
|
|
||
| def __new__(cls) -> Self: | ||
| if cls._instance is None: | ||
|
|
@@ -96,7 +96,7 @@ | |
|
|
||
| async def get_cache( | ||
| self, category: CacheCategoryEnum, max_size: int = 1000 | ||
| ) -> Cache[Any]: | ||
| ) -> Cache[T]: | ||
|
Comment on lines
97
to
+99
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: 在这里使用 建议实现: class CacheManager:
_instance = None
_cached: dict[CacheCategoryEnum, Cache[Any]] async def get_cache(
self, category: CacheCategoryEnum, max_size: int = 1000
) -> Cache[Any]:
Original comment in Englishsuggestion: The generic return type of Using Suggested implementation: class CacheManager:
_instance = None
_cached: dict[CacheCategoryEnum, Cache[Any]] async def get_cache(
self, category: CacheCategoryEnum, max_size: int = 1000
) -> Cache[Any]:
|
||
| # 为不同类别创建具有不同大小的缓存 | ||
| if category not in self._cached: | ||
| self._cached[category] = Cache(max_size=max_size) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): 在单例管理器上使用
Generic[T],在用不同类型参数实例化时会导致令人困惑或不健全的类型行为。由于
_instance是共享的,CacheManager[int]()和CacheManager[str]()实际上引用的是同一个对象,但在类型检查器看来却是不同的泛型类型。这会使_cached和get_cache变得类型不安全。如果你只需要一个全局管理器,请从CacheManager中移除Generic[T],只让Cache保持泛型。如果你确实需要按T区分的管理器,请让_instance与类型相关(例如针对每个T拥有一个单独的单例实例)。Original comment in English
issue (bug_risk): Using
Generic[T]on a singleton manager can lead to confusing or unsound typing when instantiated with different type parameters.Since
_instanceis shared,CacheManager[int]()andCacheManager[str]()refer to the same object but appear as different generic types to the type checker. This can make_cachedandget_cachetype-unsafe. If you only need one global manager, dropGeneric[T]fromCacheManagerand keep onlyCachegeneric. If you truly need per-Tmanagers, make_instancetype-specific (e.g., one singleton instance perT).