Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected keyword argument 'loop' under Python 3.10 #162

Open
felixonmars opened this issue Jan 8, 2022 · 4 comments
Open

Unexpected keyword argument 'loop' under Python 3.10 #162

felixonmars opened this issue Jan 8, 2022 · 4 comments
Labels
Milestone

Comments

@felixonmars
Copy link
Contributor

    await client.connect(config["irc"]["server"], tls=True, tls_verify=True)
  File "/usr/lib/python3.10/site-packages/pydle/features/tls.py", line 35, in connect
    return await super().connect(hostname, port, tls=tls, **kwargs)
  File "/usr/lib/python3.10/site-packages/pydle/features/rfc1459/client.py", line 190, in connect
    await super().connect(hostname, port, **kwargs)
  File "/usr/lib/python3.10/site-packages/pydle/client.py", line 124, in connect
    await self._connect(hostname=hostname, port=port, reconnect=reconnect, **kwargs)
  File "/usr/lib/python3.10/site-packages/pydle/features/tls.py", line 54, in _connect
    await self.connection.connect()
  File "/usr/lib/python3.10/site-packages/pydle/connection.py", line 48, in connect
    (self.reader, self.writer) = await asyncio.open_connection(
  File "/usr/lib/python3.10/asyncio/streams.py", line 47, in open_connection
    transport, _ = await loop.create_connection(
TypeError: BaseEventLoop.create_connection() got an unexpected keyword argument 'loop'
@Rixxan
Copy link
Contributor

Rixxan commented Jan 11, 2022

Looking through some of the other open issues, it does not appear Pydle supports Python 3.10 at present (Ref #161, #142) as a few places call asyncio.coroutine which was removed in Python 3.10.

I can't say if this issue is related to that or not, but it might be a contributing factor. Can you provide more information about your environment and the context this code is in to assist in diagnosis?

@theunkn0wn1
Copy link
Collaborator

Dug into this a bit.
There are a couple distinct issues

  • If pydle is passed an event loop to use Client(..., loop=some_event_loop), pydle will use it via the now deprecated loop= parameters in asyncio calls.
  • If pydle is not passed an event loop, it will instantiate a new one instead of fetching the current event loop.

The combination of these two issues leads to an easy footgun demonstrated by this sample code (using #165 's new feature, although not relevant to this issue) :

from pydle import Client
import asyncio

client = Client("MyBot", realname='My Bot')


@client.event
async def on_connect(self):
 await self.join('#bottest')


@client.event
async def on_message(self, target, source, message):
 # don't respond to our own messages, as this leads to a positive feedback loop
 if source != self.nickname:
   await self.message(target, message)


async def main():
 await client.connect('localhost', tls=True, tls_verify=False)
 await client.handle_forever()


if __name__ == "__main__":
 asyncio.run(main())

Pydle tries to run on a different event loop than it was called under.

RuntimeError: Task <Task pending name='Task-1' coro=<main() running at test.py:20> cb=[_run_until_complete_cb() at /usr/lib/python3.8/asyncio/base_events.py:184]> got Future <Future pending cb=[_chain_future.<locals>._call_check_cancel() at /usr/lib/python3.8/asyncio/futures.py:360]> attached to a different loop

The currently "correct" version of the above is:

from pydle import Client
import asyncio

loop = asyncio.get_event_loop()
client = Client("MyBot", realname='My Bot', loop=loop)


@client.event
async def on_connect(self):
    await self.join('#bottest')


@client.event
async def on_message(self, target, source, message):
    # don't respond to our own messages, as this leads to a positive feedback loop
    if source != self.nickname:
        await self.message(target, message)


async def main():
    await client.connect('localhost', tls=True, tls_verify=False)
    await client.handle_forever()


if __name__ == "__main__":
    loop.run_until_complete(main())

The real fix here would be to remove Pydle's internal handling of the event loop object entirely, and instead depend upon the fact that pydle's coroutines will be awaited by downstream code - from a valid event loop.
By removing the loop parameter from pydle.Client and all internal logic that uses self.eventloop, we can eliminate this class of issue all together.

Doing so would be a breaking change by semver, as it changes the public api in a backward-incompatible way.

@theunkn0wn1 theunkn0wn1 added this to the v1.0 milestone Mar 27, 2022
felixonmars added a commit to felixonmars/pydle that referenced this issue Aug 13, 2022
Implements suggestions in
shizmob#162 (comment) to
remove Pydle's internal handling of the event loop object entirely.
felixonmars added a commit to felixonmars/pydle that referenced this issue Oct 23, 2022
Implements suggestions in
shizmob#162 (comment) to
remove Pydle's internal handling of the event loop object entirely.
felixonmars added a commit to felixonmars/pydle that referenced this issue Oct 24, 2022
Implements suggestions in
shizmob#162 (comment) to
remove Pydle's internal handling of the event loop object entirely.
@Baughn
Copy link

Baughn commented Nov 16, 2022

Is this still a problem on 3.11, or is upgrading Python a potential solution?

@Rixxan
Copy link
Contributor

Rixxan commented Nov 18, 2022

@Baughn

Pydle is also broken on 3.11. Upgrading is not a fix. See #180 for the current discussion on various potential fixes.

I'll also note for the record that 3.11 removed coroutine as a valid import from asyncio (see: https://docs.python.org/3.11/whatsnew/3.11.html#removed) but Pydle still attempts in some places to import that, so once 3.10 compatibility is confirmed 3.11 will need to have another look.

Harmon758 added a commit to Harmon758/Harmonbot that referenced this issue Feb 16, 2023
shizmob/pydle#51 (comment)
shizmob/pydle#162

Add jaraco.collections, jaraco.functools, jaraco.logging, jaraco.stream, jaraco.text, and tempora as secondary requirements for irc
Add autocommand and jaraco.classes as tertiary requirements for irc
bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this issue Feb 24, 2023
https://build.opensuse.org/request/show/1067570
by user dgarcia + dimstar_suse
- Delete python-pydle-poetry-syntax.patch
- Skip python 310 and python 311, pydle doesn't python 3.10
  gh#shizmob/pydle#162, There's a WIP PR but looks like it's not good
  enough yet to be applied gh#shizmob/pydle#180
- Update to version 1.0.1
  * [Docs] Document Dropping of 3.5 by @Rixxan in #179
  * Adjust python version inequality string for Poetry by @txtsd in #182
  * bump version to 1.0.1 by @theunkn0wn1 in #183
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants