console command: AttributeError: '_SpecialForm' object has no attribute 'setdefault'
rhiller opened this issue · comments
Test program:
#!/usr/bin/env python
import asyncio
import aiomonitor
async def amain():
while True:
await asyncio.sleep(5)
print('async ticking')
loop = asyncio.get_event_loop()
with aiomonitor.start_monitor(loop):
loop.run_until_complete(amain())
While this is running, I connect to it with: nc localhost 50101
and type console
. Immediate crash with:
Task exception was never retrieved
future: <Task finished coro=<handle_connect() done, defined at /home/abc/venv/lib/python3.7/site-packages/aioconsole/server.py:8> exception=AttributeError("'_SpecialForm' object has no attribute 'setdefault'")>
Traceback (most recent call last):
File "/home/abc/venv/lib/python3.7/site-packages/aioconsole/server.py", line 11, in handle_connect
interface = factory(streams=streams)
File "/home/abc/venv/lib/python3.7/site-packages/aiomonitor/utils.py", line 73, in _factory
locals=locals, streams=streams, loop=loop)
File "/home/abc/venv/lib/python3.7/site-packages/aioconsole/code.py", line 56, in __init__
self.locals.setdefault('asyncio', asyncio)
File "/usr/lib/python3.7/typing.py", line 698, in __getattr__
return getattr(self.__origin__, attr)
AttributeError: '_SpecialForm' object has no attribute 'setdefault'
Python 3.7.1
aioconsole 0.1.11
aiomonitor 0.3.1
uvloop not installed
Linux
@jettify would you take a look?
Works for me locally, tried your script with nc
:
$ nc localhost 50101
Asyncio Monitor: 1 task running
Type help for available commands
monitor >>> console
Python 3.7.2 (default, Dec 27 2018, 07:35:06)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
---
This console is running in an asyncio event loop.
It allows you to wait for coroutines using the 'await' syntax.
Try: await asyncio.sleep(1, result=3)
---
>>> import asyncio
>>> await asyncio.sleep(0.1)
>>>
Only difference, I have Python 3.7.2 and macOS
May be clean virtual env can help?
My initial test (above) was done on a Raspberry Pi.
The following tests were all done with fresh virtual envs.
I just did a build from source of python3.7.2 on an AWS Amazon Linux machine. I get the same result:
Task exception was never retrieved
future: <Task finished coro=<handle_connect() done, defined at /home/abc/aiomon372/lib/python3.7/site-packages/aioconsole/server.py:8> exception=AttributeError("'_SpecialForm' object has no attribute 'setdefault'")>
Traceback (most recent call last):
File "/home/abc/aiomon372/lib/python3.7/site-packages/aioconsole/server.py", line 11, in handle_connect
interface = factory(streams=streams)
File "/home/abc/aiomon372/lib/python3.7/site-packages/aiomonitor/utils.py", line 73, in _factory
locals=locals, streams=streams, loop=loop)
File "/home/abc/aiomon372/lib/python3.7/site-packages/aioconsole/code.py", line 56, in __init__
self.locals.setdefault('asyncio', asyncio)
File "/usr/local/lib/python3.7/typing.py", line 698, in __getattr__
return getattr(self.__origin__, attr)
AttributeError: '_SpecialForm' object has no attribute 'setdefault'
Python 3.7.2
aioconsole 0.1.11
aiomonitor 0.3.1
I also tried with Python 3.6.5 on an AWS Amazon Linux machine and get nearly the same result:
Task exception was never retrieved
future: <Task finished coro=<handle_connect() done, defined at /home/abc/aiomon/lib/python3.6/site-packages/aioconsole/server.py:8> exception=AttributeError("'_Union' object has no attribute 'setdefault'",)>
Traceback (most recent call last):
File "/home/abc/aiomon/lib/python3.6/site-packages/aioconsole/server.py", line 11, in handle_connect
interface = factory(streams=streams)
File "/home/abc/aiomon/lib/python3.6/site-packages/aiomonitor/utils.py", line 73, in _factory
locals=locals, streams=streams, loop=loop)
File "/home/abc/aiomon/lib/python3.6/site-packages/aioconsole/code.py", line 56, in __init__
self.locals.setdefault('asyncio', asyncio)
AttributeError: '_Union' object has no attribute 'setdefault'
The difference being the AttributeError
on _Union
versus _SpecialForm
.
Python 3.6.5
aioconsole 0.1.11
aiomonitor 0.3.1
Perhaps a clue is that when I connect with nc when running the Python 3.7.2 test, I see:
$ nc localhost 50101
Asyncio Monitor: 2 tasks running
Type help for commands
monitor >>> ps
+-----------------+----------+----------------------------------------------------------------------------+
| Task ID | State | Task |
+-----------------+----------+----------------------------------------------------------------------------+
| 140306876217288 | PENDING | <Task pending coro=<amain() running at wss6:8> wait_for=<Future pending |
| | | cb=[<TaskWakeupMethWrapper object at 0x7f9bbcd8a1c8>()]> |
| | | cb=[_run_until_complete_cb() at |
| | | /usr/local/lib/python3.7/asyncio/base_events.py:158]> |
| 140306876217448 | FINISHED | <Task finished coro=<start_interactive_server() done, defined at |
| | | /home/abc/aiomon372/lib/python3.7/site-packages/aioconsole/server.py:17> |
| | | result=<Server socke....1', 50102)>]>> |
+-----------------+----------+----------------------------------------------------------------------------+
monitor >>>
Your example only shows one task. I notice that all of my tests (Raspberry Pi with Python 3.7.1, and Python 3.6.5) show two tasks.
Can confirm this.
$ python -V
Python 3.6.6
$ pip freeze
aioconsole==0.1.11
aiomonitor==0.3.1
terminaltables==3.1.0
Clean virtualenv. Investigating.
This issue was introduced in: 0b71c7f#diff-51363086d2299da2efead1b3d155a45bR32 (notice locals assigment) and presents in 0.3.1 release, but not on master. How about make a new year release? (:
I confirm that locals=None
works as a workaround.
as in:
loop = asyncio.get_event_loop()
with aiomonitor.start_monitor(loop, locals=None):
loop.run_until_complete(amain())
I probably contaminated my env with master version, as result failed to repro... Anyway new release should fix things.
Kicked release pipeline https://travis-ci.com/aio-libs/aiomonitor/builds/96348771
New version on PyPI https://pypi.org/project/aiomonitor/0.4.0/
🎉 🎅