Ejemplo n.º 1
0
    def cancel_all(self, loop=None):
        if loop is None:
            loop = asyncio.get_event_loop()

        popitem_iter = iter_except(self.sessions.popitem, KeyError)
        stop_tasks = (maybe_awaitable(inst.stop) for _, inst in popitem_iter)
        loop.create_task(asyncio.gather(*stop_tasks))   
Ejemplo n.º 2
0
    def test_multiple(self):
        """ensure can catch multiple exceptions"""

        class Fiz(Exception):
            pass

        class Buzz(Exception):
            pass

        i = 0

        def fizbuzz():
            nonlocal i
            i += 1
            if i % 3 == 0:
                raise Fiz
            if i % 5 == 0:
                raise Buzz
            return i

        expected = ([1, 2], [4], [], [7, 8], [])
        for x in expected:
            self.assertEqual(list(mi.iter_except(fizbuzz, (Fiz, Buzz))), x)
Ejemplo n.º 3
0
 def test_first(self):
     """ensure first is run before the function"""
     l = [1, 2, 3]
     f = lambda: 25
     i = mi.iter_except(l.pop, IndexError, f)
     self.assertEqual(list(i), [25, 3, 2, 1])
Ejemplo n.º 4
0
 def test_uncaught_exception_is_raised(self):
     """ensure a non-specified exception is raised"""
     l = [1, 2, 3]
     i = mi.iter_except(l.pop, KeyError)
     self.assertRaises(IndexError, lambda: list(i))
Ejemplo n.º 5
0
 def test_generic_exception(self):
     """ensure the generic exception can be caught"""
     l = [1, 2]
     i = mi.iter_except(l.pop, Exception)
     self.assertEqual(list(i), [2, 1])
Ejemplo n.º 6
0
 def test_exact_exception(self):
     """ensure the exact specified exception is caught"""
     l = [1, 2, 3]
     i = mi.iter_except(l.pop, IndexError)
     self.assertEqual(list(i), [3, 2, 1])
Ejemplo n.º 7
0
 def test_first(self):
     """ensure first is run before the function"""
     l = [1, 2, 3]
     f = lambda: 25
     i = mi.iter_except(l.pop, IndexError, f)
     self.assertEqual(list(i), [25, 3, 2, 1])
Ejemplo n.º 8
0
 def test_uncaught_exception_is_raised(self):
     """ensure a non-specified exception is raised"""
     l = [1, 2, 3]
     i = mi.iter_except(l.pop, KeyError)
     self.assertRaises(IndexError, lambda: list(i))
Ejemplo n.º 9
0
 def test_generic_exception(self):
     """ensure the generic exception can be caught"""
     l = [1, 2]
     i = mi.iter_except(l.pop, Exception)
     self.assertEqual(list(i), [2, 1])
Ejemplo n.º 10
0
 def test_exact_exception(self):
     """ensure the exact specified exception is caught"""
     l = [1, 2, 3]
     i = mi.iter_except(l.pop, IndexError)
     self.assertEqual(list(i), [3, 2, 1])
Ejemplo n.º 11
0
    async def run(self, *, timeout=120, delete_after=True, release_connection=True):
        """Run the interactive loop"""
        _validate_context(self.context)
        if release_connection:
            with contextlib.suppress(AttributeError):
                await self.context.release()

        await self.start()
        if self._message is None:
            # start() was overridden but no message was set
            raise RuntimeError('start() must set self._message')

        message = self._message
        triggers = self._message_callbacks.copy()
        task = None
        listeners = []

        def listen(func):
            listeners.append(func)
            return self._bot.listen()(func)

        # XXX: Can we accomplish without context???
        if self._channel.permissions_for(self.context.me).add_reactions:
            task = self._bot.loop.create_task(self.add_reactions())

            @listen
            async def on_reaction_add(reaction, user):
                if (
                    not self._blocking
                    and reaction.message.id == message.id
                    and user.id in self._users
                    and self.check(reaction, user)
                    and not _trigger_cooldown .is_rate_limited(message.id, user.id)
                ):
                    callback, self._blocking = self._reaction_map[reaction.emoji]
                    cleanup = functools.partial(message.remove_reaction, reaction.emoji, user)
                    await self._queue.put((callback, cleanup))
        else:
            triggers.extend(self._message_fallbacks)

        if triggers:
            @listen
            async def on_message(msg):
                if (
                    self._blocking
                    or msg.channel != self._channel
                    or msg.author.id not in self._users
                ):
                    return

                patterns, callbacks = zip(*triggers)
                selectors = map(re.fullmatch, patterns, itertools.repeat(msg.content))
                callback = next(itertools.compress(callbacks, selectors), None)
                if callback is None:
                    return

                if _trigger_cooldown.is_rate_limited(message.id, msg.author.id):
                    return

                callback, self._blocking = callback
                await self._queue.put((callback, msg.delete))

        try:
            while True:
                # TODO: Would async_timeout be better here?
                try:
                    job = await asyncio.wait_for(self._queue.get(), timeout=timeout)
                except asyncio.TimeoutError:
                    break

                if job is None:
                    break

                callback, after = job

                result = await maybe_awaitable(callback, self)

                with contextlib.suppress(discord.HTTPException):
                    await after()

                self._blocking = False

                if result is None:
                    continue
                self._current = result  # backwards compat...

                try:
                    await message.edit(embed=result)
                except discord.NotFound:  # Message was deleted
                    break

        finally:
            for listener in listeners:
                self._bot.remove_listener(listener)

            if not (task is None or task.done()):
                task.cancel()

            consume(iter_except(self._queue.get_nowait, asyncio.QueueEmpty))
            await self.cleanup(delete_after=delete_after)
Ejemplo n.º 12
0
 def clear(self):
     print(self._placed_numbers)
     for x, y in iter_except(self._placed_numbers.pop, KeyError):
         self._board[y][x] = None
     self.stored_numbers.clear()