Exception raised with trace_variable() - python

I have a function that is supposed to build a window according to which option in a dropdown menu is selected:
def buildview():
value = StringVar()
options = ["one", "two", "three"]
menu = OptionMenu(*(root, value) + tuple(options))
### Some window building accoring to the value selected... ###
value.trace_variable("w", buildview)
The exception that is raised looks like this (EDIT: Entire Traceback):
Traceback (most recent call last):
File "D:\Dropbox\PRO\infograbber\Infograbber 0.1.py", line 102, in <module>
mainloop()
File "C:\Python35\Python3564\lib\tkinter\__init__.py", line 405, in mainloop
_default_root.tk.mainloop(n)
File "C:\Python35\Python3564\lib\tkinter\__init__.py", line 1553, in __call__
self.widget._report_exception()
AttributeError: 'StringVar' object has no attribute '_report_exception'
What exactly is causing this? Can I not have a method call back itself like this? I don't even know where to start fixing this problem, so I'd appreciate any help.
I'm using Python 3.5 64 bit, Sublime Text 2, Windows 10.
EDIT:
Added a test callback function:
def test(*args):
print("test")
and changed the above trace to
value.trace_variable("w", test)
Now the exception changed to this:
Traceback (most recent call last):
File "C:\Python35\Python3564\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "D:\Dropbox\PRO\infograbber\Infograbber 0.1.py", line 56, in buildview
root.trace_variable("w", self.printcurrentarticle)
File "C:\Python35\Python3564\lib\tkinter\__init__.py", line 1948, in __getattr__
return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'trace_variable'

I'm not entirely sure if this is the only problem, but it's definitely a problem. When a trace fires it passes in three arguments. The function you've defined takes no arguments. You need to pass in a reference to a function that takes at least three arguments.
You also have the problem that each time the trace fires, you are creating another variable and another trace. On the surface that seems like a bad idea, unless you really do want to create a new option menu every time an optionmenu changes.

Related

Python 2 to 3, error converting a list(zip(*aList)[1])

I have a small chunk of code which not being a python guru I am not sure what it is really 'doing', but it fails under python3:
if indSoundsToPlay:
indSoundsToPlay = list(indSoundsToPlay)
indSoundsToPlay.sort()
soundsToPlay = list(zip(*indSoundsToPlay)[1]) <-- fails
soundsToPlay.reverse() # since played from back to front
self.playSounds(soundsToPlay)
This worked fine in Python2, but upon converting it did not like the list zip line at all. So I converted that line to:
soundsToPlay = list(zip(*indSoundsToPlay))
It was okay with that, I am not sure what the list zip * is really doing in python. Though the error subsided but now I realized that I painted myself into either a) another error or b) a new error just near the same code. The slice of code that now breaks is :
What error I get now is on the function call to playSounds:
def playSounds(self, sounds):
"""Play one or more of a set of sounds; played in order from last to first.
"""
if not sounds:
return
soundFunc = sounds.pop(-1)
soundFunc()
if sounds:
self._soundTimer.start(_SoundInterval, self.playSounds, sounds)
KeyVar('tcc', 'AxisCmdState') <bound method AxisStatusWdg.setAxisCmdState of <TUI.TCC.StatusWdg.AxisStatus.AxisStatusWdg object .!toplevel46.!statuswdg.!axisstatuswdg>>(*(['Drifting', 'Drifting', 'Drifting'],), **{'isCurrent': True, 'keyVar': KeyVar('tcc', 'AxisCmdState', 3, str)}) failed: 'tuple' object is not callable
Traceback (most recent call last):
File "/Users/st/TUI3/RO/AddCallback.py", line 77, in safeCall2
return func(*args, **kwargs)
File "/Users/st/TUI3/TUI/TCC/StatusWdg/AxisStatus.py", line 300, in setAxisCmdState
self.playSounds(soundsToPlay)
File "/Users/st/TUI3/TUI/TCC/StatusWdg/AxisStatus.py", line 359, in playSounds
soundFunc()
TypeError: 'tuple' object is not callable
KeyVar('tcc', 'AxisCmdState') <bound method AxisStatusWdg.setAxisCmdState of <TUI.TCC.StatusWdg.AxisStatus.AxisStatusWdg object .!toplevel46.!statuswdg.!axisstatuswdg>>(*(['Tracking', 'Tracking', 'Tracking'],), **{'isCurrent': True, 'keyVar': KeyVar('tcc', 'AxisCmdState', 3, str)}) failed: 'tuple' object is not callable
Traceback (most recent call last):
File "/Users/st/TUI3/RO/AddCallback.py", line 77, in safeCall2
return func(*args, **kwargs)
File "/Users/st/TUI3/TUI/TCC/StatusWdg/AxisStatus.py", line 300, in setAxisCmdState
self.playSounds(soundsToPlay)
File "/Users/st/TUI3/TUI/TCC/StatusWdg/AxisStatus.py", line 359, in playSounds
soundFunc()
TypeError: 'tuple' object is not callable
I don't know if it's what I did to indSoundsToPlay with the changing of that list(zip command or if it is a separate error in general. So not really sure where to start with this one besides learning what list(zip(* means in python.

AttributeError: 'str' object has no attribute 'errno'

I placed a ClientConnectionError exception in a multiprocessing.Queue that was generated by asyncio. I did this to pass an exception generated in asyncio land back to a client in another thread/process.
My assumption is that this exception occurred during the deserialization process reading the exception out of the queue. It looks pretty much impossible to reach otherwise.
Traceback (most recent call last):
File "model_neural_simplified.py", line 318, in <module>
main(**arg_parser())
File "model_neural_simplified.py", line 314, in main
globals()[command](**kwargs)
File "model_neural_simplified.py", line 304, in predict
next_neural_data, next_sample = reader.get_next_result()
File "/project_neural_mouse/src/asyncs3/s3reader.py", line 174, in get_next_result
result = future.result()
File "/usr/lib/python3.6/concurrent/futures/_base.py", line 432, in result
return self.__get_result()
File "/usr/lib/python3.6/concurrent/futures/_base.py", line 384, in __get_result
raise self._exception
File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "model_neural_simplified.py", line 245, in read_sample
f_bytes = s3f.read(read_size)
File "/project_neural_mouse/src/asyncs3/s3reader.py", line 374, in read
size, b = self._issue_request(S3Reader.READ, (self.url, size, self.position))
File "/project_neural_mouse/src/asyncs3/s3reader.py", line 389, in _issue_request
response = self.communication_channels[uuid].get()
File "/usr/lib/python3.6/multiprocessing/queues.py", line 113, in get
return _ForkingPickler.loads(res)
File "/usr/local/lib/python3.6/dist-packages/aiohttp/client_exceptions.py", line 133, in __init__
super().__init__(os_error.errno, os_error.strerror)
AttributeError: 'str' object has no attribute 'errno'
I figure it's a long shot to ask, but does anyone know anything about this issue?
Python 3.6.8, aiohttp.__version__ == 3.6.0
Update:
I managed to reproduce the issue (credit to Samuel in comments for improving the minimal reproducible test case, and later xtreak at bugs.python.org for furthing distilling it to a pickle-only test case):
import pickle
ose = OSError(1, 'unittest')
class SubOSError(OSError):
def __init__(self, foo, os_error):
super().__init__(os_error.errno, os_error.strerror)
cce = SubOSError(1, ose)
cce_pickled = pickle.dumps(cce)
pickle.loads(cce_pickled)
./python.exe ../backups/bpo38254.py
Traceback (most recent call last):
File "/Users/karthikeyansingaravelan/stuff/python/cpython/../backups/bpo38254.py", line 12, in <module>
pickle.loads(cce_pickled)
File "/Users/karthikeyansingaravelan/stuff/python/cpython/../backups/bpo38254.py", line 8, in __init__
super().__init__(os_error.errno, os_error.strerror)
AttributeError: 'str' object has no attribute 'errno'
References:
https://github.com/aio-libs/aiohttp/issues/4077
https://bugs.python.org/issue38254
OSError has a custom __reduce__ implementation; unfortunately, it's not subclass friendly for subclasses that don't match the expected arguments. You can see the intermediate state of the pickling by calling __reduce__ manually:
>>> SubOSError.__reduce__(cce)
(modulename.SubOSError, (1, 'unittest'))
The first element of the tuple is the callable to call, the second is the tuple of arguments to pass. So when it tries to recreate your class, it does:
modulename.SubOSError(1, 'unittest')
having lost the information about the OSError you were originally created with.
If you must accept arguments that don't match what OSError.__reduce__/OSError.__init__ expects, you're going to need to write your own __reduce__ override to ensure the correct information is pickled. A simple version might be:
class SubOSError(OSError):
def __init__(self, foo, os_error):
self.foo = foo # Must preserve information for pickling later
super().__init__(os_error.errno, os_error.strerror)
def __reduce__(self):
# Pickle as type plus tuple of args expected by type
return type(self), (self.foo, OSError(*self.args))
With that design, SubOSError.__reduce__(cce) would now return:
(modulename.SubOSError, (1, PermissionError(1, 'unittest')))
where the second element of the tuple is the correct arguments needed to recreate the instance (the change from OSError to PermissionError is expected; OSError actually returns its own subclasses based on the errno).
This issue was fixed and merged to master in aiohttp on 25 Sep 2019. I'll update this answer in the future if I note a version that the fix goes into (feel free to edit this answer in the future to note a version containing this update).
Git issue with the fix:
https://github.com/aio-libs/aiohttp/issues/4077

python bind not working

I have the basic screensaver program. I want to bind Mouse button 1 to delete everything on screen, but when I press the Button-1 I get this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python34\lib\idlelib\run.py", line 121, in main
seq, request = rpc.request_queue.get(block=True, timeout=0.05)
File "C:\Python34\lib\queue.py", line 175, in get
raise Empty
queue.Empty
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1533, in __call__
return self.func(*args)
TypeError: delete() takes 0 positional arguments but 1 was given
.
.
.
.
This is my program:
import tkinter
canvas=tkinter.Canvas(width=1000,height=800)
canvas.pack()
from random import *
entry1=tkinter.Entry()
entry1.pack()
def setric():
x=randrange(900)
y=randrange(700)
global a
canvas.delete('all')
farba=choice(("red","purple","blue","lightblue","green","lightgreen"))
if a>-90:
a=a-10
else:
a=-10
if entry1.get()=="":
canvas.update()
canvas.after(3000,setric)
a=0
else:
canvas.create_text(x,y,text=entry1.get(),font="Arial 40",fill=farba,angle=a)
canvas.after(2000, setric)
def delete():
canvas.delete("all")
a=0
setric()
canvas.bind('<Button-1>',delete)
Even when I change what is in the def delete I still get the error.
Thanks for your time! I am new to this so I have no idea where is the problem
....................................................................................................................................................................................................................................................
Functions called via bindings are automatically passed an object that represents the event. Your delete method needs to be able to accept this parameter even if you don't use it.
def delete(event):
canvas.delete("all")

function inputs in classes

So i have started using classes in python and i am still learning how it works. so in this part of my code and i found something that i don't understand.
def Button(self):
self.Button = QPushButton("Push me Bitch!",self)
self.Button.setGeometry(QtCore.QRect(500, 500, 5, 5))
self.Button.resize(self.Button.minimumSizeHint())
self.Button.clicked.connect(self.ButtonPress(someInput))
# Do functions
def ButtonPress(self , someInput):
print('someInput')
self.OutputBox1.setText('I Has Been Pressed!')
And this is the error that i got:
Traceback (most recent call last):
File "C:\Users\Gebruiker\Desktop\Python shizzle\BijHillen\BijGui.py", line 92, in <module>
ex = Example()
File "C:\Users\Gebruiker\Desktop\Python shizzle\BijHillen\BijGui.py", line 40, in __init__
self.Button()
File "C:\Users\Gebruiker\Desktop\Python shizzle\BijHillen\BijGui.py", line 68, in Button
self.Button.clicked.connect(self.ButtonPress(5))
File "C:\Users\Gebruiker\Desktop\Python shizzle\BijHillen\BijGui.py", line 74, in ButtonPress
self.OutputBox1.setText('I Have Been Pressed!!!')
AttributeError: 'Example' object has no attribute 'OutputBox1'
If i remove the someInput. Then there is no problem. How does this work?
Best regards
Your event setup is wrong, when you attach an event to a button you generally want to link the function, not the result of the function to the clicked event.
Instead of:
self.Button.clicked.connect(self.ButtonPress(someInput))
You want:
self.Button.clicked.connect(self.ButtonPress)
That way the function will get called when the button is clicked.
You might have some other issues with your code, but start by fixing that.

Using pdb, how can I run a program and pause where reaching an error?

Using python interpreter and/or pdb, can we run a program and pause whenever reaching an error, so that I can examine all the frames of the call stack of the program at the time of crashing?
When I run a program directly inside python interpreter, when reaching an error, it tells where the line of code it happens, but it seems return to the topmost frame, and I can't examine the frame where the error actually happens. E.g.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 194, in <module>
addlevel(root_toc, 0)
File "test.py", line 191, in addlevel
addlevel(child, root_level+1)
File "test.py", line 188, in addlevel
root.value.append(root_level)
AttributeError: 'str' object has no attribute 'append'
>>> root_level
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'root_level' is not defined
The error happens at the lowest frame, and I can't examine the value of root_level at that frame. Is it because it returns to the topmost frame after the error happens? How can examine the lowest frame?
THanks.
Run pdb as a module, passing the script you want to debug. It will break on abnormal exits. (This is mentioned early in the docs.)
python -m pdb my_script.py
If you're in the interpreter, you can use pdb.pm() to debug the last traceback.
Or, use the IPython interpreter. Typing debug after an uncaught exception will enter a pdb session for the last traceback, similar to pm().

Categories

Resources