<commit_before>#
# This file is part of Evergreen. See the NOTICE for more information.
#

import pyuv

import evergreen
from evergreen.io.stream import BaseStream, StreamError, StreamConnection, StreamServer
from evergreen.io.util import Result, convert_errno

__all__ = ['TCPServer', 'TCPClient', 'TCPConnection', 'TCPError']


class TCPError(StreamError):
    pass


class TCPStream(BaseStream):
    error_class = TCPError

    def __init__(self, handle):
        super(TCPStream, self).__init__()
        self._handle = handle
        self._read_result = Result()

    @property
    def readable(self):
        return self._handle.readable

    @property
    def writable(self):
        return self._handle.writable

    @property
    def sockname(self):
        self._check_closed()
        return self._handle.getsockname()

    @property
    def peername(self):
        self._check_closed()
        return self._handle.getpeername()

    def _read(self, n):
        try:
            self._handle.start_read(self.__read_cb)
        except pyuv.error.TCPError as e:
            self.close()
            raise TCPError(convert_errno(e.args[0]), e.args[1])
        try:
            data = self._read_result.wait()
        except TCPError as e:
            self.close()
            raise
        else:
            if not data:
                self.close()
                return
            self._read_buffer.feed(data)
        finally:
            self._read_result.clear()

    def _write(self, data):
        try:
            self._handle.write(data, self.__write_cb)
        except pyuv.error.TCPError as e:
            self.close()
            raise TCPError(convert_errno(e.args[0]), e.args[1])

    def _close(self):
        self._handle.shutdown(self.__shutdown_cb)

    def __read_cb(self, handle, data, error):
        self._handle.stop_read()
        if error is not None:
            if error != pyuv.errno.UV_EOF:
                self._read_result.set_exception(TCPError(error, pyuv.errno.strerror(error)))
            else:
                self._read_result.set_result(b'')
        else:
            self._read_result.set_result(data)

    def __write_cb(self, handle, error):
        if error is not None:
            # TODO: save error?
            self.close()

    def __shutdown_cb(self, handle, error):
        self._handle.close()


class TCPClient(TCPStream):

    def __init__(self):
        loop = evergreen.current.loop
        handle = pyuv.TCP(loop._loop)
        super(TCPClient, self).__init__(handle)
        self._connect_result = None

    def connect(self, target, source_address=None):
        if self._connected:
            raise TCPError('already connected')
        # TODO: getaddrinfo
        if source_address:
            try:
                self._handle.bind(source_address)
            except pyuv.error.TCPError as e:
                raise TCPError(convert_errno(e.args[0]), e.args[1])
        try:
            self._handle.connect(target, self.__connect_cb)
        except pyuv.error.TCPError as e:
            raise TCPError(convert_errno(e.args[0]), e.args[1])
        self._connect_result = Result()
        try:
            self._connect_result.wait()
        except TCPError:
            self.close()
            raise
        else:
            self._set_connected()
        finally:
            self._connect_result = None

    def __connect_cb(self, handle, error):
        if error is not None:
            self._connect_result.set_exception(TCPError(convert_errno(error), pyuv.errno.strerror(error)))
        else:
            self._connect_result.set_result(None)


class TCPConnection(TCPStream, StreamConnection):
    pass


class TCPServer(StreamServer):
    connection_class = TCPConnection
    error_class = TCPError

    def __init__(self):
        super(TCPServer, self).__init__()
        loop = evergreen.current.loop
        self._handle = pyuv.TCP(loop._loop)

    @property
    def sockname(self):
        self._check_closed()
        return self._handle.getsockname()

    def _bind(self, address):
        self._handle.bind(address)
<commit_msg>Allow hostnames in TCPClient.connect, use getaddrinfo<commit_after>#
# This file is part of Evergreen. See the NOTICE for more information.
#

import pyuv

import evergreen
from evergreen.io.stream import BaseStream, StreamError, StreamConnection, StreamServer
from evergreen.io.util import Result, convert_errno
from evergreen.lib import socket

__all__ = ['TCPServer', 'TCPClient', 'TCPConnection', 'TCPError']


class TCPError(StreamError):
    pass


class TCPStream(BaseStream):
    error_class = TCPError

    def __init__(self, handle):
        super(TCPStream, self).__init__()
        self._handle = handle
        self._read_result = Result()

    @property
    def readable(self):
        return self._handle.readable

    @property
    def writable(self):
        return self._handle.writable

    @property
    def sockname(self):
        self._check_closed()
        return self._handle.getsockname()

    @property
    def peername(self):
        self._check_closed()
        return self._handle.getpeername()

    def _read(self, n):
        try:
            self._handle.start_read(self.__read_cb)
        except pyuv.error.TCPError as e:
            self.close()
            raise TCPError(convert_errno(e.args[0]), e.args[1])
        try:
            data = self._read_result.wait()
        except TCPError as e:
            self.close()
            raise
        else:
            if not data:
                self.close()
                return
            self._read_buffer.feed(data)
        finally:
            self._read_result.clear()

    def _write(self, data):
        try:
            self._handle.write(data, self.__write_cb)
        except pyuv.error.TCPError as e:
            self.close()
            raise TCPError(convert_errno(e.args[0]), e.args[1])

    def _close(self):
        self._handle.shutdown(self.__shutdown_cb)

    def __read_cb(self, handle, data, error):
        self._handle.stop_read()
        if error is not None:
            if error != pyuv.errno.UV_EOF:
                self._read_result.set_exception(TCPError(error, pyuv.errno.strerror(error)))
            else:
                self._read_result.set_result(b'')
        else:
            self._read_result.set_result(data)

    def __write_cb(self, handle, error):
        if error is not None:
            # TODO: save error?
            self.close()

    def __shutdown_cb(self, handle, error):
        self._handle.close()


class TCPClient(TCPStream):

    def __init__(self):
        loop = evergreen.current.loop
        handle = pyuv.TCP(loop._loop)
        super(TCPClient, self).__init__(handle)
        self._connect_result = None

    def connect(self, target, source_address=None):
        if self._connected:
            raise TCPError('already connected')
        try:
            r = socket.getaddrinfo(*target)
        except socket.error as e:
            raise TCPError(e)
        if not r:
            raise TCPError('getaddrinfo returned no result')
        self._connect_result = Result()
        err = None
        loop = self._handle.loop
        for item in r:
            addr = item[-1]
            if '%' in addr[0]:
                # Skip addresses such as 'fe80::1%lo0'
                # TODO: handle this properly
                continue
            handle = pyuv.TCP(loop)
            try:
                if source_address:
                    handle.bind(source_address)
                handle.connect(addr, self.__connect_cb)
            except pyuv.error.TCPError as e:
                err = TCPError(convert_errno(e.args[0]), e.args[1])
                handle.close()
                continue
            try:
                self._connect_result.wait()
            except TCPError as e:
                err = e
                handle.close()
                self._connect_result.clear()
                continue
            else:
                self._handle.close()
                self._handle = handle
                break
        self._connect_result = None
        if err is not None:
            raise err
        self._set_connected()

    def __connect_cb(self, handle, error):
        if error is not None:
            self._connect_result.set_exception(TCPError(convert_errno(error), pyuv.errno.strerror(error)))
        else:
            self._connect_result.set_result(None)


class TCPConnection(TCPStream, StreamConnection):
    pass


class TCPServer(StreamServer):
    connection_class = TCPConnection
    error_class = TCPError

    def __init__(self):
        super(TCPServer, self).__init__()
        loop = evergreen.current.loop
        self._handle = pyuv.TCP(loop._loop)

    @property
    def sockname(self):
        self._check_closed()
        return self._handle.getsockname()

    def _bind(self, address):
        self._handle.bind(address)

{'fraction_non_alphanumeric': 0.09430585076630496, 'fraction_numerical': 0.0022373867322966774, 'mean_word_length': 1.9730628533422014, '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': '6157845', 'n_tokens_mistral': 2566, 'n_tokens_neox': 2530, 'n_words': 570}