<commit_before>""" asyncio-based rfc2812-compliant IRC Client """
import collections
import asyncio
import inspect
import route
import rfc
__all__ = ["Client"]


class Client(object):
    def __init__(self, host, port):
        self.handler = Handler()
        self.connection = Connection(host, port, self.handler)

    def run(self):
        ''' Run the bot forever '''
        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.connection.loop())

    def on(self, command):
        '''
        Decorate a function to be invoked on any :param:`command` message.

        Returns
        -------
        A function decorator that adds the decorated function to this
        :class:`~Client` handlers and returns the underlying function.

        Example
        -------

        bot = Client('localhost', 6697)

        @bot.on('ping')
        def pong(message):
            bot.send('PONG', message=message)

        @bot.on('client_connect')
        def autojoin(host, port):
            bot.send('NICK', 'weatherbot')
            bot.send('USER', 'weatherbot', 0,
                     '*', message="Bill's Weather Bot")
            bot.send('JOIN', '#weather-alert')
            bot.send('JOIN', '#weather-interest')

        bot.run()
        '''
        command = rfc.unique_command(command)

        def wrap(func):
            ''' Add the function to this client's handlers and return it '''
            self.handler.add(command, func)
            return func
        return wrap

    def send(self, command, *params, message=None, prefix=None):
        '''
        Send a message to the server.

        :param:`prefix` and :param:`message` will be prefixed with a ':'

        Examples
        --------
        bot.send('nick', 'weatherbot')
        bot.send('user', 'weatherbot', 0, '*', message='Real Name')

        '''
        self.connection.send(rfc.wire_format(
            command, params=params, message=message, prefix=prefix))

    @asyncio.coroutine
    def connect(self):
        yield from self.connection.connect()

    @asyncio.coroutine
    def disconnect(self):
        yield from self.connection.disconnect()


class Connection(object):
    def __init__(self, host, port, handler):
        # TODO: extract ssl, encoding into configurable settings
        self.handle = handler
        self._connected = False
        self.host, self.port = host, port
        self.reader, self.writer = None, None
        self.encoding, self.ssl = 'UTF-8', True

    @asyncio.coroutine
    def connect(self):
        self.reader, self.writer = yield from asyncio.open_connection(
            self.host, self.port, ssl=self.ssl)
        self._connected = True
        yield from self.handle("CLIENT_CONNECT",
                               {'host': self.host, 'port': self.port})

    @asyncio.coroutine
    def disconnect(self):
        if self.writer:
            self.writer.close()
        self._connected = False
        yield from self.handle("CLIENT_DISCONNECT",
                               {'host': self.host, 'port': self.port})

    @property
    def connected(self):<commit_msg>Refactor Client.run to make loop.run call clearer<commit_after>""" asyncio-based rfc2812-compliant IRC Client """
import collections
import asyncio
import inspect
import route
import rfc
__all__ = ["Client"]


def sync_call(func):
    ''' Blocking invocation of an asynchronous function '''
    loop = asyncio.get_event_loop()
    loop.run_until_complete(func())


class Client(object):
    def __init__(self, host, port):
        self.handler = Handler()
        self.connection = Connection(host, port, self.handler)

    def run(self):
        ''' Run the bot forever '''
        sync_call(self.connection.loop)

    def on(self, command):
        '''
        Decorate a function to be invoked on any :param:`command` message.

        Returns
        -------
        A function decorator that adds the decorated function to this
        :class:`~Client` handlers and returns the underlying function.

        Example
        -------

        bot = Client('localhost', 6697)

        @bot.on('ping')
        def pong(message):
            bot.send('PONG', message=message)

        @bot.on('client_connect')
        def autojoin(host, port):
            bot.send('NICK', 'weatherbot')
            bot.send('USER', 'weatherbot', 0,
                     '*', message="Bill's Weather Bot")
            bot.send('JOIN', '#weather-alert')
            bot.send('JOIN', '#weather-interest')

        bot.run()
        '''
        command = rfc.unique_command(command)

        def wrap(func):
            ''' Add the function to this client's handlers and return it '''
            self.handler.add(command, func)
            return func
        return wrap

    def send(self, command, *params, message=None, prefix=None):
        '''
        Send a message to the server.

        :param:`prefix` and :param:`message` will be prefixed with a ':'

        Examples
        --------
        bot.send('nick', 'weatherbot')
        bot.send('user', 'weatherbot', 0, '*', message='Real Name')

        '''
        self.connection.send(rfc.wire_format(
            command, params=params, message=message, prefix=prefix))

    @asyncio.coroutine
    def connect(self):
        # TODO: make it possible to call Client.connect() inside one of the
        # handlers without any coroutine syntax.  (ie. no yield from)
        yield from self.connection.connect()

    @asyncio.coroutine
    def disconnect(self):
        # TODO: make it possible to call Client.disconnect() inside one of the
        # handlers without any coroutine syntax.  (ie. no yield from)
        yield from self.connection.disconnect()


class Connection(object):
    def __init__(self, host, port, handler):
        # TODO: extract ssl, encoding into configurable settings
        self.handle = handler
        self._connected = False
        self.host, self.port = host, port
        self.reader, self.writer = None, None
        self.encoding, self.ssl = 'UTF-8', True

    @asyncio.coroutine
    def connect(self):
        self.reader, self.writer = yield from asyncio.open_connection(
            self.host, self.port, ssl=self.ssl)
        self._connected = True
        yield from self.handle("CLIENT_CONNECT",
                               {'host': self.host, 'port': self.port})

    @asyncio.coroutine
    def disconnect(self):
        if self.writer:
            self.writer.close()
        self._connected = False
        yield from self.handle("CLIENT_DISCONNECT",
                               {'host': self.host, 'port': self.port})

    @property
    def connected(self):
{'fraction_non_alphanumeric': 0.12091699130955949, 'fraction_numerical': 0.003296373988612526, 'mean_word_length': 2.1396989651928506, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1710519', 'n_tokens_mistral': 1874, 'n_tokens_neox': 1792, 'n_words': 510}