[Mailman-Developers] Python 1.5 compatible ? no!
Barry A. Warsaw
bwarsaw@cnri.reston.va.us (Barry A. Warsaw)
Thu, 3 Sep 1998 16:26:38 -0400 (EDT)
--6QK9bPyZ8q
Content-Type: text/plain; charset=us-ascii
Content-Description: message body text
Content-Transfer-Encoding: 7bit
>>>>> "CT" == Christian Tismer <tismer@appliedbiometrics.com> writes:
CT> I could not find an attachment, just the line above.
I'll try again below as plaintext.
CT> How do I get at the CVS tree?
<http://www.python.org/mailman/listinfo/mailman-checkins>
-Barry
--6QK9bPyZ8q
Content-Type: text/plain
Content-Disposition: inline;
filename="driver"
Content-Transfer-Encoding: 7bit
#! /usr/bin/env python
#
# Copyright (C) 1998 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# This better succeed. If this fails, Python is royally screwed so we might
# as well let the Web server give us a fatal and obtrusive error.
import sys
# From here on we are as bulletproof as possible!
# This function is useful for debugging. When an error occurs, this attaches
# the file name to the exception string and re-raises. This will be
# unnecessary in Python 1.5.2, which also does sensible things to most os
# module functions.
realopen = open
def open(filename, mode='r', bufsize=-1, realopen=realopen):
try:
return realopen(filename, mode, bufsize)
except IOError, e:
strerror = e.strerror + ': ' + filename
e.strerror = strerror
e.filename = filename
e.args = (e.args[0], strerror)
# Python 1.5
raise e, None, sys.exc_info()[2]
# Python 1.5.1
#raise
import __builtin__
__builtin__.__dict__['open'] = open
# This standard driver script is used to run CGI programs, wrapped in code
# that catches errors, and displays them as HTML. This guarantees that
# (almost) any problems in the Mailman software doesn't result in a Web server
# error. It is much more helpful to generate and show a traceback, which the
# user could send to the administrator, than to display a server error and
# have to trudge through server logs.
# Note: this isn't 100% perfect! Here are some things that can go wrong that
# are not caught and reported as traceback-containing HTML:
#
# - This file could contain a syntax error. In that case, you would indeed
# get a Web server error since this file wouldn't even compile, and there's
# no way to catch that.
#
# - The sys module could be royally screwed, probably we couldn't import it.
# Both those would indicate serious problems in the Python installation.
# These won't generate Web server errors, but neither will they give
# meaningful tracebacks.
#
# I consider these pretty unlikely.
def run_main():
try:
# These will ensure that even if something between now and the
# creation of the real logger below fails, we can still get
# *something* meaningful
logger = None
# insert the relative path to the parent of the Mailman package
# directory, so we can pick up the Utils module
import os
# sys gets imported at module level below
sys.path.insert(0, os.pardir)
# map stderr to a logger, if possible
from Mailman.Logging.StampedLogger import StampedLogger
logger = StampedLogger('error',
label='admin',
manual_reprime=1,
nofail=0,
immediate=1)
# The name of the module to run is passed in argv[1]. What we
# actually do is import the module named by argv[1] that lives in the
# Mailman.Cgi package. That module must have a main() function, which
# we dig out and call.
#
scriptname = sys.argv[1]
# See the reference manual for why we have to do things this way.
# Note that importing should have no side-effects!
pkg = __import__('Mailman.Cgi', globals(), locals(), [scriptname])
module = getattr(pkg, scriptname)
main = getattr(module, 'main')
try:
main()
except SystemExit:
# this is a valid way for the function to exit
pass
except:
print_traceback(logger)
print_environment(logger)
# We are printing error reporting to two places. One will always be stdout
# and the other will always be the log file. It is assumed that stdout is an
# HTML sink and the log file is a plain text sink.
def print_traceback(logfp=None):
if logfp is None:
logfp = sys.__stderr__
try:
import traceback
except ImportError:
traceback = None
# write to the log file first
logfp.write('[----- Traceback ------]\n')
if traceback:
traceback.print_exc(file=logfp)
else:
logfp.write('[failed to import module traceback]\n')
logfp.write('[exc: %s, var: %s]\n' % sys.exc_info()[0:2])
# print to the HTML sink
print """\
Content-type: text/html
<p><h3>We're sorry, we hit a bug!</h3>
<p>If you would like to help us identify the problem, please
email a copy of this page to the webmaster for this site with
a description of what happened. Thanks!
<h4>Traceback:</h4>
<p><pre>
"""
if traceback:
traceback.print_exc(file=sys.stdout)
else:
print '[failed to import module traceback]'
print '[exc: %s, var: %s]' % sys.exc_info()[0:2]
print '\n\n</pre>'
def print_environment(logfp=None):
if logfp is None:
logfp = sys.__stderr__
try:
import os
except ImportError:
os = None
# write to the log file first
logfp.write('[----- Environment Variables -----]\n')
if os:
for k, v in os.environ.items():
logfp.write('\t%s: %s\n' % (k, v))
else:
logfp.write('[failed to import module os]\n')
# write to the HTML sink
if os:
print '''\
<p><hr><h4>Environment variables:</h4>
<p><table>
<tr><td><strong>Variable</strong></td>
<td><strong>Value</strong></td></tr>
'''
for k, v in os.environ.items():
print '<tr><td>', k, '</td><td>', v, '</td></tr>'
print '</table>'
else:
print '<p><hr>[failed to import module os]'
try:
# Python 1.5 doesn't have these by default. Let's make our lives easy
if not hasattr(sys, '__stderr__'):
sys.__stderr__ = sys.stderr
if not hasattr(sys, '__stdout__'):
sys.__stdout__ = sys.stdout
run_main()
except:
# Some exception percolated all the way back up to the top. This
# generally shouldn't happen because the run_main() call is similarly
# wrapped, but just in case, we'll give it one last ditch effort to report
# problems to *somebody*. Most likely this will end up in the Web server
# log file.
try:
print_traceback()
print_environment()
except:
# Nope, we're quite screwed
print """\
Content-type: text/html
<p><h3>We're sorry, we hit a bug!</h3>
Mailman experienced a very low level failure and could not even generate a
useful traceback for you. Please report this to the Mailman administrator at
this site.
"""
sys.__stderr__.write('[Mailman: low level unrecoverable exception]\n')
--6QK9bPyZ8q--