示例#1
0
 def test___setitem___when_limit_reached_and_expire_callback_set(self):
     expire_callback = mock.Mock()
     mock_map = collections.LimitedCapacityCacheMap(limit=4, on_expire=expire_callback)
     mock_map.update({"bll": "no", "ieiei": "lslsl", "pacify": "me", "qt": "pie"})
     mock_map["eva"] = "Rei"
     mock_map.update({"shinji": "ikari"})
     expire_callback.assert_has_calls((mock.call("no"), mock.call("lslsl")))
示例#2
0
    def test_copy(self):
        mock_map = collections.LimitedCapacityCacheMap({"o": "n", "b": "a", "a": "v"}, limit=42)
        result = mock_map.copy()

        assert result is not mock_map
        assert isinstance(result, collections.LimitedCapacityCacheMap)
        assert result == {"o": "n", "b": "a", "a": "v"}
示例#3
0
 def test___iter___(self):
     mock_map = collections.LimitedCapacityCacheMap(limit=50)
     mock_map.update({
         "OK": "blam",
         "blaaa": "neoeo",
         "neon": "genesis",
         "evangelion": None
     })
     assert list(mock_map) == ["OK", "blaaa", "neon", "evangelion"]
示例#4
0
 def test___len___(self):
     mock_map = collections.LimitedCapacityCacheMap(limit=50)
     mock_map.update({
         "ooga": "blam",
         "blaaa": "neoeo",
         "the": "boys",
         "neon": "genesis",
         "evangelion": None
     })
     assert len(mock_map) == 5
示例#5
0
    def test_freeze(self):
        mock_map = collections.LimitedCapacityCacheMap(
            {
                "o": "no",
                "good": "bye"
            }, limit=5)
        result = mock_map.freeze()

        assert isinstance(result, dict)
        assert result == {"o": "no", "good": "bye"}
示例#6
0
    def test_clear(self):
        mock_map = collections.LimitedCapacityCacheMap(
            {
                "o": "n",
                "b": "a",
                "a": "v"
            }, limit=42)
        mock_map.clear()

        assert mock_map._data == {}
示例#7
0
 def test___setitem___when_limit_not_reached(self):
     mock_map = collections.LimitedCapacityCacheMap(limit=50)
     mock_map["OK"] = 523
     mock_map["blam"] = 512387
     mock_map.update({"bll": "no", "ieiei": "lslsl"})
     assert mock_map == {
         "OK": 523,
         "blam": 512387,
         "bll": "no",
         "ieiei": "lslsl"
     }
示例#8
0
 def test___setitem___when_limit_reached(self):
     mock_map = collections.LimitedCapacityCacheMap(limit=4)
     mock_map.update({
         "bll": "no",
         "ieiei": "lslsl",
         "pacify": "me",
         "qt": "pie"
     })
     mock_map["eva"] = "Rei"
     mock_map.update({"shinji": "ikari"})
     assert mock_map == {
         "pacify": "me",
         "qt": "pie",
         "eva": "Rei",
         "shinji": "ikari"
     }
示例#9
0
 def test___getitem___for_non_existing_entry(self):
     mock_map = collections.LimitedCapacityCacheMap(limit=50)
     with pytest.raises(KeyError):
         mock_map["CIA"]
示例#10
0
 def test___getitem___for_existing_entry(self):
     mock_map = collections.LimitedCapacityCacheMap(limit=50)
     mock_map["blat"] = 42
     assert mock_map["blat"] == 42
示例#11
0
 def test___delitem___for_existing_entry(self):
     mock_map = collections.LimitedCapacityCacheMap(limit=50)
     mock_map["Ok"] = 42
     del mock_map["Ok"]
     assert "Ok" not in mock_map
示例#12
0
 def test___init___with_source(self):
     raw_map = {"voo": "doo", "blam": "blast", "foo": "bye"}
     mock_map = collections.LimitedCapacityCacheMap(raw_map, limit=2)
     assert mock_map == {"blam": "blast", "foo": "bye"}
示例#13
0
class StatefulGuildChunkerImpl(chunker.GuildChunker):
    """Guild chunker implementation.

    Parameters
    ----------
    app : hikari.traits.BotAware
        The object of the bot aware app this is bound to.
    limit : builtins.int
        The maximum amount of requests that this chunker should store information
        about for each shard.
    """

    __slots__: typing.Sequence[str] = ("_app", "_limit", "_tracked")

    def __init__(self, app: traits.BotAware, limit: int = 200) -> None:
        self._app = app
        self._limit = limit
        self._tracked: typing.MutableMapping[
            int, collections.LimitedCapacityCacheMap[str,
                                                     _TrackedRequests]] = {}

    def _default_include_presences(
            self, guild_id: snowflakes.Snowflake,
            include_presences: undefined.UndefinedOr[bool]) -> bool:
        if include_presences is not undefined.UNDEFINED:
            return include_presences

        shard_id = snowflakes.calculate_shard_id(self._app, guild_id)
        shard = self._app.shards[shard_id]
        return bool(shard.intents & intents_.Intents.GUILD_PRESENCES)

    def fetch_members_for_guild(
        self,
        guild: snowflakes.SnowflakeishOr[guilds.GatewayGuild],
        *,
        timeout: typing.Union[int, float, None],
        limit: typing.Optional[int] = None,
        include_presences: undefined.UndefinedOr[bool] = undefined.UNDEFINED,
        query_limit: int = 0,
        query: str = "",
        users: undefined.UndefinedOr[typing.Sequence[snowflakes.SnowflakeishOr[
            users_.User]]] = undefined.UNDEFINED,
    ) -> event_stream.Streamer[shard_events.MemberChunkEvent]:
        guild_id = snowflakes.Snowflake(guild)
        return ChunkStream(
            app=self._app,
            guild_id=guild_id,
            timeout=timeout,
            limit=limit,
            include_presences=self._default_include_presences(
                guild_id, include_presences),
            query_limit=query_limit,
            query=query,
            users=users,
        )

    async def get_request_status(
            self, nonce: str,
            /) -> typing.Optional[chunker.RequestInformation]:
        try:
            shard_id = int(nonce.split(".", 1)[0])
        except ValueError:
            return None
        else:
            return copy.copy(self._tracked[shard_id].get(
                nonce)) if shard_id in self._tracked else None

    async def list_requests_for_shard(
            self, shard: typing.Union[gateway_shard.GatewayShard, int],
            /) -> typing.Sequence[chunker.RequestInformation]:
        shard_id = shard if isinstance(shard, int) else shard.id

        if shard_id not in self._tracked:
            return ()

        return tuple(
            copy.copy(chunk)
            for chunk in self._tracked[shard_id].copy().values())

    async def list_requests_for_guild(
            self, guild: snowflakes.SnowflakeishOr[guilds.GatewayGuild],
            /) -> typing.Sequence[chunker.RequestInformation]:
        guild_id = snowflakes.Snowflake(guild)
        shard_id = snowflakes.calculate_shard_id(self._app, guild_id)
        if shard_id not in self._tracked:
            return ()

        return tuple(
            copy.copy(event) for event in self._tracked[shard_id].values()
            if event.guild_id == guild_id)

    async def consume_chunk_event(self, event: shard_events.MemberChunkEvent,
                                  /) -> None:
        if (event.shard.id not in self._tracked or event.nonce is None
                or event.nonce not in self._tracked[event.shard.id]):
            return

        self._tracked[event.shard.id][event.nonce].update(event)

    async def request_guild_members(
        self,
        guild: snowflakes.SnowflakeishOr[guilds.GatewayGuild],
        /,
        include_presences: undefined.UndefinedOr[bool] = undefined.UNDEFINED,
        limit: int = 0,
        query: str = "",
        users: undefined.UndefinedOr[typing.Sequence[snowflakes.SnowflakeishOr[
            users_.User]]] = undefined.UNDEFINED,
    ) -> str:
        guild_id = snowflakes.Snowflake(guild)
        shard_id = snowflakes.calculate_shard_id(self._app, guild_id)
        nonce = f"{shard_id}.{_random_nonce()}"
        if shard_id not in self._tracked:
            self._tracked[shard_id] = collections.LimitedCapacityCacheMap(
                limit=self._limit)

        tracker = _TrackedRequests(guild_id=guild_id, nonce=nonce)
        self._tracked[shard_id][nonce] = tracker
        await self._app.shards[shard_id].request_guild_members(
            guild=guild_id,
            include_presences=self._default_include_presences(
                guild_id, include_presences),
            limit=limit,
            nonce=nonce,
            query=query,
            users=users,
        )
        return nonce