Brian Dorsey <briandorsey@...> writes:
> Hi everyone,
>
> All the talk about .py, .py and .pyw files recently got me thinking
> about my little traceback question with py2exe.
>
> When exceptions happen in py2exe'd applications, the tracebacks no
> longer include the actual lines of code where the error was raised.
> After a little bit of playing around, this appears to be a standard
> python trait, rather than anything py2exe is causing. When only pyc
> files are available, tracebacks include line numbers, but not the
> actual code. I went ahead and tried the easy thing and copied py files
> into the library.zip file, but they don't seem to be found.
>
> Oddly enough, if you copy the py files into the current directory, the
> py2exe app will include code in the tracebacks.
Interesting! This wasn't supposed to work. There is code in
py2exe\boot_common.py, which should prevent this:
# Disable linecache.getline() which is called by
# traceback.extract_stack() when an exception occurs to try and read
# the filenames embedded in the packaged python code. This is really
# annoying on windows when the d: or e: on our build box refers to
# someone elses removable or network drive so the getline() call
# causes it to ask them to insert a disk in that drive.
import linecache
def fake_getline(filename, lineno):
return ''
linecache.orig_getline = linecache.getline
linecache.getline = fake_getline
del linecache, fake_getline
Actually, I never had the problem described here - this code is from
Mark Hammond, and I believe him. Ok, the reason seems to be that when
an exception is raised, which is not catched by *python* code, the
traceback is printed by C code: Python\taceback.c, function
tb_displayline().
I have not really read the code, but it doesn't seem the code tries to
locate the .py sources in the zipfile (which may or may not be a bug).
Ok, and when we catch the error in Python code, and print the traceback,
Mark's code is triggered, and you won't get the source lines in your
traceback any more, even if the .py file is available.
But this gives a hint how this problem can be solved:
Implement a new linecache.getline function, which will find the source
file in the zip, and be sure to catch all tracebacks in your python
code.
Here is a script which demonstrates this approach (loding the source
from the zip is left for you ;-):
"""
def test(a, b):
return a / b
def divide(x):
return test(100, x)
def my_getline(filename, lineno):
return "X " + linecache.orig_getline(filename, lineno)
import linecache
linecache.getline = my_getline
if __name__ == "__main__":
try:
divide(10)
divide(0)
except:
import traceback
traceback.print_exc()
"""
and this is printed when running the exe, with the .py module in the
current directory:
C:\temp>dist\error.exe
Traceback (most recent call last):
File "error.py", line 17, in ?
X divide(0)
File "error.py", line 5, in divide
X return test(100, x)
File "error.py", line 2, in test
X return a / b
ZeroDivisionError: integer division or modulo by zero
C:\temp>
>
> So, my question is really this... is there some easy way to include
> the .py files in the library.zip file (and have them be noticed) that
> I've missed? And, failing that, does anyone have any suggesstions of
> where to start poking around if I wanted to get more detailed
> tracebacks?
Thomas
|