quamash
quamash copied to clipboard
Name mangling causes 'NoneType' object has no attribute 'append'
While I was looking at the code I saw some double underscored attributes. One of them was __timers in QEventLoop. When I was trying the library I had series of same traceback. I tried to debug the problem, When I tried to access __timers in _add_callback I had AttributeError and when I did dir(self) I saw _QEventLoop__timers attribute.
This library is too much for me to understand but as far as I see, there's a problem with name mangling here.
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/quamash/__init__.py", line 215, in <lambda>
signaller.signal.connect(lambda callback, args: self.call_soon(callback, *args))
File "/usr/local/lib/python3.4/dist-packages/quamash/__init__.py", line 331, in call_soon
return self.call_later(0, callback, *args)
File "/usr/local/lib/python3.4/dist-packages/quamash/__init__.py", line 307, in call_later
return self._add_callback(asyncio.Handle(callback, args, self), delay)
File "/usr/local/lib/python3.4/dist-packages/quamash/__init__.py", line 325, in _add_callback
self.__timers.append(timer)
AttributeError: 'NoneType' object has no attribute 'append'
Are you on windows? On Jan 6, 2016 4:26 AM, "Umut Karcı" [email protected] wrote:
While I was looking at the code I saw some double underscored attributes One of them was __timers in QEventLoop When I was trying the library I had series of same traceback I tried to debug the problem, When I tried to access __timers in _add_callback I had AttributeError and when I did dir(self) I saw _QEventLoop__timers attribute
This library is too much for me to understand but as far as I see, there's a problem with name mangling here
Traceback (most recent call last): File "/usr/local/lib/python34/dist-packages/quamash/__init__py", line 215, in
signallersignalconnect(lambda callback, args: selfcall_soon(callback, *args)) File "/usr/local/lib/python34/dist-packages/quamash/__init__py", line 331, in call_soon return selfcall_later(0, callback, *args) File "/usr/local/lib/python34/dist-packages/quamash/__init__py", line 307, in call_later return self_add_callback(asyncioHandle(callback, args, self), delay) File "/usr/local/lib/python34/dist-packages/quamash/__init__py", line 325, in _add_callback self__timersappend(timer) AttributeError: 'NoneType' object has no attribute 'append' — Reply to this email directly or view it on GitHub https://github.com/harvimt/quamash/issues/60.
I don't understand why name mangling would cause self.__timers
to be None. If anything you should get an AttributeError
.
Anyhow, when you debug, you have to use the mangled name of course since at runtime the attribute name will already be mangled.
"/usr/local/lib/"
probably not a windows problem then.
hrm. if you can produce a reduced test case that's always the best.
On Wed, Jan 6, 2016 at 9:40 AM, Arve Knudsen [email protected] wrote:
Anyhow, when you debug, you have to use the mangled name of course since at runtime the attribute name will already be mangled.
— Reply to this email directly or view it on GitHub https://github.com/harvimt/quamash/issues/60#issuecomment-169399925.
Sorry for late response, Okay, I'll try to create a test case as soon as possible. Meanwhile, this is some of my code, I hope it helps until I can create a test case.
### gui.py
app = QtWidgets.QApplication(sys.argv)
loop = QEventLoop(app)
asyncio.set_event_loop(loop)
### downloader.py
def _start(queue):
loop = asyncio.get_event_loop()
results = loop.run_until_complete(asyncio.gather(*[worker(page_obj) for page_obj in queue]))
I'm on python 3.4, Linux Mint 17.3 (ubuntu 14.04.3 derivative) and PyQt 5.2.1
Hey, I have encountered a similar traceback:
Connected to pydev debugger (build 145.260)
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/local/src/test3.py", line 26, in on_exit
task.cancel()
File "/usr/lib/python3.4/asyncio/tasks.py", line 211, in cancel
if self._fut_waiter.cancel():
File "/usr/lib/python3.4/asyncio/futures.py", line 228, in cancel
self._schedule_callbacks()
File "/usr/lib/python3.4/asyncio/futures.py", line 243, in _schedule_callbacks
self._loop.call_soon(callback, self)
File "/usr/local/lib/python3.4/dist-packages/quamash/__init__.py", line 352, in call_soon
return self.call_later(0, callback, *args)
File "/usr/local/lib/python3.4/dist-packages/quamash/__init__.py", line 329, in call_later
return self._add_callback(asyncio.Handle(callback, args, self), delay)
File "/usr/local/lib/python3.4/dist-packages/quamash/__init__.py", line 346, in _add_callback
self.__timers.append(timer)
AttributeError: 'NoneType' object has no attribute 'append'
Task was destroyed but it is pending!
task: <Task pending coro=<master() done, defined at /usr/local/src/test3.py:35> wait_for=<Future cancelled>>
This is my test code:
from atexit import register, unregister
from PySide.QtGui import QApplication, QProgressBar
from quamash import QEventLoop
import sys
import asyncio
import signal
import os
app = QApplication(sys.argv)
loop = QEventLoop(app)
asyncio.set_event_loop(loop) # NEW must set the event loop
loop.add_signal_handler(signal.SIGINT, lambda *a: loop.stop())
def safe_spawn(coro):
def on_done(*a, **kw):
assert isinstance(task, asyncio.Task)
task.result()
unregister(on_exit)
def on_exit(*a, **kw):
assert isinstance(task, asyncio.Task)
task.remove_done_callback(on_done)
task.cancel()
task = loop.create_task(coro)
assert isinstance(task, asyncio.Task)
task.add_done_callback(on_done)
register(on_exit)
return task
@asyncio.coroutine
def master():
process = yield from asyncio.create_subprocess_exec(
'/usr/bin/env', 'true')
yield from process.wait()
progress = QProgressBar()
progress.setRange(0, 99)
progress.show()
os.system("{ sleep 0.5; kill -INT %s; } &" % os.getpid())
yield from asyncio.sleep(1)
progress.hide()
loop.call_later(2, lambda: safe_spawn(master()))
with loop:
safe_spawn(master())
loop.run_forever()
I think there is a problem with my shutdown logic, but I hope this helps @Cediddi
OK, so this has nothing to do with name mangling. It's clearly a problem with trying to run _add_callback after the loop is closed.
If you're getting this, you may want to refrain from using with loop
and call loop.close
manually, when you know that you're done with the loop. (or just let garbage collection clean it up)
I may work on making the error message friendlier.
(or we've found out why the builtin event loop doesn't use a context manager)
Thanks David, but my issue was on runtime, not at exit. Problem is I left the project, so this issue is no longer in my scope.
I have also seen that error..
- Trying to use:
with loop: ## context manager calls .close() when loop completes, and releases all resources
loop.run_until_complete(master())
with loop: ## context manager calls .close() when loop completes, and releases all resources
loop.run_until_complete(master())
the application is closed with a deadly report:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "D:\Python34\lib\site-packages\quamash-0.5.5-py3.4.egg\quamash\__init__.p
y", line 260, in run_until_complete
File "D:\Python34\lib\asyncio\tasks.py", line 505, in async
task = loop.create_task(coro_or_future)
File "D:\Python34\lib\asyncio\base_events.py", line 172, in create_task
task = tasks.Task(coro, loop=self)
File "D:\Python34\lib\asyncio\tasks.py", line 74, in __init__
self._loop.call_soon(self._step)
File "D:\Python34\lib\site-packages\quamash-0.5.5-py3.4.egg\quamash\__init__.p
y", line 352, in call_soon
File "D:\Python34\lib\site-packages\quamash-0.5.5-py3.4.egg\quamash\__init__.p
y", line 329, in call_later
File "D:\Python34\lib\site-packages\quamash-0.5.5-py3.4.egg\quamash\__init__.p
y", line 346, in _add_callback
AttributeError: 'NoneType' object has no attribute 'append'
>>> Traceback (most recent call last):
File "D:\Python34\lib\site-packages\quamash-0.5.5-py3.4.egg\quamash\__init__.p
y", line 192, in timerEvent
File "D:\Python34\lib\site-packages\quamash-0.5.5-py3.4.egg\quamash\__init__.p
y", line 335, in upon_timeout
TypeError: argument of type 'NoneType' is not iterable
F:\miguel 2\Proyectos\instaladores>
this is expected. once a loop closes it can't be started again.
(though the error message could be better)
(I'm starting to realize why the builtin loop isn't a context manager maybe?)
If you start/stop the loop multiple times then you need to manage the loop yourself, and call close on it when you're done.