/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to boot_common.py

  • Committer: Gary van der Merwe
  • Date: 2010-07-26 10:49:37 UTC
  • mto: (5050.3.19 2.2) (5340.4.7 bzrw)
  • mto: This revision was merged to the branch mainline in revision 5371.
  • Revision ID: garyvdm@gmail.com-20100726104937-tccq24p2ynw7tjrj
Add copy of boot_common.py for py2exe svn rev 688.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Common py2exe boot script - executed for all target types.
 
2
 
 
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).
 
6
#
 
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.
 
11
#
 
12
# We only open the logfile if something is written to sys.stderr.
 
13
#
 
14
# If the logfile cannot be opened for *any* reason, we have no choice
 
15
# but silently ignore the error.
 
16
#
 
17
# It remains to be seen if the 'a' flag for opening the logfile is a
 
18
# good choice, or 'w' would be better.
 
19
#
 
20
# More elaborate explanation on why this is needed:
 
21
#
 
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
 
24
# in the same way.
 
25
#
 
26
# To demonstrate, run this program with pythonw.exe:
 
27
#
 
28
# import sys
 
29
# sys.stderr = open("out.log", "w")
 
30
# for i in range(10000):
 
31
#     print i
 
32
#
 
33
# and open the 'out.log' file.  It contains this:
 
34
#
 
35
# Traceback (most recent call last):
 
36
#   File "out.py", line 6, in ?
 
37
#     print i
 
38
# IOError: [Errno 9] Bad file descriptor
 
39
#
 
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.
 
42
#
 
43
 
 
44
import sys
 
45
if sys.frozen == "windows_exe":
 
46
    class Stderr(object):
 
47
        softspace = 0
 
48
        _file = None
 
49
        _error = None
 
50
        def write(self, text, alert=sys._MessageBox, fname=sys.executable + '.log'):
 
51
            if self._file is None and self._error is None:
 
52
                try:
 
53
                    self._file = open(fname, 'a')
 
54
                except Exception, details:
 
55
                    self._error = details
 
56
                    import atexit
 
57
                    atexit.register(alert, 0,
 
58
                                    "The logfile '%s' could not be opened:\n %s" % \
 
59
                                    (fname, details),
 
60
                                    "Errors occurred")
 
61
                else:
 
62
                    import atexit
 
63
                    atexit.register(alert, 0,
 
64
                                    "See the logfile '%s' for details" % fname,
 
65
                                    "Errors occurred")
 
66
            if self._file is not None:
 
67
                self._file.write(text)
 
68
                self._file.flush()
 
69
        def flush(self):
 
70
            if self._file is not None:
 
71
                self._file.flush()
 
72
    sys.stderr = Stderr()
 
73
    del sys._MessageBox
 
74
    del Stderr
 
75
 
 
76
    class Blackhole(object):
 
77
        softspace = 0
 
78
        def write(self, text):
 
79
            pass
 
80
        def flush(self):
 
81
            pass
 
82
    sys.stdout = Blackhole()
 
83
    del Blackhole
 
84
del sys
 
85
 
 
86
# Disable linecache.getline() which is called by
 
87
# traceback.extract_stack() when an exception occurs to try and read
 
88
# the filenames embedded in the packaged python code.  This is really
 
89
# annoying on windows when the d: or e: on our build box refers to
 
90
# someone elses removable or network drive so the getline() call
 
91
# causes it to ask them to insert a disk in that drive.
 
92
import linecache
 
93
def fake_getline(filename, lineno, module_globals=None):
 
94
    return ''
 
95
linecache.orig_getline = linecache.getline
 
96
linecache.getline = fake_getline
 
97
 
 
98
del linecache, fake_getline