feat: python3.12のジェネリックスの書き方に

pull/125/head
yupix 9 months ago
parent e09a405169
commit 0ed9a99e6e
No known key found for this signature in database
GPG Key ID: 2FF705F5C56D9C06

@ -299,10 +299,7 @@ class ClientChannelActions(AbstractAction):
} }
) )
raw_channel: IChannel = await self._session.request( raw_channel: IChannel = await self._session.request(
Route("POST", "/api/channels/update"), Route("POST", "/api/channels/update"), json=data, auth=True, remove_none=False
json=data,
auth=True,
remove_none=False
) )
return Channel(raw_channel=raw_channel, client=self._client) return Channel(raw_channel=raw_channel, client=self._client)

@ -341,7 +341,7 @@ class FileActions(ClientFileActions):
) )
return [File(raw_file, client=self._client) for raw_file in raw_files] return [File(raw_file, client=self._client) for raw_file in raw_files]
async def find(self, name: str, folder_id:str|None=None) -> list[File]: async def find(self, name: str, folder_id: str | None = None) -> list[File]:
"""Find a file by its name """Find a file by its name
Endpoint: `/api/drive/files/find` Endpoint: `/api/drive/files/find`

@ -297,7 +297,7 @@ class FolderActions(ClientFolderActions):
limit: int = 10, limit: int = 10,
since_id: str | None = None, since_id: str | None = None,
until_id: str | None = None, until_id: str | None = None,
folder_id: str|None=None, folder_id: str | None = None,
) -> list[Folder]: ) -> list[Folder]:
"""Get folders """Get folders
@ -411,7 +411,7 @@ class FolderActions(ClientFolderActions):
return Folder(raw_folder=raw_folder, client=self._client) return Folder(raw_folder=raw_folder, client=self._client)
async def update( async def update(
self, folder_id: str |None=None, name: str | None = None, parent_id: str | None = None self, folder_id: str | None = None, name: str | None = None, parent_id: str | None = None
) -> Folder: ) -> Folder:
"""Update a folder """Update a folder

@ -60,7 +60,7 @@ class PollActions(ClientPollActions):
Route("POST", "/api/notes/polls/recommendation"), Route("POST", "/api/notes/polls/recommendation"),
json=data, json=data,
pagination_type="count", pagination_type="count",
auth=True auth=True,
) )
while True: while True:

@ -25,7 +25,7 @@ class ReactionActions(AbstractAction):
"""Add reaction to note """Add reaction to note
Endpoint: `/api/notes/reactions/create` Endpoint: `/api/notes/reactions/create`
Parameters Parameters
---------- ----------
reaction : str reaction : str
@ -48,14 +48,14 @@ class ReactionActions(AbstractAction):
async def remove(self, note_id: str | None = None) -> bool: async def remove(self, note_id: str | None = None) -> bool:
"""Remove reaction from note """Remove reaction from note
Endpoint: `/api/notes/reactions/delete` Endpoint: `/api/notes/reactions/delete`
Parameters Parameters
---------- ----------
note_id : str, optional note_id : str, optional
note id, by default None note id, by default None
Returns Returns
------- -------
bool bool

@ -19,6 +19,6 @@ class UsernameActions(AbstractAction):
async def available(self, username: str) -> UsernameAvailable: async def available(self, username: str) -> UsernameAvailable:
data = {"username": username} data = {"username": username}
res: IUsernameAvailable = await self.__session.request( res: IUsernameAvailable = await self.__session.request(
Route('POST', "/api/username/available"), json=data, auth=True Route("POST", "/api/username/available"), json=data, auth=True
) )
return UsernameAvailable(res) return UsernameAvailable(res)

@ -28,4 +28,6 @@ class DriveManager(AbstractManager):
return ClientFileManager(file_id=file_id, session=self.__session, client=self.__client) return ClientFileManager(file_id=file_id, session=self.__session, client=self.__client)
def _create_client_folder_manager(self, *, folder_id: str) -> ClientFolderManager: def _create_client_folder_manager(self, *, folder_id: str) -> ClientFolderManager:
return ClientFolderManager(folder_id=folder_id, session=self.__session, client=self.__client) return ClientFolderManager(
folder_id=folder_id, session=self.__session, client=self.__client
)

@ -15,7 +15,6 @@ if TYPE_CHECKING:
class ClientFolderManager(AbstractManager): class ClientFolderManager(AbstractManager):
def __init__(self, folder_id: str, *, session: HTTPClient, client: ClientManager): def __init__(self, folder_id: str, *, session: HTTPClient, client: ClientManager):
self.__folder_id: str = folder_id self.__folder_id: str = folder_id
self.__session: HTTPClient = session self.__session: HTTPClient = session

@ -9,19 +9,21 @@ if TYPE_CHECKING:
from mipac.http import HTTPClient from mipac.http import HTTPClient
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
class ClientPollManager(AbstractManager): class ClientPollManager(AbstractManager):
def __init__(self, note_id: str|None=None, *, session: HTTPClient, client: ClientManager): def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):
self.__note_id: str | None = note_id self.__note_id: str | None = note_id
self.__session: HTTPClient = session self.__session: HTTPClient = session
self.__client: ClientManager = client self.__client: ClientManager = client
@property @property
def action(self) -> ClientPollActions: def action(self) -> ClientPollActions:
return ClientPollActions( return ClientPollActions(
note_id=self.__note_id, note_id=self.__note_id,
session=self.__session, session=self.__session,
client=self.__client, client=self.__client,
) )
class PollManager(AbstractManager): class PollManager(AbstractManager):
def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager): def __init__(self, note_id: str | None = None, *, session: HTTPClient, client: ClientManager):

@ -14,7 +14,7 @@ class UsernameManager(AbstractManager):
def __init__(self, *, session: HTTPClient, client: ClientManager): def __init__(self, *, session: HTTPClient, client: ClientManager):
self.__session: HTTPClient = session self.__session: HTTPClient = session
self.__client: ClientManager = client self.__client: ClientManager = client
@property @property
def action(self) -> UsernameActions: def action(self) -> UsernameActions:
return UsernameActions(session=self.__session, client=self.__client) return UsernameActions(session=self.__session, client=self.__client)

@ -61,7 +61,6 @@ class Clip(AbstractModel):
"""The number of times the clip has been favorited""" """The number of times the clip has been favorited"""
return self.__clip["favorited_count"] return self.__clip["favorited_count"]
@property @property
def is_favorited(self) -> bool: def is_favorited(self) -> bool:
"""Whether the clip is favorited""" """Whether the clip is favorited"""

@ -73,11 +73,12 @@ class InviteCode:
def api(self) -> ClientInviteManager: def api(self) -> ClientInviteManager:
return self.__client._create_client_invite_manager(invite_id=self.id) return self.__client._create_client_invite_manager(invite_id=self.id)
class InviteLimit: class InviteLimit:
def __init__(self, raw_invite_limit: IInviteLimit, *, client:ClientManager) -> None: def __init__(self, raw_invite_limit: IInviteLimit, *, client: ClientManager) -> None:
self.__raw_invite_limit: IInviteLimit = raw_invite_limit self.__raw_invite_limit: IInviteLimit = raw_invite_limit
self.__client = client self.__client = client
@property @property
def remaining(self) -> int | None: def remaining(self) -> int | None:
return self.__raw_invite_limit["remaining"] return self.__raw_invite_limit["remaining"]

@ -1,8 +1,7 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, Generic, TypeVar from typing import TYPE_CHECKING, TypeVar
from mipac.abstract.model import AbstractModel
from mipac.types.ads import IAdPlaces, IPartialAd from mipac.types.ads import IAdPlaces, IPartialAd
if TYPE_CHECKING: if TYPE_CHECKING:
@ -12,7 +11,7 @@ if TYPE_CHECKING:
T = TypeVar("T", bound=IPartialAd) T = TypeVar("T", bound=IPartialAd)
class PartialAd(AbstractModel, Generic[T]): class PartialAd[T: IPartialAd]:
def __init__(self, raw_ad: T, *, client: ClientManager) -> None: def __init__(self, raw_ad: T, *, client: ClientManager) -> None:
self._raw_ad: T = raw_ad self._raw_ad: T = raw_ad

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, Generic, TypeVar from typing import TYPE_CHECKING
from mipac.abstract.model import AbstractModel from mipac.abstract.model import AbstractModel
from mipac.models.lite.ad import PartialAd from mipac.models.lite.ad import PartialAd
@ -9,8 +9,6 @@ from mipac.types.meta import IPartialMeta, IPolicies
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
T = TypeVar("T", bound=IPartialMeta)
class Policies(AbstractModel): class Policies(AbstractModel):
def __init__(self, raw_policies: IPolicies) -> None: def __init__(self, raw_policies: IPolicies) -> None:
@ -118,7 +116,7 @@ class Policies(AbstractModel):
return self.__raw_policies["rate_limit_factor"] return self.__raw_policies["rate_limit_factor"]
class PartialMeta(AbstractModel, Generic[T]): class PartialMeta[T: IPartialMeta]:
def __init__(self, raw_meta: T, *, client: ClientManager) -> None: def __init__(self, raw_meta: T, *, client: ClientManager) -> None:
self._raw_meta: T = raw_meta self._raw_meta: T = raw_meta
self.__client: ClientManager = client self.__client: ClientManager = client

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, Generic, TypeVar from typing import TYPE_CHECKING
from mipac.types.roles import IPartialRole from mipac.types.roles import IPartialRole
@ -8,10 +8,8 @@ if TYPE_CHECKING:
from mipac.manager.admins.roles import AdminRolesModelManager from mipac.manager.admins.roles import AdminRolesModelManager
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
T = TypeVar("T", bound=IPartialRole)
class PartialRole[T: IPartialRole]:
class PartialRole(Generic[T]):
def __init__(self, role_data: T, *, client: ClientManager) -> None: def __init__(self, role_data: T, *, client: ClientManager) -> None:
self._raw_role: T = role_data self._raw_role: T = role_data
self.__client = client self.__client = client

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, Generic, TypeVar from typing import TYPE_CHECKING
from mipac.models.lite.instance import LiteInstance from mipac.models.lite.instance import LiteInstance
from mipac.types.user import IAvatarDecoration, IBadgeRole, IPartialUser, IUserOnlineStatus from mipac.types.user import IAvatarDecoration, IBadgeRole, IPartialUser, IUserOnlineStatus
@ -10,11 +10,8 @@ if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
from mipac.manager.user import ClientUserManager from mipac.manager.user import ClientUserManager
T = TypeVar("T", bound=IBadgeRole)
PU = TypeVar("PU", bound=IPartialUser)
class BadgeRole[T: IBadgeRole]:
class BadgeRole(Generic[T]):
def __init__(self, data: T, *, client: ClientManager) -> None: def __init__(self, data: T, *, client: ClientManager) -> None:
self._data: T = data self._data: T = data
self._client = client self._client = client
@ -103,7 +100,7 @@ class AvatarDecoration:
return self.__raw_avatar_decoration["url"] return self.__raw_avatar_decoration["url"]
class PartialUser(Generic[PU]): class PartialUser[PU: IPartialUser]:
def __init__(self, raw_user: PU, *, client: ClientManager) -> None: def __init__(self, raw_user: PU, *, client: ClientManager) -> None:
self._raw_user: PU = raw_user self._raw_user: PU = raw_user
self._client: ClientManager = client self._client: ClientManager = client
@ -266,7 +263,6 @@ class PartialUser(Generic[PU]):
if badge_roles is None: if badge_roles is None:
return None return None
return [BadgeRole(data, client=self._client) for data in badge_roles] return [BadgeRole(data, client=self._client) for data in badge_roles]
@property @property
def api(self) -> ClientUserManager: def api(self) -> ClientUserManager:

@ -1,7 +1,7 @@
from __future__ import annotations from __future__ import annotations
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Generic, TypeVar from typing import TYPE_CHECKING
from mipac.abstract.model import AbstractModel from mipac.abstract.model import AbstractModel
from mipac.models.announcement import Announcement from mipac.models.announcement import Announcement
@ -43,12 +43,8 @@ if TYPE_CHECKING:
__all__ = ("PartialUser", "Achievement", "BlockingUser", "MeDetailed") __all__ = ("PartialUser", "Achievement", "BlockingUser", "MeDetailed")
T = TypeVar("T", bound=IUserDetailedNotMeSchema)
FFC = TypeVar("FFC", bound=IFederationFollowCommon) class FollowCommon[FFC: IFederationFollowCommon]:
class FollowCommon(Generic[FFC]):
def __init__(self, raw_follow: FFC, *, client: ClientManager) -> None: def __init__(self, raw_follow: FFC, *, client: ClientManager) -> None:
self._raw_follow: FFC = raw_follow self._raw_follow: FFC = raw_follow
self._client: ClientManager = client self._client: ClientManager = client
@ -507,7 +503,7 @@ class MeDetailedOnly:
return self._raw_user.get("security_keys_list") return self._raw_user.get("security_keys_list")
class UserDetailedNotMe(PartialUser[T], UserDetailedNotMeOnly, Generic[T]): class UserDetailedNotMe[T: IUserDetailedNotMeSchema](PartialUser[T], UserDetailedNotMeOnly):
def __init__(self, raw_user: T, *, client: ClientManager) -> None: def __init__(self, raw_user: T, *, client: ClientManager) -> None:
super().__init__(raw_user, client=client) super().__init__(raw_user, client=client)
@ -554,31 +550,35 @@ class UserList:
def api(self) -> ClientUserListManager: def api(self) -> ClientUserListManager:
return self.__client.user._create_client_user_list_manager(self.id) return self.__client.user._create_client_user_list_manager(self.id)
class UserListMembership: class UserListMembership:
def __init__(self, raw_user_list_membership: IUserListMembership,*, client:ClientManager) -> None: def __init__(
self, raw_user_list_membership: IUserListMembership, *, client: ClientManager
) -> None:
self.__raw_user_list_membership: IUserListMembership = raw_user_list_membership self.__raw_user_list_membership: IUserListMembership = raw_user_list_membership
self.__client: ClientManager = client self.__client: ClientManager = client
@property @property
def id(self) -> str: def id(self) -> str:
return self.__raw_user_list_membership["id"] return self.__raw_user_list_membership["id"]
@property @property
def created_at(self) -> datetime: def created_at(self) -> datetime:
return str_to_datetime(self.__raw_user_list_membership["created_at"]) return str_to_datetime(self.__raw_user_list_membership["created_at"])
@property @property
def user_id(self) -> str: def user_id(self) -> str:
return self.__raw_user_list_membership["user_id"] return self.__raw_user_list_membership["user_id"]
@property @property
def user(self) -> PartialUser: def user(self) -> PartialUser:
return PartialUser(self.__raw_user_list_membership["user"], client=self.__client) return PartialUser(self.__raw_user_list_membership["user"], client=self.__client)
@property @property
def with_replies(self) -> bool: def with_replies(self) -> bool:
return self.__raw_user_list_membership["with_replies"] return self.__raw_user_list_membership["with_replies"]
class FrequentlyRepliedUser: class FrequentlyRepliedUser:
def __init__( def __init__(
self, self,

@ -4,7 +4,7 @@ from mipac.types.username import IUsernameAvailable
class UsernameAvailable: class UsernameAvailable:
def __init__(self, raw_username_available: IUsernameAvailable) -> None: def __init__(self, raw_username_available: IUsernameAvailable) -> None:
self.__raw_username_available: IUsernameAvailable = raw_username_available self.__raw_username_available: IUsernameAvailable = raw_username_available
@property @property
def available(self) -> bool: def available(self) -> bool:
return self.__raw_username_available["available"] return self.__raw_username_available["available"]

@ -3,17 +3,17 @@ from typing import NotRequired, TypedDict
class IAnnouncement(TypedDict): class IAnnouncement(TypedDict):
id: str id: str
createdAt: str created_at: str
updatedAt: str | None updated_at: str | None
text: str text: str
title: str title: str
imageUrl: str | None image_url: str | None
icon: str | None icon: str
display: str display: str
needConfirmationToRead: bool need_confirmation_to_read: bool
silence: bool silence: bool
forYou: bool for_you: bool
isRead: NotRequired[bool] is_read: NotRequired[bool]
class IAnnouncementDetailed(TypedDict): class IAnnouncementDetailed(TypedDict):
@ -22,14 +22,15 @@ class IAnnouncementDetailed(TypedDict):
id: str id: str
created_at: str created_at: str
updated_at: str | None updated_at: str | None
title: str
text: str text: str
title: str
image_url: str | None image_url: str | None
icon: str | None icon: str
display: str display: str
need_confirmation_to_read: bool
silence: bool
is_active: bool is_active: bool
for_existing_users: bool for_existing_users: bool
silence: bool
need_confirmation_to_read: bool
user_id: str | None user_id: str | None
reads: int reads: int

@ -13,5 +13,6 @@ class IInviteCode(TypedDict):
used_at: str | None used_at: str | None
used: bool used: bool
class IInviteLimit(TypedDict): class IInviteLimit(TypedDict):
remaining: int | None remaining: int | None

@ -247,6 +247,4 @@ class IUpdateMetaBody(TypedDict, total=False):
object_storage_use_proxy: bool object_storage_use_proxy: bool
object_storage_set_public_read: bool object_storage_set_public_read: bool
object_storage_s3_force_path_style: bool object_storage_s3_force_path_style: bool
server_rules: NotRequired[ server_rules: NotRequired[list[str]] # v13.11.3以降のバージョンから追加。その場合は使わないとエラー出るかも
list[str]
] # v13.11.3以降のバージョンから追加。その場合は使わないとエラー出るかも

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import Any, Generic, Literal, NotRequired, Optional, TypedDict, TypeVar from typing import Any, Literal, NotRequired, Optional, TypedDict, TypeVar
from mipac.types.drive import IFile from mipac.types.drive import IFile
from mipac.types.emoji import ICustomEmojiLite from mipac.types.emoji import ICustomEmojiLite
@ -18,7 +18,7 @@ class INoteState(TypedDict):
is_muted_thread: bool is_muted_thread: bool
class INoteUpdated(TypedDict, Generic[T]): class INoteUpdated[T](TypedDict):
type: Literal["noteUpdated"] type: Literal["noteUpdated"]
body: T body: T

@ -2,4 +2,4 @@ from typing import TypedDict
class IUsernameAvailable(TypedDict): class IUsernameAvailable(TypedDict):
available: bool available: bool

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, Any, AsyncGenerator, Generic, Literal, Type, TypeVar from typing import TYPE_CHECKING, Any, AsyncGenerator, Literal, Type, TypeVar
from mipac.abstract.model import AbstractModel from mipac.abstract.model import AbstractModel
from mipac.http import HTTPClient, Route from mipac.http import HTTPClient, Route
@ -8,11 +8,10 @@ from mipac.http import HTTPClient, Route
if TYPE_CHECKING: if TYPE_CHECKING:
from mipac.manager.client import ClientManager from mipac.manager.client import ClientManager
T = TypeVar("T")
M = TypeVar("M", bound=AbstractModel) M = TypeVar("M", bound=AbstractModel)
class Pagination(Generic[T]): class Pagination[T]:
def __init__( def __init__(
self, self,
http_client: HTTPClient, http_client: HTTPClient,

@ -19,21 +19,24 @@ if HAS_ORJSON:
else: else:
_from_json = json.loads _from_json = json.loads
class Missing: class Missing:
def __repr__(self) -> str: def __repr__(self) -> str:
return "MISSING" return "MISSING"
def __bool__(self) -> bool: def __bool__(self) -> bool:
return False return False
def __eq__(self, other: Any) -> bool: def __eq__(self, other: Any) -> bool:
return isinstance(other, Missing) return isinstance(other, Missing)
def __ne__(self, other: Any) -> bool: def __ne__(self, other: Any) -> bool:
return not isinstance(other, Missing) return not isinstance(other, Missing)
MISSING: Any = Missing() MISSING: Any = Missing()
def credentials_required(func): def credentials_required(func):
@functools.wraps(func) @functools.wraps(func)
async def wrapper(self: AbstractAction, *args, **kwargs): async def wrapper(self: AbstractAction, *args, **kwargs):

Loading…
Cancel
Save