1
1
# Common py2exe boot script - executed for all target types.
3
# When we are a windows_exe we have no console, and writing to
4
# sys.stderr or sys.stdout will sooner or later raise an exception,
5
# and tracebacks will be lost anyway (see explanation below).
7
# We assume that output to sys.stdout can go to the bitsink, but we
8
# *want* to see tracebacks. So we redirect sys.stdout into an object
9
# with a write method doing nothing, and sys.stderr into a logfile
10
# having the same name as the executable, with '.log' appended.
12
# We only open the logfile if something is written to sys.stderr.
14
# If the logfile cannot be opened for *any* reason, we have no choice
15
# but silently ignore the error.
17
# It remains to be seen if the 'a' flag for opening the logfile is a
18
# good choice, or 'w' would be better.
20
# More elaborate explanation on why this is needed:
22
# The sys.stdout and sys.stderr that GUI programs get (from Windows) are
23
# more than useless. This is not a py2exe problem, pythonw.exe behaves
26
# To demonstrate, run this program with pythonw.exe:
29
# sys.stderr = open("out.log", "w")
30
# for i in range(10000):
33
# and open the 'out.log' file. It contains this:
35
# Traceback (most recent call last):
36
# File "out.py", line 6, in ?
38
# IOError: [Errno 9] Bad file descriptor
40
# In other words, after printing a certain number of bytes to the
41
# system-supplied sys.stdout (or sys.stderr) an exception will be raised.
3
# In the standard py2exe boot script, it setup stderr so that anything written
4
# to it will be written to exe.log, and a message dialog is shown.
5
# For Bazaar, we log most things to .bzr.log, and there are many things that
6
# write to stderr, that are not errors, and so we don't want the py2exe dialog
7
# message, So also blackhole stderr.
45
10
if sys.frozen == "windows_exe":
50
def write(self, text, alert=sys._MessageBox, fname=sys.executable + '.log'):
51
if self._file is None and self._error is None:
53
self._file = open(fname, 'a')
54
except Exception, details:
57
atexit.register(alert, 0,
58
"The logfile '%s' could not be opened:\n %s" % \
63
atexit.register(alert, 0,
64
"See the logfile '%s' for details" % fname,
66
if self._file is not None:
67
self._file.write(text)
70
if self._file is not None:
76
12
class Blackhole(object):