diff --git a/disnake/abc.py b/disnake/abc.py index 1cc6b95d6d..ff3f6539d7 100644 --- a/disnake/abc.py +++ b/disnake/abc.py @@ -603,7 +603,7 @@ def category(self) -> Optional[CategoryChannel]: """ if isinstance(self.guild, Object): return None - return self.guild.get_channel(self.category_id) # type: ignore + return self.guild.get_channel(self.category_id) # pyright: ignore[reportArgumentType, reportReturnType] @property def permissions_synced(self) -> bool: @@ -1082,7 +1082,7 @@ async def _clone_impl( obj = cls(state=self._state, guild=self.guild, data=data) # temporarily add it to the cache - self.guild._channels[obj.id] = obj # type: ignore + self.guild._channels[obj.id] = obj # pyright: ignore[reportArgumentType] return obj async def clone(self, *, name: Optional[str] = None, reason: Optional[str] = None) -> Self: diff --git a/disnake/activity.py b/disnake/activity.py index 2bda908a4f..e0880c2c0b 100644 --- a/disnake/activity.py +++ b/disnake/activity.py @@ -398,8 +398,8 @@ def __repr__(self) -> str: inner = " ".join(f"{k!s}={v!r}" for k, v in attrs) return f"" - def to_dict(self) -> Dict[str, Any]: - ret: Dict[str, Any] = {} + def to_dict(self) -> ActivityPayload: + ret: ActivityPayload = {} # pyright: ignore[reportAssignmentType] for attr in self.__slots__: value = getattr(self, attr, None) if value is None: @@ -408,16 +408,16 @@ def to_dict(self) -> Dict[str, Any]: if isinstance(value, dict) and len(value) == 0: continue - ret[attr] = value + ret[attr] = value # pyright: ignore[reportGeneralTypeIssues] # fix type field - ret["type"] = int(self.type) + ret["type"] = int(self.type) # pyright: ignore[reportGeneralTypeIssues] # ActivityPayload.type does not include -1 if self.status_display_type: - ret["status_display_type"] = int(self.status_display_type) + ret["status_display_type"] = int(self.status_display_type) # pyright: ignore[reportGeneralTypeIssues] if self.emoji: - ret["emoji"] = self.emoji.to_dict() + ret["emoji"] = self.emoji.to_dict() # pyright: ignore[reportGeneralTypeIssues] # defined in base class slots if self._timestamps: ret["timestamps"] = self._timestamps @@ -608,8 +608,8 @@ def twitch_name(self) -> Optional[str]: name = self.assets["large_image"] return name[7:] if name[:7] == "twitch:" else None - def to_dict(self) -> Dict[str, Any]: - ret: Dict[str, Any] = { + def to_dict(self) -> ActivityPayload: + ret: ActivityPayload = { "type": ActivityType.streaming.value, "name": str(self.name), "url": str(self.url), @@ -891,7 +891,7 @@ def to_dict(self) -> ActivityPayload: } if self.emoji: - o["emoji"] = self.emoji.to_dict() # type: ignore + o["emoji"] = self.emoji.to_dict() # pyright: ignore[reportGeneralTypeIssues] return o def __eq__(self, other: Any) -> bool: @@ -945,16 +945,16 @@ def create_activity( if game_type is ActivityType.playing and not ( "application_id" in data or "session_id" in data or "state" in data ): - activity = Game(**data) # type: ignore # pyright bug(?) + activity = Game(**data) # pyright: ignore[reportArgumentType] # pyright bug(?) elif game_type is ActivityType.custom and "name" in data: - activity = CustomActivity(**data) # type: ignore + activity = CustomActivity(**data) # pyright: ignore[reportArgumentType] elif game_type is ActivityType.streaming and "url" in data: # url won't be None here - activity = Streaming(**data) # type: ignore + activity = Streaming(**data) # pyright: ignore[reportArgumentType] elif game_type is ActivityType.listening and "sync_id" in data and "session_id" in data: activity = Spotify(**data) else: - activity = Activity(**data) # type: ignore + activity = Activity(**data) # pyright: ignore[reportArgumentType] if isinstance(activity, (Activity, CustomActivity)) and activity.emoji and state: activity.emoji._state = state diff --git a/disnake/app_commands.py b/disnake/app_commands.py index e5fca96792..48414065b1 100644 --- a/disnake/app_commands.py +++ b/disnake/app_commands.py @@ -1254,13 +1254,13 @@ def __init__(self, *, data: ApplicationCommandPermissionsPayload, guild_id: int) def __repr__(self) -> str: return f"" - def __eq__(self, other) -> bool: + def __eq__(self, other: ApplicationCommandPermissions) -> bool: return ( self.id == other.id and self.type == other.type and self.permission == other.permission ) def to_dict(self) -> ApplicationCommandPermissionsPayload: - return {"id": self.id, "type": int(self.type), "permission": self.permission} # type: ignore + return {"id": self.id, "type": self.type.value, "permission": self.permission} def is_everyone(self) -> bool: """Whether this permission object is affecting the @everyone role. diff --git a/disnake/audit_logs.py b/disnake/audit_logs.py index 6e81652792..c7d4d1d5ec 100644 --- a/disnake/audit_logs.py +++ b/disnake/audit_logs.py @@ -145,14 +145,16 @@ def _transform_icon(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset if data is None: return None if entry.action.name.startswith("role_"): - return Asset._from_role_icon(entry._state, entry._target_id, data) # type: ignore + assert entry._target_id is not None + return Asset._from_role_icon(entry._state, entry._target_id, data) return Asset._from_guild_icon(entry._state, entry.guild.id, data) def _transform_avatar(entry: AuditLogEntry, data: Optional[str]) -> Optional[Asset]: if data is None: return None - return Asset._from_avatar(entry._state, entry._target_id, data) # type: ignore + assert entry._target_id is not None + return Asset._from_avatar(entry._state, entry._target_id, data) def _guild_hash_transformer(path: str) -> Callable[[AuditLogEntry, Optional[str]], Optional[Asset]]: @@ -260,7 +262,8 @@ def _transform_guild_scheduled_event_image( ) -> Optional[Asset]: if data is None: return None - return Asset._from_guild_scheduled_event_image(entry._state, entry._target_id, data) # type: ignore + assert entry._target_id is not None + return Asset._from_guild_scheduled_event_image(entry._state, entry._target_id, data) def _transform_automod_action( @@ -378,10 +381,12 @@ def __init__(self, entry: AuditLogEntry, data: List[AuditLogChangePayload]) -> N # special cases for role add/remove if attr == "$add": - self._handle_role(self.before, self.after, entry, elem["new_value"]) # type: ignore + assert "new_value" in elem + self._handle_role(self.before, self.after, entry, elem["new_value"]) # pyright: ignore[reportArgumentType] continue elif attr == "$remove": - self._handle_role(self.after, self.before, entry, elem["new_value"]) # type: ignore + assert "new_value" in elem + self._handle_role(self.after, self.before, entry, elem["new_value"]) # pyright: ignore[reportArgumentType] continue # special case for application command permissions update @@ -454,7 +459,7 @@ def _handle_role( if role is None: role = Object(id=role_id) - role.name = e["name"] # type: ignore + role.name = e["name"] # pyright: ignore[reportAttributeAccessIssue] data.append(role) @@ -647,7 +652,7 @@ def _from_data(self, data: AuditLogEntryPayload) -> None: role = self.guild.get_role(instance_id) if role is None: role = Object(id=instance_id) - role.name = extra.get("role_name") # type: ignore + role.name = extra.get("role_name") # pyright: ignore[reportAttributeAccessIssue] self.extra = role elif self.action.name.startswith("stage_instance"): elems = { diff --git a/disnake/automod.py b/disnake/automod.py index 35b0e82fed..171e3d39fc 100644 --- a/disnake/automod.py +++ b/disnake/automod.py @@ -355,7 +355,7 @@ def with_changes( :class:`AutoModTriggerMetadata` The new metadata instance. """ - return self.__class__( # type: ignore # call doesn't match any overloads + return self.__class__( keyword_filter=self.keyword_filter if keyword_filter is MISSING else keyword_filter, regex_patterns=self.regex_patterns if regex_patterns is MISSING else regex_patterns, presets=self.presets if presets is MISSING else presets, @@ -368,7 +368,7 @@ def with_changes( if mention_raid_protection_enabled is MISSING else mention_raid_protection_enabled ), - ) + ) # pyright: ignore[reportCallIssue] # call doesn't match any overloads @classmethod def _from_dict(cls, data: AutoModTriggerMetadataPayload) -> Self: @@ -377,14 +377,14 @@ def _from_dict(cls, data: AutoModTriggerMetadataPayload) -> Self: else: presets = None - return cls( # type: ignore # call doesn't match any overloads + return cls( keyword_filter=data.get("keyword_filter"), regex_patterns=data.get("regex_patterns"), presets=presets, allow_list=data.get("allow_list"), mention_total_limit=data.get("mention_total_limit"), mention_raid_protection_enabled=data.get("mention_raid_protection_enabled"), - ) + ) # pyright: ignore[reportCallIssue] # call doesn't match any overloads def to_dict(self) -> AutoModTriggerMetadataPayload: data: AutoModTriggerMetadataPayload = {} @@ -393,7 +393,7 @@ def to_dict(self) -> AutoModTriggerMetadataPayload: if self.regex_patterns is not None: data["regex_patterns"] = list(self.regex_patterns) if self.presets is not None: - data["presets"] = self.presets.values # type: ignore # `values` contains ints instead of preset literal values + data["presets"] = self.presets.values # pyright: ignore[reportGeneralTypeIssues] # `values` contains ints instead of preset literal values if self.allow_list is not None: data["allow_list"] = list(self.allow_list) if self.mention_total_limit is not None: diff --git a/disnake/channel.py b/disnake/channel.py index ab036d0f58..b5b6d2f20a 100644 --- a/disnake/channel.py +++ b/disnake/channel.py @@ -153,7 +153,7 @@ def __init__(self, *, data: VoiceChannelEffectPayload, state: ConnectionState) - else: sound_data: PartialSoundboardSoundPayload = { "sound_id": sound_id, - "volume": data.get("sound_volume"), # type: ignore # assume this exists if sound_id is set + "volume": data.get("sound_volume"), # pyright: ignore[reportAssignmentType] # assume this exists if sound_id is set } self.sound = PartialSoundboardSound(data=sound_data, state=state) @@ -547,7 +547,7 @@ async def edit( ) if payload is not None: # the payload will always be the proper channel payload - return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore + return self.__class__(state=self._state, guild=self.guild, data=payload) # pyright: ignore[reportArgumentType] async def clone( self, @@ -1091,25 +1091,22 @@ async def create_thread( :class:`Thread` The newly created thread """ - if not ((message is None) ^ (type is None)): - raise ValueError("Exactly one of message and type must be provided.") - if auto_archive_duration is not None: auto_archive_duration = cast( "ThreadArchiveDurationLiteral", try_enum_to_int(auto_archive_duration) ) - if message is None: + if message is None and type is not None: data = await self._state.http.start_thread_without_message( self.id, name=name, auto_archive_duration=auto_archive_duration or self.default_auto_archive_duration, - type=type.value, # type: ignore + type=type.value, invitable=invitable if invitable is not None else True, rate_limit_per_user=slowmode_delay, reason=reason, ) - else: + elif message is not None and type is None: data = await self._state.http.start_thread_with_message( self.id, message.id, @@ -1118,6 +1115,8 @@ async def create_thread( rate_limit_per_user=slowmode_delay, reason=reason, ) + else: + raise ValueError("Exactly one of message and type must be provided.") return Thread(guild=self.guild, state=self._state, data=data) @@ -1706,7 +1705,7 @@ async def edit( ) if payload is not None: # the payload will always be the proper channel payload - return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore + return self.__class__(state=self._state, guild=self.guild, data=payload) # pyright: ignore[reportArgumentType] async def delete_messages(self, messages: Iterable[Snowflake]) -> None: """|coro| @@ -2561,7 +2560,7 @@ async def edit( ) if payload is not None: # the payload will always be the proper channel payload - return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore + return self.__class__(state=self._state, guild=self.guild, data=payload) # pyright: ignore[reportArgumentType] async def delete_messages(self, messages: Iterable[Snowflake]) -> None: """|coro| @@ -3052,7 +3051,7 @@ async def edit( ) if payload is not None: # the payload will always be the proper channel payload - return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore + return self.__class__(state=self._state, guild=self.guild, data=payload) # pyright: ignore[reportArgumentType] @overload async def move( @@ -3462,7 +3461,7 @@ def last_thread(self) -> Optional[Thread]: Optional[:class:`Thread`] The last created thread in this channel or ``None`` if not found. """ - return self._state.get_channel(self.last_thread_id) if self.last_thread_id else None # type: ignore + return self._state.get_channel(self.last_thread_id) if self.last_thread_id else None # pyright: ignore[reportReturnType] @property def available_tags(self) -> List[ForumTag]: @@ -4208,7 +4207,7 @@ async def edit( ) if payload is not None: # the payload will always be the proper channel payload - return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore + return self.__class__(state=self._state, guild=self.guild, data=payload) # pyright: ignore[reportArgumentType] async def clone( self, @@ -4606,7 +4605,7 @@ async def edit( ) if payload is not None: # the payload will always be the proper channel payload - return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore + return self.__class__(state=self._state, guild=self.guild, data=payload) # pyright: ignore[reportArgumentType] async def clone( self, @@ -4780,7 +4779,7 @@ def __init__(self, *, me: ClientUser, state: ConnectionState, data: DMChannelPay self._state: ConnectionState = state self.recipient: Optional[User] = None if recipients := data.get("recipients"): - self.recipient = state.store_user(recipients[0]) # type: ignore + self.recipient = state.store_user(recipients[0]) # pyright: ignore[reportArgumentType] self.me: ClientUser = me self.id: int = int(data["id"]) diff --git a/disnake/client.py b/disnake/client.py index 5a24514cf4..0fa1f9f65d 100644 --- a/disnake/client.py +++ b/disnake/client.py @@ -403,7 +403,7 @@ def __init__( member_cache_flags: Optional[MemberCacheFlags] = None, ) -> None: # self.ws is set in the connect method - self.ws: DiscordWebSocket = None # type: ignore + self.ws: DiscordWebSocket = None # pyright: ignore[reportAttributeAccessIssue] if loop is None: self.loop: asyncio.AbstractEventLoop = utils.get_event_loop() @@ -616,7 +616,7 @@ def application_id(self) -> int: .. versionadded:: 2.0 """ - return self._connection.application_id # type: ignore + return self._connection.application_id # pyright: ignore[reportReturnType] @property def application_flags(self) -> ApplicationFlags: @@ -1340,8 +1340,7 @@ def activity(self, value: Optional[ActivityTypes]) -> None: if value is None: self._connection._activity = None elif isinstance(value, BaseActivity): - # ConnectionState._activity is typehinted as ActivityPayload, we're passing Dict[str, Any] - self._connection._activity = value.to_dict() # type: ignore + self._connection._activity = value.to_dict() else: raise TypeError("activity must derive from BaseActivity.") @@ -1928,7 +1927,7 @@ async def change_presence( continue # Member.activities is typehinted as Tuple[ActivityType, ...], we may be setting it as Tuple[BaseActivity, ...] - me.activities = activities # type: ignore + me.activities = activities # pyright: ignore[reportAttributeAccessIssue] me.status = status # Guild stuff @@ -2224,7 +2223,11 @@ async def fetch_stage_instance(self, channel_id: int, /) -> StageInstance: """ data = await self.http.get_stage_instance(channel_id) guild = self.get_guild(int(data["guild_id"])) - return StageInstance(guild=guild, state=self._connection, data=data) # type: ignore + return StageInstance( + guild=guild, # pyright: ignore[reportArgumentType] + state=self._connection, + data=data, + ) # Invite management @@ -2582,13 +2585,21 @@ async def fetch_channel( if ch_type in (ChannelType.group, ChannelType.private): # the factory will be a DMChannel or GroupChannel here - channel = factory(me=self.user, data=data, state=self._connection) # type: ignore + channel = factory( + me=self.user, # pyright: ignore[reportCallIssue] + data=data, # pyright: ignore[reportArgumentType] + state=self._connection, + ) else: # the factory can't be a DMChannel or GroupChannel here - guild_id = int(data["guild_id"]) # type: ignore + guild_id = int(data["guild_id"]) # pyright: ignore[reportGeneralTypeIssues] guild = self.get_guild(guild_id) or Object(id=guild_id) # GuildChannels expect a Guild, we may be passing an Object - channel = factory(guild=guild, state=self._connection, data=data) # type: ignore + channel = factory( # pyright: ignore[reportCallIssue] + guild=guild, # pyright: ignore[reportArgumentType, reportCallIssue] + data=data, # pyright: ignore[reportArgumentType] + state=self._connection, + ) return channel @@ -2644,8 +2655,8 @@ async def fetch_sticker(self, sticker_id: int, /) -> Union[StandardSticker, Guil The sticker you requested. """ data = await self.http.get_sticker(sticker_id) - cls, _ = _sticker_factory(data["type"]) # type: ignore - return cls(state=self._connection, data=data) # type: ignore + cls, _ = _sticker_factory(data["type"]) # pyright: ignore[reportGeneralTypeIssues] + return cls(state=self._connection, data=data) # pyright: ignore[reportReturnType] async def fetch_sticker_pack(self, pack_id: int, /) -> StickerPack: """|coro| diff --git a/disnake/components.py b/disnake/components.py index d66dc8647d..372461c178 100644 --- a/disnake/components.py +++ b/disnake/components.py @@ -274,7 +274,7 @@ def __init__(self, data: ActionRowPayload) -> None: self.id = data.get("id", 0) children = [_component_factory(d) for d in data.get("components", [])] - self.children: List[ActionRowChildComponentT] = children # type: ignore + self.children: List[ActionRowChildComponentT] = children # pyright: ignore[reportAttributeAccessIssue] def to_dict(self) -> ActionRowPayload: return { @@ -448,7 +448,7 @@ class BaseSelectMenu(Component): # fully support readonly items yet (which would help avoid this) def __init__(self, data: AnySelectMenuPayload) -> None: component_type = try_enum(ComponentType, data["type"]) - self.type: SelectMenuType = component_type # type: ignore + self.type: SelectMenuType = component_type # pyright: ignore[reportAttributeAccessIssue] self.id = data.get("id", 0) self.custom_id: str = data["custom_id"] @@ -1039,7 +1039,7 @@ def __init__(self, data: SectionComponentPayload) -> None: ] accessory = _component_factory(data["accessory"]) - self.accessory: SectionAccessoryComponent = accessory # type: ignore + self.accessory: SectionAccessoryComponent = accessory # pyright: ignore[reportAttributeAccessIssue] def to_dict(self) -> SectionComponentPayload: return { @@ -1457,7 +1457,7 @@ def __init__(self, data: ContainerComponentPayload) -> None: self.id = data.get("id", 0) components = [_component_factory(d) for d in data.get("components", [])] - self.children: List[ContainerChildComponent] = components # type: ignore + self.children: List[ContainerChildComponent] = components # pyright: ignore[reportAttributeAccessIssue] self.accent_colour: Optional[Colour] = ( Colour(accent_color) if (accent_color := data.get("accent_color")) is not None else None @@ -1528,7 +1528,7 @@ def __init__(self, data: LabelComponentPayload) -> None: self.description: Optional[str] = data.get("description") component = _component_factory(data["component"]) - self.component: LabelChildComponent = component # type: ignore + self.component: LabelChildComponent = component # pyright: ignore[reportAttributeAccessIssue] def to_dict(self) -> LabelComponentPayload: payload: LabelComponentPayload = { @@ -1605,9 +1605,9 @@ def _component_factory(data: ComponentPayload, *, type: Type[C] = Component) -> except KeyError: # if we encounter an unknown component type, just construct a placeholder component for it as_enum = try_enum(ComponentType, component_type) - return Component._raw_construct(type=as_enum) # type: ignore + return Component._raw_construct(type=as_enum) # pyright: ignore[reportReturnType] else: - return component_cls(data) # type: ignore + return component_cls(data) # pyright: ignore[reportCallIssue, reportReturnType] # this is just a rebranded _component_factory, as a workaround to Python not supporting typescript-like mapped types diff --git a/disnake/emoji.py b/disnake/emoji.py index e474bbbed3..ead291435d 100644 --- a/disnake/emoji.py +++ b/disnake/emoji.py @@ -105,8 +105,9 @@ def __init__( def _from_data(self, emoji: EmojiPayload) -> None: self.require_colons: bool = emoji.get("require_colons", False) self.managed: bool = emoji.get("managed", False) - self.id: int = int(emoji["id"]) # type: ignore - self.name: str = emoji["name"] # type: ignore + assert emoji["id"] is not None + self.id: int = int(emoji["id"]) + self.name: str = emoji["name"] # pyright: ignore[reportAttributeAccessIssue] self.animated: bool = emoji.get("animated", False) self.available: bool = emoji.get("available", True) self._roles: SnowflakeList = SnowflakeList(map(int, emoji.get("roles", []))) @@ -165,11 +166,10 @@ def roles(self) -> List[Role]: Emojis with :attr:`subscription roles ` are considered premium emojis, and count towards a separate limit of 25 emojis. """ - guild = self.guild - if guild is None: + if self.guild is None: return [] - return [role for role in guild.roles if self._roles.has(role.id)] + return [role for role in self.guild.roles if self._roles.has(role.id)] @property def guild(self) -> Optional[Guild]: diff --git a/disnake/enums.py b/disnake/enums.py index 7ea1957269..97ebd8318a 100644 --- a/disnake/enums.py +++ b/disnake/enums.py @@ -13,6 +13,7 @@ NamedTuple, NoReturn, Optional, + Tuple, Type, TypeVar, ) @@ -82,12 +83,13 @@ "NameplatePalette", ) -EnumMetaT = TypeVar("EnumMetaT", bound="Type[EnumMeta]") +EnumMetaT = TypeVar("EnumMetaT", bound="EnumMeta") class _EnumValueBase(NamedTuple): if TYPE_CHECKING: - _cls_name: ClassVar[str] # type: ignore + _cls_name: ClassVar[str] # pyright: ignore[reportGeneralTypeIssues, reportInvalidTypeForm] + _actual_enum_cls_: ClassVar[EnumMeta] # pyright: ignore[reportGeneralTypeIssues, reportInvalidTypeForm] name: str value: Any @@ -110,7 +112,7 @@ def __lt__(self, other: object) -> bool: def _create_value_cls(name: str, comparable: bool) -> Type[_EnumValueBase]: parent = _EnumValueComparable if comparable else _EnumValueBase - return type(f"{parent.__name__}_{name}", (parent,), {"_cls_name": name}) # type: ignore + return type(f"{parent.__name__}_{name}", (parent,), {"_cls_name": name}) # pyright: ignore[reportReturnType] def _is_descriptor(obj) -> bool: @@ -125,7 +127,14 @@ class EnumMeta(type): _enum_value_map_: ClassVar[Dict[Any, Any]] _enum_value_cls_: ClassVar[Type[_EnumValueBase]] - def __new__(cls: EnumMetaT, name: str, bases, attrs, *, comparable: bool = False) -> EnumMetaT: + def __new__( + cls: Type[EnumMetaT], + name: str, + bases: Tuple[Type, ...], + attrs: Dict[str, Any], + *, + comparable: bool = False, + ) -> EnumMetaT: value_mapping = {} member_mapping = {} member_names = [] @@ -159,8 +168,7 @@ def __new__(cls: EnumMetaT, name: str, bases, attrs, *, comparable: bool = False attrs["_enum_member_map_"] = member_mapping attrs["_enum_member_names_"] = member_names attrs["_enum_value_cls_"] = value_cls - actual_cls = super().__new__(cls, name, bases, attrs) - value_cls._actual_enum_cls_ = actual_cls # type: ignore + value_cls._actual_enum_cls_ = actual_cls = super().__new__(cls, name, bases, attrs) return actual_cls def __iter__(cls) -> Iterator[EnumMetaT]: @@ -191,14 +199,14 @@ def __getitem__(cls, key: str) -> Any: def __setattr__(cls, name: str, value: Any) -> NoReturn: raise TypeError("Enums are immutable.") - def __delattr__(cls, attr) -> NoReturn: - raise TypeError("Enums are immutable") + def __delattr__(cls, attr: str) -> NoReturn: + raise TypeError("Enums are immutable.") - def __instancecheck__(self, instance) -> bool: + def __instancecheck__(self, instance: object) -> bool: # isinstance(x, Y) # -> __instancecheck__(Y, x) try: - return instance._actual_enum_cls_ is self + return instance._actual_enum_cls_ is self # pyright: ignore[reportAttributeAccessIssue] except AttributeError: return False @@ -620,7 +628,7 @@ class StatusDisplayType(Enum): .. versionadded:: 2.11 """ - name = 0 # type: ignore[reportAssignmentType] + name = 0 # pyright: ignore[reportAssignmentType] """The name of the activity is displayed, e.g: ``Listening to Spotify``.""" state = 1 """The state of the activity is displayed, e.g: ``Listening to Rick Astley``.""" @@ -2446,11 +2454,11 @@ class NameplatePalette(Enum): """White color palette.""" -T = TypeVar("T") +T = TypeVar("T", bound="Enum") def create_unknown_value(cls: Type[T], val: Any) -> T: - value_cls = cls._enum_value_cls_ # type: ignore + value_cls = cls._enum_value_cls_ # pyright: ignore[reportAttributeAccessIssue] name = f"unknown_{val}" return value_cls(name=name, value=val) @@ -2461,7 +2469,7 @@ def try_enum(cls: Type[T], val: Any) -> T: If it fails it returns a proxy invalid value instead. """ try: - return cls._enum_value_map_[val] # type: ignore + return cls._enum_value_map_[val] # pyright: ignore[reportAttributeAccessIssue] except (KeyError, TypeError, AttributeError): return create_unknown_value(cls, val) diff --git a/disnake/errors.py b/disnake/errors.py index 1bab2cf8ba..e44ce516d6 100644 --- a/disnake/errors.py +++ b/disnake/errors.py @@ -110,7 +110,7 @@ def __init__( self, response: _ResponseType, message: Optional[Union[str, Dict[str, Any]]] ) -> None: self.response: _ResponseType = response - self.status: int = response.status # type: ignore + self.status: int = response.status # pyright: ignore[reportAttributeAccessIssue] self.code: int self.text: str if isinstance(message, dict): diff --git a/disnake/ext/commands/base_core.py b/disnake/ext/commands/base_core.py index b655a1f4c8..65d0f0da4d 100644 --- a/disnake/ext/commands/base_core.py +++ b/disnake/ext/commands/base_core.py @@ -373,11 +373,11 @@ def _prepare_cooldowns(self, inter: ApplicationCommandInteraction) -> None: if self._buckets.valid: dt = inter.created_at current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() - bucket = self._buckets.get_bucket(inter, current) # type: ignore + bucket = self._buckets.get_bucket(inter, current) # pyright: ignore[reportArgumentType] if bucket is not None: # pyright: ignore[reportUnnecessaryComparison] retry_after = bucket.update_rate_limit(current) if retry_after: - raise CommandOnCooldown(bucket, retry_after, self._buckets.type) # type: ignore + raise CommandOnCooldown(bucket, retry_after, self._buckets.type) # pyright: ignore[reportArgumentType] async def prepare(self, inter: ApplicationCommandInteraction) -> None: inter.application_command = self @@ -386,14 +386,14 @@ async def prepare(self, inter: ApplicationCommandInteraction) -> None: raise CheckFailure(f"The check functions for command {self.qualified_name!r} failed.") if self._max_concurrency is not None: - await self._max_concurrency.acquire(inter) # type: ignore + await self._max_concurrency.acquire(inter) # pyright: ignore[reportArgumentType] try: self._prepare_cooldowns(inter) await self.call_before_hooks(inter) except Exception: if self._max_concurrency is not None: - await self._max_concurrency.release(inter) # type: ignore + await self._max_concurrency.release(inter) # pyright: ignore[reportArgumentType] raise def is_on_cooldown(self, inter: ApplicationCommandInteraction) -> bool: @@ -412,7 +412,7 @@ def is_on_cooldown(self, inter: ApplicationCommandInteraction) -> bool: if not self._buckets.valid: return False - bucket = self._buckets.get_bucket(inter) # type: ignore + bucket = self._buckets.get_bucket(inter) # pyright: ignore[reportArgumentType] dt = inter.created_at current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() return bucket.get_tokens(current) == 0 @@ -426,7 +426,7 @@ def reset_cooldown(self, inter: ApplicationCommandInteraction) -> None: The interaction with this application command """ if self._buckets.valid: - bucket = self._buckets.get_bucket(inter) # type: ignore + bucket = self._buckets.get_bucket(inter) # pyright: ignore[reportArgumentType] bucket.reset() def get_cooldown_retry_after(self, inter: ApplicationCommandInteraction) -> float: @@ -444,7 +444,7 @@ def get_cooldown_retry_after(self, inter: ApplicationCommandInteraction) -> floa If this is ``0.0`` then the command isn't on cooldown. """ if self._buckets.valid: - bucket = self._buckets.get_bucket(inter) # type: ignore + bucket = self._buckets.get_bucket(inter) # pyright: ignore[reportArgumentType] dt = inter.created_at current = dt.replace(tzinfo=datetime.timezone.utc).timestamp() return bucket.get_retry_after(current) @@ -468,7 +468,7 @@ async def invoke(self, inter: ApplicationCommandInteraction, *args: Any, **kwarg raise CommandInvokeError(exc) from exc finally: if self._max_concurrency is not None: - await self._max_concurrency.release(inter) # type: ignore + await self._max_concurrency.release(inter) # pyright: ignore[reportArgumentType] await self.call_after_hooks(inter) @@ -531,9 +531,9 @@ async def call_before_hooks(self, inter: ApplicationCommandInteraction) -> None: # __self__ only exists for methods, not functions # however, if @command.before_invoke is used, it will be a function if instance: - await self._before_invoke(instance, inter) # type: ignore + await self._before_invoke(instance, inter) # pyright: ignore[reportCallIssue, reportArgumentType] else: - await self._before_invoke(inter) # type: ignore + await self._before_invoke(inter) # pyright: ignore[reportArgumentType, reportCallIssue] if inter.data.type is ApplicationCommandType.chat_input: partial_attr_name = "slash_command" @@ -561,9 +561,9 @@ async def call_after_hooks(self, inter: ApplicationCommandInteraction) -> None: if self._after_invoke is not None: instance = getattr(self._after_invoke, "__self__", cog) if instance: - await self._after_invoke(instance, inter) # type: ignore + await self._after_invoke(instance, inter) # pyright: ignore[reportCallIssue, reportArgumentType] else: - await self._after_invoke(inter) # type: ignore + await self._after_invoke(inter) # pyright: ignore[reportArgumentType, reportCallIssue] if inter.data.type is ApplicationCommandType.chat_input: partial_attr_name = "slash_command" @@ -691,7 +691,7 @@ async def can_run(self, inter: ApplicationCommandInteraction) -> bool: # since we have no checks, then we just return True. return True - return await async_all(predicate(inter) for predicate in predicates) # type: ignore + return await async_all(predicate(inter) for predicate in predicates) # pyright: ignore[reportCallIssue] finally: inter.application_command = original @@ -827,7 +827,7 @@ def decorator(func: T) -> T: ) func.body._default_member_permissions = perms_value else: - func.__default_member_permissions__ = perms_value # type: ignore + func.__default_member_permissions__ = perms_value # pyright: ignore[reportAttributeAccessIssue] return func return decorator @@ -864,7 +864,7 @@ def decorator(func: T) -> T: raise ValueError("Cannot set `install_types` in both parameter and decorator") func.body.install_types = install_types else: - func.__install_types__ = install_types # type: ignore + func.__install_types__ = install_types # pyright: ignore[reportAttributeAccessIssue] return func return decorator @@ -908,7 +908,7 @@ def decorator(func: T) -> T: raise ValueError("Cannot set `contexts` in both parameter and decorator") func.body.contexts = contexts else: - func.__contexts__ = contexts # type: ignore + func.__contexts__ = contexts # pyright: ignore[reportAttributeAccessIssue] return func return decorator diff --git a/disnake/ext/commands/bot_base.py b/disnake/ext/commands/bot_base.py index ab5e6b9856..9902adddcd 100644 --- a/disnake/ext/commands/bot_base.py +++ b/disnake/ext/commands/bot_base.py @@ -52,7 +52,7 @@ def when_mentioned(bot: BotBase, msg: Message) -> List[str]: These are meant to be passed into the :attr:`.Bot.command_prefix` attribute. """ # bot.user will never be None when this is called - return [f"<@{bot.user.id}> ", f"<@!{bot.user.id}> "] # type: ignore + return [f"<@{bot.user.id}> ", f"<@!{bot.user.id}> "] # pyright: ignore[reportAttributeAccessIssue] def when_mentioned_or(*prefixes: str) -> Callable[[BotBase, Message], List[str]]: @@ -276,7 +276,7 @@ def check_commands(ctx): """ # T was used instead of Check to ensure the type matches on return - self.add_check(func) # type: ignore + self.add_check(func) # pyright: ignore[reportArgumentType] return func def check_once(self, func: CFT) -> CFT: @@ -325,7 +325,7 @@ async def can_run(self, ctx: Context, *, call_once: bool = False) -> bool: return True # type-checker doesn't distinguish between functions and methods - return await disnake.utils.async_all(f(ctx) for f in data) # type: ignore + return await disnake.utils.async_all(f(ctx) for f in data) # pyright: ignore[reportCallIssue] def before_invoke(self, coro: CFT) -> CFT: """A decorator that registers a coroutine as a pre-invoke hook. @@ -503,7 +503,7 @@ class be provided, it must be similar enough to :class:`.Context`\'s view = StringView(message.content) ctx = cls(prefix=None, view=view, bot=self, message=message) - if message.author.id == self.user.id: # type: ignore + if message.author.id == self.user.id: # pyright: ignore[reportAttributeAccessIssue] return ctx prefix = await self.get_prefix(message) @@ -547,7 +547,7 @@ class be provided, it must be similar enough to :class:`.Context`\'s invoker = view.get_word() ctx.invoked_with = invoker # type-checker fails to narrow invoked_prefix type. - ctx.prefix = invoked_prefix # type: ignore + ctx.prefix = invoked_prefix # pyright: ignore[reportAttributeAccessIssue] ctx.command = self.all_commands.get(invoker) return ctx diff --git a/disnake/ext/commands/cog.py b/disnake/ext/commands/cog.py index b7551beed3..c9cbd68cec 100644 --- a/disnake/ext/commands/cog.py +++ b/disnake/ext/commands/cog.py @@ -258,12 +258,13 @@ def __new__(cls, *args: Any, **kwargs: Any) -> Self: cog_app_commands.append(c) - self.__cog_app_commands__ = tuple(cog_app_commands) # type: ignore # overriding ClassVar + # FIXME: __cog_app_commands__ is annotated as List, assigning tuple here? + self.__cog_app_commands__ = tuple(cog_app_commands) # pyright: ignore[reportAttributeAccessIssue] # overriding ClassVar # Replace the old command objects with the new copies for app_command in self.__cog_app_commands__: setattr(self, app_command.callback.__name__, app_command) - self.__cog_commands__ = tuple(c._update_copy(cmd_attrs) for c in cls.__cog_commands__) # type: ignore # overriding ClassVar + self.__cog_commands__ = tuple(c._update_copy(cmd_attrs) for c in cls.__cog_commands__) # pyright: ignore[reportAttributeAccessIssue] # overriding ClassVar lookup = {cmd.qualified_name: cmd for cmd in self.__cog_commands__} for command in self.__cog_commands__: @@ -271,11 +272,11 @@ def __new__(cls, *args: Any, **kwargs: Any) -> Self: parent = command.parent if parent is not None: # Get the latest parent reference - parent = lookup[parent.qualified_name] # type: ignore + parent = lookup[parent.qualified_name] # pyright: ignore[reportAttributeAccessIssue] # Update our parent's reference to our self - parent.remove_command(command.name) # type: ignore - parent.add_command(command) # type: ignore + parent.remove_command(command.name) # pyright: ignore[reportAttributeAccessIssue] + parent.add_command(command) # pyright: ignore[reportAttributeAccessIssue] return self @@ -739,12 +740,12 @@ def _inject(self, bot: AnyBot) -> Self: command.cog = self if command.parent is None: try: - bot.add_command(command) # type: ignore + bot.add_command(command) # pyright: ignore[reportAttributeAccessIssue] except Exception: # undo our additions for to_undo in self.__cog_commands__[:index]: if to_undo.parent is None: - bot.remove_command(to_undo.name) # type: ignore + bot.remove_command(to_undo.name) # pyright: ignore[reportAttributeAccessIssue] raise for index, command in enumerate(self.__cog_app_commands__): @@ -834,7 +835,7 @@ def _eject(self, bot: AnyBot) -> None: try: for command in self.__cog_commands__: if command.parent is None: - bot.remove_command(command.name) # type: ignore + bot.remove_command(command.name) # pyright: ignore[reportAttributeAccessIssue] for app_command in self.__cog_app_commands__: if isinstance(app_command, InvokableSlashCommand): @@ -848,10 +849,10 @@ def _eject(self, bot: AnyBot) -> None: bot.remove_listener(getattr(self, method_name), name) if cls.bot_check is not Cog.bot_check: - bot.remove_check(self.bot_check) # type: ignore + bot.remove_check(self.bot_check) # pyright: ignore[reportAttributeAccessIssue] if cls.bot_check_once is not Cog.bot_check_once: - bot.remove_check(self.bot_check_once, call_once=True) # type: ignore + bot.remove_check(self.bot_check_once, call_once=True) # pyright: ignore[reportAttributeAccessIssue] # Remove application command checks if cls.bot_slash_command_check is not Cog.bot_slash_command_check: diff --git a/disnake/ext/commands/common_bot_base.py b/disnake/ext/commands/common_bot_base.py index 38b2da8566..b276b934a4 100644 --- a/disnake/ext/commands/common_bot_base.py +++ b/disnake/ext/commands/common_bot_base.py @@ -70,13 +70,13 @@ def __init__( # FIXME: make event name pos-only or remove entirely in v3.0 def dispatch(self, event_name: str, *args: Any, **kwargs: Any) -> None: # super() will resolve to Client - super().dispatch(event_name, *args, **kwargs) # type: ignore + super().dispatch(event_name, *args, **kwargs) # pyright: ignore[reportAttributeAccessIssue] async def _fill_owners(self) -> None: if self.owner_id or self.owner_ids: return - app: disnake.AppInfo = await self.application_info() # type: ignore + app: disnake.AppInfo = await self.application_info() # pyright: ignore[reportAttributeAccessIssue] if app.team: self.owners = owners = { member @@ -106,13 +106,13 @@ async def close(self) -> None: error.__suppress_context__ = True _log.exception("Failed to remove cog %r", cog, exc_info=error) - await super().close() # type: ignore + await super().close() # pyright: ignore[reportAttributeAccessIssue] @disnake.utils.copy_doc(disnake.Client.login) async def login(self, token: str) -> None: - await super().login(token=token) # type: ignore + await super().login(token=token) # pyright: ignore[reportAttributeAccessIssue] - loop: asyncio.AbstractEventLoop = self.loop # type: ignore + loop: asyncio.AbstractEventLoop = self.loop # pyright: ignore[reportAttributeAccessIssue] if self.reload: loop.create_task(self._watchdog()) @@ -199,7 +199,7 @@ def add_cog(self, cog: Cog, *, override: bool = False) -> None: self.remove_cog(cog_name) # NOTE: Should be covariant - cog = cog._inject(self) # type: ignore + cog = cog._inject(self) # pyright: ignore[reportArgumentType] self.__cogs[cog_name] = cog def get_cog(self, name: str) -> Optional[Cog]: @@ -251,7 +251,7 @@ def remove_cog(self, name: str) -> Optional[Cog]: if help_command and help_command.cog is cog: help_command.cog = None # NOTE: Should be covariant - cog._eject(self) # type: ignore + cog._eject(self) # pyright: ignore[reportArgumentType] return cog @@ -303,7 +303,8 @@ def _load_from_module_spec(self, spec: importlib.machinery.ModuleSpec, key: str) lib = importlib.util.module_from_spec(spec) sys.modules[key] = lib try: - spec.loader.exec_module(lib) # type: ignore + assert spec.loader is not None + spec.loader.exec_module(lib) except Exception as e: del sys.modules[key] raise errors.ExtensionFailed(key, e) from e @@ -526,7 +527,7 @@ async def _watchdog(self) -> None: if extensions: try: - self.i18n.reload() # type: ignore + self.i18n.reload() # pyright: ignore[reportAttributeAccessIssue] except Exception as e: reload_log.exception(e) diff --git a/disnake/ext/commands/converter.py b/disnake/ext/commands/converter.py index 7f403d348e..dacd411fa9 100644 --- a/disnake/ext/commands/converter.py +++ b/disnake/ext/commands/converter.py @@ -20,6 +20,7 @@ Type, TypeVar, Union, + cast, runtime_checkable, ) @@ -324,7 +325,7 @@ class UserConverter(IDConverter[disnake.User]): async def convert(self, ctx: AnyContext, argument: str) -> disnake.User: match = self._get_id_match(argument) or re.match(r"<@!?([0-9]{17,19})>$", argument) state = ctx._state - bot: disnake.Client = ctx.bot + bot: disnake.Client = cast("disnake.Client", ctx.bot) result: Optional[Union[disnake.User, disnake.Member]] = None if match is not None: @@ -343,9 +344,11 @@ async def convert(self, ctx: AnyContext, argument: str) -> disnake.User: except disnake.HTTPException: raise UserNotFound(argument) from None + # TODO: inverting this condition somehow fixes the type ignore if isinstance(result, disnake.Member): return result._user - return result # type: ignore + + return result # pyright: ignore[reportReturnType] username, _, discriminator = argument.rpartition("#") # n.b. there's no builtin method that only matches arabic digits, `isdecimal` is the closest one. @@ -408,13 +411,13 @@ def _get_id_matches(ctx: AnyContext, argument: str) -> Tuple[Optional[int], int, def _resolve_channel( ctx: AnyContext, guild_id: Optional[int], channel_id: int ) -> Optional[MessageableChannel]: - bot: disnake.Client = ctx.bot + bot: disnake.Client = cast("disnake.Client", ctx.bot) if guild_id is None: - return bot.get_channel(channel_id) if channel_id else ctx.channel # type: ignore + return bot.get_channel(channel_id) if channel_id else ctx.channel # pyright: ignore[reportReturnType] guild = bot.get_guild(guild_id) if guild is not None: - return guild._resolve_channel(channel_id) # type: ignore + return guild._resolve_channel(channel_id) # pyright: ignore[reportReturnType] return None async def convert(self, ctx: AnyContext, argument: str) -> disnake.PartialMessage: @@ -442,19 +445,19 @@ class MessageConverter(IDConverter[disnake.Message]): async def convert(self, ctx: AnyContext, argument: str) -> disnake.Message: guild_id, message_id, channel_id = PartialMessageConverter._get_id_matches(ctx, argument) - bot: disnake.Client = ctx.bot + bot: disnake.Client = cast("disnake.Client", ctx.bot) message = bot._connection._get_message(message_id) - if message: + if message is not None: return message channel = PartialMessageConverter._resolve_channel(ctx, guild_id, channel_id) - if not channel: + if channel is None: raise ChannelNotFound(str(channel_id)) try: return await channel.fetch_message(message_id) except disnake.NotFound: raise MessageNotFound(argument) from None except disnake.Forbidden: - raise ChannelNotReadable(channel) from None # type: ignore + raise ChannelNotReadable(channel) from None # pyright: ignore[reportArgumentType] class GuildChannelConverter(IDConverter[disnake.abc.GuildChannel]): @@ -1264,7 +1267,7 @@ async def _actual_conversion( param: inspect.Parameter, ) -> T: if converter is bool: - return _convert_to_bool(argument) # type: ignore + return _convert_to_bool(argument) # pyright: ignore[reportReturnType] if isinstance(converter, type): module = converter.__module__ @@ -1285,7 +1288,7 @@ async def _actual_conversion( raise ConversionError(converter, exc) from exc try: - return converter(argument) # type: ignore + return converter(argument) # pyright: ignore[reportReturnType, reportCallIssue] except CommandError: raise except Exception as exc: diff --git a/disnake/ext/commands/cooldowns.py b/disnake/ext/commands/cooldowns.py index 971af2bd0f..c49ae95d44 100644 --- a/disnake/ext/commands/cooldowns.py +++ b/disnake/ext/commands/cooldowns.py @@ -57,12 +57,14 @@ def get_key(self, msg: Message) -> Any: elif self is BucketType.member: return ((msg.guild and msg.guild.id), msg.author.id) elif self is BucketType.category: - return (msg.channel.category or msg.channel).id # type: ignore + return (msg.channel.category or msg.channel).id # pyright: ignore[reportAttributeAccessIssue] elif self is BucketType.role: # if author is not a Member we are in a private-channel context; returning its id # yields the same result as for a guild with only the @everyone role return ( - msg.author.top_role if msg.guild and isinstance(msg.author, Member) else msg.channel + msg.author.top_role + if msg.guild is not None and isinstance(msg.author, Member) + else msg.channel ).id def __call__(self, msg: Message) -> Any: @@ -230,11 +232,13 @@ def _is_default(self) -> bool: return self._type is BucketType.default def create_bucket(self, message: Message) -> Cooldown: - return self._cooldown.copy() # type: ignore + assert self._cooldown is not None + return self._cooldown.copy() def get_bucket(self, message: Message, current: Optional[float] = None) -> Cooldown: if self._is_default(): - return self._cooldown # type: ignore + assert self._cooldown is not None + return self._cooldown self._verify_cache_integrity(current) key = self._bucket_key(message) diff --git a/disnake/ext/commands/core.py b/disnake/ext/commands/core.py index f4e4d06c9c..c7c1fbe9eb 100644 --- a/disnake/ext/commands/core.py +++ b/disnake/ext/commands/core.py @@ -64,7 +64,7 @@ ) if TYPE_CHECKING: - from typing_extensions import Concatenate, ParamSpec, Self, TypeGuard + from typing_extensions import Concatenate, ParamSpec, Self from disnake.message import Message @@ -159,7 +159,7 @@ async def wrapped(*args: Any, **kwargs: Any) -> Optional[T]: raise CommandInvokeError(exc) from exc finally: if command._max_concurrency is not None: - await command._max_concurrency.release(ctx) # type: ignore + await command._max_concurrency.release(ctx) # pyright: ignore[reportArgumentType] await command.call_after_hooks(ctx) return ret @@ -348,11 +348,11 @@ def __init__( self.require_var_positional: bool = kwargs.get("require_var_positional", False) self.ignore_extra: bool = kwargs.get("ignore_extra", True) self.cooldown_after_parsing: bool = kwargs.get("cooldown_after_parsing", False) - self.cog: CogT = None # type: ignore + self.cog: CogT = None # pyright: ignore[reportAttributeAccessIssue] # bandaid for the fact that sometimes parent can be the bot instance parent = kwargs.get("parent") - self.parent: Optional[GroupMixin] = parent if isinstance(parent, _BaseCommand) else None # type: ignore + self.parent: Optional[GroupMixin] = parent if isinstance(parent, _BaseCommand) else None # pyright: ignore[reportAttributeAccessIssue] self._before_invoke: Optional[Hook] = None try: @@ -448,9 +448,9 @@ async def __call__(self, context: Context, *args: P.args, **kwargs: P.kwargs) -> .. versionadded:: 1.3 """ if self.cog is not None: - return await self.callback(self.cog, context, *args, **kwargs) # type: ignore + return await self.callback(self.cog, context, *args, **kwargs) # pyright: ignore[reportCallIssue] else: - return await self.callback(context, *args, **kwargs) # type: ignore + return await self.callback(context, *args, **kwargs) # pyright: ignore[reportCallIssue] def _ensure_assignment_on_copy(self, other: CommandT) -> CommandT: other._before_invoke = self._before_invoke @@ -461,7 +461,8 @@ def _ensure_assignment_on_copy(self, other: CommandT) -> CommandT: other._buckets = self._buckets.copy() if self._max_concurrency != other._max_concurrency: # _max_concurrency won't be None at this point - other._max_concurrency = self._max_concurrency.copy() # type: ignore + assert self._max_concurrency is not None + other._max_concurrency = self._max_concurrency.copy() try: other.on_error = self.on_error @@ -566,7 +567,8 @@ async def transform(self, ctx: Context, param: inspect.Parameter) -> Any: view.previous = previous # type-checker fails to narrow argument - return await run_converters(ctx, converter, argument, param) # type: ignore + assert argument is not None + return await run_converters(ctx, converter, argument, param) async def _transform_greedy_pos( self, ctx: Context, param: inspect.Parameter, required: bool, converter: Any @@ -580,7 +582,7 @@ async def _transform_greedy_pos( view.skip_ws() try: argument = view.get_quoted_word() - value = await run_converters(ctx, converter, argument, param) # type: ignore + value = await run_converters(ctx, converter, argument, param) # pyright: ignore[reportArgumentType] except (CommandError, ArgumentParsingError): view.index = previous break @@ -598,7 +600,7 @@ async def _transform_greedy_var_pos( previous = view.index try: argument = view.get_quoted_word() - value = await run_converters(ctx, converter, argument, param) # type: ignore + value = await run_converters(ctx, converter, argument, param) # pyright: ignore[reportArgumentType] except (CommandError, ArgumentParsingError): view.index = previous raise RuntimeError from None # break loop @@ -621,11 +623,11 @@ def full_parent_name(self) -> str: This the base command name required to execute it. For example, in ``?one two three`` the parent name would be ``one two``. """ - entries = [] + entries: list[str] = [] command: Command[CogT, ..., Any] = self # command.parent is type-hinted as GroupMixin some attributes are resolved via MRO while command.parent is not None: - command = command.parent # type: ignore + command = command.parent # pyright: ignore[reportAssignmentType] entries.append(command.name) return " ".join(reversed(entries)) @@ -640,10 +642,10 @@ def parents(self) -> List[Group[CogT, ..., Any]]: .. versionadded:: 1.1 """ - entries = [] - command: Command[CogT, ..., Any] = self + entries: list[Group[CogT, ..., Any]] = [] + command: Group[CogT, ..., Any] = self # pyright: ignore[reportAssignmentType] while command.parent is not None: - command = command.parent # type: ignore + command = command.parent # pyright: ignore[reportAssignmentType] entries.append(command) return entries @@ -721,9 +723,9 @@ async def call_before_hooks(self, ctx: Context) -> None: # __self__ only exists for methods, not functions # however, if @command.before_invoke is used, it will be a function if instance: - await self._before_invoke(instance, ctx) # type: ignore + await self._before_invoke(instance, ctx) # pyright: ignore[reportCallIssue, reportArgumentType] else: - await self._before_invoke(ctx) # type: ignore + await self._before_invoke(ctx) # pyright: ignore[reportCallIssue] # call the cog local hook if applicable: if cog is not None: @@ -741,9 +743,9 @@ async def call_after_hooks(self, ctx: Context) -> None: if self._after_invoke is not None: instance = getattr(self._after_invoke, "__self__", cog) if instance: - await self._after_invoke(instance, ctx) # type: ignore + await self._after_invoke(instance, ctx) # pyright: ignore[reportCallIssue, reportArgumentType] else: - await self._after_invoke(ctx) # type: ignore + await self._after_invoke(ctx) # pyright: ignore[reportCallIssue] # call the cog local hook if applicable: if cog is not None: @@ -763,7 +765,7 @@ def _prepare_cooldowns(self, ctx: Context) -> None: if bucket is not None: # pyright: ignore[reportUnnecessaryComparison] retry_after = bucket.update_rate_limit(current) if retry_after: - raise CommandOnCooldown(bucket, retry_after, self._buckets.type) # type: ignore + raise CommandOnCooldown(bucket, retry_after, self._buckets.type) # pyright: ignore[reportArgumentType] async def prepare(self, ctx: Context) -> None: ctx.command = self @@ -773,7 +775,7 @@ async def prepare(self, ctx: Context) -> None: if self._max_concurrency is not None: # For this application, context can be duck-typed as a Message - await self._max_concurrency.acquire(ctx) # type: ignore + await self._max_concurrency.acquire(ctx) # pyright: ignore[reportArgumentType] try: if self.cooldown_after_parsing: @@ -786,7 +788,7 @@ async def prepare(self, ctx: Context) -> None: await self.call_before_hooks(ctx) except Exception: if self._max_concurrency is not None: - await self._max_concurrency.release(ctx) # type: ignore + await self._max_concurrency.release(ctx) # pyright: ignore[reportArgumentType] raise def is_on_cooldown(self, ctx: Context) -> bool: @@ -866,7 +868,7 @@ async def reinvoke(self, ctx: Context, *, call_hooks: bool = False) -> None: ctx.invoked_subcommand = None try: - await self.callback(*ctx.args, **ctx.kwargs) # type: ignore + await self.callback(*ctx.args, **ctx.kwargs) # pyright: ignore[reportCallIssue] except Exception: ctx.command_failed = True raise @@ -979,9 +981,11 @@ def short_doc(self) -> str: return self.help.split("\n", 1)[0] return "" - def _is_typing_optional(self, annotation: Union[T, Optional[T]]) -> TypeGuard[Optional[T]]: + def _is_typing_optional(self, annotation: object, /) -> bool: + # TODO: include types.UnionType; 'annotation' is TypeForm[object] + # TODO: use typing.get_origin/typing.get_args return ( - getattr(annotation, "__origin__", None) is Union and type(None) in annotation.__args__ # type: ignore + getattr(annotation, "__origin__", None) is Union and type(None) in annotation.__args__ # pyright: ignore[reportAttributeAccessIssue] ) @property @@ -1096,7 +1100,7 @@ async def can_run(self, ctx: Context) -> bool: # since we have no checks, then we just return True. return True - return await disnake.utils.async_all(predicate(ctx) for predicate in predicates) # type: ignore + return await disnake.utils.async_all(predicate(ctx) for predicate in predicates) # pyright: ignore[reportCallIssue] finally: ctx.command = original @@ -1255,7 +1259,7 @@ def get_command(self, name: str) -> Optional[Command[CogT, Any, Any]]: for name in names[1:]: try: - obj = obj.all_commands[name] # type: ignore + obj = obj.all_commands[name] # pyright: ignore[reportAttributeAccessIssue] except (AttributeError, KeyError): return None @@ -1424,7 +1428,8 @@ async def invoke(self, ctx: Context) -> None: injected = hooked_wrapped_callback(self, ctx, self.callback) await injected(*ctx.args, **ctx.kwargs) - ctx.invoked_parents.append(ctx.invoked_with) # type: ignore + assert ctx.invoked_with is not None + ctx.invoked_parents.append(ctx.invoked_with) if trigger and ctx.invoked_subcommand: ctx.invoked_with = trigger @@ -1456,7 +1461,7 @@ async def reinvoke(self, ctx: Context, *, call_hooks: bool = False) -> None: if early_invoke: try: - await self.callback(*ctx.args, **ctx.kwargs) # type: ignore + await self.callback(*ctx.args, **ctx.kwargs) # pyright: ignore[reportCallIssue] except Exception: ctx.command_failed = True raise @@ -1464,7 +1469,8 @@ async def reinvoke(self, ctx: Context, *, call_hooks: bool = False) -> None: if call_hooks: await self.call_after_hooks(ctx) - ctx.invoked_parents.append(ctx.invoked_with) # type: ignore + assert ctx.invoked_with is not None + ctx.invoked_parents.append(ctx.invoked_with) if trigger and ctx.invoked_subcommand: ctx.invoked_with = trigger @@ -1703,9 +1709,9 @@ def decorator( func.checks.append(predicate) else: if not hasattr(func, "__commands_checks__"): - func.__commands_checks__ = [] # type: ignore + func.__commands_checks__ = [] # pyright: ignore[reportAttributeAccessIssue] - func.__commands_checks__.append(predicate) # type: ignore + func.__commands_checks__.append(predicate) # pyright: ignore[reportAttributeAccessIssue] return func @@ -1713,13 +1719,13 @@ def decorator( decorator.predicate = predicate else: - @functools.wraps(predicate) # type: ignore + @functools.wraps(predicate) # pyright: ignore[reportArgumentType] async def wrapper(ctx): - return predicate(ctx) # type: ignore + return predicate(ctx) # pyright: ignore[reportCallIssue] decorator.predicate = wrapper - return decorator # type: ignore + return decorator # pyright: ignore[reportReturnType] def check_any(*checks: Check) -> Callable[[T], T]: @@ -1802,7 +1808,7 @@ def app_check(predicate: AppCheck) -> Callable[[T], T]: predicate: Callable[[:class:`disnake.ApplicationCommandInteraction`], :class:`bool`] The predicate to check if the command should be invoked. """ - return check(predicate) # type: ignore # impl is the same, typings are different + return check(predicate) # pyright: ignore[reportArgumentType] # impl is the same, typings are different def app_check_any(*checks: AppCheck) -> Callable[[T], T]: @@ -1826,7 +1832,7 @@ def app_check_any(*checks: AppCheck) -> Callable[[T], T]: decorator. """ try: - return check_any(*checks) # type: ignore # impl is the same, typings are different + return check_any(*checks) # pyright: ignore[reportArgumentType] # impl is the same, typings are different except TypeError as e: msg = str(e).replace("commands.check", "commands.app_check") # fix err message raise TypeError(msg) from None @@ -1864,10 +1870,12 @@ def predicate(ctx: AnyContext) -> bool: raise NoPrivateMessage # ctx.guild is None doesn't narrow ctx.author to Member + assert isinstance(ctx.author, disnake.Member) + if isinstance(item, int): - role = disnake.utils.get(ctx.author.roles, id=item) # type: ignore + role = disnake.utils.get(ctx.author.roles, id=item) else: - role = disnake.utils.get(ctx.author.roles, name=item) # type: ignore + role = disnake.utils.get(ctx.author.roles, name=item) if role is None: raise MissingRole(item) return True @@ -1912,14 +1920,16 @@ def predicate(ctx: AnyContext) -> bool: raise NoPrivateMessage # ctx.guild is None doesn't narrow ctx.author to Member - getter = functools.partial(disnake.utils.get, ctx.author.roles) # type: ignore + assert isinstance(ctx.author, disnake.Member) + + getter = functools.partial(disnake.utils.get, ctx.author.roles) if any( getter(id=item) is not None if isinstance(item, int) else getter(name=item) is not None for item in items ): return True # NOTE: variance problems - raise MissingAnyRole(list(items)) # type: ignore + raise MissingAnyRole(list(items)) # pyright: ignore[reportArgumentType] return check(predicate) @@ -2097,7 +2107,8 @@ def predicate(ctx: AnyContext) -> bool: permissions = ctx.permissions else: ch = ctx.channel - permissions = ch.permissions_for(ctx.author, ignore_timeout=False) # type: ignore + assert isinstance(ctx.author, disnake.Member) + permissions = ch.permissions_for(ctx.author, ignore_timeout=False) missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] @@ -2200,7 +2211,8 @@ def predicate(ctx: AnyContext) -> bool: permissions = ctx.app_permissions else: ch = ctx.channel - permissions = ch.permissions_for(ctx.me, ignore_timeout=False) # type: ignore + assert isinstance(ctx.me, disnake.Member) + permissions = ch.permissions_for(ctx.me, ignore_timeout=False) missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] @@ -2301,7 +2313,8 @@ def predicate(ctx: AnyContext) -> bool: if not ctx.guild: raise NoPrivateMessage - permissions = ctx.author.guild_permissions # type: ignore + assert isinstance(ctx.author, disnake.Member) + permissions = ctx.author.guild_permissions missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] if not missing: @@ -2398,7 +2411,8 @@ def predicate(ctx: AnyContext) -> bool: if not ctx.guild: raise NoPrivateMessage - permissions = ctx.me.guild_permissions # type: ignore + assert isinstance(ctx.me, disnake.Member) + permissions = ctx.me.guild_permissions missing = [perm for perm, value in perms.items() if getattr(permissions, perm) != value] if not missing: @@ -2496,7 +2510,7 @@ def pred(ctx: AnyContext) -> bool: and ch.is_nsfw() ): return True - raise NSFWChannelRequired(ch) # type: ignore + raise NSFWChannelRequired(ch) # pyright: ignore[reportArgumentType] return check(pred) @@ -2536,10 +2550,10 @@ def decorator( if hasattr(func, "__command_flag__"): func._buckets = CooldownMapping(Cooldown(rate, per), type) else: - func.__commands_cooldown__ = CooldownMapping(Cooldown(rate, per), type) # type: ignore + func.__commands_cooldown__ = CooldownMapping(Cooldown(rate, per), type) # pyright: ignore[reportAttributeAccessIssue] return func - return decorator # type: ignore + return decorator # pyright: ignore[reportReturnType] def dynamic_cooldown( @@ -2582,10 +2596,10 @@ def decorator( if hasattr(func, "__command_flag__"): func._buckets = DynamicCooldownMapping(cooldown, type) else: - func.__commands_cooldown__ = DynamicCooldownMapping(cooldown, type) # type: ignore + func.__commands_cooldown__ = DynamicCooldownMapping(cooldown, type) # pyright: ignore[reportAttributeAccessIssue] return func - return decorator # type: ignore + return decorator # pyright: ignore[reportReturnType] def max_concurrency( @@ -2621,10 +2635,10 @@ def decorator( if hasattr(func, "__command_flag__"): func._max_concurrency = value else: - func.__commands_max_concurrency__ = value # type: ignore + func.__commands_max_concurrency__ = value # pyright: ignore[reportAttributeAccessIssue] return func - return decorator # type: ignore + return decorator # pyright: ignore[reportReturnType] def before_invoke(coro) -> Callable[[T], T]: @@ -2671,10 +2685,10 @@ def decorator( if hasattr(func, "__command_flag__"): func.before_invoke(coro) else: - func.__before_invoke__ = coro # type: ignore + func.__before_invoke__ = coro # pyright: ignore[reportAttributeAccessIssue] return func - return decorator # type: ignore + return decorator # pyright: ignore[reportReturnType] def after_invoke(coro) -> Callable[[T], T]: @@ -2692,7 +2706,7 @@ def decorator( if hasattr(func, "__command_flag__"): func.after_invoke(coro) else: - func.__after_invoke__ = coro # type: ignore + func.__after_invoke__ = coro # pyright: ignore[reportAttributeAccessIssue] return func - return decorator # type: ignore + return decorator # pyright: ignore[reportReturnType] diff --git a/disnake/ext/commands/flag_converter.py b/disnake/ext/commands/flag_converter.py index fadfd65f6f..05c59ec2f6 100644 --- a/disnake/ext/commands/flag_converter.py +++ b/disnake/ext/commands/flag_converter.py @@ -349,7 +349,8 @@ async def tuple_convert_all( ) -> Tuple[Any, ...]: view = StringView(argument) results = [] - param: inspect.Parameter = ctx.current_parameter # type: ignore + assert ctx.current_parameter is not None + param: inspect.Parameter = ctx.current_parameter while not view.eof: view.skip_ws() if view.eof: @@ -376,7 +377,8 @@ async def tuple_convert_flag( ) -> Tuple[Any, ...]: view = StringView(argument) results = [] - param: inspect.Parameter = ctx.current_parameter # type: ignore + assert ctx.current_parameter is not None + param: inspect.Parameter = ctx.current_parameter for converter in converters: view.skip_ws() if view.eof: @@ -402,7 +404,8 @@ async def tuple_convert_flag( async def convert_flag(ctx: Context, argument: str, flag: Flag, annotation: Any = None) -> Any: - param: inspect.Parameter = ctx.current_parameter # type: ignore + assert ctx.current_parameter is not None + param: inspect.Parameter = ctx.current_parameter annotation = annotation or flag.annotation if origin := get_origin(annotation): args = get_args(annotation) diff --git a/disnake/ext/commands/help.py b/disnake/ext/commands/help.py index dbad617712..39a323489c 100644 --- a/disnake/ext/commands/help.py +++ b/disnake/ext/commands/help.py @@ -325,8 +325,8 @@ def __new__(cls, *args: Any, **kwargs: Any) -> Self: # The keys can be safely copied as-is since they're 99.99% certain of being # string keys deepcopy = copy.deepcopy - self.__original_kwargs__ = {k: deepcopy(v) for k, v in kwargs.items()} # type: ignore - self.__original_args__ = deepcopy(args) # type: ignore + self.__original_kwargs__ = {k: deepcopy(v) for k, v in kwargs.items()} # pyright: ignore[reportAttributeAccessIssue] + self.__original_args__ = deepcopy(args) # pyright: ignore[reportAttributeAccessIssue] return self def __init__(self, **options: Any) -> None: @@ -342,7 +342,7 @@ def __init__(self, **options: Any) -> None: self._command_impl: _HelpCommandImpl = _HelpCommandImpl(self, **self.command_attrs) def copy(self) -> Self: - obj = self.__class__(*self.__original_args__, **self.__original_kwargs__) # type: ignore + obj = self.__class__(*self.__original_args__, **self.__original_kwargs__) # pyright: ignore[reportAttributeAccessIssue] obj._command_impl = self._command_impl return obj @@ -429,14 +429,14 @@ def get_command_signature(self, command: Command[Any, ..., Any]) -> str: :class:`str` The signature for the command. """ - parent: Optional[Group[Any, ..., Any]] = command.parent # type: ignore + parent: Optional[Group[Any, ..., Any]] = command.parent # pyright: ignore[reportAssignmentType] entries = [] while parent is not None: if not parent.signature or parent.invoke_without_command: entries.append(parent.name) else: entries.append(f"{parent.name} {parent.signature}") - parent = parent.parent # type: ignore + parent = parent.parent # pyright: ignore[reportAssignmentType] parent_sig = " ".join(reversed(entries)) if len(command.aliases) > 0: @@ -878,7 +878,7 @@ async def command_callback(self, ctx: Context[BotT], *, command: Optional[str] = for key in keys[1:]: try: - found = cmd.all_commands.get(key) # type: ignore # cmd may be a Group here + found = cmd.all_commands.get(key) # pyright: ignore[reportAttributeAccessIssue] # cmd may be a Group here except AttributeError: string = await maybe_coro(self.subcommand_not_found, cmd, self.remove_mentions(key)) return await self.send_error_message(string) diff --git a/disnake/ext/commands/interaction_bot_base.py b/disnake/ext/commands/interaction_bot_base.py index 550b4ba935..747a79c4fd 100644 --- a/disnake/ext/commands/interaction_bot_base.py +++ b/disnake/ext/commands/interaction_bot_base.py @@ -1181,7 +1181,7 @@ def remove_app_command_check( def slash_command_check(self, func: T) -> T: """Similar to :meth:`.check` but for slash commands.""" # T was used instead of Check to ensure the type matches on return - self.add_app_command_check(func, slash_commands=True) # type: ignore + self.add_app_command_check(func, slash_commands=True) # pyright: ignore[reportArgumentType] return func def slash_command_check_once(self, func: CFT) -> CFT: @@ -1192,7 +1192,7 @@ def slash_command_check_once(self, func: CFT) -> CFT: def user_command_check(self, func: T) -> T: """Similar to :meth:`.check` but for user commands.""" # T was used instead of Check to ensure the type matches on return - self.add_app_command_check(func, user_commands=True) # type: ignore + self.add_app_command_check(func, user_commands=True) # pyright: ignore[reportArgumentType] return func def user_command_check_once(self, func: CFT) -> CFT: @@ -1203,7 +1203,7 @@ def user_command_check_once(self, func: CFT) -> CFT: def message_command_check(self, func: T) -> T: """Similar to :meth:`.check` but for message commands.""" # T was used instead of Check to ensure the type matches on return - self.add_app_command_check(func, message_commands=True) # type: ignore + self.add_app_command_check(func, message_commands=True) # pyright: ignore[reportArgumentType] return func def message_command_check_once(self, func: CFT) -> CFT: @@ -1405,12 +1405,12 @@ async def process_application_commands( # and the current command was registered to a guild and interaction.data.get("guild_id") # and we don't know the command - and not self.get_guild_command(interaction.guild_id, interaction.data.id) # type: ignore + and not self.get_guild_command(interaction.guild_id, interaction.data.id) # pyright: ignore[reportAttributeAccessIssue] ): # don't do anything if we aren't allowed to disable them if self._command_sync_flags.allow_command_deletion: try: - await self.bulk_overwrite_guild_commands(interaction.guild_id, []) # type: ignore + await self.bulk_overwrite_guild_commands(interaction.guild_id, []) # pyright: ignore[reportAttributeAccessIssue] except disnake.HTTPException: # for some reason we were unable to sync the command # either malformed API request, or some other error diff --git a/disnake/ext/commands/params.py b/disnake/ext/commands/params.py index 40d535b493..22d349a8c6 100644 --- a/disnake/ext/commands/params.py +++ b/disnake/ext/commands/params.py @@ -219,9 +219,9 @@ def __call__(self, *args: P.args, **kwargs: P.kwargs) -> T_: .. versionadded:: 2.6 """ if self._injected is not None: - return self.function(self._injected, *args, **kwargs) # type: ignore + return self.function(self._injected, *args, **kwargs) # pyright: ignore[reportCallIssue] else: - return self.function(*args, **kwargs) # type: ignore + return self.function(*args, **kwargs) # pyright: ignore[reportCallIssue] @classmethod def register( @@ -684,7 +684,7 @@ async def convert_argument(self, inter: ApplicationCommandInteraction, argument: def _parse_enum(self, annotation: Any) -> None: if isinstance(annotation, (EnumMeta, disnake.enums.EnumMeta)): self.choices = [ - OptionChoice(name, value.value) # type: ignore + OptionChoice(name, value.value) # pyright: ignore[reportAttributeAccessIssue] for name, value in annotation.__members__.items() ] else: @@ -1362,7 +1362,7 @@ def option_enum( choices = choices or kwargs first, *_ = choices.values() - return Enum("", choices, type=type(first)) # type: ignore + return Enum("", choices, type=type(first)) # pyright: ignore[reportReturnType] class ConverterMethod(classmethod): diff --git a/disnake/ext/commands/slash_core.py b/disnake/ext/commands/slash_core.py index 213af66291..b28badf1e7 100644 --- a/disnake/ext/commands/slash_core.py +++ b/disnake/ext/commands/slash_core.py @@ -382,7 +382,7 @@ async def invoke(self, inter: ApplicationCommandInteraction, *args: Any, **kwarg raise CommandInvokeError(exc) from exc finally: if self._max_concurrency is not None: - await self._max_concurrency.release(inter) # type: ignore + await self._max_concurrency.release(inter) # pyright: ignore[reportArgumentType] await self.call_after_hooks(inter) @@ -771,7 +771,7 @@ async def invoke(self, inter: ApplicationCommandInteraction) -> None: raise CommandInvokeError(exc) from exc finally: if self._max_concurrency is not None: - await self._max_concurrency.release(inter) # type: ignore + await self._max_concurrency.release(inter) # pyright: ignore[reportArgumentType] await self.call_after_hooks(inter) diff --git a/disnake/ext/tasks/__init__.py b/disnake/ext/tasks/__init__.py index 1026e4e11a..8d17e61191 100644 --- a/disnake/ext/tasks/__init__.py +++ b/disnake/ext/tasks/__init__.py @@ -552,7 +552,7 @@ def error(self, coro: ET) -> ET: if not iscoroutinefunction(coro): raise TypeError(f"Expected coroutine function, received {coro.__class__.__name__!r}.") - self._error = coro # type: ignore + self._error = coro # pyright: ignore[reportAttributeAccessIssue] return coro def _get_next_sleep_time(self) -> datetime.datetime: diff --git a/disnake/gateway.py b/disnake/gateway.py index 56ff150fc2..0656e65a7c 100644 --- a/disnake/gateway.py +++ b/disnake/gateway.py @@ -420,7 +420,7 @@ async def from_client( ws = cls(socket, loop=client.loop) # dynamically add attributes needed - ws.token = client.http.token # type: ignore + ws.token = client.http.token # pyright: ignore[reportAttributeAccessIssue] ws._connection = client._connection ws._discord_parsers = client._connection.parsers ws._dispatch = client.dispatch @@ -522,8 +522,8 @@ async def resume(self) -> None: """Sends the RESUME packet.""" # these should never be None if resuming, but instead of asserting # we just send those values and handle the INVALIDATE_SESSION - seq: int = self.sequence # type: ignore - session_id: str = self.session_id # type: ignore + seq: int = self.sequence # pyright: ignore[reportAssignmentType] + session_id: str = self.session_id # pyright: ignore[reportAssignmentType] payload: ResumeCommand = { "op": self.RESUME, @@ -633,7 +633,7 @@ async def received_message(self, raw_msg: Union[str, bytes], /) -> None: ) try: - func = self._discord_parsers[event] # type: ignore + func = self._discord_parsers[event] # pyright: ignore[reportArgumentType] except KeyError: _log.debug("Unknown event %s.", event) else: @@ -647,7 +647,7 @@ async def received_message(self, raw_msg: Union[str, bytes], /) -> None: if event in {"READY", "RESUMED"}: # exceptions in these events are fatal raise - event_name: str = event # type: ignore # event can't be None here + event_name: str = event # pyright: ignore[reportAssignmentType] # event can't be None here asyncio.create_task( self._dispatch_gateway_error(event_name, data, self.shard_id, e) ) diff --git a/disnake/guild.py b/disnake/guild.py index 82a683e7b8..998e0c9048 100644 --- a/disnake/guild.py +++ b/disnake/guild.py @@ -550,7 +550,7 @@ def _update_voice_state( self, data: GuildVoiceState, channel_id: Optional[int] ) -> Tuple[Optional[Member], VoiceState, VoiceState]: user_id = int(data["user_id"]) - channel: Optional[VocalGuildChannel] = self.get_channel(channel_id) # type: ignore + channel: Optional[VocalGuildChannel] = self.get_channel(channel_id) # pyright: ignore[reportAssignmentType, reportArgumentType] try: # check if we should remove the voice state from cache if channel is None: @@ -717,7 +717,7 @@ def _from_data(self, guild: GuildPayload) -> None: self_id = self._state.self_id for mdata in guild.get("members", []): # NOTE: Are we sure it's fine to not have the user part here? - member = Member(data=mdata, guild=self, state=state) # type: ignore + member = Member(data=mdata, guild=self, state=state) # pyright: ignore[reportArgumentType] if cache_joined or member.id == self_id: self._add_member(member) @@ -726,7 +726,7 @@ def _from_data(self, guild: GuildPayload) -> None: self.owner_id: Optional[int] = utils._get_as_snowflake(guild, "owner_id") self.afk_channel: Optional[VocalGuildChannel] = self.get_channel( - utils._get_as_snowflake(guild, "afk_channel_id") # type: ignore + utils._get_as_snowflake(guild, "afk_channel_id") # pyright: ignore[reportAttributeAccessIssue, reportArgumentType] ) for obj in guild.get("voice_states", []): @@ -742,14 +742,14 @@ def _sync(self, data: GuildPayload) -> None: user_id = int(presence["user"]["id"]) member = self.get_member(user_id) if member is not None: - member._presence_update(presence, empty_tuple) # type: ignore + member._presence_update(presence, empty_tuple) # pyright: ignore[reportArgumentType] if "channels" in data: channels = data["channels"] for c in channels: factory, _ = _guild_channel_factory(c["type"]) if factory: - self._add_channel(factory(guild=self, data=c, state=self._state)) # type: ignore + self._add_channel(factory(guild=self, data=c, state=self._state)) # pyright: ignore[reportArgumentType] if "threads" in data: threads = data["threads"] @@ -836,7 +836,7 @@ def me(self) -> Member: """ self_id = self._state.user.id # The self member is *always* cached - return self.get_member(self_id) # type: ignore + return self.get_member(self_id) # pyright: ignore[reportReturnType] @property def voice_client(self) -> Optional[VoiceProtocol]: @@ -892,7 +892,7 @@ def key(t: ByCategoryItem) -> Tuple[Tuple[int, int], List[GuildChannel]]: return ((k.position, k.id) if k else (-1, -1), v) _get = self._channels.get - as_list: List[ByCategoryItem] = [(_get(k), v) for k, v in grouped.items()] # type: ignore + as_list: List[ByCategoryItem] = [(_get(k), v) for k, v in grouped.items()] # pyright: ignore[reportAssignmentType, reportArgumentType] as_list.sort(key=key) for _, channels in as_list: channels.sort(key=lambda c: (c._sorting_bucket, c.position, c.id)) @@ -964,7 +964,7 @@ def system_channel(self) -> Optional[TextChannel]: If no channel is set, then this returns ``None``. """ channel_id = self._system_channel_id - return channel_id and self._channels.get(channel_id) # type: ignore + return channel_id and self._channels.get(channel_id) # pyright: ignore[reportReturnType] @property def system_channel_flags(self) -> SystemChannelFlags: @@ -981,7 +981,7 @@ def rules_channel(self) -> Optional[TextChannel]: .. versionadded:: 1.3 """ channel_id = self._rules_channel_id - return channel_id and self._channels.get(channel_id) # type: ignore + return channel_id and self._channels.get(channel_id) # pyright: ignore[reportReturnType] @property def public_updates_channel(self) -> Optional[TextChannel]: @@ -994,7 +994,7 @@ def public_updates_channel(self) -> Optional[TextChannel]: .. versionadded:: 1.4 """ channel_id = self._public_updates_channel_id - return channel_id and self._channels.get(channel_id) # type: ignore + return channel_id and self._channels.get(channel_id) # pyright: ignore[reportReturnType] @property def safety_alerts_channel(self) -> Optional[TextChannel]: @@ -1007,7 +1007,7 @@ def safety_alerts_channel(self) -> Optional[TextChannel]: .. versionadded:: 2.9 """ channel_id = self._safety_alerts_channel_id - return channel_id and self._channels.get(channel_id) # type: ignore + return channel_id and self._channels.get(channel_id) # pyright: ignore[reportReturnType] @property def emoji_limit(self) -> int: @@ -1103,7 +1103,7 @@ def get_role(self, role_id: int, /) -> Optional[Role]: def default_role(self) -> Role: """:class:`Role`: Gets the @everyone role that all members have by default.""" # The @everyone role is *always* given - return self.get_role(self.id) # type: ignore + return self.get_role(self.id) # pyright: ignore[reportReturnType] @property def premium_subscriber_role(self) -> Optional[Role]: @@ -1183,7 +1183,7 @@ def get_scheduled_event(self, event_id: int, /) -> Optional[GuildScheduledEvent] @property def owner(self) -> Optional[Member]: """Optional[:class:`Member`]: Returns the member that owns the guild.""" - return self.get_member(self.owner_id) # type: ignore + return self.get_member(self.owner_id) # pyright: ignore[reportArgumentType] @property def icon(self) -> Optional[Asset]: @@ -2542,7 +2542,7 @@ def convert(d: GuildChannelPayload) -> GuildChannel: channel = factory( guild=self, state=self._state, - data=d, # type: ignore + data=d, # pyright: ignore[reportArgumentType] ) return channel @@ -3099,11 +3099,16 @@ async def fetch_channel(self, channel_id: int, /) -> Union[GuildChannel, Thread] if ch_type in (ChannelType.group, ChannelType.private): raise InvalidData("Channel ID resolved to a private channel") - guild_id = int(data["guild_id"]) # type: ignore + assert "guild_id" in data + guild_id = int(data["guild_id"]) if self.id != guild_id: raise InvalidData("Guild ID resolved to a different guild") - channel: GuildChannel = factory(guild=self, state=self._state, data=data) # type: ignore + channel: GuildChannel = factory( # pyright: ignore[reportAssignmentType] + guild=self, + state=self._state, + data=data, # pyright: ignore[reportArgumentType] + ) return channel def bans( @@ -4922,7 +4927,7 @@ async def fetch_voice_state(self, member_id: int, /) -> VoiceState: data = await self._state.http.get_voice_state(self.id, member_id) channel_id = utils._get_as_snowflake(data, "channel_id") - channel: Optional[VocalGuildChannel] = self.get_channel(channel_id) # type: ignore + channel: Optional[VocalGuildChannel] = self.get_channel(channel_id) # pyright: ignore[reportAssignmentType, reportArgumentType] return VoiceState(data=data, channel=channel) async def change_voice_state( @@ -5641,9 +5646,9 @@ def add_role( actual_colour = colour or color or Colour.default() if isinstance(actual_colour, int): - data["color"] = actual_colour # type: ignore + data["color"] = actual_colour # pyright: ignore[reportGeneralTypeIssues] else: - data["color"] = actual_colour.value # type: ignore + data["color"] = actual_colour.value # pyright: ignore[reportGeneralTypeIssues] if hoist is not MISSING: data["hoist"] = hoist diff --git a/disnake/http.py b/disnake/http.py index 70e7f549ce..c3cfb506d5 100644 --- a/disnake/http.py +++ b/disnake/http.py @@ -221,7 +221,7 @@ def __exit__( # For some reason, the Discord voice websocket expects this header to be # completely lowercase while aiohttp respects spec and does it as case-insensitive -aiohttp.hdrs.WEBSOCKET = "websocket" # type: ignore +aiohttp.hdrs.WEBSOCKET = "websocket" # pyright: ignore[reportAttributeAccessIssue] class HTTPClient: @@ -260,7 +260,9 @@ def recreate(self) -> None: async def ws_connect(self, url: str, *, compress: int = 0) -> aiohttp.ClientWebSocketResponse: timeout = cast( "Any", - aiohttp.ClientWSTimeout(ws_close=30.0) if hasattr(aiohttp, "ClientWSTimeout") else 30.0, # type: ignore + aiohttp.ClientWSTimeout(ws_close=30.0) # pyright: ignore[reportCallIssue] + if hasattr(aiohttp, "ClientWSTimeout") + else 30.0, ) return await self.__session.ws_connect( url, diff --git a/disnake/integrations.py b/disnake/integrations.py index 0bd92a762c..1c852c8c58 100644 --- a/disnake/integrations.py +++ b/disnake/integrations.py @@ -246,7 +246,7 @@ def expire_behavior(self) -> ExpireBehaviour: @property def role(self) -> Optional[Role]: """Optional[:class:`Role`] The role which the integration uses for subscribers.""" - return self.guild.get_role(self._role_id) # type: ignore + return self.guild.get_role(self._role_id) # pyright: ignore[reportArgumentType] @deprecated() async def edit( diff --git a/disnake/interactions/application_command.py b/disnake/interactions/application_command.py index 3538c341c8..37d262675c 100644 --- a/disnake/interactions/application_command.py +++ b/disnake/interactions/application_command.py @@ -260,7 +260,7 @@ def __init__( self.resolved = InteractionDataResolved(data=data.get("resolved", {}), parent=parent) self.target_id: Optional[int] = utils._get_as_snowflake(data, "target_id") target = self.resolved.get_by_id(self.target_id) - self.target: Optional[Union[User, Member, Message]] = target # type: ignore + self.target: Optional[Union[User, Member, Message]] = target # pyright: ignore[reportAttributeAccessIssue] self.options: List[ApplicationCommandInteractionDataOption] = [ ApplicationCommandInteractionDataOption(data=d, resolved=self.resolved) @@ -300,9 +300,9 @@ def _get_focused_option(self) -> Optional[ApplicationCommandInteractionDataOptio @property def focused_option(self) -> ApplicationCommandInteractionDataOption: - """The focused option""" + """The focused option.""" # don't annotate as None for user experience - return self._get_focused_option() # type: ignore + return self._get_focused_option() # pyright: ignore[reportReturnType] class ApplicationCommandInteractionDataOption(Dict[str, Any]): diff --git a/disnake/interactions/base.py b/disnake/interactions/base.py index 0f2c2966f9..3fa4b5837c 100644 --- a/disnake/interactions/base.py +++ b/disnake/interactions/base.py @@ -87,6 +87,7 @@ ) from ..types.snowflake import Snowflake from ..types.user import User as UserPayload + from ..types.webhook import Webhook as WebhookPayload from ..ui._types import MessageComponents, ModalComponents, ModalTopLevelComponent from ..ui.modal import Modal from ..ui.view import View @@ -232,7 +233,7 @@ def __init__(self, *, data: InteractionPayload, state: ConnectionState) -> None: self.data: Mapping[str, Any] = data.get("data") or {} self._state: ConnectionState = state # TODO: Maybe use a unique session - self._session: ClientSession = state.http._HTTPClient__session # type: ignore + self._session: ClientSession = state.http._HTTPClient__session # pyright: ignore[reportAttributeAccessIssue] self.client: ClientT = cast("ClientT", state._get_client()) self._original_response: Optional[InteractionMessage] = None @@ -264,7 +265,7 @@ def __init__(self, *, data: InteractionPayload, state: ConnectionState) -> None: and guild_fallback.get_member(int(member["user"]["id"])) ) or Member( state=self._state, - guild=guild_fallback, # type: ignore # may be `Object` + guild=guild_fallback, # pyright: ignore[reportArgumentType] # may be `Object` data=member, ) self._permissions = int(member.get("permissions", 0)) @@ -377,7 +378,7 @@ def response(self) -> InteractionResponse: @utils.cached_slot_property("_cs_followup") def followup(self) -> Webhook: """:class:`Webhook`: Returns the follow up webhook for follow up interactions.""" - payload = { + payload: WebhookPayload = { "id": self.application_id, "type": WebhookType.application.value, "token": self.token, @@ -436,7 +437,7 @@ async def original_response(self) -> InteractionMessage: session=self._session, ) state = _InteractionMessageState(self, self._state) - message = InteractionMessage(state=state, channel=self.channel, data=data) # type: ignore + message = InteractionMessage(state=state, channel=self.channel, data=data) # pyright: ignore[reportArgumentType] self._original_response = message return message @@ -619,7 +620,7 @@ async def edit_original_response( # The message channel types should always match state = _InteractionMessageState(self, self._state) - message = InteractionMessage(state=state, channel=self.channel, data=data) # type: ignore + message = InteractionMessage(state=state, channel=self.channel, data=data) # pyright: ignore[reportArgumentType] if view and not view.is_finished(): self._state.store_view(view, message.id) @@ -1534,7 +1535,7 @@ async def send_modal( parent = self._parent if parent.type is InteractionType.modal_submit: - raise ModalChainNotSupported(parent) # type: ignore + raise ModalChainNotSupported(parent) # pyright: ignore[reportArgumentType] if self._response_type is not None: raise InteractionResponded(parent) @@ -1566,7 +1567,7 @@ async def send_modal( parent.token, session=parent._session, type=response_type.value, - data=modal_data, # type: ignore + data=modal_data, # pyright: ignore[reportArgumentType] ) self._response_type = response_type @@ -2052,7 +2053,7 @@ def __init__( self.members[user_id] = (guild and guild.get_member(user_id)) or Member( data=member, user_data=user, - guild=guild_fallback, # type: ignore + guild=guild_fallback, # pyright: ignore[reportArgumentType] state=state, ) else: @@ -2060,7 +2061,7 @@ def __init__( for str_id, role in roles.items(): self.roles[int(str_id)] = Role( - guild=guild_fallback, # type: ignore + guild=guild_fallback, # pyright: ignore[reportArgumentType] state=state, data=role, ) diff --git a/disnake/interactions/modal.py b/disnake/interactions/modal.py index 220725ed24..b18989cffe 100644 --- a/disnake/interactions/modal.py +++ b/disnake/interactions/modal.py @@ -233,7 +233,7 @@ def resolved_values(self) -> ResolvedValues[Union[str, Member, User, Role, AnyCh """ resolved_data = self.data.resolved # we expect the api to only provide valid values; there won't be any messages/attachments here. - return self._resolve_values(lambda id, type: resolved_data.get_with_type(id, type, str(id))) # type: ignore + return self._resolve_values(lambda id, type: resolved_data.get_with_type(id, type, str(id))) # pyright: ignore[reportReturnType] @cached_slot_property("_cs_text_values") def text_values(self) -> Dict[str, str]: diff --git a/disnake/invite.py b/disnake/invite.py index 5f7ea64e8a..3ca80a0124 100644 --- a/disnake/invite.py +++ b/disnake/invite.py @@ -438,7 +438,7 @@ def __init__( inviter_data = data.get("inviter") self.inviter: Optional[User] = ( - None if inviter_data is None else self._state.create_user(inviter_data) # type: ignore + None if inviter_data is None else self._state.create_user(inviter_data) # pyright: ignore[reportArgumentType] ) self.channel: Optional[InviteChannelType] = self._resolve_channel( @@ -455,14 +455,14 @@ def __init__( self.guild_welcome_screen: Optional[WelcomeScreen] = WelcomeScreen( state=self._state, data=guild_data["welcome_screen"], - guild=self.guild, # type: ignore + guild=self.guild, # pyright: ignore[reportArgumentType] ) else: self.guild_welcome_screen: Optional[WelcomeScreen] = None target_user_data = data.get("target_user") self.target_user: Optional[User] = ( - None if target_user_data is None else self._state.create_user(target_user_data) # type: ignore + None if target_user_data is None else self._state.create_user(target_user_data) # pyright: ignore[reportArgumentType] ) self.target_type: InviteTarget = try_enum(InviteTarget, data.get("target_type", 0)) @@ -517,8 +517,8 @@ def from_gateway(cls, *, state: ConnectionState, data: GatewayInvitePayload) -> state=state, data=data, # objects may be partial due to missing cache - guild=guild, # type: ignore - channel=channel, # type: ignore + guild=guild, # pyright: ignore[reportArgumentType] + channel=channel, # pyright: ignore[reportArgumentType] ) def _resolve_guild( diff --git a/disnake/iterators.py b/disnake/iterators.py index 8146380058..f095765ff8 100644 --- a/disnake/iterators.py +++ b/disnake/iterators.py @@ -304,16 +304,16 @@ def __init__( self._retrieve_messages = self._retrieve_messages_around_strategy if self.before and self.after: - self._filter = lambda m: self.after.id < int(m["id"]) < self.before.id # type: ignore + self._filter = lambda m: self.after.id < int(m["id"]) < self.before.id # pyright: ignore[reportOptionalMemberAccess] elif self.before: - self._filter = lambda m: int(m["id"]) < self.before.id # type: ignore + self._filter = lambda m: int(m["id"]) < self.before.id # pyright: ignore[reportOptionalMemberAccess] elif self.after: self._filter = lambda m: self.after.id < int(m["id"]) else: if self.reverse: self._retrieve_messages = self._retrieve_messages_after_strategy if self.before: - self._filter = lambda m: int(m["id"]) < self.before.id # type: ignore + self._filter = lambda m: int(m["id"]) < self.before.id # pyright: ignore[reportOptionalMemberAccess] else: self._retrieve_messages = self._retrieve_messages_before_strategy if self.after and self.after != OLDEST_OBJECT: @@ -527,7 +527,7 @@ def __init__( if oldest_first: self._strategy = self._after_strategy if self.before: - self._filter = lambda m: int(m["id"]) < self.before.id # type: ignore + self._filter = lambda m: int(m["id"]) < self.before.id # pyright: ignore[reportOptionalMemberAccess] else: self._strategy = self._before_strategy if self.after and self.after != OLDEST_OBJECT: @@ -707,7 +707,7 @@ def __init__( self.reverse = True self._retrieve_guilds = self._retrieve_guilds_before_strategy if self.after: - self._filter = lambda m: int(m["id"]) > self.after.id # type: ignore + self._filter = lambda m: int(m["id"]) > self.after.id # pyright: ignore[reportOptionalMemberAccess, reportUnknownLambdaType] else: self.reverse = False self._retrieve_guilds = self._retrieve_guilds_after_strategy @@ -895,7 +895,7 @@ def get_archive_timestamp(data: ThreadPayload) -> str: @staticmethod def get_thread_id(data: ThreadPayload) -> str: - return data["id"] # type: ignore + return data["id"] # pyright: ignore[reportReturnType] async def fill_queue(self) -> None: if not self.has_more: @@ -1083,7 +1083,7 @@ def __init__( if oldest_first: self._strategy = self._after_strategy if self.before: - self._filter = lambda m: int(m["id"]) < self.before.id # type: ignore + self._filter = lambda m: int(m["id"]) < self.before.id # pyright: ignore[reportOptionalMemberAccess] else: self._strategy = self._before_strategy if self.after and self.after != OLDEST_OBJECT: diff --git a/disnake/member.py b/disnake/member.py index fb05bffbc2..9810a36a01 100644 --- a/disnake/member.py +++ b/disnake/member.py @@ -190,12 +190,12 @@ def generate_function(x: str) -> Callable[..., Any]: # We want sphinx to properly show coroutine functions as coroutines if utils.iscoroutinefunction(value): # noqa: B023 - async def general(self, *args, **kwargs): # type: ignore + async def general(self, *args: Any, **kwargs: Any) -> Any: # pyright: ignore[reportRedeclaration] return await getattr(self._user, x)(*args, **kwargs) else: - def general(self, *args, **kwargs): + def general(self, *args: Any, **kwargs: Any) -> Any: return getattr(self._user, x)(*args, **kwargs) general.__name__ = x @@ -372,11 +372,11 @@ def __hash__(self) -> int: @classmethod def _from_message(cls, *, message: Message, data: MemberPayload) -> Self: - user_data = message.author._to_minimal_user_json() # type: ignore + user_data = message.author._to_minimal_user_json() # pyright: ignore[reportAttributeAccessIssue] return cls( data=data, user_data=user_data, - guild=message.guild, # type: ignore + guild=message.guild, # pyright: ignore[reportArgumentType] state=message._state, ) @@ -453,7 +453,7 @@ def _presence_update( ) -> Optional[Tuple[User, User]]: self.activities = tuple(create_activity(a, state=self._state) for a in data["activities"]) self._client_status = { - sys.intern(key): sys.intern(value) # type: ignore + sys.intern(key): sys.intern(value) # pyright: ignore[reportArgumentType] for key, value in data.get("client_status", {}).items() } self._client_status[None] = sys.intern(data["status"]) @@ -835,12 +835,12 @@ async def ban( Bans this member. Equivalent to :meth:`Guild.ban`. """ - await self.guild.ban( # type: ignore # no matching overload + await self.guild.ban( self, reason=reason, clean_history_duration=clean_history_duration, delete_message_days=delete_message_days, - ) + ) # pyright: ignore[reportCallIssue] # no matching overload async def unban(self, *, reason: Optional[str] = None) -> None: """|coro| diff --git a/disnake/mentions.py b/disnake/mentions.py index a5d867bc47..b72a3e4ed5 100644 --- a/disnake/mentions.py +++ b/disnake/mentions.py @@ -108,8 +108,9 @@ def from_message(cls, message: Message) -> Self: return cls( everyone=message.mention_everyone, - users=message.mentions.copy(), # type: ignore # mentions is a list of Snowflakes - roles=message.role_mentions.copy(), # type: ignore # mentions is a list of Snowflakes + # TODO: casting to list fixes those + users=message.mentions.copy(), # pyright: ignore[reportArgumentType] # mentions is a list of Snowflakes + roles=message.role_mentions.copy(), # pyright: ignore[reportArgumentType] # mentions is a list of Snowflakes replied_user=bool( message.type is MessageType.reply and message.reference @@ -120,11 +121,12 @@ def from_message(cls, message: Message) -> Self: def to_dict(self) -> AllowedMentionsPayload: parse: List[AllowedMentionTypePayload] = [] - data: AllowedMentionsPayload = {} # type: ignore + data: AllowedMentionsPayload = {"parse": parse} # pyright: ignore[reportAssignmentType] if self.everyone: parse.append("everyone") + # NOTE: not using 'is True/False' because of _FakeBool if self.users == True: # noqa: E712 parse.append("users") elif self.users != False: # noqa: E712 @@ -138,7 +140,6 @@ def to_dict(self) -> AllowedMentionsPayload: if self.replied_user: data["replied_user"] = True - data["parse"] = parse return data def merge(self, other: AllowedMentions) -> AllowedMentions: diff --git a/disnake/message.py b/disnake/message.py index ab6d47aaf2..f7ac782783 100644 --- a/disnake/message.py +++ b/disnake/message.py @@ -576,7 +576,8 @@ def __repr__(self) -> str: def id(self) -> int: """:class:`int`: The message ID of the deleted referenced message.""" # the parent's message id won't be None here - return self._parent.message_id # type: ignore + assert self._parent.message_id is not None + return self._parent.message_id @property def channel_id(self) -> int: @@ -1187,7 +1188,7 @@ def __init__( self.activity: Optional[MessageActivityPayload] = data.get("activity") # for user experience, on_message has no business getting partials # TODO: Subscripted message to include the channel - self.channel: Union[GuildMessageable, DMChannel, GroupChannel] = channel # type: ignore + self.channel: Union[GuildMessageable, DMChannel, GroupChannel] = channel # pyright: ignore[reportAttributeAccessIssue] self.position: Optional[int] = data.get("position", None) self._edited_timestamp: Optional[datetime.datetime] = utils.parse_time( data["edited_timestamp"] @@ -1213,7 +1214,7 @@ def __init__( try: # if the channel doesn't have a guild attribute, we handle that - self.guild = channel.guild # type: ignore + self.guild = channel.guild # pyright: ignore[reportAttributeAccessIssue] except AttributeError: self.guild = state._get_guild(utils._get_as_snowflake(data, "guild_id")) @@ -1252,7 +1253,11 @@ def __init__( chan, _ = state._get_guild_channel(resolved) # the channel will be the correct type here - ref.resolved = self.__class__(channel=chan, data=resolved, state=state) # type: ignore + ref.resolved = self.__class__( + channel=chan, # pyright: ignore[reportArgumentType] + data=resolved, + state=state, + ) _ref = data.get("message_reference", {}) self.message_snapshots: List[ForwardedMessage] = [ @@ -1267,7 +1272,7 @@ def __init__( for handler in ("author", "member", "mentions", "mention_roles"): if handler in data: - getattr(self, f"_handle_{handler}")(data[handler]) # type: ignore + getattr(self, f"_handle_{handler}")(data[handler]) # pyright: ignore[reportTypedDictNotRequiredAccess] def __repr__(self) -> str: name = self.__class__.__name__ @@ -1412,7 +1417,7 @@ def _handle_member(self, member: MemberPayload) -> None: author = self.author try: # Update member reference - author._update_from_message(member) # type: ignore + author._update_from_message(member) # pyright: ignore[reportAttributeAccessIssue] except AttributeError: # It's a user here # TODO: consider adding to cache here @@ -1696,7 +1701,7 @@ def system_content(self) -> Optional[str]: if self.type is MessageType.guild_stream: # the author will be a Member - return f"{self.author.name} is live! Now streaming {self.author.activity.name}." # type: ignore + return f"{self.author.name} is live! Now streaming {self.author.activity.name}." # pyright: ignore[reportOptionalMemberAccess, reportAttributeAccessIssue] if self.type is MessageType.guild_discovery_disqualified: return "This server has been removed from Server Discovery because it no longer passes all the requirements. Check Server Settings for more details." @@ -1723,7 +1728,7 @@ def system_content(self) -> Optional[str]: return "Sorry, we couldn't load the first message in this thread" # the resolved message for the reference will be a Message - return self.reference.resolved.content # type: ignore + return self.reference.resolved.content # pyright: ignore[reportAttributeAccessIssue] if self.type is MessageType.guild_invite_reminder: # todo: determine if this should be the owner content or the user content @@ -2569,7 +2574,7 @@ class PartialMessage(Hashable): __slots__ = ("channel", "id", "_cs_guild", "_state") - jump_url: str = Message.jump_url # type: ignore + jump_url = Message.jump_url delete = Message.delete publish = Message.publish pin = Message.pin @@ -2604,7 +2609,7 @@ def __init__(self, *, channel: MessageableChannel, id: int) -> None: self._state: ConnectionState = channel._state self.id: int = id - def _update(self, data) -> None: + def _update(self, data: Any) -> None: # This is used for duck typing purposes. # Just do nothing with the data. pass @@ -2957,7 +2962,7 @@ def __init__( self.content: str = data["content"] self.embeds: List[Embed] = [Embed.from_dict(a) for a in data["embeds"]] # should never be None in message_reference(s) that are forwarding - self.channel_id: int = channel_id # type: ignore + self.channel_id: int = channel_id # pyright: ignore[reportAttributeAccessIssue] self.attachments: List[Attachment] = [ Attachment(data=a, state=state) for a in data["attachments"] ] diff --git a/disnake/opus.py b/disnake/opus.py index b68c17ce34..c5498fe68d 100644 --- a/disnake/opus.py +++ b/disnake/opus.py @@ -211,7 +211,7 @@ def libopus_loader(name: str) -> Any: try: if item[1]: - func.argtypes = item[1] # type: ignore + func.argtypes = item[1] # pyright: ignore[reportAttributeAccessIssue] func.restype = item[2] except KeyError: @@ -354,7 +354,7 @@ def __del__(self) -> None: if hasattr(self, "_state"): _lib.opus_encoder_destroy(self._state) # This is a destructor, so it's okay to assign None - self._state = None # type: ignore + self._state = None # pyright: ignore[reportAttributeAccessIssue] def _create_state(self) -> EncoderStruct: ret = ctypes.c_int() @@ -395,7 +395,7 @@ def set_expected_packet_loss_percent(self, percentage: float) -> None: def encode(self, pcm: bytes, frame_size: int) -> bytes: max_data_bytes = len(pcm) # bytes can be used to reference pointer - pcm_ptr = ctypes.cast(pcm, c_int16_ptr) # type: ignore + pcm_ptr = ctypes.cast(pcm, c_int16_ptr) # pyright: ignore[reportArgumentType] data = (ctypes.c_char * max_data_bytes)() ret = _lib.opus_encode(self._state, pcm_ptr, frame_size, data, max_data_bytes) @@ -413,7 +413,7 @@ def __del__(self) -> None: if hasattr(self, "_state"): _lib.opus_decoder_destroy(self._state) # This is a destructor, so it's okay to assign None - self._state = None # type: ignore + self._state = None # pyright: ignore[reportAttributeAccessIssue] def _create_state(self) -> DecoderStruct: ret = ctypes.c_int() diff --git a/disnake/player.py b/disnake/player.py index 5117896e12..bea52c1330 100644 --- a/disnake/player.py +++ b/disnake/player.py @@ -158,7 +158,8 @@ def __init__( kwargs.update(subprocess_kwargs) self._process: subprocess.Popen[bytes] = self._spawn_process(args, **kwargs) - self._stdout: IO[bytes] = self._process.stdout # type: ignore + assert self._process.stdout is not None + self._stdout: IO[bytes] = self._process.stdout self._stdin: Optional[IO[bytes]] = None self._pipe_thread: Optional[threading.Thread] = None @@ -172,7 +173,7 @@ def __init__( def _spawn_process(self, args: Any, **subprocess_kwargs: Any) -> subprocess.Popen[bytes]: try: - return subprocess.Popen(args, creationflags=CREATE_NO_WINDOW, **subprocess_kwargs) # type: ignore + return subprocess.Popen(args, creationflags=CREATE_NO_WINDOW, **subprocess_kwargs) # pyright: ignore[reportReturnType] except FileNotFoundError: executable = args.partition(" ")[0] if isinstance(args, str) else args[0] raise ClientException(f"{executable} was not found.") from None @@ -212,7 +213,7 @@ def _kill_process(self) -> None: ) def _pipe_writer(self, source: io.BufferedIOBase) -> None: - assert self._stdin # noqa: S101 # TODO: remove this ignore (didn't want to touch this) + assert self._stdin is not None while self._process: # arbitrarily large read size data = source.read(8192) @@ -503,7 +504,8 @@ def custom_probe(source, executable): """ executable = kwargs.get("executable") codec, bitrate = await cls.probe(source, method=method, executable=executable) - return cls(source, bitrate=bitrate, codec=codec, **kwargs) # type: ignore + assert bitrate is not None + return cls(source, bitrate=bitrate, codec=codec, **kwargs) @classmethod async def probe( @@ -691,7 +693,7 @@ def cleanup(self) -> None: def read(self) -> bytes: ret = self.original.read() - return audioop.mul(ret, 2, min(self._volume, 2.0)) # type: ignore[reportPossiblyUnboundVariable] + return audioop.mul(ret, 2, min(self._volume, 2.0)) # pyright: ignore[reportPossiblyUnboundVariable] class AudioPlayer(threading.Thread): diff --git a/disnake/poll.py b/disnake/poll.py index 39f4140945..baab6f5e74 100644 --- a/disnake/poll.py +++ b/disnake/poll.py @@ -380,10 +380,12 @@ def from_dict( return poll + # TODO: why is this private? other models' to_dict is not def _to_dict(self) -> PollCreatePayload: + assert self.duration is not None payload: PollCreatePayload = { "question": self.question._to_dict(), - "duration": (int(self.duration.total_seconds()) // 3600), # type: ignore + "duration": int(self.duration.total_seconds()) // 3600, "allow_multiselect": self.allow_multiselect, "layout_type": self.layout_type.value, "answers": [answer._to_dict() for answer in self._answers.values()], diff --git a/disnake/reaction.py b/disnake/reaction.py index 0720759f6a..da68f1408e 100644 --- a/disnake/reaction.py +++ b/disnake/reaction.py @@ -65,9 +65,9 @@ def __init__( ) -> None: self.message: Message = message # _get_emoji_from_data won't return None - self.emoji: Union[PartialEmoji, Emoji, str] = emoji or message._state._get_emoji_from_data( # type: ignore + self.emoji: Union[PartialEmoji, Emoji, str] = emoji or message._state._get_emoji_from_data( data["emoji"] - ) + ) # pyright: ignore[reportAttributeAccessIssue] self.count: int = data.get("count", 1) self.me: bool = data["me"] diff --git a/disnake/shard.py b/disnake/shard.py index c17a05400d..c6f0594c56 100644 --- a/disnake/shard.py +++ b/disnake/shard.py @@ -111,7 +111,8 @@ def __init__( @property def id(self) -> int: # DiscordWebSocket.shard_id is set in the from_client classmethod - return self.ws.shard_id # type: ignore + assert self.ws.shard_id is not None + return self.ws.shard_id def launch(self) -> None: self._task = self.loop.create_task(self.worker()) @@ -398,8 +399,10 @@ def _get_websocket( self, guild_id: Optional[int] = None, *, shard_id: Optional[int] = None ) -> DiscordWebSocket: if shard_id is None: - # guild_id won't be None if shard_id is None and shard_count won't be None here - shard_id = (guild_id >> 22) % self.shard_count # type: ignore + # guild_id and shard_count won't be None if shard_id is None here + assert guild_id is not None + assert self.shard_count is not None + shard_id = (guild_id >> 22) % self.shard_count return self.__shards[shard_id].ws def _get_state(self, **options: Any) -> AutoShardedConnectionState: @@ -611,7 +614,7 @@ async def change_presence( continue # Member.activities is typehinted as Tuple[ActivityType, ...], we may be setting it as Tuple[BaseActivity, ...] - me.activities = activities # type: ignore + me.activities = activities # pyright: ignore[reportAttributeAccessIssue] me.status = status_enum def is_ws_ratelimited(self) -> bool: diff --git a/disnake/soundboard.py b/disnake/soundboard.py index 0d1d701dac..a609664549 100644 --- a/disnake/soundboard.py +++ b/disnake/soundboard.py @@ -228,7 +228,7 @@ def __repr__(self) -> str: def guild(self) -> Guild: """:class:`Guild`: The guild that this sound is from.""" # this will most likely never return None - return self._state._get_guild(self.guild_id) # type: ignore + return self._state._get_guild(self.guild_id) # pyright: ignore[reportReturnType] async def edit( self, diff --git a/disnake/stage_instance.py b/disnake/stage_instance.py index deff882916..ddcad6f025 100644 --- a/disnake/stage_instance.py +++ b/disnake/stage_instance.py @@ -97,7 +97,7 @@ def created_at(self) -> datetime.datetime: def channel(self) -> Optional[StageChannel]: """Optional[:class:`StageChannel`]: The channel that stage instance is running in.""" # the returned channel will always be a StageChannel or None - return self._state.get_channel(self.channel_id) # type: ignore + return self._state.get_channel(self.channel_id) # pyright: ignore[reportReturnType] @property def discoverable_disabled(self) -> bool: diff --git a/disnake/state.py b/disnake/state.py index 06c8400d02..247290b1e3 100644 --- a/disnake/state.py +++ b/disnake/state.py @@ -376,7 +376,7 @@ def voice_clients(self) -> List[VoiceProtocol]: def _get_voice_client(self, guild_id: Optional[int]) -> Optional[VoiceProtocol]: # the keys of self._voice_clients are ints - return self._voice_clients.get(guild_id) # type: ignore + return self._voice_clients.get(guild_id) # pyright: ignore[reportArgumentType] def _add_voice_client(self, guild_id: int, voice: VoiceProtocol) -> None: self._voice_clients[guild_id] = voice @@ -386,7 +386,7 @@ def _remove_voice_client(self, guild_id: int) -> None: def _update_references(self, ws: DiscordWebSocket) -> None: for vc in self.voice_clients: - vc.main_ws = ws # type: ignore + vc.main_ws = ws # pyright: ignore[reportAttributeAccessIssue] def store_user(self, data: UserPayload) -> User: user_id = int(data["id"]) @@ -403,11 +403,12 @@ def create_user(self, data: UserPayload) -> User: def get_user(self, id: Optional[int]) -> Optional[User]: # the keys of self._users are ints - return self._users.get(id) # type: ignore + return self._users.get(id) # pyright: ignore[reportArgumentType] def store_emoji(self, guild: Guild, data: EmojiPayload) -> Emoji: # the id will be present here - emoji_id = int(data["id"]) # type: ignore + assert data["id"] is not None + emoji_id = int(data["id"]) self._emojis[emoji_id] = emoji = Emoji(guild=guild, state=self, data=data) return emoji @@ -544,15 +545,15 @@ def soundboard_sounds(self) -> List[GuildSoundboardSound]: def get_emoji(self, emoji_id: Optional[int]) -> Optional[Emoji]: # the keys of self._emojis are ints - return self._emojis.get(emoji_id) # type: ignore + return self._emojis.get(emoji_id) # pyright: ignore[reportArgumentType] def get_sticker(self, sticker_id: Optional[int]) -> Optional[GuildSticker]: # the keys of self._stickers are ints - return self._stickers.get(sticker_id) # type: ignore + return self._stickers.get(sticker_id) # pyright: ignore[reportArgumentType] def get_soundboard_sound(self, sound_id: Optional[int]) -> Optional[GuildSoundboardSound]: # the keys of self._soundboard_sounds are ints - return self._soundboard_sounds.get(sound_id) # type: ignore + return self._soundboard_sounds.get(sound_id) # pyright: ignore[reportArgumentType] @property def private_channels(self) -> List[PrivateChannel]: @@ -561,16 +562,16 @@ def private_channels(self) -> List[PrivateChannel]: def _get_private_channel(self, channel_id: Optional[int]) -> Optional[PrivateChannel]: try: # the keys of self._private_channels are ints - value = self._private_channels[channel_id] # type: ignore + value = self._private_channels[channel_id] # pyright: ignore[reportArgumentType] except KeyError: return None else: - self._private_channels.move_to_end(channel_id) # type: ignore + self._private_channels.move_to_end(channel_id) # pyright: ignore[reportArgumentType] return value def _get_private_channel_by_user(self, user_id: Optional[int]) -> Optional[DMChannel]: # the keys of self._private_channels are ints - return self._private_channels_by_user.get(user_id) # type: ignore + return self._private_channels_by_user.get(user_id) # pyright: ignore[reportArgumentType] def _add_private_channel(self, channel: PrivateChannel) -> None: channel_id = channel.id @@ -606,7 +607,7 @@ def _get_message(self, msg_id: Optional[int]) -> Optional[Message]: def _add_guild_from_data(self, data: Union[GuildPayload, UnavailableGuildPayload]) -> Guild: guild = Guild( - data=data, # type: ignore # may be unavailable guild + data=data, # pyright: ignore[reportArgumentType] # may be unavailable guild state=self, ) self._add_guild(guild) @@ -754,7 +755,7 @@ def parse_ready(self, data: gateway.ReadyEvent) -> None: self.clear(views=False, application_commands=False, modals=False) self.user = ClientUser(state=self, data=data["user"]) # self._users is a list of Users, we're setting a ClientUser - self._users[self.user.id] = self.user # type: ignore + self._users[self.user.id] = self.user # pyright: ignore[reportArgumentType] try: application = data["application"] @@ -784,7 +785,7 @@ def parse_application_command_permissions_update( def parse_message_create(self, data: gateway.MessageCreateEvent) -> None: channel, _ = self._get_guild_channel(data) # channel would be the correct type here - message = Message(channel=channel, data=data, state=self) # type: ignore + message = Message(channel=channel, data=data, state=self) # pyright: ignore[reportArgumentType] self.dispatch("message", message) if self._messages is not None: self._messages.append(message) @@ -792,7 +793,7 @@ def parse_message_create(self, data: gateway.MessageCreateEvent) -> None: if channel: # we ensure that the channel is a type that implements last_message_id if channel.__class__ in (TextChannel, Thread, VoiceChannel, StageChannel): - channel.last_message_id = message.id # type: ignore + channel.last_message_id = message.id # pyright: ignore[reportAttributeAccessIssue] # Essentially, messages *don't* count towards message_count, if: # - they're the thread starter message # - or, they're the initial message of a forum channel thread (which uses MessageType.default) @@ -800,12 +801,12 @@ def parse_message_create(self, data: gateway.MessageCreateEvent) -> None: if channel.__class__ is Thread and not ( message.type is MessageType.thread_starter_message or ( - type(channel.parent) in (ForumChannel, MediaChannel) # type: ignore + type(channel.parent) in (ForumChannel, MediaChannel) # pyright: ignore[reportAttributeAccessIssue] and channel.id == message.id ) ): - channel.total_message_sent += 1 # type: ignore - channel.message_count += 1 # type: ignore + channel.total_message_sent += 1 # pyright: ignore[reportAttributeAccessIssue] + channel.message_count += 1 # pyright: ignore[reportAttributeAccessIssue] def parse_message_delete(self, data: gateway.MessageDeleteEvent) -> None: raw = RawMessageDeleteEvent(data) @@ -844,9 +845,10 @@ def parse_message_delete_bulk(self, data: gateway.MessageDeleteBulkEvent) -> Non thread.message_count = max(0, thread.message_count - to_subtract) if found_messages: self.dispatch("bulk_message_delete", found_messages) + # self._messages won't be None here + assert self._messages is not None for msg in found_messages: - # self._messages won't be None here - self._messages.remove(msg) # type: ignore + self._messages.remove(msg) def parse_message_update(self, data: gateway.MessageUpdateEvent) -> None: raw = RawMessageUpdateEvent(data) @@ -873,7 +875,7 @@ def parse_message_reaction_add(self, data: gateway.MessageReactionAddEvent) -> N self, id=emoji_id, animated=emoji.get("animated", False), - name=emoji["name"], # type: ignore + name=emoji["name"], # pyright: ignore[reportArgumentType] ) raw = RawReactionActionEvent(data, emoji, "REACTION_ADD") @@ -919,7 +921,7 @@ def parse_message_reaction_remove(self, data: gateway.MessageReactionRemoveEvent animated=emoji.get("animated", False), # may be `None` in gateway events if custom emoji data isn't available anymore # https://discord.com/developers/docs/resources/emoji#emoji-object-custom-emoji-examples - name=emoji["name"], # type: ignore + name=emoji["name"], # pyright: ignore[reportArgumentType] ) raw = RawReactionActionEvent(data, emoji, "REACTION_REMOVE") self.dispatch("raw_reaction_remove", raw) @@ -947,7 +949,7 @@ def parse_message_reaction_remove_emoji( animated=emoji.get("animated", False), # may be `None` in gateway events if custom emoji data isn't available anymore # https://discord.com/developers/docs/resources/emoji#emoji-object-custom-emoji-examples - name=emoji["name"], # type: ignore + name=emoji["name"], # pyright: ignore[reportArgumentType] ) raw = RawReactionClearEmojiEvent(data, emoji) self.dispatch("raw_reaction_clear_emoji", raw) @@ -1094,7 +1096,7 @@ def parse_channel_update(self, data: gateway.ChannelUpdateEvent) -> None: channel = self._get_private_channel(channel_id) old_channel = copy.copy(channel) # the channel is a GroupChannel - channel._update_group(data) # type: ignore + channel._update_group(data) # pyright: ignore[reportOptionalMemberAccess, reportAttributeAccessIssue] self.dispatch("private_channel_update", old_channel, channel) return @@ -1106,7 +1108,7 @@ def parse_channel_update(self, data: gateway.ChannelUpdateEvent) -> None: old_channel = copy.copy(channel) channel._update( guild, - data, # type: ignore # data type will always match channel type + data, # pyright: ignore[reportArgumentType] # data type will always match channel type ) self.dispatch("guild_channel_update", old_channel, channel) else: @@ -1130,7 +1132,7 @@ def parse_channel_create(self, data: gateway.ChannelCreateEvent) -> None: channel = factory( guild=guild, state=self, - data=data, # type: ignore # data type will always match channel type + data=data, # pyright: ignore[reportArgumentType] # data type will always match channel type ) guild._add_channel(channel) self.dispatch("guild_channel_create", channel) @@ -1178,8 +1180,8 @@ def parse_thread_create(self, data: gateway.ThreadCreateEvent) -> None: guild._add_thread(thread) if not has_thread: if data.get("newly_created"): - if type(thread.parent) in (ForumChannel, MediaChannel): - thread.parent.last_thread_id = thread.id # type: ignore + if isinstance(thread.parent, (ForumChannel, MediaChannel)): + thread.parent.last_thread_id = thread.id self.dispatch("thread_create", thread) else: @@ -1429,7 +1431,7 @@ def _get_create_guild(self, data: gateway.GuildCreateEvent) -> Guild: guild = self._get_guild(int(data["id"])) if guild is not None: guild.unavailable = False - guild._from_data(data) # type: ignore # data type not narrowed correctly to full guild + guild._from_data(data) # pyright: ignore[reportArgumentType] # data type not narrowed correctly to full guild return guild return self._add_guild_from_data(data) @@ -2139,7 +2141,7 @@ def _get_emoji_from_data( self, # This may be `None` when custom emoji data in reactions isn't available. # Should generally be fine, since we have an id at this point. - name=data["name"], # type: ignore + name=data["name"], # pyright: ignore[reportArgumentType] id=emoji_id, animated=data.get("animated", False), ) @@ -2227,18 +2229,22 @@ def _get_partial_interaction_channel( ) if ch_type in (ChannelType.group, ChannelType.private): - return ( + return ( # pyright: ignore[reportReturnType] self._get_private_channel(channel_id) # the factory will be a DMChannel or GroupChannel here - or factory(me=self.user, data=data, state=self) # type: ignore + or factory( # pyright: ignore[reportCallIssue] + me=self.user, # pyright: ignore[reportCallIssue] + data=data, # pyright: ignore[reportArgumentType] + state=self, + ) ) # the factory can't be a DMChannel or GroupChannel here - data.setdefault("position", 0) # type: ignore + data.setdefault("position", 0) # pyright: ignore[reportArgumentType, reportCallIssue] return (isinstance(guild, Guild) and guild.get_channel_or_thread(channel_id)) or factory( - guild=guild, # type: ignore # FIXME: create proper fallback guild instead of passing Object + guild=guild, # pyright: ignore[reportArgumentType, reportCallIssue] # FIXME: create proper fallback guild instead of passing Object state=self, - data=data, # type: ignore # generic payload type + data=data, # pyright: ignore[reportArgumentType] # generic payload type ) def get_channel(self, id: Optional[int]) -> Optional[Union[Channel, Thread]]: @@ -2274,22 +2280,23 @@ async def fetch_global_commands( *, with_localizations: bool = True, ) -> List[APIApplicationCommand]: + assert self.application_id is not None results = await self.http.get_global_commands( - self.application_id, # type: ignore - with_localizations=with_localizations, + self.application_id, with_localizations=with_localizations ) return [application_command_factory(data) for data in results] async def fetch_global_command(self, command_id: int) -> APIApplicationCommand: - result = await self.http.get_global_command(self.application_id, command_id) # type: ignore + assert self.application_id is not None + result = await self.http.get_global_command(self.application_id, command_id) return application_command_factory(result) async def create_global_command( self, application_command: ApplicationCommand ) -> APIApplicationCommand: + assert self.application_id is not None result = await self.http.upsert_global_command( - self.application_id, # type: ignore - application_command.to_dict(), + self.application_id, application_command.to_dict() ) cmd = application_command_factory(result) self._add_global_application_command(cmd) @@ -2298,24 +2305,25 @@ async def create_global_command( async def edit_global_command( self, command_id: int, new_command: ApplicationCommand ) -> APIApplicationCommand: + assert self.application_id is not None result = await self.http.edit_global_command( - self.application_id, # type: ignore - command_id, - new_command.to_dict(), + self.application_id, command_id, new_command.to_dict() ) cmd = application_command_factory(result) self._add_global_application_command(cmd) return cmd async def delete_global_command(self, command_id: int) -> None: - await self.http.delete_global_command(self.application_id, command_id) # type: ignore + assert self.application_id is not None + await self.http.delete_global_command(self.application_id, command_id) self._remove_global_application_command(command_id) async def bulk_overwrite_global_commands( self, application_commands: List[ApplicationCommand] ) -> List[APIApplicationCommand]: + assert self.application_id is not None payload = [cmd.to_dict() for cmd in application_commands] - results = await self.http.bulk_upsert_global_commands(self.application_id, payload) # type: ignore + results = await self.http.bulk_upsert_global_commands(self.application_id, payload) commands = [application_command_factory(data) for data in results] self._global_application_commands = {cmd.id: cmd for cmd in commands} return commands @@ -2328,24 +2336,23 @@ async def fetch_guild_commands( *, with_localizations: bool = True, ) -> List[APIApplicationCommand]: + assert self.application_id is not None results = await self.http.get_guild_commands( - self.application_id, # type: ignore - guild_id, - with_localizations=with_localizations, + self.application_id, guild_id, with_localizations=with_localizations ) return [application_command_factory(data) for data in results] async def fetch_guild_command(self, guild_id: int, command_id: int) -> APIApplicationCommand: - result = await self.http.get_guild_command(self.application_id, guild_id, command_id) # type: ignore + assert self.application_id is not None + result = await self.http.get_guild_command(self.application_id, guild_id, command_id) return application_command_factory(result) async def create_guild_command( self, guild_id: int, application_command: ApplicationCommand ) -> APIApplicationCommand: + assert self.application_id is not None result = await self.http.upsert_guild_command( - self.application_id, # type: ignore - guild_id, - application_command.to_dict(), + self.application_id, guild_id, application_command.to_dict() ) cmd = application_command_factory(result) self._add_guild_application_command(guild_id, cmd) @@ -2354,33 +2361,25 @@ async def create_guild_command( async def edit_guild_command( self, guild_id: int, command_id: int, new_command: ApplicationCommand ) -> APIApplicationCommand: + assert self.application_id is not None result = await self.http.edit_guild_command( - self.application_id, # type: ignore - guild_id, - command_id, - new_command.to_dict(), + self.application_id, guild_id, command_id, new_command.to_dict() ) cmd = application_command_factory(result) self._add_guild_application_command(guild_id, cmd) return cmd async def delete_guild_command(self, guild_id: int, command_id: int) -> None: - await self.http.delete_guild_command( - self.application_id, # type: ignore - guild_id, - command_id, - ) + assert self.application_id is not None + await self.http.delete_guild_command(self.application_id, guild_id, command_id) self._remove_guild_application_command(guild_id, command_id) async def bulk_overwrite_guild_commands( self, guild_id: int, application_commands: List[ApplicationCommand] ) -> List[APIApplicationCommand]: + assert self.application_id is not None payload = [cmd.to_dict() for cmd in application_commands] - results = await self.http.bulk_upsert_guild_commands( - self.application_id, # type: ignore - guild_id, - payload, - ) + results = await self.http.bulk_upsert_guild_commands(self.application_id, guild_id, payload) commands = [application_command_factory(data) for data in results] self._guild_application_commands[guild_id] = {cmd.id: cmd for cmd in commands} return commands @@ -2390,19 +2389,18 @@ async def bulk_overwrite_guild_commands( async def bulk_fetch_command_permissions( self, guild_id: int ) -> List[GuildApplicationCommandPermissions]: + assert self.application_id is not None array = await self.http.get_guild_application_command_permissions( - self.application_id, # type: ignore - guild_id, + self.application_id, guild_id ) return [GuildApplicationCommandPermissions(state=self, data=obj) for obj in array] async def fetch_command_permissions( self, guild_id: int, command_id: int ) -> GuildApplicationCommandPermissions: + assert self.application_id is not None data = await self.http.get_application_command_permissions( - self.application_id, # type: ignore - guild_id, - command_id, + self.application_id, guild_id, command_id ) return GuildApplicationCommandPermissions(state=self, data=data) @@ -2425,7 +2423,7 @@ def _update_guild_channel_references(self) -> None: channel_id = msg.channel.id channel = new_guild._resolve_channel(channel_id) or Object(id=channel_id) # channel will either be a TextChannel, VoiceChannel, Thread, StageChannel, or Object - msg._rebind_cached_references(new_guild, channel) # type: ignore + msg._rebind_cached_references(new_guild, channel) # pyright: ignore[reportArgumentType] # these generally get deallocated once the voice reconnect times out # (it never succeeds after gateway reconnects) @@ -2441,7 +2439,7 @@ def _update_guild_channel_references(self) -> None: # TODO: use PartialMessageable instead of Object (3.0) new_channel = new_guild._resolve_channel(vc.channel.id) or Object(id=vc.channel.id) if new_channel is not vc.channel: - vc.channel = new_channel # type: ignore + vc.channel = new_channel # pyright: ignore[reportAttributeAccessIssue] def _update_member_references(self) -> None: messages: Sequence[Message] = self._messages or [] @@ -2572,7 +2570,7 @@ def parse_ready(self, data: gateway.ReadyEvent) -> None: self.user = user = ClientUser(state=self, data=data["user"]) # self._users is a list of Users, we're setting a ClientUser - self._users[user.id] = user # type: ignore + self._users[user.id] = user # pyright: ignore[reportArgumentType] try: application = data["application"] @@ -2587,7 +2585,7 @@ def parse_ready(self, data: gateway.ReadyEvent) -> None: self._add_guild_from_data(guild_data) self.dispatch("connect") - self.dispatch("shard_connect", data["__shard_id__"]) # type: ignore # set in websocket receive + self.dispatch("shard_connect", data["__shard_id__"]) # pyright: ignore[reportGeneralTypeIssues] # set in websocket receive self.call_handlers("connect_internal") if self._ready_task is None: @@ -2595,4 +2593,4 @@ def parse_ready(self, data: gateway.ReadyEvent) -> None: def parse_resumed(self, data: gateway.ResumedEvent) -> None: self.dispatch("resumed") - self.dispatch("shard_resumed", data["__shard_id__"]) # type: ignore # set in websocket receive + self.dispatch("shard_resumed", data["__shard_id__"]) # pyright: ignore[reportGeneralTypeIssues] # set in websocket receive diff --git a/disnake/sticker.py b/disnake/sticker.py index 58303c2162..d79bde43b6 100644 --- a/disnake/sticker.py +++ b/disnake/sticker.py @@ -219,7 +219,7 @@ async def fetch(self) -> Union[Sticker, StandardSticker, GuildSticker]: The retrieved sticker. """ data: StickerPayload = await self._state.http.get_sticker(self.id) - cls, _ = _sticker_factory(data["type"]) # type: ignore + cls, _ = _sticker_factory(data["type"]) # pyright: ignore[reportGeneralTypeIssues] return cls(state=self._state, data=data) diff --git a/disnake/template.py b/disnake/template.py index e0b998d2bb..ed29b564d9 100644 --- a/disnake/template.py +++ b/disnake/template.py @@ -136,7 +136,7 @@ def _store(self, data: TemplatePayload) -> None: source_serialised["id"] = guild_id state = _PartialTemplateState(state=self._state) # Guild expects a ConnectionState, we're passing a _PartialTemplateState - self.source_guild = Guild(data=source_serialised, state=state) # type: ignore + self.source_guild = Guild(data=source_serialised, state=state) # pyright: ignore[reportArgumentType] else: self.source_guild = guild diff --git a/disnake/threads.py b/disnake/threads.py index d02b5ba06f..ed3001a747 100644 --- a/disnake/threads.py +++ b/disnake/threads.py @@ -188,7 +188,7 @@ def _from_data(self, data: ThreadPayload) -> None: self.parent_id: int = int(data["parent_id"]) self.owner_id: Optional[int] = _get_as_snowflake(data, "owner_id") self.name: str = data["name"] - self._type: ThreadType = try_enum(ChannelType, data["type"]) # type: ignore + self._type: ThreadType = try_enum(ChannelType, data["type"]) # pyright: ignore[reportAttributeAccessIssue] self.last_message_id: Optional[int] = _get_as_snowflake(data, "last_message_id") self.slowmode_delay: int = data.get("rate_limit_per_user", 0) self.message_count: int = data.get("message_count") or 0 @@ -245,7 +245,7 @@ def parent(self) -> Optional[Union[TextChannel, ForumChannel, MediaChannel]]: """Optional[Union[:class:`TextChannel`, :class:`ForumChannel`, :class:`MediaChannel`]]: The parent channel this thread belongs to.""" if isinstance(self.guild, Object): return None - return self.guild.get_channel(self.parent_id) # type: ignore + return self.guild.get_channel(self.parent_id) # pyright: ignore[reportReturnType] @property def owner(self) -> Optional[Member]: @@ -775,7 +775,7 @@ async def edit( data = await self._state.http.edit_channel(self.id, **payload, reason=reason) # The data payload will always be a Thread payload - return Thread(data=data, state=self._state, guild=self.guild) # type: ignore + return Thread(data=data, state=self._state, guild=self.guild) # pyright: ignore[reportArgumentType] async def join(self) -> None: """|coro| diff --git a/disnake/ui/action_row.py b/disnake/ui/action_row.py index f9f056bcb9..9339a33cdf 100644 --- a/disnake/ui/action_row.py +++ b/disnake/ui/action_row.py @@ -209,7 +209,7 @@ def __init__(self, *components: WrappedComponent, id: int = 0) -> None: raise TypeError( f"components should be of type WrappedComponent, got {type(component).__name__}." ) - self.append_item(component) # type: ignore + self.append_item(component) # pyright: ignore[reportArgumentType] def __len__(self) -> int: return len(self._children) @@ -1086,10 +1086,10 @@ def _walk_internal(component: ComponentT, seen: Set[ComponentT]) -> Iterator[Com elif isinstance(component, (SectionComponent, Section)): yield from _walk_internal(component.accessory, seen) for item in component.children: - yield from _walk_internal(item, seen) # type: ignore # this is fine, pyright loses the conditional type when iterating + yield from _walk_internal(item, seen) # pyright: ignore[reportArgumentType] # this is fine, pyright loses the conditional type when iterating elif isinstance(component, (ContainerComponent, Container)): for item in component.children: - yield from _walk_internal(item, seen) # type: ignore + yield from _walk_internal(item, seen) # pyright: ignore[reportArgumentType] elif isinstance(component, (LabelComponent, Label)): yield from _walk_internal(component.component, seen) @@ -1188,7 +1188,7 @@ def _message_component_to_item( ChannelSelectComponent, ), ): - return _to_ui_component(component) # type: ignore + return _to_ui_component(component) # pyright: ignore[reportReturnType] assert_never(component) return None diff --git a/disnake/ui/button.py b/disnake/ui/button.py index bb16ca9485..d1756e9295 100644 --- a/disnake/ui/button.py +++ b/disnake/ui/button.py @@ -359,6 +359,6 @@ def decorator(func: ItemCallbackType[V_co, B_co]) -> DecoratedItem[B_co]: func.__discord_ui_model_type__ = cls func.__discord_ui_model_kwargs__ = kwargs - return func # type: ignore + return func # pyright: ignore[reportReturnType] return decorator diff --git a/disnake/ui/item.py b/disnake/ui/item.py index a529f02693..588cddf67b 100644 --- a/disnake/ui/item.py +++ b/disnake/ui/item.py @@ -167,7 +167,7 @@ def __init__(self: Item[None]) -> None: ... def __init__(self: Item[V_co]) -> None: ... def __init__(self) -> None: - self._view: V_co = None # type: ignore + self._view: V_co = None # pyright: ignore[reportAttributeAccessIssue] self._row: Optional[int] = None self._rendered_row: Optional[int] = None # This works mostly well but there is a gotcha with diff --git a/disnake/ui/select/base.py b/disnake/ui/select/base.py index def5bd1e65..5029b72427 100644 --- a/disnake/ui/select/base.py +++ b/disnake/ui/select/base.py @@ -200,7 +200,7 @@ def refresh_component(self, component: SelectMenuT) -> None: self._underlying = component def refresh_state(self, interaction: MessageInteraction) -> None: - self._selected_values = interaction.resolved_values # type: ignore + self._selected_values = interaction.resolved_values # pyright: ignore[reportAttributeAccessIssue] @classmethod @abstractmethod @@ -273,6 +273,6 @@ def decorator(func: ItemCallbackType[V_co, S_co]) -> DecoratedItem[S_co]: func.__discord_ui_model_type__ = cls func.__discord_ui_model_kwargs__ = kwargs - return func # type: ignore + return func # pyright: ignore[reportReturnType] return decorator diff --git a/disnake/ui/view.py b/disnake/ui/view.py index cac0872a02..5e093d1ea9 100644 --- a/disnake/ui/view.py +++ b/disnake/ui/view.py @@ -133,7 +133,7 @@ def __init__(self, *, timeout: Optional[float] = 180.0) -> None: self.children: List[Item[Self]] = [] for func in self.__view_children_items__: item: Item[Self] = func.__discord_ui_model_type__(**func.__discord_ui_model_kwargs__) - item.callback = partial(func, self, item) # type: ignore + item.callback = partial(func, self, item) # pyright: ignore[reportAttributeAccessIssue] item._view = self setattr(self, func.__name__, item) self.children.append(item) @@ -390,7 +390,7 @@ def _dispatch_item(self, item: Item, interaction: MessageInteraction) -> None: def refresh(self, components: List[ActionRowComponent[ActionRowMessageComponent]]) -> None: # TODO: this is pretty hacky at the moment, see https://github.com/DisnakeDev/disnake/commit/9384a72acb8c515b13a600592121357e165368da old_state: Dict[Tuple[int, str], Item] = { - (item.type.value, item.custom_id): item # type: ignore + (item.type.value, item.custom_id): item # pyright: ignore[reportAttributeAccessIssue] for item in self.children if item.is_dispatchable() } @@ -399,7 +399,7 @@ def refresh(self, components: List[ActionRowComponent[ActionRowMessageComponent] for component in (c for row in components for c in row.children): older: Optional[Item] = None try: - older = old_state[(component.type.value, component.custom_id)] # type: ignore + older = old_state[component.type.value, component.custom_id] # pyright: ignore[reportArgumentType] except (KeyError, AttributeError): # workaround for non-interactive buttons, since they're not part of `old_state` if isinstance(component, ButtonComponent): @@ -415,7 +415,7 @@ def refresh(self, components: List[ActionRowComponent[ActionRowMessageComponent] break if older: - older.refresh_component(component) # type: ignore # this is fine, pyright is trying to be smart + older.refresh_component(component) # pyright: ignore[reportArgumentType] # this is fine, pyright is trying to be smart children.append(older) else: # fallback, should not happen as long as implementation covers all cases @@ -508,7 +508,7 @@ def add_view(self, view: View, message_id: Optional[int] = None) -> None: view._start_listening_from_store(self) for item in view.children: if item.is_dispatchable(): - self._views[(item.type.value, message_id, item.custom_id)] = (view, item) # type: ignore + self._views[item.type.value, message_id, item.custom_id] = (view, item) # pyright: ignore[reportAttributeAccessIssue] if message_id is not None: self._synced_message_views[message_id] = view @@ -516,7 +516,10 @@ def add_view(self, view: View, message_id: Optional[int] = None) -> None: def remove_view(self, view: View) -> None: for item in view.children: if item.is_dispatchable(): - self._views.pop((item.type.value, item.custom_id), None) # type: ignore + self._views.pop( # pyright: ignore[reportCallIssue] + (item.type.value, item.custom_id), # pyright: ignore[reportArgumentType, reportAttributeAccessIssue] + None, + ) for key, value in self._synced_message_views.items(): if value.id == view.id: diff --git a/disnake/utils.py b/disnake/utils.py index 5d7709f813..08e99d916c 100644 --- a/disnake/utils.py +++ b/disnake/utils.py @@ -272,7 +272,7 @@ def copy_doc(original: Union[Callable[..., Any], property]) -> Callable[[T], T]: def decorator(overridden: T) -> T: overridden.__doc__ = original.__doc__ if callable(original): - overridden.__signature__ = _signature(original) # type: ignore + overridden.__signature__ = _signature(original) # pyright: ignore[reportAttributeAccessIssue] return overridden return decorator @@ -314,7 +314,8 @@ def warn_deprecated( warnings.simplefilter("always", DeprecationWarning) warnings.warn(*args, stacklevel=stacklevel + 1, category=DeprecationWarning, **kwargs) finally: - warnings.filters[:] = old_filters # type: ignore + assert isinstance(warnings.filters, list) + warnings.filters[:] = old_filters def oauth_url( @@ -588,9 +589,9 @@ async def _assetbytes_to_base64_data(data: Optional[AssetBytes]) -> Optional[str if HAS_ORJSON: def _to_json(obj: Any) -> str: - return orjson.dumps(obj).decode("utf-8") # type: ignore + return orjson.dumps(obj).decode("utf-8") # pyright: ignore[reportPossiblyUnboundVariable] - _from_json = orjson.loads # type: ignore + _from_json = orjson.loads # pyright: ignore[reportPossiblyUnboundVariable] else: @@ -718,7 +719,7 @@ class SnowflakeList(array.array): def __init__(self, data: Iterable[int], *, is_sorted: bool = False) -> None: ... def __new__(cls, data: Iterable[int], *, is_sorted: bool = False) -> Self: - return array.array.__new__(cls, "Q", data if is_sorted else sorted(data)) # type: ignore + return array.array.__new__(cls, "Q", data if is_sorted else sorted(data)) # pyright: ignore[reportReturnType] def add(self, element: int) -> None: i = bisect_left(self, element) diff --git a/disnake/voice_client.py b/disnake/voice_client.py index 0e12e09fed..80711833cb 100644 --- a/disnake/voice_client.py +++ b/disnake/voice_client.py @@ -260,9 +260,10 @@ async def on_voice_state_update(self, data: GuildVoiceStatePayload) -> None: if channel_id is None: # We're being disconnected so cleanup await self.disconnect() + elif self.guild is None: # pyright: ignore[reportUnnecessaryComparison] + self.channel = None # pyright: ignore[reportAttributeAccessIssue] else: - guild = self.guild - self.channel = channel_id and guild and guild.get_channel(int(channel_id)) # type: ignore + self.channel = self.guild.get_channel(int(channel_id)) # pyright: ignore[reportAttributeAccessIssue] else: self._voice_state_complete.set() @@ -529,8 +530,8 @@ def _get_nonce(self, pad: int) -> Tuple[bytes, bytes]: return (nonce, nonce.ljust(pad, b"\0")) def _encrypt_aead_xchacha20_poly1305_rtpsize(self, header: bytes, data) -> bytes: - box = nacl.secret.Aead(bytes(self.secret_key)) # type: ignore[reportPossiblyUnboundVariable] - nonce, padded_nonce = self._get_nonce(nacl.secret.Aead.NONCE_SIZE) # type: ignore[reportPossiblyUnboundVariable] + box = nacl.secret.Aead(bytes(self.secret_key)) # pyright: ignore[reportPossiblyUnboundVariable] + nonce, padded_nonce = self._get_nonce(nacl.secret.Aead.NONCE_SIZE) # pyright: ignore[reportPossiblyUnboundVariable] return ( header diff --git a/disnake/webhook/async_.py b/disnake/webhook/async_.py index 432afe025c..b36d89ec99 100644 --- a/disnake/webhook/async_.py +++ b/disnake/webhook/async_.py @@ -39,7 +39,7 @@ from ..mixins import Hashable from ..object import Object from ..ui.action_row import normalize_components_to_dict -from ..user import BaseUser, User +from ..user import BaseUser, ClientUser, User __all__ = ( "Webhook", @@ -193,7 +193,8 @@ async def request( if not response.headers.get("Via"): raise HTTPException(response, data) - retry_after: float = data["retry_after"] # type: ignore + assert isinstance(data, dict) + retry_after: float = data["retry_after"] _log.warning( "Webhook ID %s is rate limited. Retrying in %.2f seconds", webhook_id, @@ -760,11 +761,11 @@ def store_user(self, data) -> Union[BaseUser, User]: if self._parent is not None: return self._parent.store_user(data) # state parameter is artificial - return BaseUser(state=self, data=data) # type: ignore + return BaseUser(state=self, data=data) # pyright: ignore[reportArgumentType] def create_user(self, data) -> BaseUser: # state parameter is artificial - return BaseUser(state=self, data=data) # type: ignore + return BaseUser(state=self, data=data) # pyright: ignore[reportArgumentType] @property def http(self) -> HTTPClient: @@ -773,7 +774,7 @@ def http(self) -> HTTPClient: # Some data classes assign state.http and that should be kosher # however, using it should result in a late-binding error. - return _FriendlyHttpAttributeErrorHelper() # type: ignore + return _FriendlyHttpAttributeErrorHelper() # pyright: ignore[reportReturnType] def __getattr__(self, attr) -> Any: if self._parent is not None: @@ -1003,7 +1004,7 @@ def _update(self, data: WebhookPayload) -> None: self.user: Optional[Union[BaseUser, User]] = None if user is not None: # state parameter may be _WebhookState - self.user = User(state=self._state, data=user) # type: ignore + self.user = User(state=self._state, data=user) # pyright: ignore[reportArgumentType] source_channel = data.get("source_channel") if source_channel: @@ -1057,8 +1058,9 @@ def channel( They can only create new threads (see ``thread_name`` for :attr:`Webhook.send`) and interact with existing threads. """ - guild = self.guild - return guild and guild.get_channel(self.channel_id) # type: ignore + if self.guild is None or self.channel_id is None: + return None + return self.guild.get_channel(self.channel_id) # pyright: ignore[reportReturnType] @property def created_at(self) -> datetime.datetime: @@ -1266,12 +1268,12 @@ def from_url( if m is None: raise ValueError("Invalid webhook URL given.") - data: Dict[str, Any] = m.groupdict() - data["type"] = 1 - return cls(data, session, token=bot_token) # type: ignore + data: WebhookPayload = {"id": m["id"], "type": 1, "token": m["token"]} + return cls(data, session, token=bot_token) + # FIXME: data comes from HTTPClient.follow_webhook, but is hinted as returning Response[None]? @classmethod - def _as_follower(cls, data, *, channel, user) -> Webhook: + def _as_follower(cls, data: Any, *, channel: TextChannel, user: ClientUser) -> Webhook: name = f"{channel.guild} #{channel}" feed: WebhookPayload = { "id": data["webhook_id"], @@ -1289,12 +1291,12 @@ def _as_follower(cls, data, *, channel, user) -> Webhook: } state = channel._state - session = channel._state.http._HTTPClient__session + session = channel._state.http._HTTPClient__session # pyright: ignore[reportAttributeAccessIssue] return cls(feed, session=session, state=state, token=state.http.token) @classmethod - def from_state(cls, data, state) -> Webhook: - session = state.http._HTTPClient__session + def from_state(cls, data: WebhookPayload, state: ConnectionState) -> Webhook: + session = state.http._HTTPClient__session # pyright: ignore[reportAttributeAccessIssue] return cls(data, session=session, state=state, token=state.http.token) async def fetch(self, *, prefer_auth: bool = True) -> Webhook: @@ -1512,12 +1514,12 @@ def _create_message( else: msg_channel = self.channel - if not msg_channel: + if msg_channel is None: # state may be artificial (unlikely at this point...) - msg_channel = PartialMessageable(state=self._state, id=channel_id) # type: ignore + msg_channel = PartialMessageable(state=self._state, id=channel_id) # pyright: ignore[reportArgumentType] # state is artificial - return WebhookMessage(data=data, state=state, channel=msg_channel) # type: ignore + return WebhookMessage(data=data, state=state, channel=msg_channel) # pyright: ignore[reportArgumentType] @overload async def send( @@ -1831,11 +1833,8 @@ async def send( msg = None if wait: - msg = self._create_message( - data, # type: ignore - thread=thread, - thread_name=thread_name, - ) + assert data is not None + msg = self._create_message(data, thread=thread, thread_name=thread_name) if delete_after is not MISSING: await msg.delete(delay=delete_after) diff --git a/disnake/webhook/sync.py b/disnake/webhook/sync.py index 1da14d4ff0..8dabbc25bb 100644 --- a/disnake/webhook/sync.py +++ b/disnake/webhook/sync.py @@ -159,7 +159,7 @@ def request( ) response.encoding = "utf-8" # Compatibility with aiohttp - response.status = response.status_code # type: ignore + response.status = response.status_code # pyright: ignore[reportAttributeAccessIssue] data = response.text or None if data and response.headers["Content-Type"] == "application/json": @@ -183,7 +183,8 @@ def request( if not response.headers.get("Via"): raise HTTPException(response, data) - retry_after: float = data["retry_after"] # type: ignore + assert isinstance(data, dict) + retry_after: float = data["retry_after"] _log.warning( "Webhook ID %s is rate limited. Retrying in %.2f seconds", webhook_id, @@ -683,7 +684,7 @@ def partial( if not isinstance(session, requests.Session): raise TypeError(f"expected requests.Session not {session.__class__!r}") else: - session = requests # type: ignore + session = requests # pyright: ignore[reportAssignmentType] return cls(data, session, token=bot_token) @classmethod @@ -726,16 +727,15 @@ def from_url( if m is None: raise ValueError("Invalid webhook URL given.") - data: Dict[str, Any] = m.groupdict() - data["type"] = 1 + data: WebhookPayload = {"id": m["id"], "type": 1, "token": m["token"]} import requests if session is not MISSING: if not isinstance(session, requests.Session): raise TypeError(f"expected requests.Session not {session.__class__!r}") else: - session = requests # type: ignore - return cls(data, session, token=bot_token) # type: ignore + session = requests # pyright: ignore[reportAssignmentType] + return cls(data, session, token=bot_token) def fetch(self, *, prefer_auth: bool = True) -> SyncWebhook: """Fetches the current webhook. @@ -909,7 +909,11 @@ def edit( ) def _create_message( - self, data, *, thread: Optional[Snowflake] = None, thread_name: Optional[str] = None + self, + data: MessagePayload, + *, + thread: Optional[Snowflake] = None, + thread_name: Optional[str] = None, ) -> SyncWebhookMessage: # see async webhook's _create_message for details channel_id = int(data["channel_id"]) @@ -918,10 +922,10 @@ def _create_message( state = _WebhookState(self, parent=self._state, thread=thread) channel = self.channel - if not channel or self.channel_id != channel_id: - channel = PartialMessageable(state=self._state, id=channel_id) # type: ignore + if channel is None or self.channel_id != channel_id: + channel = PartialMessageable(state=self._state, id=channel_id) # pyright: ignore[reportArgumentType] # state is artificial - return SyncWebhookMessage(data=data, state=state, channel=channel) # type: ignore + return SyncWebhookMessage(data=data, state=state, channel=channel) # pyright: ignore[reportArgumentType] @overload def send( diff --git a/disnake/welcome_screen.py b/disnake/welcome_screen.py index a2e2fa171c..0b1c56ee65 100644 --- a/disnake/welcome_screen.py +++ b/disnake/welcome_screen.py @@ -83,9 +83,10 @@ def _from_data( return cls(id=int(data["channel_id"]), description=data["description"], emoji=emoji) def to_dict(self) -> WelcomeScreenChannelPayload: - result: WelcomeScreenChannelPayload = {} # type: ignore - result["channel_id"] = self.id - result["description"] = self.description + result: WelcomeScreenChannelPayload = { + "channel_id": self.id, + "description": self.description, + } # pyright: ignore[reportAssignmentType] if self.emoji is not None: if self.emoji.id: diff --git a/docs/conf.py b/docs/conf.py index 40b4b3dc7d..e3183a43da 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -110,7 +110,7 @@ version = "" with open("../disnake/__init__.py") as f: - version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1) # type: ignore + version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1) # pyright: ignore[reportOptionalMemberAccess] # The full version, including alpha/beta/rc tags. release = version @@ -218,9 +218,13 @@ def linkcode_resolve(domain: str, info: Dict[str, Any]) -> Optional[str]: obj = inspect.unwrap(obj) if isinstance(obj, property): - obj = inspect.unwrap(obj.fget) # type: ignore + assert obj.fget is not None + obj = inspect.unwrap(obj.fget) - path = os.path.relpath(inspect.getsourcefile(obj), start=_disnake_module_path) # type: ignore + path = os.path.relpath( # pyright: ignore[reportCallIssue] + inspect.getsourcefile(obj), # pyright: ignore[reportArgumentType] + start=_disnake_module_path, + ) src, lineno = inspect.getsourcelines(obj) except Exception: return None @@ -503,4 +507,4 @@ def setup(app: Sphinx) -> None: # HACK: avoid deprecation warnings caused by sphinx always iterating over all class attributes import disnake - del disnake.Embed.Empty # type: ignore + del disnake.Embed.Empty # pyright: ignore[reportAttributeAccessIssue] diff --git a/docs/extensions/attributetable.py b/docs/extensions/attributetable.py index 4589d73e6d..955b884dd0 100644 --- a/docs/extensions/attributetable.py +++ b/docs/extensions/attributetable.py @@ -66,7 +66,7 @@ def visit_attributetablebadge_node(self: HTMLTranslator, node: nodes.Element) -> attributes = { "class": f"badge-{badge_type}", } - self.body.append(self.starttag(node, "span", **attributes)) # type: ignore[reportArgumentType] + self.body.append(self.starttag(node, "span", **attributes)) # pyright: ignore[reportArgumentType] def visit_attributetable_item_node(self: HTMLTranslator, node: nodes.Element) -> None: diff --git a/docs/extensions/builder.py b/docs/extensions/builder.py index 6eee763436..6c5736a6b7 100644 --- a/docs/extensions/builder.py +++ b/docs/extensions/builder.py @@ -56,7 +56,7 @@ def patch_genindex(*args: Any) -> None: # copying the entire method body while only changing one parameter (group_entries), # we just patch the method we want to change instead. new_create_index = functools.partialmethod(IndexEntries.create_index, group_entries=False) - IndexEntries.create_index = new_create_index # type: ignore + IndexEntries.create_index = new_create_index # pyright: ignore[reportAttributeAccessIssue] def patch_opengraph(*args: Any) -> None: diff --git a/docs/extensions/collapse.py b/docs/extensions/collapse.py index a37bdd3780..22b27c36a6 100644 --- a/docs/extensions/collapse.py +++ b/docs/extensions/collapse.py @@ -20,7 +20,7 @@ class collapse(nodes.General, nodes.Element): def visit_collapse_node(self: HTMLTranslator, node: nodes.Element) -> None: attrs = {"open": ""} if node["open"] else {} - self.body.append(self.starttag(node, "details", **attrs)) # type: ignore[reportArgumentType] + self.body.append(self.starttag(node, "details", **attrs)) # pyright: ignore[reportArgumentType] self.body.append("") diff --git a/docs/extensions/fulltoc.py b/docs/extensions/fulltoc.py index d5d4f62ba8..2bed5bfc31 100644 --- a/docs/extensions/fulltoc.py +++ b/docs/extensions/fulltoc.py @@ -29,7 +29,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, cast +from typing import TYPE_CHECKING, Any, List, cast from docutils import nodes from sphinx import addnodes @@ -46,7 +46,9 @@ GROUPED_SECTIONS = {"api/": "api/index", "ext/commands/api/": "ext/commands/api/index"} -def html_page_context(app: Sphinx, docname: str, templatename, context, doctree) -> None: +def html_page_context( + app: Sphinx, docname: str, templatename: str, context: Any, doctree: Any +) -> None: """Event handler for the html-page-context signal. Modifies the context directly, if `docname` matches one of the items in `GROUPED_SECTIONS`. @@ -68,7 +70,7 @@ def html_page_context(app: Sphinx, docname: str, templatename, context, doctree) return rendered_toc = get_rendered_toctree( - app.builder, # type: ignore + app.builder, # pyright: ignore[reportArgumentType] docname, index, # don't prune tree at a certain depth; always include all entries @@ -85,7 +87,9 @@ def html_page_context(app: Sphinx, docname: str, templatename, context, doctree) context["parent_index"] = index -def get_rendered_toctree(builder: StandaloneHTMLBuilder, docname: str, index: str, **kwargs) -> str: +def get_rendered_toctree( + builder: StandaloneHTMLBuilder, docname: str, index: str, **kwargs: Any +) -> str: """Build the toctree relative to the named document, with the given parameters, and then return the rendered HTML fragment. @@ -101,7 +105,7 @@ def get_rendered_toctree(builder: StandaloneHTMLBuilder, docname: str, index: st def build_full_toctree( - builder: StandaloneHTMLBuilder, docname: str, index: str, **kwargs + builder: StandaloneHTMLBuilder, docname: str, index: str, **kwargs: Any ) -> nodes.bullet_list: """Return a single toctree starting from docname containing all sub-document doctrees. diff --git a/docs/extensions/redirects.py b/docs/extensions/redirects.py index 46114dd743..5de73d3da6 100644 --- a/docs/extensions/redirects.py +++ b/docs/extensions/redirects.py @@ -35,7 +35,7 @@ def copy_redirect_script(app: Sphinx, exception: Exception) -> None: context = {"redirect_data": json.dumps(redirect_mapping)} # sanity check - assert Path(SCRIPT_PATH).exists() # noqa: S101 + assert Path(SCRIPT_PATH).exists() copy_asset_file( SCRIPT_PATH, diff --git a/examples/basic_voice.py b/examples/basic_voice.py index 0ff34a7b5f..1fa20103b8 100644 --- a/examples/basic_voice.py +++ b/examples/basic_voice.py @@ -12,7 +12,7 @@ from typing import Any, Dict, Optional import disnake -import youtube_dl # type: ignore +import youtube_dl # pyright: ignore[reportMissingImports] from disnake.ext import commands # Suppress noise about console usage from errors diff --git a/noxfile.py b/noxfile.py index 7dc54e12f7..9c0637a186 100755 --- a/noxfile.py +++ b/noxfile.py @@ -20,6 +20,7 @@ Final, List, Optional, + Sequence, Tuple, ) @@ -34,10 +35,10 @@ PYPROJECT = nox.project.load_toml() -SUPPORTED_PYTHONS: Final[List[str]] = nox.project.python_versions(PYPROJECT) +SUPPORTED_PYTHONS: Final[Sequence[str]] = nox.project.python_versions(PYPROJECT) # TODO(onerandomusername): add 3.14 once CI supports 3.14. -EXPERIMENTAL_PYTHON_VERSIONS: Final[List[str]] = [] -ALL_PYTHONS: Final[List[str]] = [*SUPPORTED_PYTHONS, *EXPERIMENTAL_PYTHON_VERSIONS] +EXPERIMENTAL_PYTHON_VERSIONS: Final[Sequence[str]] = [] +ALL_PYTHONS: Final[Sequence[str]] = [*SUPPORTED_PYTHONS, *EXPERIMENTAL_PYTHON_VERSIONS] MIN_PYTHON: Final[str] = SUPPORTED_PYTHONS[0] CI: Final[bool] = "CI" in os.environ @@ -67,10 +68,10 @@ def __post_init__(self) -> None: if self.python in EXPERIMENTAL_PYTHON_VERSIONS: self.experimental = True for key in self.__dataclass_fields__.keys(): - self[key] = getattr(self, key) # type: ignore + self[key] = getattr(self, key) # pyright: ignore[reportIndexIssue] -EXECUTION_GROUPS: List[ExecutionGroup] = [ +EXECUTION_GROUPS: Sequence[ExecutionGroup] = [ ## pyright *( ExecutionGroup( @@ -125,7 +126,7 @@ def __post_init__(self) -> None: ] -def get_groups_for_session(name: str) -> List[ExecutionGroup]: +def get_groups_for_session(name: str) -> Sequence[ExecutionGroup]: return [g for g in EXECUTION_GROUPS if name in g.sessions] diff --git a/pyproject.toml b/pyproject.toml index dcb3f7b29e..f446e840c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -141,6 +141,7 @@ ignore = [ "ANN0", "ANN4", ## flake8-bandit + "S101", # use of assert is fine "S311", # use of random is fine in most cases "S603", # calling subprocess with dynamic arguments is generally fine, the only way to avoid this is ignoring it "S607", # partial executable paths (i.e. "git" instead of "/usr/bin/git") are fine @@ -191,8 +192,6 @@ ignore = [ "E731", # lambda expression assigned ## pydocstyle "D1", "D205", "D301", "D400", "D401", - ## pygrep-hooks - "PGH003", # blanket type ignores ## Pylint # PLC "PLC0105", @@ -350,6 +349,9 @@ ignore = [ # this is one of the diagnostics that aren't enabled by default, even in strict mode reportUnnecessaryTypeIgnoreComment = true +# prefer "# pyright: ignore[ruleName]" over "# type: ignore" +enableTypeIgnoreComments = false + # it's unlikely that these will ever be enabled reportOverlappingOverload = false reportPrivateUsage = false diff --git a/scripts/codemods/typed_flags.py b/scripts/codemods/typed_flags.py index 827dc1149d..3861cced39 100644 --- a/scripts/codemods/typed_flags.py +++ b/scripts/codemods/typed_flags.py @@ -144,7 +144,7 @@ def __init__(self): codevisitors.AddImportsVisitor.add_needed_import( self.context, "disnake.utils", "_generated" ) - node = node.deep_replace(old_init, init) # type: ignore + node = node.deep_replace(old_init, init) # pyright: ignore[reportAssignmentType] else: # the init exists, so we need to make overloads diff --git a/scripts/codemods/typed_permissions.py b/scripts/codemods/typed_permissions.py index 4bb389b0c9..adc5e12709 100644 --- a/scripts/codemods/typed_permissions.py +++ b/scripts/codemods/typed_permissions.py @@ -81,7 +81,7 @@ def leave_ClassDef(self, _: cst.ClassDef, node: cst.ClassDef) -> Union[cst.Class else: raise RuntimeError("could not find TYPE_CHECKING block in PermissionOverwrite.") - og_type_check: cst.If = b # type: ignore + og_type_check: cst.If = b # pyright: ignore[reportAssignmentType] body = [ cst.SimpleStatementLine( diff --git a/setup.py b/setup.py index 0f6db17d46..ac3541d377 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ version = "" with open("disnake/__init__.py", encoding="utf-8") as f: - version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1) # type: ignore + version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1) # pyright: ignore[reportOptionalMemberAccess] if not version: raise RuntimeError("version is not set") diff --git a/tests/ext/commands/test_core.py b/tests/ext/commands/test_core.py index f98744d46c..645b61cadb 100644 --- a/tests/ext/commands/test_core.py +++ b/tests/ext/commands/test_core.py @@ -22,13 +22,13 @@ async def f1(ctx: CustomContext, a: int, b: str) -> bool: ... for cd in (commands.command(), base.command()): reveal_type( - cd(f1), # type: ignore + cd(f1), # pyright: ignore # noqa: PGH003 expected_text="Command[None, (a: int, b: str), bool]", ) for gd in (commands.group(), base.group()): reveal_type( - gd(f1), # type: ignore + gd(f1), # pyright: ignore # noqa: PGH003 expected_text="Group[None, (a: int, b: str), bool]", ) @@ -39,13 +39,13 @@ async def f2(_self: CustomCog, ctx: CustomContext, a: int, b: str) -> bool: ... for cd in (commands.command(), base.command()): reveal_type( - cd(f2), # type: ignore + cd(f2), # pyright: ignore # noqa: PGH003 expected_text="Command[CustomCog, (a: int, b: str), bool]", ) for gd in (commands.group(), base.group()): reveal_type( - gd(f2), # type: ignore + gd(f2), # pyright: ignore # noqa: PGH003 expected_text="Group[CustomCog, (a: int, b: str), bool]", ) diff --git a/tests/ext/tasks/test_loops.py b/tests/ext/tasks/test_loops.py index 28a8dd54ed..d28de1f1c5 100644 --- a/tests/ext/tasks/test_loops.py +++ b/tests/ext/tasks/test_loops.py @@ -20,7 +20,7 @@ async def task(self) -> None: ... with pytest.raises(TypeError, match="must be a coroutine"): - @loop() # type: ignore + @loop() # pyright: ignore[reportArgumentType] def task() -> None: ... def test_mixing_time(self) -> None: @@ -70,5 +70,5 @@ async def task(self) -> None: ... with pytest.raises(TypeError, match="subclass of Loop"): - @loop(cls=WhileTrueLoop) # type: ignore + @loop(cls=WhileTrueLoop) # pyright: ignore[reportUntypedFunctionDecorator, reportArgumentType] async def task() -> None: ... diff --git a/tests/helpers.py b/tests/helpers.py index bcf957d98e..f2ebec3bd0 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -20,8 +20,8 @@ def reveal_type(*args, **kwargs) -> None: # NOTE: using undocumented `expected_text` parameter of pyright instead of `assert_type`, # as `assert_type` can't handle bound ParamSpecs reveal_type( - 42, # type: ignore # suppress "revealed type is ..." output - expected_text="str", # type: ignore # ensure the functionality we want still works as expected + 42, # pyright: ignore # noqa: PGH003 # suppress "revealed type is ..." output + expected_text="str", # pyright: ignore[reportGeneralTypeIssues] # ensure the functionality we want still works as expected ) @@ -67,7 +67,7 @@ async def wrap_async(*args, **kwargs): with self: return await func(*args, **kwargs) - return wrap_async # type: ignore + return wrap_async # pyright: ignore[reportReturnType] else: @@ -76,4 +76,4 @@ def wrap_sync(*args, **kwargs): with self: return func(*args, **kwargs) - return wrap_sync # type: ignore + return wrap_sync # pyright: ignore[reportReturnType] diff --git a/tests/test_colour.py b/tests/test_colour.py index 365edff619..89998c0741 100644 --- a/tests/test_colour.py +++ b/tests/test_colour.py @@ -10,7 +10,7 @@ def test_init() -> None: with pytest.raises(TypeError, match=r"Expected int parameter, received str instead."): - Colour("0") # type: ignore + Colour("0") # pyright: ignore[reportArgumentType] @pytest.mark.parametrize( diff --git a/tests/test_embeds.py b/tests/test_embeds.py index 2037435fad..901271a4c9 100644 --- a/tests/test_embeds.py +++ b/tests/test_embeds.py @@ -246,7 +246,7 @@ def test_image_remove(file: File) -> None: def test_file_params(file: File) -> None: embed = Embed() with pytest.raises(TypeError): - embed.set_image("https://disnake.dev/assets/disnake-logo.png", file=file) # type: ignore + embed.set_image("https://disnake.dev/assets/disnake-logo.png", file=file) # pyright: ignore[reportCallIssue] assert embed._files == {} assert embed.to_dict() == _BASE @@ -471,12 +471,12 @@ def test_copy_fields(embed: Embed) -> None: # backwards compatibility def test_emptyembed() -> None: with pytest.warns(DeprecationWarning): - assert embeds.EmptyEmbed is None # type: ignore + assert embeds.EmptyEmbed is None # pyright: ignore[reportAttributeAccessIssue] with pytest.warns(DeprecationWarning): - assert Embed.Empty is None # type: ignore + assert Embed.Empty is None # pyright: ignore[reportAttributeAccessIssue] with pytest.warns(DeprecationWarning): - assert Embed().Empty is None # type: ignore + assert Embed().Empty is None # pyright: ignore[reportAttributeAccessIssue] # make sure unknown module attrs continue to raise with pytest.raises(AttributeError): - _ = embeds.this_does_not_exist # type: ignore + _ = embeds.this_does_not_exist # pyright: ignore[reportAttributeAccessIssue] diff --git a/tests/test_events.py b/tests/test_events.py index ecbcd435b3..0eec869b31 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -36,7 +36,7 @@ def test_event(client_or_bot: disnake.Client) -> None: @client_or_bot.event async def on_message_edit(self, *args: Any) -> None: ... - assert client_or_bot.on_message_edit is on_message_edit # type: ignore + assert client_or_bot.on_message_edit is on_message_edit # pyright: ignore[reportAttributeAccessIssue] # Client.wait_for diff --git a/tests/test_flags.py b/tests/test_flags.py index 24bd0ef8bd..2dd9e8a6b0 100644 --- a/tests/test_flags.py +++ b/tests/test_flags.py @@ -120,16 +120,16 @@ def test_flag_value_or(self) -> None: assert (ins | TestFlags.one).value == 1 with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for |:")): - _ = TestFlags.four | 32 # type: ignore + _ = TestFlags.four | 32 # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for |:")): - _ = 32 | TestFlags.four # type: ignore + _ = 32 | TestFlags.four # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for |:")): - _ = TestFlags.four | OtherTestFlags.other_one # type: ignore + _ = TestFlags.four | OtherTestFlags.other_one # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for |:")): - _ = TestFlags.four | OtherTestFlags(other_one=True) # type: ignore + _ = TestFlags.four | OtherTestFlags(other_one=True) # pyright: ignore[reportOperatorIssue] def test_flag_value_invert(self) -> None: ins = ~TestFlags.four @@ -165,12 +165,12 @@ def test__init__invalid_kwargs(self) -> None: def test_set_require_bool(self) -> None: with pytest.raises(TypeError, match=r"Value to set for TestFlags must be a bool."): - TestFlags(one="h") # type: ignore + TestFlags(one="h") # pyright: ignore[reportArgumentType] ins = TestFlags() with pytest.raises(TypeError, match=r"Value to set for TestFlags must be a bool."): - ins.two = "h" # type: ignore + ins.two = "h" # pyright: ignore[reportAttributeAccessIssue] def test__eq__(self) -> None: ins = TestFlags(one=True, two=True) @@ -214,10 +214,10 @@ def test__and__(self) -> None: assert third.value == 0b010 with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for &:")): - _ = ins & "44" # type: ignore + _ = ins & "44" # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for &:")): - _ = "44" & ins # type: ignore + _ = "44" & ins # pyright: ignore[reportOperatorIssue] def test__iand__(self) -> None: ins = TestFlags(one=True, two=True) @@ -235,7 +235,7 @@ def test__iand__(self) -> None: assert ins.value == 0b001 with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for &=:")): - ins &= 14 # type: ignore + ins &= 14 # pyright: ignore[reportOperatorIssue] def test__or__(self) -> None: ins = TestFlags(one=True, two=False) @@ -258,13 +258,13 @@ def test__or__(self) -> None: assert third.value == 0b10 with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for |:")): - _ = ins | 28 # type: ignore + _ = ins | 28 # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for |:")): - _ = 28 | ins # type: ignore + _ = 28 | ins # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for |:")): - _ = ins | OtherTestFlags.other_one # type: ignore + _ = ins | OtherTestFlags.other_one # pyright: ignore[reportOperatorIssue] def test__ior__(self) -> None: ins = TestFlags(one=True, two=False) @@ -281,10 +281,10 @@ def test__ior__(self) -> None: assert ins.value == 0b111 with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for |=:")): - ins |= True # type: ignore + ins |= True # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for |=:")): - ins |= OtherTestFlags.other_one # type: ignore + ins |= OtherTestFlags.other_one # pyright: ignore[reportOperatorIssue] def test__xor__(self) -> None: ins = TestFlags(one=True, two=False) @@ -299,13 +299,13 @@ def test__xor__(self) -> None: assert third.value == 0b010 with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for ^:")): - _ = ins ^ "h" # type: ignore + _ = ins ^ "h" # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for ^:")): - _ = "h" ^ ins # type: ignore + _ = "h" ^ ins # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for ^:")): - _ = ins ^ OtherTestFlags.other_one # type: ignore + _ = ins ^ OtherTestFlags.other_one # pyright: ignore[reportOperatorIssue] def test__ixor__(self) -> None: ins = TestFlags(one=True, two=False) @@ -322,10 +322,10 @@ def test__ixor__(self) -> None: assert ins.value == 0b010 with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for ^=:")): - ins ^= "stability" # type: ignore + ins ^= "stability" # pyright: ignore[reportOperatorIssue] with pytest.raises(TypeError, match=re.escape("unsupported operand type(s) for ^=:")): - ins ^= OtherTestFlags.other_one # type: ignore + ins ^= OtherTestFlags.other_one # pyright: ignore[reportOperatorIssue] def test__le__(self) -> None: ins = TestFlags(one=True, two=False) @@ -338,7 +338,7 @@ def test__le__(self) -> None: with pytest.raises( TypeError, match="'<=' not supported between instances of 'TestFlags' and 'int'" ): - _ = ins <= 4 # type: ignore + _ = ins <= 4 # pyright: ignore[reportOperatorIssue] other.value = ins.value assert ins <= other @@ -354,7 +354,7 @@ def test__ge__(self) -> None: with pytest.raises( TypeError, match="'>=' not supported between instances of 'TestFlags' and 'int'" ): - _ = ins >= 4 # type: ignore + _ = ins >= 4 # pyright: ignore[reportOperatorIssue] other.value = ins.value assert ins >= other @@ -370,7 +370,7 @@ def test__lt__(self) -> None: with pytest.raises( TypeError, match="'<' not supported between instances of 'TestFlags' and 'int'" ): - _ = ins < 4 # type: ignore + _ = ins < 4 # pyright: ignore[reportOperatorIssue] other.value = ins.value assert not ins < other @@ -386,7 +386,7 @@ def test__gt__(self) -> None: with pytest.raises( TypeError, match="'>' not supported between instances of 'TestFlags' and 'int'" ): - _ = ins > 4 # type: ignore + _ = ins > 4 # pyright: ignore[reportOperatorIssue] other.value = ins.value assert not ins > other diff --git a/tests/test_message.py b/tests/test_message.py index d0001882b8..e42d5fca83 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -37,7 +37,7 @@ def test_convert_emoji_reaction__custom(emoji) -> None: def _create_emoji(animated: bool) -> disnake.Emoji: return disnake.Emoji( - guild=disnake.Object(1), # type: ignore + guild=disnake.Object(1), # pyright: ignore[reportArgumentType] state=MISSING, data={"name": "test", "id": 1234, "animated": animated}, ) diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 4fcbf5bf01..41b2dfb7c5 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -25,11 +25,11 @@ def test_init_permissions_keyword_arguments_with_aliases(self) -> None: def test_init_invalid_value(self) -> None: with pytest.raises(TypeError, match=r"Expected int parameter, received str instead."): - Permissions("h") # type: ignore + Permissions("h") # pyright: ignore[reportArgumentType, reportCallIssue] def test_init_invalid_perms(self) -> None: with pytest.raises(TypeError, match=r"'h' is not a valid permission name."): - Permissions(h=True) # type: ignore + Permissions(h=True) # pyright: ignore[reportCallIssue] @pytest.mark.parametrize( ("perms_int", "other_int", "expected"), @@ -47,7 +47,7 @@ def test_is_subset(self, perms_int: int, other_int: int, expected: bool) -> None def test_is_subset_only_permissions(self) -> None: perms = Permissions() with pytest.raises(TypeError, match="cannot compare Permissions with int"): - perms.is_subset(5) # type: ignore + perms.is_subset(5) # pyright: ignore[reportArgumentType] @pytest.mark.parametrize( ("perms_int", "other_int", "expected"), @@ -65,7 +65,7 @@ def test_is_superset(self, perms_int: int, other_int: int, expected: bool) -> No def test_is_superset_only_permissions(self) -> None: perms = Permissions() with pytest.raises(TypeError, match="cannot compare Permissions with int"): - perms.is_superset(5) # type: ignore + perms.is_superset(5) # pyright: ignore[reportArgumentType] @pytest.mark.parametrize( ("perms_int", "other_int", "expected"), @@ -152,7 +152,7 @@ def test_iter(self, parameters: Dict[str, bool], expected: Optional[Dict[str, bo def test_update_ignores(self) -> None: perms = Permissions() - perms.update(h=True) # type: ignore + perms.update(h=True) # pyright: ignore[reportCallIssue] @pytest.mark.parametrize( ("initial", "allow", "deny", "expected"), @@ -209,7 +209,7 @@ def test_init(self) -> None: def test_init_invalid_perms(self) -> None: with pytest.raises(ValueError, match=r"'h' is not a valid permission name."): - PermissionOverwrite(h=True) # type: ignore + PermissionOverwrite(h=True) # pyright: ignore[reportCallIssue] def test_equality(self) -> None: one = PermissionOverwrite() @@ -235,12 +235,12 @@ def test_set(self) -> None: def test_set_invalid_type(self) -> None: po = PermissionOverwrite() with pytest.raises(TypeError, match="Expected bool or NoneType, received str"): - po.connect = "h" # type: ignore + po.connect = "h" # pyright: ignore[reportAttributeAccessIssue] with pytest.raises( AttributeError, match="'PermissionOverwrite' object has no attribute 'oh'" ): - po.oh = False # type: ignore + po.oh = False # pyright: ignore[reportAttributeAccessIssue] @pytest.mark.parametrize( ("allow", "deny"), @@ -317,7 +317,7 @@ def test_update(self) -> None: assert po.manage_emojis is None # invalid names are silently ignored - po.update(h=True) # type: ignore + po.update(h=True) # pyright: ignore[reportCallIssue] assert not hasattr(po, "h") @pytest.mark.parametrize( diff --git a/tests/test_utils.py b/tests/test_utils.py index fcc1ed60e8..29141eaffa 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -190,12 +190,12 @@ def test_time_snowflake(dt, expected) -> None: def test_find() -> None: - pred = lambda i: i == 42 # type: ignore + pred: Callable[[Any], bool] = lambda i: i == 42 assert utils.find(pred, []) is None assert utils.find(pred, [42]) == 42 assert utils.find(pred, [1, 2, 42, 3, 4]) == 42 - pred = lambda i: i.id == 42 # type: ignore + pred = lambda i: i.id == 42 lst = list(map(disnake.Object, [1, 42, 42, 2])) assert utils.find(pred, lst) is lst[1] @@ -256,7 +256,7 @@ def test_get_as_snowflake(data, expected) -> None: def test_maybe_cast() -> None: - convert = lambda v: v + 1 # type: ignore + convert: Callable[[int], int] = lambda v: v + 1 default = object() assert utils._maybe_cast(utils.MISSING, convert) is None diff --git a/tests/ui/test_action_row.py b/tests/ui/test_action_row.py index 38884d7ac0..a32b59c705 100644 --- a/tests/ui/test_action_row.py +++ b/tests/ui/test_action_row.py @@ -82,7 +82,7 @@ def test_add_button(self, index) -> None: _ = ActionRow().add_button _ = ActionRow.with_message_components().add_button # should not work - _ = ActionRow.with_modal_components().add_button # type: ignore + _ = ActionRow.with_modal_components().add_button # pyright: ignore[reportAttributeAccessIssue] def test_add_select(self) -> None: r = ActionRow.with_message_components() @@ -96,7 +96,7 @@ def test_add_select(self) -> None: _ = ActionRow().add_string_select _ = ActionRow.with_message_components().add_string_select # should not work - _ = ActionRow.with_modal_components().add_select # type: ignore + _ = ActionRow.with_modal_components().add_select # pyright: ignore[reportAttributeAccessIssue] def test_add_text_input(self) -> None: with pytest.warns(DeprecationWarning): @@ -112,7 +112,7 @@ def test_add_text_input(self) -> None: _ = ActionRow().add_text_input _ = ActionRow.with_modal_components().add_text_input # should not work - _ = ActionRow.with_message_components().add_text_input # type: ignore + _ = ActionRow.with_message_components().add_text_input # pyright: ignore[reportAttributeAccessIssue] def test_clear_items(self) -> None: r = ActionRow(button1, button2) @@ -285,10 +285,10 @@ def test_normalize_components__modal(value, expected) -> None: def test_normalize_components__invalid() -> None: for value in (42, [42], [ActionRow(), 42], iter([button1])): with pytest.raises(TypeError, match=r"`components` must be a"): - normalize_components(value) # type: ignore + normalize_components(value) # pyright: ignore[reportArgumentType, reportCallIssue] for value in ([[[]]], [[[ActionRow()]]]): with pytest.raises(TypeError, match=r"components should be of type"): - normalize_components(value) # type: ignore + normalize_components(value) # pyright: ignore[reportArgumentType, reportCallIssue] def test_normalize_components_to_dict() -> None: diff --git a/tests/ui/test_decorators.py b/tests/ui/test_decorators.py index 2e9f3fec42..16552d246b 100644 --- a/tests/ui/test_decorators.py +++ b/tests/ui/test_decorators.py @@ -67,5 +67,5 @@ def test_cls(self, cls: Type[_CustomButton[ui.View]]) -> None: def _test_typing_cls(self) -> None: ui.button( cls=_CustomButton, - this_should_not_work="h", # type: ignore + this_should_not_work="h", # pyright: ignore[reportCallIssue] )