Repository: redis/redis-py
File: redis/commands/core.py (Python)

Code before:
    see https://redis.io/topics/pubsub
    """

    def publish(self, channel: ChannelT, message: EncodableT, **kwargs) -> ResponseT:
        """
        Publish ``message`` on ``channel``.
        Returns the number of subscribers the message was delivered to.

        For more information, see https://redis.io/commands/publish
        """
        response = self.execute_command("PUBLISH", channel, message, **kwargs)
        self._event_dispatcher.dispatch(
            OnPubSubMessageEvent(
                direction=PubSubDirection.PUBLISH,
                channel=channel,
            )
        )
        return response

    def spublish(self, shard_channel: ChannelT, message: EncodableT) -> ResponseT:
        """
        Posts a message to the given shard channel.
        Returns the number of clients that received the message

        For more information, see https://redis.io/commands/spublish
        """
        response = self.execute_command("SPUBLISH", shard_channel, message)
        self._event_dispatcher.dispatch(
            OnPubSubMessageEvent(
                direction=PubSubDirection.PUBLISH,
                channel=shard_channel,
                sharded=True,
            )
        )
        return response

    def pubsub_channels(self, pattern: PatternT = "*", **kwargs) -> ResponseT:
        """
        Return a list of channels that have at least one subscriber

        For more information, see https://redis.io/commands/pubsub-channels
        """
        return self.execute_command("PUBSUB CHANNELS", pattern, **kwargs)

    def pubsub_shardchannels(self, pattern: PatternT = "*", **kwargs) -> ResponseT:
        """
        Return a list of shard_channels that have at least one subscriber

        For more information, see https://redis.io/commands/pubsub-shardchannels
        """
        return self.execute_command("PUBSUB SHARDCHANNELS", pattern, **kwargs)

Review comment (suggestion):
The channel parameter has type ChannelT which is Union[bytes, str, memoryview], but OnPubSubMessageEvent expects a str type for the channel field. The channel should be converted to string using str_if_bytes() before passing it to the event, to ensure type consistency and avoid potential issues in the metric recording layer.

Code after:
            # Overwrite the sha just in case there was a discrepancy.
            self.sha = await client.script_load(self.script)
            return await client.evalsha(self.sha, len(keys), *args)


class PubSubCommands(CommandsProtocol):
    """
    Redis PubSub commands.
    see https://redis.io/topics/pubsub
    """

    def publish(self, channel: ChannelT, message: EncodableT, **kwargs) -> ResponseT:
        """
        Publish ``message`` on ``channel``.
        Returns the number of subscribers the message was delivered to.

        For more information, see https://redis.io/commands/publish
        """
        response = self.execute_command("PUBLISH", channel, message, **kwargs)
        self._event_dispatcher.dispatch(
            OnPubSubMessageEvent(
                direction=PubSubDirection.PUBLISH,
                channel=str_if_bytes(channel),
            )
        )
        return response

    def spublish(self, shard_channel: ChannelT, message: EncodableT) -> ResponseT:
        """
        Posts a message to the given shard channel.
        Returns the number of clients that received the message

        For more information, see https://redis.io/commands/spublish
        """
        response = self.execute_command("SPUBLISH", shard_channel, message)
        self._event_dispatcher.dispatch(
            OnPubSubMessageEvent(
                direction=PubSubDirection.PUBLISH,
                channel=str_if_bytes(shard_channel),
                sharded=True,
            )
        )
        return response

    def pubsub_channels(self, pattern: PatternT = "*", **kwargs) -> ResponseT:
        """
        Return a list of channels that have at least one subscriber

        For more information, see https://redis.io/commands/pubsub-channels
        """
        return self.execute_command("PUBSUB CHANNELS", pattern, **kwargs)