0005785: print statements in Check.py causing a crash in Windows (pythonw.exe) after outputting 4096 characters. Setup logging in gramps.py before anything else; for Windows divert stderr/stdout to a log file; use logging instead of print for errors or warnings.

svn: r20014
This commit is contained in:
Tim G L Lyons 2012-07-16 22:55:36 +00:00
parent 679178d3bb
commit 7f5f855df1
2 changed files with 74 additions and 49 deletions

View File

@ -34,6 +34,7 @@ import gettext
import sys
import os
import locale
import logging
#-------------------------------------------------------------------------
#
@ -58,8 +59,9 @@ else:
if lang and lang[:2] == 'en':
pass # No need to display warning, we're in English
else:
print 'Locale dir does not exist at ' + os.path.join(PREFIXDIR, "share/locale")
print 'Running ./configure --prefix=YourPrefixDir might fix the problem'
logging.warning('Locale dir does not exist at ' +
os.path.join(PREFIXDIR, "share/locale"))
logging.warning('Running ./configure --prefix=YourPrefixDir might fix the problem')
LOCALEDIR = None
LOCALEDOMAIN = 'gramps'
@ -77,7 +79,7 @@ else:
try:
lang = locale.getdefaultlocale()[0] + '.UTF-8'
except TypeError:
print 'Unable to determine your Locale, using English'
logging.warning('Unable to determine your Locale, using English')
lang = 'en.UTF-8'
os.environ["LANG"] = lang
@ -100,7 +102,7 @@ def setup_gettext():
try:
locale.bindtextdomain(LOCALEDOMAIN, LOCALEDIR)
except ValueError:
print 'Failed to bind text domain, gtk.Builder() has no translation'
logging.warning('Failed to bind text domain, gtk.Builder() has no translation')
#following installs _ as a python function, we avoid this as this module is
#used sometimes:
@ -217,8 +219,8 @@ def setup_windows_gettext():
return
# No complete/working translation found
print "Translation might not be complete/not working for",\
locale.getlocale()[0]
logging.warning("Translation might not be complete/not working for",\
locale.getlocale()[0])
def get_localedomain():

View File

@ -31,7 +31,6 @@
#-------------------------------------------------------------------------
import sys
import os
from gen.const import APP_GRAMPS, USER_DIRLIST
import signal
import gettext
_ = gettext.gettext
@ -47,9 +46,67 @@ from subprocess import Popen, PIPE
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gen.const import APP_GRAMPS, USER_DIRLIST, HOME_DIR, VERSION_TUPLE
from gen.constfunc import win
#-------------------------------------------------------------------------
#
# Setup logging
#
# Ideally, this needs to be done before any Gramps modules are imported, so that
# any code that is executed as the modules are imported can log errors or
# warnings. Errors and warnings are particularly applicable to TransUtils and
# setting up internationalisation in this module. const and constfunc have to be
# imported before this code is executed because they are used in this code.
#-------------------------------------------------------------------------
"""Setup basic logging support."""
# Setup a formatter
form = logging.Formatter(fmt="%(relativeCreated)d: %(levelname)s: %(filename)s: line %(lineno)d: %(message)s")
# Create the log handlers
if win():
# If running in GUI mode redirect stdout and stderr to log file
if hasattr(sys.stdout, "fileno") and sys.stdout.fileno() < 0:
logfile = os.path.join(HOME_DIR,
"Gramps%s%s.log") % (VERSION_TUPLE[0],
VERSION_TUPLE[1])
# We now carry out the first step in build_user_paths(), to make sure
# that the user home directory is available to store the log file. When
# build_user_paths() is called, the call is protected by a try...except
# block, and any failure will be logged. However, if the creation of the
# user directory fails here, there is no way to report the failure,
# because stdout/stderr are not available, and neither is the logfile.
if os.path.islink(HOME_DIR):
pass # ok
elif not os.path.isdir(HOME_DIR):
os.makedirs(HOME_DIR)
sys.stdout = sys.stderr = open(logfile, "w")
stderrh = logging.StreamHandler(sys.stderr)
stderrh.setFormatter(form)
stderrh.setLevel(logging.DEBUG)
# Setup the base level logger, this one gets
# everything.
l = logging.getLogger()
l.setLevel(logging.WARNING)
l.addHandler(stderrh)
# put a hook on to catch any completely unhandled exceptions.
def exc_hook(type, value, tb):
if type == KeyboardInterrupt:
# Ctrl-C is not a bug.
return
if type == IOError:
# strange Windows logging error on close
return
import traceback
LOG.error("Unhandled exception\n" +
"".join(traceback.format_exception(type, value, tb)))
sys.excepthook = exc_hook
from gen.mime import mime_type_is_defined
from gen.utils.trans import LOCALEDOMAIN, LOCALEDIR, setup_windows_gettext
from gen.constfunc import win
#-------------------------------------------------------------------------
#
# Load internationalization setup
@ -64,9 +121,8 @@ gettext.bindtextdomain(LOCALEDOMAIN, LOCALEDIR)
try:
locale.setlocale(locale.LC_ALL,'')
except:
# FIXME: This should use LOG.warn, but logging has not been initialised yet
print >> sys.stderr, _("WARNING: Setting locale failed. Please fix the "
"LC_* and/or the LANG environment variables to prevent this error")
logging.warning(_("WARNING: Setting locale failed. Please fix the "
"LC_* and/or the LANG environment variables to prevent this error"))
try:
# It is probably not necessary to set the locale to 'C'
# because the locale will just stay at whatever it was,
@ -75,7 +131,7 @@ except:
# functions are working
locale.setlocale(locale.LC_ALL,'C')
except:
print >> sys.stderr, _("ERROR: Setting the 'C' locale didn't work either")
logging.warning(_("ERROR: Setting the 'C' locale didn't work either"))
# FIXME: This should propagate the exception,
# if that doesn't break Gramps under Windows
# raise
@ -94,7 +150,7 @@ elif operating_system == 'FreeBSD':
try:
gettext.bindtextdomain(LOCALEDOMAIN, LOCALEDIR)
except locale.Error:
print 'No translation in some gtk.Builder strings, '
logging.warning('No translation in some gtk.Builder strings, ')
elif operating_system == 'OpenBSD':
pass
else: # normal case
@ -102,7 +158,7 @@ else: # normal case
locale.bindtextdomain(LOCALEDOMAIN, LOCALEDIR)
#locale.textdomain(LOCALEDOMAIN)
except locale.Error:
print 'No translation in some gtk.Builder strings, '
logging.warning('No translation in some gtk.Builder strings, ')
#-------------------------------------------------------------------------
#
@ -112,7 +168,7 @@ else: # normal case
MIN_PYTHON_VERSION = (2, 6, 0, '', 0)
if not sys.version_info >= MIN_PYTHON_VERSION :
print (_("Your Python version does not meet the "
logging.warning(_("Your Python version does not meet the "
"requirements. At least python %(v1)d.%(v2)d.%(v3)d is needed to"
" start Gramps.\n\n"
"Gramps will terminate now.") % {
@ -148,37 +204,6 @@ except:
args = sys.argv
def setup_logging():
"""Setup basic logging support."""
# Setup a formatter
form = logging.Formatter(fmt="%(relativeCreated)d: %(levelname)s: %(filename)s: line %(lineno)d: %(message)s")
# Create the log handlers
stderrh = logging.StreamHandler(sys.stderr)
stderrh.setFormatter(form)
stderrh.setLevel(logging.DEBUG)
# Setup the base level logger, this one gets
# everything.
l = logging.getLogger()
l.setLevel(logging.WARNING)
l.addHandler(stderrh)
# put a hook on to catch any completely unhandled exceptions.
def exc_hook(type, value, tb):
if type == KeyboardInterrupt:
# Ctrl-C is not a bug.
return
if type == IOError:
# strange Windows logging error on close
return
import traceback
LOG.error("Unhandled exception\n" +
"".join(traceback.format_exception(type, value, tb)))
sys.excepthook = exc_hook
def build_user_paths():
""" check/make user-dirs on each Gramps session"""
for path in USER_DIRLIST:
@ -346,8 +371,6 @@ def show_settings():
def run():
error = []
setup_logging()
try:
build_user_paths()
except OSError, msg:
@ -442,4 +465,4 @@ def run():
errors = run()
if errors and isinstance(errors, list):
for error in errors:
print error[0], error[1]
logging.warning(error[0] + error[1])