From 7f5f855df199406557535f0fd95c2968174784ca Mon Sep 17 00:00:00 2001 From: Tim G L Lyons Date: Mon, 16 Jul 2012 22:55:36 +0000 Subject: [PATCH] 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 --- src/gen/utils/trans.py | 14 +++--- src/gramps.py | 109 +++++++++++++++++++++++++---------------- 2 files changed, 74 insertions(+), 49 deletions(-) diff --git a/src/gen/utils/trans.py b/src/gen/utils/trans.py index f0d95312f..6bc6b30f5 100644 --- a/src/gen/utils/trans.py +++ b/src/gen/utils/trans.py @@ -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(): diff --git a/src/gramps.py b/src/gramps.py index c926c5792..84ab3f2e3 100644 --- a/src/gramps.py +++ b/src/gramps.py @@ -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])