Giter Site home page Giter Site logo

irc's Introduction

image

image

tests

Ruff

image

image

Join the chat at https://gitter.im/jaraco/irc

image

Full-featured Python IRC library for Python.

Overview

This library provides a low-level implementation of the IRC protocol for Python. It provides an event-driven IRC client framework. It has a fairly thorough support for the basic IRC protocol, CTCP, and DCC connections.

In order to understand how to make an IRC client, it's best to read up first on the IRC specifications.

Client Features

The main features of the IRC client framework are:

  • Abstraction of the IRC protocol.
  • Handles multiple simultaneous IRC server connections.
  • Handles server PONGing transparently.
  • Messages to the IRC server are done by calling methods on an IRC connection object.
  • Messages from an IRC server triggers events, which can be caught by event handlers.
  • Multiple options for reading from and writing to an IRC server: you can use sockets in an internal select() loop OR use Python3's asyncio event loop
  • Functions can be registered to execute at specified times by the event-loop.
  • Decodes CTCP tagging correctly (hopefully); I haven't seen any other IRC client implementation that handles the CTCP specification subtleties.
  • A kind of simple, single-server, object-oriented IRC client class that dispatches events to instance methods is included.
  • DCC connection support.

Current limitations:

  • The IRC protocol shines through the abstraction a bit too much.
  • Data is not written asynchronously to the server (and DCC peers), i.e. the write() may block if the TCP buffers are stuffed.
  • Like most projects, documentation is lacking ...
  • DCC is not currently implemented in the asyncio-based version

Unfortunately, this library isn't as well-documented as I would like it to be. I think the best way to get started is to read and understand the example program irccat, which is included in the distribution.

The following modules might be of interest:

  • irc.client

    The library itself. Read the code along with comments and docstrings to get a grip of what it does. Use it at your own risk and read the source, Luke!

  • irc.client_aio

    All the functionality of the above library, but utilizing Python 3's native asyncio library for the core event loop. Interface/API is otherwise functionally identical to the classes in irc.client

  • irc.bot

    An IRC bot implementation.

  • irc.server

    A basic IRC server implementation. Suitable for testing, but not intended as a production service.

    Invoke the server with python -m irc.server.

Examples

Example scripts in the scripts directory:

  • irccat

    A simple example of how to use the IRC client. irccat reads text from stdin and writes it to a specified user or channel on an IRC server.

  • irccat2

    The same as above, but using the SimpleIRCClient class.

  • aio_irccat

    Same as above, but uses the asyncio-based event loop in AioReactor instead of the select() based Reactor.

  • aio_irccat2

    Same as above, but using the AioSimpleIRCClient class

  • servermap

    Another simple example. servermap connects to an IRC server, finds out what other IRC servers there are in the net and prints a tree-like map of their interconnections.

  • testbot

    An example bot that uses the SingleServerIRCBot class from irc.bot. The bot enters a channel and listens for commands in private messages or channel traffic. It also accepts DCC invitations and echos back sent DCC chat messages.

  • dccreceive

    Receives a file over DCC.

  • dccsend

    Sends a file over DCC.

NOTE: If you're running one of the examples on a unix command line, you need to escape the # symbol in the channel. For example, use \\#test or "#test" instead of #test.

Scheduling Events

The library includes a default event Scheduler as irc.schedule.DefaultScheduler, but this scheduler can be replaced with any other scheduler. For example, to use the schedule package, include it in your dependencies and install it into the IRC library as so:

class ScheduleScheduler(irc.schedule.IScheduler):
def execute_every(self, period, func):

schedule.every(period).do(func)

def execute_at(self, when, func):

schedule.at(when).do(func)

def execute_after(self, delay, func):

raise NotImplementedError("Not supported")

def run_pending(self):

schedule.run_pending()

irc.client.Reactor.scheduler_class = ScheduleScheduler

Decoding Input

By default, the IRC library attempts to decode all incoming streams as UTF-8, even though the IRC spec stipulates that no specific encoding can be expected. Since assuming UTF-8 is not reasonable in the general case, the IRC library provides options to customize decoding of input by customizing the ServerConnection class. The buffer_class attribute on the ServerConnection determines which class is used for buffering lines from the input stream, using the buffer module in jaraco.stream. By default it is buffer.DecodingLineBuffer, but may be re-assigned with another class, following the interface of buffer.LineBuffer. The buffer_class attribute may be assigned for all instances of ServerConnection by overriding the class attribute.

For example:

from jaraco.stream import buffer

irc.client.ServerConnection.buffer_class = buffer.LenientDecodingLineBuffer

The LenientDecodingLineBuffer attempts UTF-8 but falls back to latin-1, which will avoid UnicodeDecodeError in all cases (but may produce unexpected behavior if an IRC user is using another encoding).

The buffer may be overridden on a per-instance basis (as long as it's overridden before the connection is established):

server = irc.client.Reactor().server()
server.buffer_class = buffer.LenientDecodingLineBuffer
server.connect()

Alternatively, some clients may still want to decode the input using a different encoding. To decode all input as latin-1 (which decodes any input), use the following:

irc.client.ServerConnection.buffer_class.encoding = "latin-1"

Or decode to UTF-8, but use a replacement character for unrecognized byte sequences:

irc.client.ServerConnection.buffer_class.errors = "replace"

Or, to simply ignore all input that cannot be decoded:

class IgnoreErrorsBuffer(buffer.DecodingLineBuffer):
    def handle_exception(self):
        pass


irc.client.ServerConnection.buffer_class = IgnoreErrorsBuffer

The library requires text for message processing, so a decoding buffer must be used. Clients must use one of the above techniques for decoding input to text.

Notes and Contact Info

Enjoy.

Maintainer: Jason R. Coombs <[email protected]>

Original Author: Joel Rosdahl <[email protected]>

Copyright © 1999-2002 Joel Rosdahl Copyright © 2011-2016 Jason R. Coombs Copyright © 2009 Ferry Boender

For Enterprise

Available as part of the Tidelift Subscription.

This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.

Learn more.

irc's People

Contributors

abravalheri avatar ai0867 avatar anisse avatar bd808 avatar bswck avatar cclauss avatar coolacid avatar danieloaks avatar dimitripapadopoulos avatar edman80 avatar eric-s-raymond avatar fake-name avatar fitnub-bosbud avatar hugovk avatar jaraco avatar jheddings avatar kimen avatar lizzytrickster avatar mattbroach avatar moshekaplan avatar nickraptis avatar pefoley2 avatar pta2002 avatar puzzlet avatar sbraz avatar skriems avatar strictlymike avatar urhengulas avatar webknjaz avatar williamjacksn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

irc's Issues

remove getter functions

(Copied from [[https://sourceforge.net/p/python-irclib/feature-requests/4/|SourceForge]])

They are horribly ugly and unpythonic.
Instead of e.g. whatever.source().xyz it should be whatever.source.xyz.
The easiest way to change this while keeping the read-only style of those properties is simply decorating all those getters with @Property and then using them like normal variables.


privmsg with embedded carriage returns

It was reported to me via e-mail that when calling privmsg with a string containing carriage returns, only the text preceding the first carriage return is transmitted, which is unexpected. If embedded carriage returns aren't allowed, the client should raise an error. If they are allowed, the client should transmit them.


strange log messages MODE requests

logger data:

#!log

_dispatcher: join
FROM SERVER: :[email protected] MODE #honbots +qo Inomares_ Inomares_
_dispatcher: all_raw_messages
command: mode, source: [email protected], target: #honbots, arguments: [u'+qo', u'Inomares_', u'Inomares_']
_dispatcher: mode
TO SERVER: MODE +qo 
FROM SERVER: :s2games.ca.us.chattingaway.com 401 bsmith +qo :No such nick/channel
_dispatcher: all_raw_messages
command: nosuchnick, source: s2games.ca.us.chattingaway.com, target: bsmith, arguments: [u'+qo', u'No such nick/channel']
_dispatcher: nosuchnick

equivalent irc channel event:

#!irc

00:06 --              | Mode #honbots [+qo Inomares_ Inomares_] by ChanServ  

why is this irc lib acting on mode commands that are triggered by other channel events?


Library fuzzing

ircfuzz is a nice little program written by Ilja van Sprundel, available here.

Basically, it throws (mostly) random data at a given client connection, and sees what breaks under load. This is useful if, for instance, somebody wants to shut your connection down and does this, crashing whatever process is running, or if a server legitimately (accidentally) sends you crap for whatever reason.

I'm wondering whether jaraco would be interested in me running through, fuzzing the hay out of this library, and tryna fix/point out whatever issues come up?

First off, here's one that crashed on my machine:

Raw message received by client from ircfuzz, split by irc's arguments:

    <type> <source> <target> <arguments>

    all_raw_messages danneh.riz None ['�J\x1a�:�q`Y�\x13�n�6�y�R9W�ةC��\x04��\x0e�!(i[\x1cڻu��L1R���*\x0b\x04���*!s�%\x1a�3��\\\x0fJx�\x06���9�&�����g\x7fӑ�F��`W�\x06FT\x15������k\U000c846f\x1e���y�>L�ޒ\x17��n����\x0fD�\x0e�v�FjA�\x19_Z�\x1eӫ\\\x1f9:�Pݥ�x�rh��%���t�\x05��\x1f\x14']


Traceback:

    File "/usr/lib/python3.3/site-packages/irc/client.py", line 264, in process_forever
        self.process_data(i)

        File "/usr/lib/python3.3/site-packages/irc/client.py", line 210, in process_data
            c.process_data()

            File "/usr/lib/python3.3/site-packages/irc/client.py", line 633, in process_data
                target = arguments[0]

Large DCC spam crashes bot

When in a DCC chat with our logbot (source: http://code.google.com/p/bitfighter/source/browse/?repo=tools#hg%2Fbitfighter-logbot), the main thread in the bot will fully crash. Here is the stack trace:

  File "main.py", line 280, in main
    bot.our_start()
  File "main.py", line 64, in our_start
    self.start()
  File "bitfighter-logbot/irc/bot.py", line 266, in start
    super(SingleServerIRCBot, self).start()
  File "bitfighter-logbot/irc/client.py", line 1225, in start
    self.ircobj.process_forever()
  File "bitfighter-logbot/irc/client.py", line 267, in process_forever
    self.process_once(timeout)
  File "bitfighter-logbot/irc/client.py", line 248, in process_once
    self.process_data(i)
  File "bitfighter-logbot/irc/client.py", line 213, in process_data
    c.process_data()
  File "bitfighter-logbot/irc/client.py", line 1124, in process_data
    Event(command, prefix, target, arguments))
  File "bitfighter-logbot/irc/client.py", line 387, in _handle_event
    result = handler.callback(connection, event)
  File "bitfighter-logbot/irc/client.py", line 1184, in _dispatcher
    method(connection, event)
  File "main.py", line 182, in on_dccmsg
    c.privmsg("You said: " + e.arguments[0])
  File "bitfighter-logbot/irc/client.py", line 1135, in privmsg
    return self.send_bytes(bytes)
  File "bitfighter-logbot/irc/client.py", line 1142, in send_bytes
    self.socket.send(bytes)
AttributeError: 'NoneType' object has no attribute 'send'

self.socket is ends up NULL if too much data is pasted for some reason


PrioritizedHandler not sortable

Playing around with event handlers, you may encounter this error:

File "\irc\client.py", line 292 in add_global_handler

bisect.insort(event_handlers, handler)

TypeError: unorderable types: method() < method()

To fix it, replace this:

#!python

PrioritizedHandler = collections.namedtuple('PrioritizedHandler',
    ('priority', 'callback'))

with:

#!python

PrioritizedHandlerBase = collections.namedtuple('PrioritizedHandlerBase',
    ('priority', 'callback'))

class PrioritizedHandler(PrioritizedHandlerBase):
    def __lt__(self, other):
        return (self.priority < other.priority)

Handle Invalid IRC Password

Some IRC servers need a password when you are joining.

This is handled in irc.client.py line 493:

#!python

  # Log on...
        if self.password:
            self.pass_(self.password)
        self.nick(self.nickname)
        self.user(self.username, self.ircname)
        return self

This sends the PASS aPassword command to the server before NICK and USER.

This is all following perfectly to the RFC on passwords.

The problem arises if this password is invalid.

I cannot see how the server tells us if the password we just sent was bad. I don't see it handled in the flow of the code in client.py and my tinkering around seems to show the program just sits there doing nothing if this happens.

Can an error be raised on bad password, allowing the program to react to this corner case?

The RFC says we can get back a "ERR_NEEDMOREPARAMS" when we send a "PASS" command but I don't think this is going to help here.

Any idea, or am I missing something?


Throttle and set_rate_limit have limited usability

I refrained from reopening issue #18 and opened a new issue instead.

Right now, Throttle and set_rate_limit work fine as long as the calls to the function are made as fast as possible.

However, if the function is not called for some time, a following burst of calls will not get limited. This is not useful as a burst to, for example, send_raw can happen in any point in time.

I propose a different implementation where Throttle keeps the time it was last called and decides to throttle based on that.

If you agree that this should be the intended behavior, I can happily write a patch and also append to the relevant test.
However, the test will likely take a couple more seconds to run as I'll need to idle for a bit between bursts.


KeyError: u'*' bot.py _on_namreply traceback

Hi -
First of all, thanks for this library.
I recently upgraded to version 8.3 after using a several year old version. I have an IRC bot that will occasionally crash with the following traceback. Can you take a look?

If there is anything else I can do to provide more information, please let me know. I am also a Python programmer, so if you give me some guidance I may be able to submit a patch or pull request.

Thanks!

#!python

Traceback (most recent call last):
195   File "/svr/irc/sg101bot/sg101bot/sg101botlib/main.py", line 53, in run
196     self.bot.start()
197   File "/svr/irc/sg101bot/sg101bot/sg101botlib/bot.py", line 28, in start
198     super(Bot, self).start()
199   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/bot.py", line 260, in start
200     super(SingleServerIRCBot, self).start()
201   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/client.py", line 1212, in start
202     self.ircobj.process_forever()
203   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/client.py", line 264, in process_f    orever
204     self.process_once(timeout)
205   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/client.py", line 245, in process_o    nce
206     self.process_data(i)
207   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/client.py", line 210, in process_d    ata
208     c.process_data()
209   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/client.py", line 643, in process_d    ata
210     self._handle_event(Event(command, NickMask(prefix), target, arguments))
211   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/client.py", line 647, in _handle_e    vent
212     self.irclibobj._handle_event(self, event)
213   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/client.py", line 384, in _handle_e    vent
214     result = handler.callback(connection, event)
215   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/bot.py", line 173, in _on_namreply
216     self.channels[ch].add_user(nick)
217   File "/svr/irc/sg101bot/local/lib/python2.7/site-packages/irc/dict.py", line 30, in __getitem__
218     return super(KeyTransformingDict, self).__getitem__(key)
219 KeyError: u'*'


ssl-cat.py fails to run

Running scripts/ssl-cat.py with valid arguments causes a TypeError exception.

This is with python 2.6 (running on RedHat Enterprise 6).

For example:

$ python ssl-cat.py -p 7000 example.com foobot somechannel

Traceback (most recent call last):
File "ssl-cat.py", line 76, in
main()
File "ssl-cat.py", line 63, in main
connect_factory=ssl_factory,
File "/usr/lib/python2.6/site-packages/irc/functools.py", line 35, in wrapper
return method(self, _args, *_kwargs)
File "/usr/lib/python2.6/site-packages/irc/client.py", line 488, in connect
self.socket = self.connect_factory(self.server_address)
File "/usr/lib/python2.6/site-packages/irc/connection.py", line 60, in connect
sock.bind(self.bind_address)
File "", line 1, in bind
TypeError: getsockaddrarg: AF_INET address must be tuple, not function


Cannot install irc 5.1 under Python 3, due to 2to3 fixer exclusions

Although setup.py excludes the fixer for the print statement, irc/server.py contains print statements. As a result, even after running 2to3, the source is not Python-3 compatible, and installation fails.

Example of failure: line 399 of irc/server.py.

Note that the previous release (5.0.1) doesn't have this problem, as it doesn't include irc/server.py.


irc.bot.get_version() fails with exception.

The relevant exception is

#!python

TypeError: sequence item 0: expected string, int found

What happens is that irc.client.VERSION is a tuple of integers. In fact, it is tested that this is the case.

Problem is that bot.get_version() tries to do

#!python

'.'.join(irc.client.VERSION)

which raises the Type Error since it can't join said tuple of integers and instead expects a tuple of strings.

Easiest way to fix would be to change the above call to

#!python

'.'.join(map(str, irc.client.VERSION))

but I'm figuring you'll opt for a more readable fix and perhaps an accompanying test.


LineBuffer.__iter__ doesn't return an iterator

In irc 3.4.1, a bug was introduced whereby the LineBuffer is not returning an iterable:

>>> import irc.client
>>> buf = irc.client.LineBuffer()
>>> buf.feed('foo\n')
>>> for x in buf:
...   print(x)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iter() returned non-iterator of type 'list'

What the heck is the "Manifold" object?

I've been going through the source-code for this library, and trying to write code that uses it.

From what I can tell, everything seems to be piped through the "Manifold" object, which seems to be global (?), and looks a lot like a reactor.

What the hell is a "Manifold"? It's not documented anywhere in the documentation, and where it's mentioned it's treated as calling it "the manifold" is self-explanitory.

The only results for googling lead to either the Manifold GIS system, or wikipedia pages for unrelated gometric terminology.

If it's functionally a reactor (and it certainly looks kind of like one), can you possibly use standard terminology, or at least add a blurb to the documentation ("the manifold is a reactor. We're using this non-standard term for {insert reason here}")?


client crashes on EINTR

I have been using irclib to build an irc bot daemon, but after I handle any signal, process_forever of client.py raises an InterruptedSystemCall exception. I traced the source down to the select.select statement in process_once. The select() system call always returns EINTR whenever it's interrupted by any signal (even ignoring siginterrupt), and for some reason the Python select library chose not to handle this by retrying, instead simply reraising the exception for the user.

There's nothing for an irclib user to do but to let process_forever die and restart the entire client (or maybe there's some weird hack around it?), but this is a fixable issue in the library if the select.select is wrapped in something like:

#!python

while 1:
  try:
    (i, o, e) = select.select(sockets, [], [], timeout)
    break
  except select.error as e
    if e[0] != errno.EINTR: raise

DecodingLineBuffer doctest fails

On my system, the DecodingLineBuffer doctest fails. It seems that doctest is expecting the exception output to exactly match by default.

Per a quick read of https://docs.python.org/2/library/doctest.html#what-about-exceptions, it seems like you need either +ELLIPSIS or +IGNORE_EXCEPTION_DETAIL.

The attached patch sets IGNORE_EXCEPTION_DETAIL, since it's supposedly more strict, but ELLIPSIS works too.

$ nosetests --with-doctest
.F............................F.......
======================================================================
FAIL: Doctest: irc.buffer.DecodingLineBuffer
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/doctest.py", line 2226, in runTest
    raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for irc.buffer.DecodingLineBuffer
  File "/home/user/src/irc/irc/buffer.py", line 57, in DecodingLineBuffer

----------------------------------------------------------------------
File "/home/user/src/irc/irc/buffer.py", line 81, in irc.buffer.DecodingLineBuffer
Failed example:
    list(b.lines())
Expected:
    Traceback (most recent call last):
    ...
    UnicodeDecodeError: ...
Got:
    Traceback (most recent call last):
      File "/usr/lib/python2.7/doctest.py", line 1315, in __run
        compileflags, 1) in test.globs
      File "<doctest irc.buffer.DecodingLineBuffer[11]>", line 1, in <module>
        list(b.lines())
      File "/home/user/src/irc/irc/buffer.py", line 94, in lines
        self.handle_exception()
      File "/home/user/src/irc/irc/buffer.py", line 92, in lines
        yield line.decode(self.encoding, self.errors)
      File "/home/user/src/ircenv/lib/python2.7/encodings/utf_8.py", line 16, in decode
        return codecs.utf_8_decode(input, errors, True)
    UnicodeDecodeError: 'utf8' codec can't decode byte 0xe9 in position 2: unexpected end of data

(The other test failure is due to me not using setuptools/pkg_resources.)


Multiple reply numerics missing from irc.events

i noticed that the event list was missing quite a lot of numerics (I have a list from an old library that I used to use that goes up to around 999 though it's not a straight through block, so to speak)

If you want I can PR them across. (Since my bot makes use of 330: whois account for NickServ based authentication)


TestChannel.test_has_user fails in release -10.0

under all pythons

======================================================= test session starts =======================================================
platform linux -- Python 3.3.5 -- py-1.4.25 -- pytest-2.6.3
plugins: cov
collected 20 items

irc/tests/test_bot.py ......F..
irc/tests/test_client.py ......
irc/tests/test_schedule.py .....

============================ FAILURES =============================
__________________ TestChannel.test_has_user ____________________

self = <irc.tests.test_bot.TestChannel object at 0x7f12c32d9d10>

    def test_has_user(self):
        channel = irc.bot.Channel()
        channel.add_user('tester1')
>       assert channel.has_user('Tester1')
E       assert <bound method Channel.has_user of <irc.bot.Channel object at 0x7f12c32d9610>>('Tester1')
E        +  where <bound method Channel.has_user of <irc.bot.Channel object at 0x7f12c32d9610>> = <irc.bot.Channel object at 0x7f12c32d9610>.has_user

irc/tests/test_bot.py:51: AssertionError
========= 1 failed, 19 passed in 3.23 seconds ============

Can you replicate> Do you require any further info?


Concerns on encodings

I see irc/client.py assumes all the packets are encoded in UTF-8.

But in reality, non-UTF-8 texts are around: privmsg's are truncated by server by bytes hence sometimes broken, and some servers and channels still use their own local encodings other than UTF-8.

So I think the library should have an option for non-UTF-8 modes.


unicode decode issue

I have an irc bot which inherits from SingleServerIRCBot
Because it also runs on different irc network's I 1st of all wrap it in:

**class BotWrapper(threading.Thread):
    def __init__(self,bot):
        self.bot = bot
        super(BotWrapper, self).__init__()
    def run(self):
        self.bot.start()****

I have been doing this for quite some time (this bot used the original python-irc)

I only post this since it is part of this traceback:

**Traceback (most recent call last):
  File "/usr/lib64/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "./bs.py", line 588, in run
    self.bot.start()
  File "/usr/lib64/python2.7/site-packages/irc/bot.py", line 260, in start
    super(SingleServerIRCBot, self).start()
  File "/usr/lib64/python2.7/site-packages/irc/client.py", line 1174, in start
    self.ircobj.process_forever()
  File "/usr/lib64/python2.7/site-packages/irc/client.py", line 264, in process_forever
    self.process_once(timeout)
  File "/usr/lib64/python2.7/site-packages/irc/client.py", line 245, in process_once
    self.process_data(i)
  File "/usr/lib64/python2.7/site-packages/irc/client.py", line 210, in process_data
    c.process_data()
  File "/usr/lib64/python2.7/site-packages/irc/client.py", line 554, in process_data
    for line in self.buffer:
  File "/usr/lib64/python2.7/site-packages/irc/buffer.py", line 84, in <genexpr>
    for line in super(DecodingLineBuffer, self).lines())
  File "/usr/lib64/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xf6 in position 53: invalid start byte
****

in the old python-irclib I would set DEBUG to true in the client.py. this upgraded irc lib seems to use logging but I cannot get it to write to a file

**logfp = logging.FileHandler('bsmithlog.log')
logfp.setLevel(logging.DEBUG)
irc.client.log.addHandler(logfp)****

UnicodeDecodeError

Hello. I've written a bot using your very nice IRC library. Up until now, there have no been issues. Today a german used the bot w/xchat on windows and the library throws an exception while decoding lines with umlauts and ß and other unicode chars.

Here's a traceback:

  File "/usr/local/bin/hanabIRC", line 143, in <module>
    bot.start()
  File "/usr/local/lib/python2.7/dist-packages/irc/bot.py", line 266, in start
    super(SingleServerIRCBot, self).start()
  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 1263, in start
    self.manifold.process_forever()
  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 280, in process_forever
    self.process_once(timeout)
  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 261, in process_once
    self.process_data(i)
  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 218, in process_data
    c.process_data()
  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 575, in process_data
    for line in self.buffer:
  File "/usr/local/lib/python2.7/dist-packages/irc/buffer.py", line 94, in lines
    self.handle_exception()
  File "/usr/local/lib/python2.7/dist-packages/irc/buffer.py", line 92, in lines
    yield line.decode(self.encoding, self.errors)
  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xdf in position 77: invalid continuation byte

dcc file transfer (receiving) decode error

i used the script "dccreceive.py"
and when receiving a file larger then 1151 bytes (or the received byte excede this)

i tested this simply by trial and error on struct.pack("!I", bytes).encode("utf-8")
it fails on:

#!python

>>> struct.pack("!I", 1152).encode("utf-8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf8' codec can't decode byte 0x80 in position 3: invalid start byte

the private message that is returned with the received bytes can not be encoded with utf-8

the message that is supposed to be send is a string from struct.pack()
e.g.

#!python
struct.pack("!I", bytesReceived)

that output is given to the dcc privatemsg function
where it is being encoded to utf-8

#!python
string = struct.pack("!I", bytesReceived)
bytes = string.encode('utf-8')

now with small bytesReceived this works:

#!python
>>> struct.pack("!I", 14).encode("utf-8")
'\x00\x00\x00\x0e'

but

#!python
>>> struct.pack("!I", 1440).encode("utf-8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa0 in position 3: invalid start byte

i checked what "0xa0" is and its a none breaking space and apparently a utf-8 string is not allowed to start with that!

i dont understand why anything from struct.pack() is not utf-8 encodable since it should be a string representing bytes not a byte string

#!python
>>> type(struct.pack("!I", 14).encode("utf-8"))
<type 'str'>

so in conclusion i dont know if this is an error in struct.pack() or anywhere else, besides is it needed to encode the message at all ?


jaraco.util dependency

Hi, I am packaging the latest version for Debian. I've found that irc depends on jaraco.util (client.py) Since jaraco.util is not on Debian I can't make it work on the distribution. I would like to know if this is a temporary dependency or it is going to be included on the next releases? is there another option to use instead of jaraco.util?

Cheers


[Python 3.3] TypeError with buffer_class = irc.buffer.LineBuffer

Hi,

With python 3.3, when using irc.client.ServerConnection.buffer_class = irc.buffer.LineBuffer, I get the following traceback:

Traceback (most recent call last):
  File "testbot.py", line 120, in <module>
    main()
  File "testbot.py", line 117, in main
    bot.start()
  File "/usr/pkg/lib/python3.3/site-packages/irc/bot.py", line 266, in start
    super(SingleServerIRCBot, self).start()
  File "/usr/pkg/lib/python3.3/site-packages/irc/client.py", line 1225, in start
    self.ircobj.process_forever()
  File "/usr/pkg/lib/python3.3/site-packages/irc/client.py", line 267, in process_forever
    self.process_once(timeout)
  File "/usr/pkg/lib/python3.3/site-packages/irc/client.py", line 248, in process_once
    self.process_data(i)
  File "/usr/pkg/lib/python3.3/site-packages/irc/client.py", line 213, in process_data
    c.process_data()
  File "/usr/pkg/lib/python3.3/site-packages/irc/client.py", line 561, in process_data
    self._process_line(line)
  File "/usr/pkg/lib/python3.3/site-packages/irc/client.py", line 572, in _process_line
    m = _rfc_1459_command_regexp.match(line)
TypeError: can't use a string pattern on a bytes-like object

This is the testbot.py code with the following added before irc.bot.SingleServerIRCBot:
irc.client.ServerConnection.buffer_class = irc.buffer.LineBuffer
This works with python 2.7.


IRC client should not crash on failed decoding.

In the default configuration, if non-UTF-8 is transmitted to the client, it will crash with an error:

#!python

Traceback (most recent call last):
  File "irc_bot.py", line 144, in <module>
    i.run()
  File "irc_bot.py", line 120, in run
    self.client.process_forever()
  File "/usr/local/lib/python3.2/dist-packages/irc/client.py", line 267, in process_forever
    self.process_once(timeout)
  File "/usr/local/lib/python3.2/dist-packages/irc/client.py", line 248, in process_once
    self.process_data(i)
  File "/usr/local/lib/python3.2/dist-packages/irc/client.py", line 213, in process_data
    c.process_data()
  File "/usr/local/lib/python3.2/dist-packages/irc/client.py", line 558, in process_data
    for line in self.buffer:
  File "/usr/local/lib/python3.2/dist-packages/irc/buffer.py", line 84, in <genexpr>
    for line in super(DecodingLineBuffer, self).lines())
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x95 in position 96: invalid start byte


Library violates end-to-end principle, leading to needless errors

Deployed in irker, the library blew up when an IRC server instance passed it dara that contained an invalid continuation byte. A UnicodeDecodeError was raised inside the LineBuffer object, aborting one of the main processing threads and hanging the daemon.

The correct fix is for the IRC library not to care about or mess with the encoding of the data that passes through it. Knowledge of that semantics belongs to the calling application and only to the calliung application.


library does not detect that connection is lost

(Copied from [[https://sourceforge.net/p/python-irclib/bugs/11/|SourceForge issue 11]])

Platform: Linux

The server shows a ping timeout but if the packet closing the connection is lost, it appears that the client never "notices" that it's gone offline.

Client side ping not supported, so making the user of the library able to check for this isn't simple either.


dccsend.py and dccreceive.py can't parse filenames with space character correctly.

Maybe you can use another split character:

#!python

#dccsend.py
def on_welcome(self, connection, event):
        self.dcc = self.dcc_listen("raw")
        self.connection.ctcp("DCC", self.receiver, "SEND:%s:%s:%d:%d" % (
            os.path.basename(self.filename),
            irc.client.ip_quad_to_numstr(self.dcc.localaddress),
            self.dcc.localport,
            self.filesize))
#!python
#dccreceive.py

def on_ctcp(self, connection, event):
        args = event.arguments[1].split(':')


execute_every with a period of 0 causes infinite loop

Looking at process_timeout, the code looks like this:

            while self.delayed_commands:
                command = self.delayed_commands[0]
                if not command.due():
                    break
                command.function(*command.arguments)
                if isinstance(command, PeriodicCommand):
                    self._schedule_command(command.next())
                del self.delayed_commands[0]

If one of the delayed_commands is a PeriodicCommand with delay of 0 (as created by execute_every with period of 0), the _schedule_command will always re-add the command immediately after running it, and it will satisfy the command.due() on the subsequent iteration, causing an infinite loop.

At the very least, the IRC client should raise an error if one attempts to create such a command. Even better would be to support periodic commands with a delay of 0 (which one would want to run every timeout, but only once per).


Add certificate support for SSL connections

In SourceForge patches [[https://sourceforge.net/p/python-irclib/patches/14/|14]] and [[https://sourceforge.net/p/python-irclib/patches/15/|15]], patches were contributed to add support for SSL certificates. I've applied these patches as [[https://bitbucket.org/jaraco/irc/changeset/3f2fe995142e|3f2fe995142e]], but have not yet merged these with the latest tip.


IRC Client - Ping Timeout Issue

I am trying to use this library for IRC client things for a small IRC bot I'm writing. However, I've found that it always disconnects from a "Ping Timeout" and can't figure out why this is happening or how to prevent it from happening.

Library version: 8.0.1
Python version: 2.7.3
IRC Server: irc.quakenet.org:6667

I first tried incorporating the library in my own code based on the irccat.py example. However, I get the same issue with just running the irccat.py script, although I modified it to hard-code the third argument. It works perfectly until it's idle for 5-10 minutes at which point it disconnects from a ping timeout. I added a printout to the on_disconnect global handler and it's not called when the ping timeout occurs. I also tried adding a global handler for "ping", but that was never called either.

Let me know if there's anything I'm missing or if you need any more info. Thanks!


Ratelimit notices

Given certain situations, it's possible for someone to force a bot to exit if too many notices are buffered.

I'm sure I could rate limit in my code, but a forced rate limit in the lib might also be warranted.


Client PING and Keep-Alive support

In #16 and in other channels (I forget where), it appears it may be useful to have a configurable timeout for a client-side ping command in order to force connections to stay open in environments where an aggressive TCP idle timeout is in force.

Let's explore that idea.

Contributions welcome.


IRClib crashes on certain network inputs

Intermittently, on certain (unknown) kinds of network input, IRClib crashes with backtrace similar to the following:

  File "./countbot.py", line 280, in <module>
    main()
  File "./countbot.py", line 277, in main
    bot.start()
  File "/usr/lib64/python3.4/site-packages/irc-8.9.1-py3.4.egg/irc/bot.py", line 266, in start
  File "/usr/lib64/python3.4/site-packages/irc-8.9.1-py3.4.egg/irc/client.py", line 1263, in start
  File "/usr/lib64/python3.4/site-packages/irc-8.9.1-py3.4.egg/irc/client.py", line 280, in process_forever
  File "/usr/lib64/python3.4/site-packages/irc-8.9.1-py3.4.egg/irc/client.py", line 261, in process_once
  File "/usr/lib64/python3.4/site-packages/irc-8.9.1-py3.4.egg/irc/client.py", line 218, in process_data
  File "/usr/lib64/python3.4/site-packages/irc-8.9.1-py3.4.egg/irc/client.py", line 575, in process_data
  File "/usr/lib64/python3.4/site-packages/irc-8.9.1-py3.4.egg/irc/buffer.py", line 94, in lines
  File "/usr/lib64/python3.4/site-packages/irc-8.9.1-py3.4.egg/irc/buffer.py", line 92, in lines
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x81 in position 138: invalid start byte

Several different IRC bots in the same channel, running same IRClib, respond differently; one crashes as above, one apparently loses server connection but automatically reconnects, one appears to quit normally with no exception or backtrace. Unknown how exactly this is happening.


connection.whois() does not take single strings

The connection.whois() method should check to see whether the parameter it was passed was a string or a list and act accordingly.

With a string:

#!python
>>> "WHOIS " + ",".join( "JoshTheEnder" ) 
'WHOIS J,o,s,h,T,h,e,E,n,d,e,r' 

With a list (which i assume is how it's supposed to be done but seems pointless for 1 user):

#!python
>>> "WHOIS " + ",".join( ["JoshTheEnder"] )
'WHOIS JoshTheEnder' 

Suggestion: Making the function check the type of the argument and act accordingly between string and list objects


execute_every in 7.1 error

I am unable to use the execute_every function.
With whatever parameters I try, I always get this error:

#!python


File "ircbot.py", line 17, in __init__
    self.ircobj.execute_every( 60, myfunction )
File "myproject\irc\client.py", line 346, in execute_every
    command = schedule.PeriodicCommand(period, function, arguments)
File "myproject\irc\schedule.py", line 61, in __init__
    super(PeriodicCommand, self).__init__(*args, **kwargs)
TypeError: object.__init__() takes no parameters

ircbot.py contains my program, and the irc folder contains irclib.
The reason might be my incompetence and I am on Python 3.3.
execute_delayed for example works fine.


Unable to install via PIP (unsafe to install)

Attempting to install IRC to my windows using python 3.3 & PIP.

Fails to install with the following message:

"The package setup script has attempted to modify files on your system

that are not within the EasyInstall build area, and has been aborted.

This package cannot be safely installed by EasyInstall, and may not

support alternate installation locations even if you run its setup

script by hand. Please inform the package's author and the EasyInstall

maintainers to find out if a fix or workaround is available."

PIP is working on my system (tested it by installing "httpie" which went ok :( )

Any help would be greatly appreciated!!

Full log file:

Downloading/unpacking irc

Getting page https://pypi.python.org/simple/irc/
URLs to search for versions for irc:

setuptools.sandbox.SandboxViolation: SandboxViolation: open('C:\Python33\lib\lib2to3\Grammar3.3.2.final.0.pickle', 'wb') {}

The package setup script has attempted to modify files on your system

that are not within the EasyInstall build area, and has been aborted.

This package cannot be safely installed by EasyInstall, and may not

support alternate installation locations even if you run its setup

script by hand. Please inform the package's author and the EasyInstall

maintainers to find out if a fix or workaround is available.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 1016, in run_setup

run_setup(setup_script, args)

File "C:\Python33\lib\site-packages\setuptools\sandbox.py", line 69, in run_setup

lambda: execfile(

File "C:\Python33\lib\site-packages\setuptools\sandbox.py", line 120, in run

return func()

File "C:\Python33\lib\site-packages\setuptools\sandbox.py", line 71, in

{'__file__':setup_script, '__name__':'__main__'}

File "C:\Python33\lib\site-packages\setuptools\compat.py", line 94, in execfile

exec_(compile(source, fn, 'exec'), globs, locs)

File "setup.py", line 55, in

File "C:\Python33\lib\distutils\core.py", line 165, in setup

raise SystemExit("error: " + str(msg))

SystemExit: error: SandboxViolation: open('C:\Python33\lib\lib2to3\Grammar3.3.2.final.0.pickle', 'wb') {}

The package setup script has attempted to modify files on your system

that are not within the EasyInstall build area, and has been aborted.

This package cannot be safely installed by EasyInstall, and may not

support alternate installation locations even if you run its setup

script by hand. Please inform the package's author and the EasyInstall

maintainers to find out if a fix or workaround is available.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "", line 16, in

File "c:\users\tom\appdata\local\temp\pip_build_Tom\irc\setup.py", line 48, in

setuptools.setup(**setup_params)

File "C:\Python33\lib\distutils\core.py", line 109, in setup

_setup_distribution = dist = klass(attrs)

File "C:\Python33\lib\site-packages\setuptools\dist.py", line 239, in init

self.fetch_build_eggs(attrs.pop('setup_requires'))

File "C:\Python33\lib\site-packages\setuptools\dist.py", line 263, in fetch_build_eggs

parse_requirements(requires), installer=self.fetch_build_egg

File "C:\Python33\lib\site-packages\pkg_resources.py", line 568, in resolve

dist = best[req.key] = env.best_match(req, self, installer)

File "C:\Python33\lib\site-packages\pkg_resources.py", line 806, in best_match

return self.obtain(req, installer) # try and download/install

File "C:\Python33\lib\site-packages\pkg_resources.py", line 818, in obtain

return installer(requirement)

File "C:\Python33\lib\site-packages\setuptools\dist.py", line 313, in fetch_build_egg

return cmd.easy_install(req)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 609, in easy_install

return self.install_item(spec, dist.location, tmpdir, deps)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 639, in install_item

dists = self.install_eggs(spec, download, tmpdir)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 825, in install_eggs

return self.build_and_install(setup_script, setup_base)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 1031, in build_and_install

self.run_setup(setup_script, setup_base, args)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 1016, in run_setup

run_setup(setup_script, args)

File "C:\Python33\lib\site-packages\setuptools\sandbox.py", line 69, in run_setup

lambda: execfile(

File "C:\Python33\lib\site-packages\setuptools\sandbox.py", line 120, in run

return func()

File "C:\Python33\lib\site-packages\setuptools\sandbox.py", line 71, in

{'__file__':setup_script, '__name__':'__main__'}

File "C:\Python33\lib\site-packages\setuptools\compat.py", line 94, in execfile

exec_(compile(source, fn, 'exec'), globs, locs)

File "setup.py", line 30, in

"Programming Language :: Python :: 2.6",

File "C:\Python33\lib\distutils\core.py", line 109, in setup

_setup_distribution = dist = klass(attrs)

File "C:\Python33\lib\site-packages\setuptools\dist.py", line 239, in init

self.fetch_build_eggs(attrs.pop('setup_requires'))

File "C:\Python33\lib\site-packages\setuptools\dist.py", line 263, in fetch_build_eggs

parse_requirements(requires), installer=self.fetch_build_egg

File "C:\Python33\lib\site-packages\pkg_resources.py", line 568, in resolve

dist = best[req.key] = env.best_match(req, self, installer)

File "C:\Python33\lib\site-packages\pkg_resources.py", line 806, in best_match

return self.obtain(req, installer) # try and download/install

File "C:\Python33\lib\site-packages\pkg_resources.py", line 818, in obtain

return installer(requirement)

File "C:\Python33\lib\site-packages\setuptools\dist.py", line 313, in fetch_build_egg

return cmd.easy_install(req)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 609, in easy_install

return self.install_item(spec, dist.location, tmpdir, deps)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 639, in install_item

dists = self.install_eggs(spec, download, tmpdir)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 825, in install_eggs

return self.build_and_install(setup_script, setup_base)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 1031, in build_and_install

self.run_setup(setup_script, setup_base, args)

File "C:\Python33\lib\site-packages\setuptools\command\easy_install.py", line 1019, in run_setup

raise DistutilsError("Setup script exited with %s" % (v.args[0],))

distutils.errors.DistutilsError: Setup script exited with error: SandboxViolation: open('C:\Python33\lib\lib2to3\Grammar3.3.2.final.0.pickle', 'wb') {}

The package setup script has attempted to modify files on your system

that are not within the EasyInstall build area, and has been aborted.

This package cannot be safely installed by EasyInstall, and may not

support alternate installation locations even if you run its setup

script by hand. Please inform the package's author and the EasyInstall

maintainers to find out if a fix or workaround is available.


Cleaning up...

Removing temporary dir c:\users\tom\appdata\local\temp\pip_build_Tom...
Command python setup.py egg_info failed with error code 1 in c:\users\tom\appdata\local\temp\pip_build_Tom\irc

Exception information:
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\pip\basecommand.py", line 134, in main
status = self.run(options, args)
File "C:\Python33\lib\site-packages\pip\commands\install.py", line 236, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
File "C:\Python33\lib\site-packages\pip\req.py", line 1134, in prepare_files
req_to_install.run_egg_info()
File "C:\Python33\lib\site-packages\pip\req.py", line 259, in run_egg_info
command_desc='python setup.py egg_info')
File "C:\Python33\lib\site-packages\pip\util.py", line 670, in call_subprocess
% (command_desc, proc.returncode, cwd))
pip.exceptions.InstallationError: Command python setup.py egg_info failed with error code 1 in c:\users\tom\appdata\local\temp\pip_build_Tom\irc


Byte decode error

I'm currently using this library to create an IRC bot embedded into a plugin for another bot (www.bigbrotherbot.net) and I stepped into this error. This is an extract from my log file. Did someone experience this already?
This actually cause my bots to crash every now and then since the exception breaks the main loop and interrupt the thread.

#!

140716 00:38:33 ERROR   'STDERR \'Exception in thread Thread-2:\\nTraceback (most recent call last):\\n  File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner\\n    self.run()\\n  File "/usr/lib/python2.7/threading.py", line 505, in run\\n    self.__target(*self.__args, **self.__kwargs)\\n  File "/usr/local/lib/python2.7/dist-packages/irc/bot.py", line 266, in start\\n    super(SingleServerIRCBot, self).start()\\n  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 1263, in start\\n    self.manifold.process_forever()\\n  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 280, in process_forever\\n    self.process_once(timeout)\\n  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 261, in process_once\\n    self.process_data(i)\\n  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 218, in process_data\\n    c.process_data()\\n  File "/usr/local/lib/python2.7/dist-packages/irc/client.py", line 575, in process_data\\n    for line in self.buffer:\\n  File "/usr/local/lib/python2.7/dist-packages/irc/buffer.py", line 94, in lines\\n    self.handle_exception()\\n  File "/usr/local/lib/python2.7/dist-packages/irc/buffer.py", line 92, in lines\\n    yield line.decode(self.encoding, self.errors)\\n  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode\\n    return codecs.utf_8_decode(input, errors, True)\\nUnicodeDecodeError: \\\'utf8\\\' codec can\\\'t decode byte 0xe8 in position 66: invalid continuation byte\\n\\n\'

test test_client.test_version fails irc-8.5

pytest also fails.

work/irc-8.5 $ PYTHONPATH=build/lib/ pytest
going into /mnt/gen2/TmpDir/portage/dev-python/irc-8.5/work/irc-8.5/irc/tests
=========================== test_bot.py ============================

========================== test_client.py ==========================

========================= test_schedule.py =========================

no test dir found testing here: /mnt/gen2/TmpDir/portage/dev-python/irc-8.5/work/irc-8.5


Ran 0 test cases in 0.07s (0.06s CPU)
All 3 modules OK

well so much for pytest and pytest-runner, the latter of which I've not seen or used before.

work/irc-8.5 $ PYTHONPATH=build/lib/ nosetests

==================================================================
FAIL: irc.tests.test_client.test_version
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib64/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/mnt/gen2/TmpDir/portage/dev-python/irc-8.5/work/irc-8.5/irc/tests/test_client.py", line 14, in test_version
    assert irc.client.VERSION, "8, 5"
AssertionError: No VERSION detected.

----------------------------------------------------------------------
Ran 19 tests in 3.125s

FAILED (failures=1)

Not being a test suite writer I've sunk enough time in attempting to jag a correct arg for "No VERSION detected."

What I have however is

work/irc-8.5 $ python -c "from irc.client import VERSION;print(VERSION)"
(8, 5)

which says to me the test needs re-authoring to do something, well, perhaps 'right'.
Anyways. It also appears in some prior versions.


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.