Repository: hikari-py/hikari (python)

Issue:
GuildThreadChannel.is_nsfw should be removed
This is just never supplied, a thread's nsfw state is implicitly inherited from the parent channel and never supplied on the thread object itself

Might also be worth refining this further, are we sure we can't just do `is_nsfw=data["nsfw"]` or `is_nsfw=data.get("nsfw", False)` for the channel models where its applicable and just leave it out for everything else

Pull request:
Remove incorrect `is_nsfw` from threads
### Summary
`is_nsfw` now also defaults to `False` when excluded from the payload. It seems like Discord will always send the nsfw field when it is set to `True`, but randomly exclude it when its `False`.

### Checklist
<!-- Make sure to tick all the following boxes by putting an `x` in between (like this `[x]`) -->
- [x] I have run `nox` and all the pipelines have passed.
- [x] I have made unittests according to the code I have added/modified/deleted.

### Related issues
Closes #1328


Patch:
diff --git a/changes/1386.bugfix.md b/changes/1386.bugfix.md
new file mode 100644
index 00000000..7f5f02a2
--- /dev/null
+++ b/changes/1386.bugfix.md
@@ -0,0 +1,3 @@
+Remove incorrect `is_nsfw` field from threads.
+- The "NSFW" status is inherited from the parent object and not sent for threads.
+- This also involved moving the base attribute from `GuildChannel` to `PermissibleGuildChannel`.
diff --git a/dev-requirements/flake8.txt b/dev-requirements/flake8.txt
index cc51df0a..43f9e6d9 100644
--- a/dev-requirements/flake8.txt
+++ b/dev-requirements/flake8.txt
@@ -21,3 +21,4 @@ flake8-printf-formatting==1.1.2         # forbey printf-style python2 string for
 flake8-pytest-style==1.6.0              # pytest checks
 flake8-raise==0.0.5                     # exception raising linting
 flake8-use-fstring==1.4                 # format string checking
+flake8-noqa==1.3.0                      # validate noqa commands
diff --git a/hikari/api/cache.py b/hikari/api/cache.py
index 49107356..817681f9 100644
--- a/hikari/api/cache.py
+++ b/hikari/api/cache.py
@@ -462,7 +462,7 @@ def get_members_view(self) -> CacheView[snowflakes.Snowflake, CacheView[snowflak
         CacheView[hikari.snowflakes.Snowflake, CacheView[hikari.snowflakes.Snowflake, hikari.guilds.Member]]
             A view of guild IDs to views of user IDs to objects of the members
             that were found from the cache.
-        """  # noqa E501 - Line too long
+        """
 
     @abc.abstractmethod
     def get_members_view_for_guild(
@@ -665,7 +665,7 @@ def get_voice_states_view(
         CacheView[hikari.snowflakes.Snowflake, CacheView[hikari.snowflakes.Snowflake, hikari.voices.VoiceState]]
             A view of guild IDs to views of user IDs to objects of the voice
             states that were found in the cache,
-        """  # noqa E501 - Line too long
+        """
 
     @abc.abstractmethod
     def get_voice_states_view_for_channel(
@@ -992,7 +992,7 @@ def update_guild(
             A tuple of the old cached guild object if found (else `builtins.None`)
             and the object of the guild that was added to the cache if it could
             be added (else `builtins.None`).
-        """  # noqa E501 - Line too long
+        """
 
     @abc.abstractmethod
     def clear_guild_channels(self) -> CacheView[snowflakes.Snowflake, channels.PermissibleGuildChannel]:
@@ -1057,7 +1057,7 @@ def update_guild_channel(
     ) -> typing.Tuple[
         typing.Optional[channels.PermissibleGuildChannel], typing.Optional[channels.PermissibleGuildChannel]
     ]:
-        """Update a guild channel in the cache,
+        """Update a guild channel in the cache.
 
         Parameters
         ----------
@@ -1070,7 +1070,7 @@ def update_guild_channel(
             A tuple of the old cached guild channel if found (else `builtins.None`)
             and the new cached guild channel if it could be cached
             (else `builtins.None`).
-        """  # noqa E501 - Line too long
+        """  # noqa: E501 - Line too long
 
     @abc.abstractmethod
     def clear_invites(self) -> CacheView[str, invites.InviteWithMetadata]:
@@ -1169,7 +1169,7 @@ def update_invite(
             A tuple of the old cached invite object if found (else
             `builtins.None`) and the new cached invite object if it could be
             cached (else `builtins.None`).
-        """  # noqa E501 - Line too long
+        """
 
     @abc.abstractmethod
     def delete_me(self) -> typing.Optional[users.OwnUser]:
@@ -1220,7 +1220,7 @@ def clear_members(self) -> CacheView[snowflakes.Snowflake, CacheView[snowflakes.
         CacheView[hikari.snowflakes.Snowflake, CacheView[hikari.snowflakes.Snowflake, hikari.guilds.Member]]
             A view of guild IDs to views of user IDs to objects of the members
             that were removed from the cache.
-        """  # noqa E501 - Line too long
+        """
 
     @abc.abstractmethod
     def clear_members_for_guild(
@@ -1382,7 +1382,7 @@ def update_presence(
             A tuple of the old cached invite object if found (else `builtins.None`
             and the new cached invite object if it could be cached ( else
             `builtins.None`).
-        """  # noqa E501 - Line too long
+        """
 
     @abc.abstractmethod
     def clear_roles(self) -> CacheView[snowflakes.Snowflake, guilds.Role]:
@@ -1467,7 +1467,7 @@ def clear_voice_states(self) -> CacheView[snowflakes.Snowflake, CacheView[snowfl
         CacheView[hikari.snowflakes.Snowflake, CacheView[hikari.snowflakes.Snowflake, hikari.voices.VoiceState]]
             A view of guild IDs to views of user IDs to objects of the voice
             states that were removed from the states.
-        """  # noqa E501 - Line too long
+        """
 
     @abc.abstractmethod
     def clear_voice_states_for_guild(
diff --git a/hikari/api/interaction_server.py b/hikari/api/interaction_server.py
index 9b555654..8019d4cc 100644
--- a/hikari/api/interaction_server.py
+++ b/hikari/api/interaction_server.py
@@ -184,7 +184,7 @@ def get_listener(
         typing.Optional[ListenersT[hikari.interactions.base_interactions.PartialInteraction, hikari.api.special_endpoints.InteractionResponseBuilder]
             The callback registered for the provided interaction type if found,
             else `builtins.None`.
-        """  # noqa E501 - Line too long
+        """  # noqa: E501 - Line too long
 
     @typing.overload
     @abc.abstractmethod
@@ -254,4 +254,4 @@ def set_listener(
         ------
         builtins.TypeError
             If `replace` is `builtins.False` when a listener is already set.
-        """  # noqa E501 - Line too long
+        """  # noqa: E501 - Line too long
diff --git a/hikari/api/rest.py b/hikari/api/rest.py
index 22a0ffbc..00e6e043 100644
--- a/hikari/api/rest.py
+++ b/hikari/api/rest.py
@@ -315,7 +315,7 @@ async def edit_channel(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     async def follow_channel(
@@ -787,7 +787,7 @@ async def create_invite(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     def trigger_typing(
@@ -1049,7 +1049,7 @@ def fetch_messages(
             be raised once the result is awaited or iterated over. Invoking
             this function itself will not raise anything (other than
             `builtins.TypeError`).
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     async def fetch_message(
@@ -5315,7 +5315,7 @@ def fetch_public_archived_threads(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     def fetch_private_archived_threads(
@@ -5375,7 +5375,7 @@ def fetch_private_archived_threads(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     def fetch_joined_private_archived_threads(
@@ -5436,7 +5436,7 @@ def fetch_joined_private_archived_threads(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     async def reposition_channels(
@@ -6540,7 +6540,7 @@ async def estimate_guild_prune_count(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     async def begin_guild_prune(
@@ -6605,7 +6605,7 @@ async def begin_guild_prune(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     async def fetch_guild_voice_regions(
@@ -8376,7 +8376,7 @@ async def create_autocomplete_response(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     def build_action_row(self) -> special_endpoints.ActionRowBuilder:
diff --git a/hikari/api/special_endpoints.py b/hikari/api/special_endpoints.py
index 64cc6fae..87c3fc88 100644
--- a/hikari/api/special_endpoints.py
+++ b/hikari/api/special_endpoints.py
@@ -383,7 +383,7 @@ def add_category(
 
             When the guild is created, this will be replaced with a different
             ID.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     def add_text_channel(
@@ -434,7 +434,7 @@ def add_text_channel(
 
             When the guild is created, this will be replaced with a different
             ID.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     def add_voice_channel(
@@ -492,7 +492,7 @@ def add_voice_channel(
 
             When the guild is created, this will be replaced with a different
             ID.
-        """  # noqa: E501 - Line too long
+        """
 
     @abc.abstractmethod
     def add_stage_channel(
@@ -1384,7 +1384,7 @@ def set_emoji(
         -------
         ButtonBuilder
             The builder object to enable chained calls.
-        """  # noqa E501 - Line too long
+        """
 
     @abc.abstractmethod
     def set_label(self: _T, label: undefined.UndefinedOr[str], /) -> _T:
@@ -1560,7 +1560,7 @@ def set_emoji(
         -------
         SelectOptionBuilder
             The builder object to enable chained calls.
-        """  # noqa E501 - Line too long
+        """
 
     @abc.abstractmethod
     def set_is_default(self: _T, state: bool, /) -> _T:
diff --git a/hikari/channels.py b/hikari/channels.py
index 0b23cea6..6ef00f33 100644
--- a/hikari/channels.py
+++ b/hikari/channels.py
@@ -462,7 +462,7 @@ def fetch_history(
             be raised once the result is awaited or interacted with. Invoking
             this function itself will not raise anything (other than
             `builtins.TypeError`).
-        """  # noqa: E501 - Line too long
+        """
         return self.app.rest.fetch_messages(self.id, before=before, after=after, around=around)
 
     async def fetch_message(self, message: snowflakes.SnowflakeishOr[messages.PartialMessage]) -> messages.Message:
@@ -956,14 +956,6 @@ class GuildChannel(PartialChannel):
     guild_id: snowflakes.Snowflake = attr.field(eq=False, hash=False, repr=True)
     """The ID of the guild the channel belongs to."""
 
-    is_nsfw: typing.Optional[bool] = attr.field(eq=False, hash=False, repr=False)
-    """Whether the channel is marked as NSFW.
-
-    !!! warning
-        This will be `builtins.None` when received over the gateway in certain events
-        (e.g Guild Create).
-    """
-
     parent_id: typing.Optional[snowflakes.Snowflake] = attr.field(eq=False, hash=False, repr=True)
     """The ID of the parent channel the channel belongs to.
 
@@ -1113,7 +1105,7 @@ async def edit(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
         return await self.app.rest.edit_channel(
             self.id,
             name=name,
@@ -1147,6 +1139,9 @@ class PermissibleGuildChannel(GuildChannel):
     Higher numbers appear further down the channel list.
     """
 
+    is_nsfw: bool = attr.field(eq=False, hash=False, repr=False)
+    """Whether the channel is marked as NSFW."""
+
     permission_overwrites: typing.Mapping[snowflakes.Snowflake, PermissionOverwrite] = attr.field(
         eq=False, hash=False, repr=False
     )
diff --git a/hikari/colors.py b/hikari/colors.py
index 3866ab01..7ef7b498 100644
--- a/hikari/colors.py
+++ b/hikari/colors.py
@@ -223,9 +223,8 @@ def raw_hex_code(self) -> str:
         components = self.rgb
         return "".join(hex(c)[2:].zfill(2) for c in components).upper()
 
-    # Ignore docstring not starting in an imperative mood
     @property
-    def is_web_safe(self) -> bool:  # noqa: D401
+    def is_web_safe(self) -> bool:
         """`builtins.True` if the color is web safe, `builtins.False` otherwise."""
         return not (((self & 0xFF0000) % 0x110000) or ((self & 0xFF00) % 0x1100) or ((self & 0xFF) % 0x11))
 
diff --git a/hikari/impl/entity_factory.py b/hikari/impl/entity_factory.py
index e4c309ab..cb36a2fa 100644
--- a/hikari/impl/entity_factory.py
+++ b/hikari/impl/entity_factory.py
@@ -110,7 +110,6 @@ class _GuildChannelFields:
     name: typing.Optional[str] = attr.field()
     type: typing.Union[channel_models.ChannelType, int] = attr.field()
     guild_id: snowflakes.Snowflake = attr.field()
-    is_nsfw: typing.Optional[bool] = attr.field()
     parent_id: typing.Optional[snowflakes.Snowflake] = attr.field()
 
 
@@ -451,7 +450,6 @@ def __init__(self, app: traits.RESTAware) -> None:
             audit_log_models.AuditLogChangeKey.VERIFICATION_LEVEL: guild_models.GuildVerificationLevel,
             audit_log_models.AuditLogChangeKey.EXPLICIT_CONTENT_FILTER: guild_models.GuildExplicitContentFilterLevel,
             audit_log_models.AuditLogChangeKey.DEFAULT_MESSAGE_NOTIFICATIONS: guild_models.GuildMessageNotificationsLevel,
-            # noqa: E501 - Line too long
             audit_log_models.AuditLogChangeKey.PRUNE_DELETE_DAYS: _deserialize_day_timedelta,
             audit_log_models.AuditLogChangeKey.WIDGET_CHANNEL_ID: snowflakes.Snowflake,
             audit_log_models.AuditLogChangeKey.POSITION: int,
@@ -930,7 +928,6 @@ def _set_guild_channel_attributes(
             name=payload.get("name"),
             type=channel_models.ChannelType(payload["type"]),
             guild_id=guild_id,
-            is_nsfw=payload.get("nsfw"),
             parent_id=parent_id,
         )
 
@@ -952,7 +949,7 @@ def deserialize_guild_category(
             type=channel_fields.type,
             guild_id=channel_fields.guild_id,
             permission_overwrites=permission_overwrites,
-            is_nsfw=channel_fields.is_nsfw,
+            is_nsfw=payload.get("nsfw", False),
             parent_id=None,
             position=int(payload["position"]),
         )
@@ -987,7 +984,7 @@ def deserialize_guild_text_channel(
             type=channel_fields.type,
             guild_id=channel_fields.guild_id,
             permission_overwrites=permission_overwrites,
-            is_nsfw=channel_fields.is_nsfw,
+            is_nsfw=payload.get("nsfw", False),
             parent_id=channel_fields.parent_id,
             topic=payload["topic"],
             last_message_id=last_message_id,
@@ -1030,7 +1027,7 @@ def deserialize_guild_news_channel(
             type=channel_fields.type,
             guild_id=channel_fields.guild_id,
             permission_overwrites=permission_overwrites,
-            is_nsfw=channel_fields.is_nsfw,
+            is_nsfw=payload.get("nsfw", False),
             parent_id=channel_fields.parent_id,
             topic=payload["topic"],
             last_message_id=last_message_id,
@@ -1064,7 +1061,7 @@ def deserialize_guild_voice_channel(
             type=channel_fields.type,
             guild_id=channel_fields.guild_id,
             permission_overwrites=permission_overwrites,
-            is_nsfw=channel_fields.is_nsfw,
+            is_nsfw=payload.get("nsfw", False),
             parent_id=channel_fields.parent_id,
             # There seems to be an edge case where rtc_region won't be included in gateway events (e.g. GUILD_CREATE)
             # for a voice channel that just hasn't been touched since this was introduced (e.g. has been archived).
@@ -1094,7 +1091,7 @@ def deserialize_guild_stage_channel(
             type=channel_fields.type,
             guild_id=channel_fields.guild_id,
             permission_overwrites=permission_overwrites,
-            is_nsfw=channel_fields.is_nsfw,
+            is_nsfw=payload.get("nsfw", False),
             parent_id=channel_fields.parent_id,
             region=payload["rtc_region"],
             bitrate=int(payload["bitrate"]),
@@ -1164,7 +1161,6 @@ def deserialize_guild_news_thread(
             name=channel_fields.name,
             type=channel_fields.type,
             guild_id=channel_fields.guild_id,
-            is_nsfw=channel_fields.is_nsfw,
             parent_id=channel_fields.parent_id,
             last_message_id=last_message_id,
             last_pin_timestamp=last_pin_timestamp,
@@ -1213,7 +1209,6 @@ def deserialize_guild_public_thread(
             name=channel_fields.name,
             type=channel_fields.type,
             guild_id=channel_fields.guild_id,
-            is_nsfw=channel_fields.is_nsfw,
             parent_id=channel_fields.parent_id,
             last_message_id=last_message_id,
             last_pin_timestamp=last_pin_timestamp,
@@ -1262,7 +1257,6 @@ def deserialize_guild_private_thread(
             name=channel_fields.name,
             type=channel_fields.type,
             guild_id=channel_fields.guild_id,
-            is_nsfw=channel_fields.is_nsfw,
             parent_id=channel_fields.parent_id,
             last_message_id=last_message_id,
             last_pin_timestamp=last_pin_timestamp,
@@ -2671,7 +2665,7 @@ def _deserialize_message_interaction(self, payload: data_binding.JSONObject) ->
             user=self.deserialize_user(payload["user"]),
         )
 
-    def deserialize_partial_message(  # noqa CFQ001 - Function too long
+    def deserialize_partial_message(  # noqa: C901 - Too complex
         self, payload: data_binding.JSONObject
     ) -> message_models.PartialMessage:
         author: undefined.UndefinedOr[user_models.User] = undefined.UNDEFINED
@@ -2802,9 +2796,7 @@ def deserialize_partial_message(  # noqa CFQ001 - Function too long
             mentions_everyone=payload.get("mention_everyone", undefined.UNDEFINED),
         )
 
-    def deserialize_message(
-        self, payload: data_binding.JSONObject
-    ) -> message_models.Message:  # noqa CFQ001 - Function too long
+    def deserialize_message(self, payload: data_binding.JSONObject) -> message_models.Message:
         author = self.deserialize_user(payload["author"])
 
         guild_id: typing.Optional[snowflakes.Snowflake] = None
@@ -2902,7 +2894,7 @@ def deserialize_message(
     # PRESENCE MODELS #
     ###################
 
-    def deserialize_member_presence(  # noqa: CFQ001 - Max function length
+    def deserialize_member_presence(
         self,
         payload: data_binding.JSONObject,
         *,
diff --git a/hikari/impl/rate_limits.py b/hikari/impl/rate_limits.py
index 0ecd2c15..449a179d 100644
--- a/hikari/impl/rate_limits.py
+++ b/hikari/impl/rate_limits.py
@@ -509,7 +509,7 @@ def __next__(self) -> float:
             # If this happened then we can be sure that we've passed maximum.
             value = self.maximum
 
-        return value + random.random() * self.jitter_multiplier  # nosec  # noqa S311 rng for cryptography
+        return value + random.random() * self.jitter_multiplier  # noqa: S311 - rng for cryptography
 
     def __iter__(self) -> ExponentialBackOff:
         """Return this object, as it is an iterator."""
diff --git a/hikari/impl/special_endpoints.py b/hikari/impl/special_endpoints.py
index 01ed2ae5..0bc9ca8b 100644
--- a/hikari/impl/special_endpoints.py
+++ b/hikari/impl/special_endpoints.py
@@ -1391,7 +1391,7 @@ def _build_emoji(
     typing.Tuple[hikari.undefined.UndefinedOr[builtins.str], hikari.undefined.UndefinedOr[builtins.str]]
         A union of the custom emoji's id if defined (index 0) or the unicode
         emoji's string representation (index 1).
-    """  # noqa E501 - Line too long
+    """
     # Since these builder classes may be re-used, this method should be called when the builder is being constructed.
     if emoji is not undefined.UNDEFINED:
         if isinstance(emoji, (int, emojis.CustomEmoji)):
diff --git a/hikari/internal/aio.py b/hikari/internal/aio.py
index b7dae559..08f0285c 100644
--- a/hikari/internal/aio.py
+++ b/hikari/internal/aio.py
@@ -78,13 +78,13 @@ def completed_future(result: typing.Optional[T_inv] = None, /) -> asyncio.Future
 # On Python3.8.2, there appears to be a bug with the typing module:
 
 # >>> class Aiterable:
-# ...     async def __aiter__(self):  # noqa: E800
+# ...     async def __aiter__(self):
 # ...         yield ...
 # >>> isinstance(Aiterable(), typing.AsyncIterable)
 # True
 
 # >>> class Aiterator:
-# ...     async def __anext__(self):  # noqa: E800
+# ...     async def __anext__(self):
 # ...         return ...
 # >>> isinstance(Aiterator(), typing.AsyncIterator)
 # False
diff --git a/hikari/internal/data_binding.py b/hikari/internal/data_binding.py
index 40b8613e..8d54bbe4 100644
--- a/hikari/internal/data_binding.py
+++ b/hikari/internal/data_binding.py
@@ -391,7 +391,7 @@ def put_snowflake_array(
         values : hikari.undefined.UndefinedOr[typing.Iterable[hikari.snowflakes.SnowflakeishOr[hikari.snowflakes.Unique]]]
             The JSON snowflakes to put. This may alternatively be undefined.
             In the latter case, nothing is performed.
-        """  # noqa: E501 - Line too long
+        """
         if values is not undefined.UNDEFINED:
             self[key] = [str(int(value)) for value in values]
 
diff --git a/hikari/users.py b/hikari/users.py
index f4d7c566..4efc7743 100644
--- a/hikari/users.py
+++ b/hikari/users.py
@@ -749,7 +749,7 @@ class UserImpl(PartialUserImpl, User):
     """The custom banner color for the user, if set.
 
     The official client will decide the default color if not set.
-    """  # noqa: D401 - Imperative mood
+    """
 
     is_bot: bool = attr.field(eq=False, hash=False, repr=True)
     """`builtins.True` if this user is a bot account, `builtins.False` otherwise."""
diff --git a/hikari/webhooks.py b/hikari/webhooks.py
index b860abfe..c5b94290 100644
--- a/hikari/webhooks.py
+++ b/hikari/webhooks.py
@@ -761,7 +761,7 @@ async def edit(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
         token: undefined.UndefinedOr[str] = undefined.UNDEFINED
         if use_token:
             if self.token is None:
@@ -963,7 +963,7 @@ async def edit(
             nature, and will trigger this exception if they occur.
         hikari.errors.InternalServerError
             If an internal error occurs on Discord while handling the request.
-        """  # noqa: E501 - Line too long
+        """
         webhook = await self.app.rest.edit_webhook(
             self.id,
             name=name,


Test patch:
diff --git a/tests/hikari/impl/test_entity_factory.py b/tests/hikari/impl/test_entity_factory.py
index 477e5c31..9a55ace5 100644
--- a/tests/hikari/impl/test_entity_factory.py
+++ b/tests/hikari/impl/test_entity_factory.py
@@ -1670,7 +1670,7 @@ def test_deserialize_guild_category_with_unset_fields(self, entity_factory_impl,
             }
         )
         assert guild_category.parent_id is None
-        assert guild_category.is_nsfw is None
+        assert guild_category.is_nsfw is False
 
     def test_deserialize_guild_category_with_null_fields(self, entity_factory_impl, permission_overwrite_payload):
         guild_category = entity_factory_impl.deserialize_guild_category(
@@ -1723,7 +1723,7 @@ def test_deserialize_guild_text_channel_with_unset_fields(self, entity_factory_i
                 "guild_id": "123123123",
             }
         )
-        assert guild_text_channel.is_nsfw is None
+        assert guild_text_channel.is_nsfw is False
         assert guild_text_channel.rate_limit_per_user.total_seconds() == 0
         assert guild_text_channel.last_pin_timestamp is None
         assert guild_text_channel.parent_id is None
@@ -1787,7 +1787,7 @@ def test_deserialize_guild_news_channel_with_unset_fields(self, entity_factory_i
                 "guild_id": "4123",
             }
         )
-        assert news_channel.is_nsfw is None
+        assert news_channel.is_nsfw is False
         assert news_channel.parent_id is None
         assert news_channel.last_pin_timestamp is None
         assert news_channel.last_message_id is None
@@ -1869,7 +1869,7 @@ def test_deserialize_guild_voice_channel_with_unset_fields(self, entity_factory_
         )
         assert voice_channel.video_quality_mode is channel_models.VideoQualityMode.AUTO
         assert voice_channel.parent_id is None
-        assert voice_channel.is_nsfw is None
+        assert voice_channel.is_nsfw is False
         assert voice_channel.region is None
 
     @pytest.fixture()
@@ -1941,7 +1941,7 @@ def test_deserialize_guild_stage_channel_with_unset_fields(self, entity_factory_
             }
         )
         assert voice_channel.parent_id is None
-        assert voice_channel.is_nsfw is None
+        assert voice_channel.is_nsfw is False
 
     def test_deserialize_thread_member(
         self, entity_factory_impl: entity_factory.EntityFactoryImpl, thread_member_payload: typing.Dict[str, typing.Any]
diff --git a/tests/hikari/impl/test_rest.py b/tests/hikari/impl/test_rest.py
index e6a111f1..8c1a2708 100644
--- a/tests/hikari/impl/test_rest.py
+++ b/tests/hikari/impl/test_rest.py
@@ -168,7 +168,7 @@ async def test_acquire_handles_out_of_date_token(self, mock_token):
             client=3412321, client_secret="54123123", scopes=("applications.commands.update", "identify")
         )
         assert new_token != token
-        assert new_token == "Bearer okokok.fofofo.ddd"  # noqa S105: Possible Hardcoded password
+        assert new_token == "Bearer okokok.fofofo.ddd"
 
     @pytest.mark.asyncio()
     async def test_acquire_handles_token_being_set_before_lock_is_acquired(self, mock_token):
@@ -215,7 +215,7 @@ async def test_acquire_after_invalidation(self, mock_token):
             client=123, client_secret="123456", scopes=("applications.commands.update", "identify")
         )
         assert new_token != token
-        assert new_token == "Bearer okokok.fofofo.ddd"  # noqa S105: Possible Hardcoded password
+        assert new_token == "Bearer okokok.fofofo.ddd"
 
     @pytest.mark.asyncio()
     async def test_acquire_uses_newly_cached_token_after_acquiring_lock(self):
@@ -749,7 +749,7 @@ def test__transform_emoji_to_url_format(self, rest_client, emoji, expected_retur
     def test__transform_emoji_to_url_format_with_id(self, rest_client):
         assert rest_client._transform_emoji_to_url_format("rooYay", 123) == "rooYay:123"
 
-    @pytest.mark.parametrize(  # noqa: PT014 - Duplicate test cases (false positive)
+    @pytest.mark.parametrize(
         "emoji",
         [
             emojis.CustomEmoji(id=123, name="rooYay", is_animated=False),
diff --git a/tests/hikari/internal/test_signals.py b/tests/hikari/internal/test_signals.py
index 7724fea2..19ab2342 100644
--- a/tests/hikari/internal/test_signals.py
+++ b/tests/hikari/internal/test_signals.py
@@ -84,7 +84,7 @@ def test_when_disabled(self):
 
     def test_when_propagate_interrupt(self):
         with mock.patch.object(signal, "signal"):
-            with pytest.raises(errors.HikariInterrupt):  # noqa:  PT012 - raises block should contain a single statement
+            with pytest.raises(errors.HikariInterrupt):  # noqa: PT012 - raises block should contain a single statement
                 with signals.handle_interrupts(True, object(), True):
                     raise errors.HikariInterrupt(1, "t")
 
diff --git a/tests/hikari/test_channels.py b/tests/hikari/test_channels.py
index 336d9c65..977c512a 100644
--- a/tests/hikari/test_channels.py
+++ b/tests/hikari/test_channels.py
@@ -324,7 +324,6 @@ def model(self, mock_app):
             name="foo1",
             type=channels.ChannelType.GUILD_VOICE,
             guild_id=snowflakes.Snowflake(123456789),
-            is_nsfw=True,
             parent_id=None,
         )