~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/trace.py

(jelmer) Deprecate Repository.iter_reverse_revision_history(). (Jelmer
 Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
# increased cost of logging.py is not so bad, and we could standardize on
55
55
# that.
56
56
 
 
57
import codecs
57
58
import logging
58
59
import os
59
60
import sys
70
71
 
71
72
import bzrlib
72
73
 
 
74
from bzrlib.symbol_versioning import (
 
75
    deprecated_function,
 
76
    deprecated_in,
 
77
    )
 
78
 
73
79
lazy_import(globals(), """
74
80
from bzrlib import (
75
81
    debug,
110
116
 
111
117
    :return: None
112
118
    """
 
119
    # FIXME note always emits utf-8, regardless of the terminal encoding
 
120
    #
113
121
    # FIXME: clearing the ui and then going through the abstract logging
114
122
    # framework is whack; we should probably have a logging Handler that
115
123
    # deals with terminal output if needed.
122
130
    _bzr_logger.warning(*args, **kwargs)
123
131
 
124
132
 
 
133
@deprecated_function(deprecated_in((2, 1, 0)))
 
134
def info(*args, **kwargs):
 
135
    """Deprecated: use trace.note instead."""
 
136
    note(*args, **kwargs)
 
137
 
 
138
 
 
139
@deprecated_function(deprecated_in((2, 1, 0)))
 
140
def log_error(*args, **kwargs):
 
141
    """Deprecated: use bzrlib.trace.show_error instead"""
 
142
    _bzr_logger.error(*args, **kwargs)
 
143
 
 
144
 
 
145
@deprecated_function(deprecated_in((2, 1, 0)))
 
146
def error(*args, **kwargs):
 
147
    """Deprecated: use bzrlib.trace.show_error instead"""
 
148
    _bzr_logger.error(*args, **kwargs)
 
149
 
 
150
 
125
151
def show_error(*args, **kwargs):
126
152
    """Show an error message to the user.
127
153
 
282
308
    """
283
309
    start_time = osutils.format_local_date(_bzr_log_start_time,
284
310
                                           timezone='local')
 
311
    # create encoded wrapper around stderr
285
312
    bzr_log_file = _open_bzr_log()
286
313
    if bzr_log_file is not None:
287
314
        bzr_log_file.write(start_time.encode('utf-8') + '\n')
290
317
        r'%Y-%m-%d %H:%M:%S')
291
318
    # after hooking output into bzr_log, we also need to attach a stderr
292
319
    # handler, writing only at level info and with encoding
293
 
    stderr_handler = EncodedStreamHandler(sys.stderr,
294
 
        osutils.get_terminal_encoding(), 'replace', level=logging.INFO)
 
320
    term_encoding = osutils.get_terminal_encoding()
 
321
    writer_factory = codecs.getwriter(term_encoding)
 
322
    encoded_stderr = writer_factory(sys.stderr, errors='replace')
 
323
    stderr_handler = logging.StreamHandler(encoded_stderr)
 
324
    stderr_handler.setLevel(logging.INFO)
295
325
    logging.getLogger('bzr').addHandler(stderr_handler)
296
326
    return memento
297
327
 
306
336
    """
307
337
    global _trace_file
308
338
    # make a new handler
309
 
    new_handler = EncodedStreamHandler(to_file, "utf-8", level=logging.DEBUG)
 
339
    new_handler = logging.StreamHandler(to_file)
 
340
    new_handler.setLevel(logging.DEBUG)
310
341
    if log_format is None:
311
342
        log_format = '%(levelname)8s  %(message)s'
312
343
    new_handler.setFormatter(logging.Formatter(log_format, date_format))
483
514
        print_exception(exc_info, err_file)
484
515
        return errors.EXIT_ERROR
485
516
    exc_type, exc_object, exc_tb = exc_info
486
 
    if isinstance(exc_object, KeyboardInterrupt):
 
517
    if (isinstance(exc_object, IOError)
 
518
        and getattr(exc_object, 'errno', None) == errno.EPIPE):
 
519
        err_file.write("bzr: broken pipe\n")
 
520
        return errors.EXIT_ERROR
 
521
    elif isinstance(exc_object, KeyboardInterrupt):
487
522
        err_file.write("bzr: interrupted\n")
488
523
        return errors.EXIT_ERROR
489
524
    elif isinstance(exc_object, MemoryError):
501
536
    elif not getattr(exc_object, 'internal_error', True):
502
537
        report_user_error(exc_info, err_file)
503
538
        return errors.EXIT_ERROR
504
 
    elif osutils.is_environment_error(exc_object):
505
 
        if getattr(exc_object, 'errno', None) == errno.EPIPE:
506
 
            err_file.write("bzr: broken pipe\n")
507
 
            return errors.EXIT_ERROR
 
539
    elif isinstance(exc_object, (OSError, IOError)) or (
 
540
        # GZ 2010-05-20: Like (exc_type is pywintypes.error) but avoid import
 
541
        exc_type.__name__ == "error" and exc_type.__module__ == "pywintypes"):
508
542
        # Might be nice to catch all of these and show them as something more
509
543
        # specific, but there are too many cases at the moment.
510
544
        report_user_error(exc_info, err_file)
548
582
    try:
549
583
        sys.stdout.flush()
550
584
        sys.stderr.flush()
551
 
    except ValueError, e:
552
 
        # On Windows, I get ValueError calling stdout.flush() on a closed
553
 
        # handle
554
 
        pass
555
585
    except IOError, e:
556
586
        import errno
557
587
        if e.errno in [errno.EINVAL, errno.EPIPE]:
567
597
        _trace_file.flush()
568
598
 
569
599
 
570
 
class EncodedStreamHandler(logging.Handler):
571
 
    """Robustly write logging events to a stream using the specified encoding
572
 
 
573
 
    Messages are expected to be formatted to unicode, but UTF-8 byte strings
574
 
    are also accepted. An error during formatting or a str message in another
575
 
    encoding will be quitely noted as an error in the Bazaar log file.
576
 
 
577
 
    The stream is not closed so sys.stdout or sys.stderr may be passed.
578
 
    """
579
 
 
580
 
    def __init__(self, stream, encoding=None, errors='strict', level=0):
581
 
        logging.Handler.__init__(self, level)
582
 
        self.stream = stream
583
 
        if encoding is None:
584
 
            encoding = getattr(stream, "encoding", "ascii")
585
 
        self.encoding = encoding
586
 
        self.errors = errors
587
 
 
588
 
    def flush(self):
589
 
        flush = getattr(self.stream, "flush", None)
590
 
        if flush is not None:
591
 
            flush()
592
 
 
593
 
    def emit(self, record):
594
 
        try:
595
 
            line = self.format(record)
596
 
            if not isinstance(line, unicode):
597
 
                line = line.decode("utf-8")
598
 
            self.stream.write(line.encode(self.encoding, self.errors) + "\n")
599
 
        except Exception:
600
 
            log_exception_quietly()
601
 
            # Try saving the details that would have been logged in some form
602
 
            msg = args = "<Unformattable>"
603
 
            try:
604
 
                msg = repr(record.msg).encode("ascii")
605
 
                args = repr(record.args).encode("ascii")
606
 
            except Exception:
607
 
                pass
608
 
            # Using mutter() bypasses the logging module and writes directly
609
 
            # to the file so there's no danger of getting into a loop here.
610
 
            mutter("Logging record unformattable: %s %% %s", msg, args)
611
 
 
612
 
 
613
600
class Config(object):
614
601
    """Configuration of message tracing in bzrlib.
615
602