Beispiel #1
0
    def test_format(self):
        out = StringIO()
        err = StringIO()
        name = '%s.test_format' % self.__class__.__name__
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        handler = ConfigureOutputHandler(out, err)
        handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s'))
        logger.addHandler(handler)

        logger.error('foo')
        logger.warning('bar')
        logger.info('baz')
        # DEBUG level is not printed out by this handler
        logger.debug('qux')

        self.assertEqual(out.getvalue(), 'baz\n')
        self.assertEqual(err.getvalue(), 'ERROR:foo\n' 'WARNING:bar\n')
Beispiel #2
0
    def test_format(self):
        out = StringIO()
        err = StringIO()
        name = '%s.test_format' % self.__class__.__name__
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        handler =  ConfigureOutputHandler(out, err)
        handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s'))
        logger.addHandler(handler)

        logger.error('foo')
        logger.warning('bar')
        logger.info('baz')
        # DEBUG level is not printed out by this handler
        logger.debug('qux')

        self.assertEqual(out.getvalue(), 'baz\n')
        self.assertEqual(
            err.getvalue(),
            'ERROR:foo\n'
            'WARNING:bar\n'
        )
Beispiel #3
0
    def test_continuation(self):
        out = StringIO()
        name = '%s.test_continuation' % self.__class__.__name__
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        handler =  ConfigureOutputHandler(out, out)
        handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s'))
        logger.addHandler(handler)

        logger.info('foo')
        logger.info('checking bar... ')
        logger.info('yes')
        logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'foo\n'
            'checking bar... yes\n'
            'qux\n'
        )

        out.seek(0)
        out.truncate()

        logger.info('foo')
        logger.info('checking bar... ')
        logger.warning('hoge')
        logger.info('no')
        logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'foo\n'
            'checking bar... \n'
            'WARNING:hoge\n'
            ' ... no\n'
            'qux\n'
        )

        out.seek(0)
        out.truncate()

        logger.info('foo')
        logger.info('checking bar... ')
        logger.warning('hoge')
        logger.warning('fuga')
        logger.info('no')
        logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'foo\n'
            'checking bar... \n'
            'WARNING:hoge\n'
            'WARNING:fuga\n'
            ' ... no\n'
            'qux\n'
        )

        out.seek(0)
        out.truncate()
        err = StringIO()

        logger.removeHandler(handler)
        handler =  ConfigureOutputHandler(out, err)
        handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s'))
        logger.addHandler(handler)

        logger.info('foo')
        logger.info('checking bar... ')
        logger.warning('hoge')
        logger.warning('fuga')
        logger.info('no')
        logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'foo\n'
            'checking bar... no\n'
            'qux\n'
        )

        self.assertEqual(
            err.getvalue(),
            'WARNING:hoge\n'
            'WARNING:fuga\n'
        )
Beispiel #4
0
    def test_queue_debug(self):
        out = StringIO()
        name = '%s.test_queue_debug' % self.__class__.__name__
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        handler =  ConfigureOutputHandler(out, out, maxlen=3)
        handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s'))
        logger.addHandler(handler)

        with handler.queue_debug():
            logger.info('checking bar... ')
            logger.debug('do foo')
            logger.info('yes')
            logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'checking bar... yes\n'
            'qux\n'
        )

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('checking bar... ')
            logger.debug('do foo')
            logger.info('no')
            logger.error('fail')

        self.assertEqual(
            out.getvalue(),
            'checking bar... no\n'
            'DEBUG:do foo\n'
            'ERROR:fail\n'
        )

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('checking bar... ')
            logger.debug('do foo')
            logger.debug('do bar')
            logger.debug('do baz')
            logger.info('no')
            logger.error('fail')

        self.assertEqual(
            out.getvalue(),
            'checking bar... no\n'
            'DEBUG:do foo\n'
            'DEBUG:do bar\n'
            'DEBUG:do baz\n'
            'ERROR:fail\n'
        )

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('checking bar... ')
            logger.debug('do foo')
            logger.debug('do bar')
            logger.debug('do baz')
            logger.debug('do qux')
            logger.debug('do hoge')
            logger.info('no')
            logger.error('fail')

        self.assertEqual(
            out.getvalue(),
            'checking bar... no\n'
            'DEBUG:<truncated - see config.log for full output>\n'
            'DEBUG:do baz\n'
            'DEBUG:do qux\n'
            'DEBUG:do hoge\n'
            'ERROR:fail\n'
        )
Beispiel #5
0
    def __init__(self, config, environ=os.environ, argv=sys.argv,
                 stdout=sys.stdout, stderr=sys.stderr, logger=None):
        dict.__setitem__(self, '__builtins__', self.BUILTINS)

        self._environ = dict(environ)

        self._paths = []
        self._all_paths = set()
        self._templates = set()
        # Associate SandboxDependsFunctions to DependsFunctions.
        self._depends = OrderedDict()
        self._seen = set()
        # Store the @imports added to a given function.
        self._imports = {}

        self._options = OrderedDict()
        # Store raw option (as per command line or environment) for each Option
        self._raw_options = OrderedDict()

        # Store options added with `imply_option`, and the reason they were
        # added (which can either have been given to `imply_option`, or
        # inferred. Their order matters, so use a list.
        self._implied_options = []

        # Store all results from _prepare_function
        self._prepared_functions = set()

        # Queue of functions to execute, with their arguments
        self._execution_queue = []

        # Store the `when`s associated to some options.
        self._conditions = {}

        # A list of conditions to apply as a default `when` for every *_impl()
        self._default_conditions = []

        self._helper = CommandLineHelper(environ, argv)

        assert isinstance(config, dict)
        self._config = config

        # Tracks how many templates "deep" we are in the stack.
        self._template_depth = 0

        logging.addLevelName(TRACE, 'TRACE')
        if logger is None:
            logger = moz_logger = logging.getLogger('moz.configure')
            logger.setLevel(logging.DEBUG)
            formatter = logging.Formatter('%(levelname)s: %(message)s')
            handler = ConfigureOutputHandler(stdout, stderr)
            handler.setFormatter(formatter)
            queue_debug = handler.queue_debug
            logger.addHandler(handler)

        else:
            assert isinstance(logger, logging.Logger)
            moz_logger = None
            @contextmanager
            def queue_debug():
                yield

        self._logger = logger

        # Some callers will manage to log a bytestring with characters in it
        # that can't be converted to ascii. Make our log methods robust to this
        # by detecting the encoding that a producer is likely to have used.
        encoding = getpreferredencoding()

        def wrapped_log_method(logger, key):
            method = getattr(logger, key)

            def wrapped(*args, **kwargs):
                out_args = [
                    six.ensure_text(arg, encoding=encoding or 'utf-8')
                    if isinstance(arg, six.binary_type) else arg for arg in args
                ]
                return method(*out_args, **kwargs)
            return wrapped

        log_namespace = {
            k: wrapped_log_method(logger, k)
            for k in ('debug', 'info', 'warning', 'error')
        }
        log_namespace['queue_debug'] = queue_debug
        self.log_impl = ReadOnlyNamespace(**log_namespace)

        self._help = None
        self._help_option = self.option_impl(
            '--help', help='print this message', category=HELP_OPTIONS_CATEGORY)
        self._seen.add(self._help_option)

        self._always = DependsFunction(self, lambda: True, [])
        self._never = DependsFunction(self, lambda: False, [])

        if self._value_for(self._help_option):
            self._help = HelpFormatter(argv[0])
            self._help.add(self._help_option)
        elif moz_logger:
            handler = logging.FileHandler('config.log', mode='w', delay=True,
                                          encoding='utf-8')
            handler.setFormatter(formatter)
            logger.addHandler(handler)
Beispiel #6
0
    def __init__(self, config, environ=os.environ, argv=sys.argv,
                 stdout=sys.stdout, stderr=sys.stderr, logger=None):
        dict.__setitem__(self, '__builtins__', self.BUILTINS)

        self._paths = []
        self._all_paths = set()
        self._templates = set()
        # Associate SandboxDependsFunctions to DependsFunctions.
        self._depends = OrderedDict()
        self._seen = set()
        # Store the @imports added to a given function.
        self._imports = {}

        self._options = OrderedDict()
        # Store raw option (as per command line or environment) for each Option
        self._raw_options = OrderedDict()

        # Store options added with `imply_option`, and the reason they were
        # added (which can either have been given to `imply_option`, or
        # inferred. Their order matters, so use a list.
        self._implied_options = []

        # Store all results from _prepare_function
        self._prepared_functions = set()

        # Queue of functions to execute, with their arguments
        self._execution_queue = []

        # Store the `when`s associated to some options.
        self._conditions = {}

        # A list of conditions to apply as a default `when` for every *_impl()
        self._default_conditions = []

        self._helper = CommandLineHelper(environ, argv)

        assert isinstance(config, dict)
        self._config = config

        if logger is None:
            logger = moz_logger = logging.getLogger('moz.configure')
            logger.setLevel(logging.DEBUG)
            formatter = logging.Formatter('%(levelname)s: %(message)s')
            handler = ConfigureOutputHandler(stdout, stderr)
            handler.setFormatter(formatter)
            queue_debug = handler.queue_debug
            logger.addHandler(handler)

        else:
            assert isinstance(logger, logging.Logger)
            moz_logger = None
            @contextmanager
            def queue_debug():
                yield

        # Some callers will manage to log a bytestring with characters in it
        # that can't be converted to ascii. Make our log methods robust to this
        # by detecting the encoding that a producer is likely to have used.
        encoding = getpreferredencoding()
        def wrapped_log_method(logger, key):
            method = getattr(logger, key)
            if not encoding:
                return method
            def wrapped(*args, **kwargs):
                out_args = [
                    arg.decode(encoding) if isinstance(arg, str) else arg
                    for arg in args
                ]
                return method(*out_args, **kwargs)
            return wrapped

        log_namespace = {
            k: wrapped_log_method(logger, k)
            for k in ('debug', 'info', 'warning', 'error')
        }
        log_namespace['queue_debug'] = queue_debug
        self.log_impl = ReadOnlyNamespace(**log_namespace)

        self._help = None
        self._help_option = self.option_impl('--help',
                                             help='print this message')
        self._seen.add(self._help_option)

        self._always = DependsFunction(self, lambda: True, [])
        self._never = DependsFunction(self, lambda: False, [])

        if self._value_for(self._help_option):
            self._help = HelpFormatter(argv[0])
            self._help.add(self._help_option)
        elif moz_logger:
            handler = logging.FileHandler('config.log', mode='w', delay=True)
            handler.setFormatter(formatter)
            logger.addHandler(handler)
Beispiel #7
0
    def __init__(self, config, environ=os.environ, argv=sys.argv,
                 stdout=sys.stdout, stderr=sys.stderr, logger=None):
        dict.__setitem__(self, '__builtins__', self.BUILTINS)

        self._paths = []
        self._all_paths = set()
        self._templates = set()
        # Store the real function and its dependencies, behind each
        # DependsFunction generated from @depends.
        self._depends = {}
        self._seen = set()
        # Store the @imports added to a given function.
        self._imports = {}

        self._options = OrderedDict()
        # Store raw option (as per command line or environment) for each Option
        self._raw_options = OrderedDict()

        # Store options added with `imply_option`, and the reason they were
        # added (which can either have been given to `imply_option`, or
        # inferred. Their order matters, so use a list.
        self._implied_options = []

        # Store all results from _prepare_function
        self._prepared_functions = set()

        # Queue of functions to execute, with their arguments
        self._execution_queue = []

        self._helper = CommandLineHelper(environ, argv)

        assert isinstance(config, dict)
        self._config = config

        if logger is None:
            logger = moz_logger = logging.getLogger('moz.configure')
            logger.setLevel(logging.DEBUG)
            formatter = logging.Formatter('%(levelname)s: %(message)s')
            handler = ConfigureOutputHandler(stdout, stderr)
            handler.setFormatter(formatter)
            queue_debug = handler.queue_debug
            logger.addHandler(handler)

        else:
            assert isinstance(logger, logging.Logger)
            moz_logger = None
            @contextmanager
            def queue_debug():
                yield

        log_namespace = {
            k: getattr(logger, k)
            for k in ('debug', 'info', 'warning', 'error')
        }
        log_namespace['queue_debug'] = queue_debug
        self.log_impl = ReadOnlyNamespace(**log_namespace)

        self._help = None
        self._help_option = self.option_impl('--help',
                                             help='print this message')
        self._seen.add(self._help_option)
        if self._value_for(self._help_option):
            self._help = HelpFormatter(argv[0])
            self._help.add(self._help_option)
        elif moz_logger:
            handler = logging.FileHandler('config.log', mode='w', delay=True)
            handler.setFormatter(formatter)
            logger.addHandler(handler)
Beispiel #8
0
    def test_continuation(self):
        out = StringIO()
        name = '%s.test_continuation' % self.__class__.__name__
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        handler = ConfigureOutputHandler(out, out)
        handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s'))
        logger.addHandler(handler)

        logger.info('foo')
        logger.info('checking bar... ')
        logger.info('yes')
        logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'foo\n'
            'checking bar... yes\n'
            'qux\n'
        )

        out.seek(0)
        out.truncate()

        logger.info('foo')
        logger.info('checking bar... ')
        logger.warning('hoge')
        logger.info('no')
        logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'foo\n'
            'checking bar... \n'
            'WARNING:hoge\n'
            ' ... no\n'
            'qux\n'
        )

        out.seek(0)
        out.truncate()

        logger.info('foo')
        logger.info('checking bar... ')
        logger.warning('hoge')
        logger.warning('fuga')
        logger.info('no')
        logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'foo\n'
            'checking bar... \n'
            'WARNING:hoge\n'
            'WARNING:fuga\n'
            ' ... no\n'
            'qux\n'
        )

        out.seek(0)
        out.truncate()
        err = StringIO()

        logger.removeHandler(handler)
        handler = ConfigureOutputHandler(out, err)
        handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s'))
        logger.addHandler(handler)

        logger.info('foo')
        logger.info('checking bar... ')
        logger.warning('hoge')
        logger.warning('fuga')
        logger.info('no')
        logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'foo\n'
            'checking bar... no\n'
            'qux\n'
        )

        self.assertEqual(
            err.getvalue(),
            'WARNING:hoge\n'
            'WARNING:fuga\n'
        )
Beispiel #9
0
    def test_queue_debug_reentrant(self):
        out = StringIO()
        name = '%s.test_queue_debug_reentrant' % self.__class__.__name__
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        handler = ConfigureOutputHandler(out, out, maxlen=10)
        handler.setFormatter(logging.Formatter('%(levelname)s| %(message)s'))
        logger.addHandler(handler)

        try:
            with handler.queue_debug():
                logger.info('outer info')
                logger.debug('outer debug')
                with handler.queue_debug():
                    logger.info('inner info')
                    logger.debug('inner debug')
                    e = Exception('inner exception')
                    raise e
        except Exception as caught:
            self.assertIs(caught, e)

        self.assertEqual(out.getvalue(),
                         'outer info\n'
                         'inner info\n'
                         'DEBUG| outer debug\n'
                         'DEBUG| inner debug\n')

        out.seek(0)
        out.truncate()

        try:
            with handler.queue_debug():
                logger.info('outer info')
                logger.debug('outer debug')
                with handler.queue_debug():
                    logger.info('inner info')
                    logger.debug('inner debug')
                e = Exception('outer exception')
                raise e
        except Exception as caught:
            self.assertIs(caught, e)

        self.assertEqual(out.getvalue(),
                         'outer info\n'
                         'inner info\n'
                         'DEBUG| outer debug\n'
                         'DEBUG| inner debug\n')

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('outer info')
            logger.debug('outer debug')
            with handler.queue_debug():
                logger.info('inner info')
                logger.debug('inner debug')
                logger.error('inner error')
        self.assertEqual(out.getvalue(),
                         'outer info\n'
                         'inner info\n'
                         'DEBUG| outer debug\n'
                         'DEBUG| inner debug\n'
                         'ERROR| inner error\n')

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('outer info')
            logger.debug('outer debug')
            with handler.queue_debug():
                logger.info('inner info')
                logger.debug('inner debug')
            logger.error('outer error')
        self.assertEqual(out.getvalue(),
                         'outer info\n'
                         'inner info\n'
                         'DEBUG| outer debug\n'
                         'DEBUG| inner debug\n'
                         'ERROR| outer error\n')
Beispiel #10
0
    def test_queue_debug(self):
        out = StringIO()
        name = '%s.test_queue_debug' % self.__class__.__name__
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        handler = ConfigureOutputHandler(out, out, maxlen=3)
        handler.setFormatter(logging.Formatter('%(levelname)s:%(message)s'))
        logger.addHandler(handler)

        with handler.queue_debug():
            logger.info('checking bar... ')
            logger.debug('do foo')
            logger.info('yes')
            logger.info('qux')

        self.assertEqual(
            out.getvalue(),
            'checking bar... yes\n'
            'qux\n'
        )

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('checking bar... ')
            logger.debug('do foo')
            logger.info('no')
            logger.error('fail')

        self.assertEqual(
            out.getvalue(),
            'checking bar... no\n'
            'DEBUG:do foo\n'
            'ERROR:fail\n'
        )

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('checking bar... ')
            logger.debug('do foo')
            logger.debug('do bar')
            logger.debug('do baz')
            logger.info('no')
            logger.error('fail')

        self.assertEqual(
            out.getvalue(),
            'checking bar... no\n'
            'DEBUG:do foo\n'
            'DEBUG:do bar\n'
            'DEBUG:do baz\n'
            'ERROR:fail\n'
        )

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('checking bar... ')
            logger.debug('do foo')
            logger.debug('do bar')
            logger.debug('do baz')
            logger.debug('do qux')
            logger.debug('do hoge')
            logger.info('no')
            logger.error('fail')

        self.assertEqual(
            out.getvalue(),
            'checking bar... no\n'
            'DEBUG:<truncated - see config.log for full output>\n'
            'DEBUG:do baz\n'
            'DEBUG:do qux\n'
            'DEBUG:do hoge\n'
            'ERROR:fail\n'
        )

        out.seek(0)
        out.truncate()

        try:
            with handler.queue_debug():
                logger.info('checking bar... ')
                logger.debug('do foo')
                logger.debug('do bar')
                logger.info('no')
                e = Exception('fail')
                raise e
        except Exception as caught:
            self.assertIs(caught, e)

        self.assertEqual(
            out.getvalue(),
            'checking bar... no\n'
            'DEBUG:do foo\n'
            'DEBUG:do bar\n'
        )
Beispiel #11
0
    def __init__(self,
                 config,
                 environ=os.environ,
                 argv=sys.argv,
                 stdout=sys.stdout,
                 stderr=sys.stderr,
                 logger=None):
        dict.__setitem__(self, '__builtins__', self.BUILTINS)

        self._paths = []
        self._templates = set()
        # Store the real function and its dependencies, behind each
        # DependsFunction generated from @depends.
        self._depends = {}
        self._seen = set()
        # Store the @imports added to a given function.
        self._imports = {}

        self._options = OrderedDict()
        # Store the raw values returned by @depends functions
        self._results = {}
        # Store values for each Option, as per returned by Option.get_value
        self._option_values = {}
        # Store raw option (as per command line or environment) for each Option
        self._raw_options = {}

        # Store options added with `imply_option`, and the reason they were
        # added (which can either have been given to `imply_option`, or
        # inferred.
        self._implied_options = {}

        # Store all results from _prepare_function
        self._prepared_functions = set()

        self._helper = CommandLineHelper(environ, argv)

        assert isinstance(config, dict)
        self._config = config

        if logger is None:
            logger = moz_logger = logging.getLogger('moz.configure')
            logger.setLevel(logging.DEBUG)
            formatter = logging.Formatter('%(levelname)s: %(message)s')
            handler = ConfigureOutputHandler(stdout, stderr)
            handler.setFormatter(formatter)
            queue_debug = handler.queue_debug
            logger.addHandler(handler)

        else:
            assert isinstance(logger, logging.Logger)
            moz_logger = None

            @contextmanager
            def queue_debug():
                yield

        log_namespace = {
            k: getattr(logger, k)
            for k in ('debug', 'info', 'warning', 'error')
        }
        log_namespace['queue_debug'] = queue_debug
        self.log_impl = ReadOnlyNamespace(**log_namespace)

        self._help = None
        self._help_option = self.option_impl('--help',
                                             help='print this message')
        self._seen.add(self._help_option)
        # self._option_impl('--help') will have set this if --help was on the
        # command line.
        if self._option_values[self._help_option]:
            self._help = HelpFormatter(argv[0])
            self._help.add(self._help_option)
        elif moz_logger:
            handler = logging.FileHandler('config.log', mode='w', delay=True)
            handler.setFormatter(formatter)
            logger.addHandler(handler)
Beispiel #12
0
    def test_queue_debug_reentrant(self):
        out = StringIO()
        name = '%s.test_queue_debug_reentrant' % self.__class__.__name__
        logger = logging.getLogger(name)
        logger.setLevel(logging.DEBUG)
        handler =  ConfigureOutputHandler(out, out, maxlen=10)
        handler.setFormatter(logging.Formatter('%(levelname)s| %(message)s'))
        logger.addHandler(handler)

        try:
            with handler.queue_debug():
                logger.info('outer info')
                logger.debug('outer debug')
                with handler.queue_debug():
                    logger.info('inner info')
                    logger.debug('inner debug')
                    e = Exception('inner exception')
                    raise e
        except Exception as caught:
            self.assertIs(caught, e)

        self.assertEqual(out.getvalue(),
                         'outer info\n'
                         'inner info\n'
                         'DEBUG| outer debug\n'
                         'DEBUG| inner debug\n')

        out.seek(0)
        out.truncate()

        try:
            with handler.queue_debug():
                logger.info('outer info')
                logger.debug('outer debug')
                with handler.queue_debug():
                    logger.info('inner info')
                    logger.debug('inner debug')
                e = Exception('outer exception')
                raise e
        except Exception as caught:
            self.assertIs(caught, e)

        self.assertEqual(out.getvalue(),
                         'outer info\n'
                         'inner info\n'
                         'DEBUG| outer debug\n'
                         'DEBUG| inner debug\n')

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('outer info')
            logger.debug('outer debug')
            with handler.queue_debug():
                logger.info('inner info')
                logger.debug('inner debug')
                logger.error('inner error')
        self.assertEqual(out.getvalue(),
                         'outer info\n'
                         'inner info\n'
                         'DEBUG| outer debug\n'
                         'DEBUG| inner debug\n'
                         'ERROR| inner error\n')

        out.seek(0)
        out.truncate()

        with handler.queue_debug():
            logger.info('outer info')
            logger.debug('outer debug')
            with handler.queue_debug():
                logger.info('inner info')
                logger.debug('inner debug')
            logger.error('outer error')
        self.assertEqual(out.getvalue(),
                         'outer info\n'
                         'inner info\n'
                         'DEBUG| outer debug\n'
                         'DEBUG| inner debug\n'
                         'ERROR| outer error\n')
Beispiel #13
0
    def __init__(self, config, environ=os.environ, argv=sys.argv,
                 stdout=sys.stdout, stderr=sys.stderr, logger=None):
        dict.__setitem__(self, '__builtins__', self.BUILTINS)

        self._paths = []
        self._all_paths = set()
        self._templates = set()
        # Store the real function and its dependencies, behind each
        # DependsFunction generated from @depends.
        self._depends = {}
        self._seen = set()
        # Store the @imports added to a given function.
        self._imports = {}

        self._options = OrderedDict()
        # Store raw option (as per command line or environment) for each Option
        self._raw_options = OrderedDict()

        # Store options added with `imply_option`, and the reason they were
        # added (which can either have been given to `imply_option`, or
        # inferred. Their order matters, so use a list.
        self._implied_options = []

        # Store all results from _prepare_function
        self._prepared_functions = set()

        # Queue of functions to execute, with their arguments
        self._execution_queue = []

        self._helper = CommandLineHelper(environ, argv)

        assert isinstance(config, dict)
        self._config = config

        if logger is None:
            logger = moz_logger = logging.getLogger('moz.configure')
            logger.setLevel(logging.DEBUG)
            formatter = logging.Formatter('%(levelname)s: %(message)s')
            handler = ConfigureOutputHandler(stdout, stderr)
            handler.setFormatter(formatter)
            queue_debug = handler.queue_debug
            logger.addHandler(handler)

        else:
            assert isinstance(logger, logging.Logger)
            moz_logger = None
            @contextmanager
            def queue_debug():
                yield

        # Some callers will manage to log a bytestring with characters in it
        # that can't be converted to ascii. Make our log methods robust to this
        # by detecting the encoding that a producer is likely to have used.
        encoding = getpreferredencoding()
        def wrapped_log_method(logger, key):
            method = getattr(logger, key)
            if not encoding:
                return method
            def wrapped(*args, **kwargs):
                out_args = [
                    arg.decode(encoding) if isinstance(arg, str) else arg
                    for arg in args
                ]
                return method(*out_args, **kwargs)
            return wrapped

        log_namespace = {
            k: wrapped_log_method(logger, k)
            for k in ('debug', 'info', 'warning', 'error')
        }
        log_namespace['queue_debug'] = queue_debug
        self.log_impl = ReadOnlyNamespace(**log_namespace)

        self._help = None
        self._help_option = self.option_impl('--help',
                                             help='print this message')
        self._seen.add(self._help_option)
        if self._value_for(self._help_option):
            self._help = HelpFormatter(argv[0])
            self._help.add(self._help_option)
        elif moz_logger:
            handler = logging.FileHandler('config.log', mode='w', delay=True)
            handler.setFormatter(formatter)
            logger.addHandler(handler)