What does 'File "<string>"' stands for on python debugger and traceback? - python

Eventually, when I am in a debug session, the current file is named "<string>". What I would expect to see is the name of the module where the debugger is currently on.
The same happens on the traceback:
Traceback (most recent call last):
...
File "~/project_x/app/services/contacts.py", line 23, in find_account
account = self._account_repo.get_by_id(id)
File "<string>", line 2, in get_by_id
File "~/project_x/lib/python3.7/site-packages/pony/orm/core.py", li
ne 528, in new_func
result = func(*args, **kwargs)

It means that the code came from something that was not a file, but a string. My guess would be an exec() call, but maybe there are other ways of getting the same effect. The previous stack frame might give some clues.

Related

Shorten stack trace of exceptions?

I have a custom exception get raised when someone screws up with my library, which currently looks like this:
Traceback (most recent call last):
File "main.py", line 17, in <module>
StateMachine()
File "main.py", line 15, in __new__
activate(self)
File "/home/runner/va4un94x2qp/fsm.py", line 101, in activate
state = enable(machine, state)
File "/home/runner/va4un94x2qp/fsm.py", line 94, in enable
raise MissingReturnError("State '{}' in machine '{}' missing a return statement, or it returns None..".format(StateFound.fallmsg, machine.__name__))
fsm.MissingReturnError: State '__main__' in machine 'StateMachine' missing a return statement, or it returns None.
But I want it to look like this:
Traceback (most recent call last):
File "main.py", line 17, in <module>
StateMachine()
File "main.py", line 15, in __new__
activate(self)
MissingReturnError: State '__main__' in machine 'StateMachine' missing a return statement, or it returns None.
How do I do that, without any excepthook nonsense? (Because THAT doesn't just affect one exception, it affects all exceptions) I want to modify an exception. By the way, I've tried setting suppress_context to True, I've tried raising the exception from None. How else do I do it?
And if you ask, everything I want gone, isn't needed. All that is needed is the exception message, and the call of the activate() method.
And I'm not going to be messing with the Python interpreter, I'm going to be releasing this library to the public, and I want exceptions to look this way to everyone. (It's Python 3.X)

NameError python api "vishnubob/kinet"

So I am trying to run and learn all about the vishnubob/kinet api.
After I download it I try to run the example script (also after fixing a couple syntax errors) I get this error:
Traceback (most recent call last):
File "example.py", line 31, in <module>
pds = PowerSupply("192.168.1.121")
NameError: name 'PowerSupply' is not defined
I have no clue why this is happening, as the imports look good (to me at least).
If someone knows why or can point me to the right direction then I would be grateful.
The clue here is "fixing syntax errors". That code has been written for Python 2, and it uses a thing called implicit relative import which was removed in Python 3. Namely the line in kinet/__init__.py
from kinet import *
is trying to import from the top-level package in Python 3, when Python 2 defaulted to importing from a local module first (kinet/kinet.py). The fix is to change this to
from .kinet import *
However this leads down the rabbit hole, as kinet.py has more syntax errors, after which it just fails spectacularly with
Traceback (most recent call last):
File "example.py", line 31, in <module>
pds = PowerSupply("192.168.1.121")
File "./kinet/kinet.py", line 227, in __init__
self.header = Header()
File "./kinet/kinet.py", line 22, in __init__
self._struct = struct.Struct(self.struct_format)
File "./kinet/kinet.py", line 61, in __setattr__
if key not in self.Keys:
File "./kinet/kinet.py", line 56, in __getattr__
if key not in self.Keys:
File "./kinet/kinet.py", line 56, in __getattr__
if key not in self.Keys:
File "./kinet/kinet.py", line 56, in __getattr__
if key not in self.Keys:
[Previous line repeated 325 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object
It is a bad piece of code written using all the syntax that was deprecated already in Python 2.6. I'd look for a Python 3 rewrite instead of trying to fix that.

Creating a track object with track_from_file method in pyechonest

I am new to python. I am trying to use track_from_file method in pyechonest to create a track object. This is the code I wrote:
from pyechonest import config
from pyechonest.track import track_from_file
config.ECHO_NEST_API_KEY = "KRZG4XOVUQRKI45DP"
f = open("ShayneWard-NoPromises.mp3")
t = track_from_file(f, 'mp3')
But this is not working. I got an EchoNestIOError. This is the full error Traceback that i got.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "build/bdist.linux-x86_64/egg/pyechonest/track.py", line 243, in track_from_file
File "build/bdist.linux-x86_64/egg/pyechonest/track.py", line 331, in track_from_md5
File "build/bdist.linux-x86_64/egg/pyechonest/track.py", line 209, in _profile
File "build/bdist.linux-x86_64/egg/pyechonest/util.py", line 257, in callm pyechonest.util.
EchoNestIOError: Echo Nest Unknown Error
Can anyone tell me what have I done wrong?
I finally figured it out. It seems that the upload does not take place through the proxy server of my university network which uses NAT.

Intermittent KeyError raised and can not reproduce it

I tried to reproduce it with some simpler functions but didn't succeed. So the following code shows the relevant methods for a KeyError which get's thrown by our production servers, a lot.
class PokerGame:
...
def serialsNotFold(self):
return filter(lambda x: not self.serial2player[x].isFold(), self.player_list)
def playersNotFold(self):
return [self.serial2player[serial] for serial in self.serialsNotFold()]
...
And here is the Traceback.
Traceback (most recent call last):
File "/usr/lib/python2.6/dist-packages/pokernetwork/pokertable.py", line 945, in update
try: self.game.historyReduce()
File "/usr/lib/python2.6/dist-packages/pokerengine/pokergame.py", line 3949, in historyReduce
self.turn_history = PokerGame._historyReduce(self.turn_history,self.moneyMap())
File "/usr/lib/python2.6/dist-packages/pokerengine/pokergame.py", line 1323, in moneyMap
money = dict((player.serial,player.money) for player in self.playersNotFold())
File "/usr/lib/python2.6/dist-packages/pokerengine/pokergame.py", line 3753, in playersNotFold
return [self.serial2player[serial] for serial in self.serialsNotFold()]
KeyError: 21485L
self.player_list is a list with serials
self.serial2player is a dict which maps serials to Player objects
Now it shouldn't be possible that the KeyError is raised in playersNotFold because therefore the same error had to be raised in serialsNotFold, which it gets not.
I asked my 2 peers and the guys on #python but no one was able to even gues how this can happen.
If you need the full source: https://github.com/pokermania/poker-network/
EDIT:
The Problem was that we printed traceback.format_exc(limit=4) which limits from the top instead of the bottom. The last 2 calls where hidden, so it looked like playersNotFold raised the exception.
Here is a full trace.
Traceback (most recent call last):
File "/usr/lib/python2.7/pokernetwork/pokertable.py", line 704, in update
try: self.game.historyReduce()
File "/usr/lib/python2.7/pokerengine/pokergame.py", line 3953, in historyReduce
self.turn_history = PokerGame._historyReduce(self.turn_history,self.moneyMap())
File "/usr/lib/python2.7/pokerengine/pokergame.py", line 1327, in moneyMap
money = dict((player.serial,player.money) for player in self.playersNotFold())
File "/usr/lib/python2.7/pokerengine/pokergame.py", line 3757, in playersNotFold
return self.serial2player[serial] for serial in self.serialsNotFold()]
File "/usr/lib/python2.7/pokerengine/pokergame.py", line 3754, in serialsNotFold
return filter(lambda x: not self.serial2player[x].isFold(] self.player_list)
File "/usr/lib/python2.7/pokerengine/pokergame.py", line 3754, in <lambda>
return filter(lambda x: not self.serial2player[x].isFold(] self.player_list)
KeyError: 1521
I'm sorry for wasting your time :/
I guess you use threads and self.serial2player gets modified by a different thread.

Python: eliminating stack traces into library code?

When I get a runtime exception from the standard library, it's almost always a problem in my code and not in the library code. Is there a way to truncate the exception stack trace so that it doesn't show the guts of the library package?
For example, I would like to get this:
Traceback (most recent call last):
File "./lmd3-mkhead.py", line 71, in <module>
main()
File "./lmd3-mkhead.py", line 66, in main
create()
File "./lmd3-mkhead.py", line 41, in create
headver1[depotFile]=rev
TypeError: Data values must be of type string or None.
and not this:
Traceback (most recent call last):
File "./lmd3-mkhead.py", line 71, in <module>
main()
File "./lmd3-mkhead.py", line 66, in main
create()
File "./lmd3-mkhead.py", line 41, in create
headver1[depotFile]=rev
File "/usr/anim/modsquad/oses/fc11/lib/python2.6/bsddb/__init__.py", line 276, in __setitem__
_DeadlockWrap(wrapF) # self.db[key] = value
File "/usr/anim/modsquad/oses/fc11/lib/python2.6/bsddb/dbutils.py", line 68, in DeadlockWrap
return function(*_args, **_kwargs)
File "/usr/anim/modsquad/oses/fc11/lib/python2.6/bsddb/__init__.py", line 275, in wrapF
self.db[key] = value
TypeError: Data values must be of type string or None.
update: added an answer with the code, thanks to the pointer from Alex.
The traceback module in Python's standard library lets you emit error tracebacks in a way that accords to your liking, while an exception is propagating. You can use this power either in the except leg of a try/except statement, or in a function you've installed as sys.excepthook, which gets called if and when an exception propagates all the way; quoting the docs:
In an interactive session this happens
just before control is returned to the
prompt; in a Python program this
happens just before the program exits.
The handling of such top-level
exceptions can be customized by
assigning another three-argument
function to sys.excepthook.
Here's a simple, artificial example:
>>> import sys
>>> import traceback
>>> def f(n):
... if n<=0: raise ZeroDivisionError
... f(n-1)
...
>>> def excepthook(type, value, tb):
... traceback.print_exception(type, value, tb, 3)
...
>>> sys.excepthook = excepthook
>>> f(8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in f
File "<stdin>", line 3, in f
ZeroDivisionError
as you see, without needing a try/except, you can easily limit the traceback to (for example) the first three levels -- even though we know by design that there were 9 nested levels when the exception was raised.
You want something more sophisticated than a simple limit on levels, so you'll need to call traceback.format_exception, which gives you a list of lines rather than printing it, then "prune" from that list the lines that are about modules you never want to see in your tracebacks, and finally emit the remaining lines (typically to sys.stderr, but, whatever!-).
Thanks to the pointer from Alex, here's teh codez:
def trimmedexceptions(type, value, tb, pylibdir=None, lev=None):
"""trim system packages from the exception printout"""
if pylibdir is None:
import traceback, distutils.sysconfig
pylibdir = distutils.sysconfig.get_python_lib(1,1)
nlev = trimmedexceptions(type, value, tb, pylibdir, 0)
traceback.print_exception(type, value, tb, nlev)
else:
fn = tb.tb_frame.f_code.co_filename
if tb.tb_next is None or fn.startswith(pylibdir):
return lev
else:
return trimmedexceptions(type, value, tb.tb_next, pylibdir, lev+1)
import sys
sys.excepthook=trimmedexceptions
# --- test code ---
def f1(): f2()
def f2(): f3()
def f3():
import xmlrpclib
proxy = xmlrpclib.ServerProxy('http://nosuchserver')
proxy.f()
f1()
Which yields this stack trace:
Traceback (most recent call last):
File "./tsttraceback.py", line 47, in <module>
f1()
File "./tsttraceback.py", line 40, in f1
def f1(): f2()
File "./tsttraceback.py", line 41, in f2
def f2(): f3()
File "./tsttraceback.py", line 45, in f3
proxy.f()
gaierror: [Errno -2] Name or service not known
The Traceback library is probably what you want. Here's one example that might help:
import traceback
try:
your_main()
except:
lines = traceback.format_exc()
print lines[:lines.find('File "/usr')]
(This obviously won't work if there's an exception outside the library, and might not exactly fit your needs, but it's one way of using the traceback library)
Put an unqualified try...except at the top of your code (ie: in your "main") or set sys.excepthook. You can then format the stack trace however you'd like.

Categories