def _log(self, attr, msg, *args, **kwargs): prefix = kwargs.get("prefix") or self.prefix prefix = self.ext + ((":" + prefix) if prefix else "") msg = safe_unicode(msg) if args or kwargs: args = [safe_unicode(s) if isinstance(s, bytes) else s for s in args] kwargs = dict(((k, safe_unicode(v) if isinstance(v, bytes) else v) for k, v in kwargs.items())) msg = msg.format(*args, **kwargs) msg = prefix + ":" + msg key = attr + ":" + prefix if msg != self.last_msgs.get(key): getattr(self.logger, attr)(msg) self.last_msgs[key] = msg
def _log(self, attr, msg, *args, **kwargs): prefix = kwargs.get('prefix') or self.prefix prefix = self.ext + ((':' + prefix) if prefix else '') msg = safe_unicode(msg) if args or kwargs: args = [ safe_unicode(s) if isinstance(s, bytes) else s for s in args ] kwargs = dict(((k, safe_unicode(v) if isinstance(v, bytes) else v) for k, v in kwargs.items())) msg = msg.format(*args, **kwargs) msg = prefix + ':' + msg key = attr + ':' + prefix if msg != self.last_msgs.get(key): getattr(self.logger, attr)(msg) self.last_msgs[key] = msg
def get_segments(self, side=None, line=0, segment_info=None, mode=None): '''Return all segments. Function segments are called, and all segments get their before/after and ljust/rjust properties applied. :param int line: Line number for which segments should be obtained. Is counted from zero (botmost line). ''' for side in [side] if side else ['left', 'right']: parsed_segments = [] for segment in self.segments[line][side]: if segment['display_condition'](self.pl, segment_info, mode): process_segment( self.pl, side, segment_info, parsed_segments, segment, mode, self.colorscheme, ) for segment in parsed_segments: self.pl.prefix = segment['name'] try: width = segment['width'] align = segment['align'] if width == 'auto' and segment['expand'] is None: segment['expand'] = expand_functions.get(align) if segment['expand'] is None: self.pl.error('Align argument must be “r”, “l” or “c”, not “{0}”', align) try: segment['contents'] = segment['before'] + u( segment['contents'] if segment['contents'] is not None else '' ) + segment['after'] except Exception as e: self.pl.exception('Failed to compute segment contents: {0}', str(e)) segment['contents'] = safe_unicode(segment.get('contents')) # Align segment contents if segment['width'] and segment['width'] != 'auto': if segment['align'] == 'l': segment['contents'] = segment['contents'].ljust(segment['width']) elif segment['align'] == 'r': segment['contents'] = segment['contents'].rjust(segment['width']) elif segment['align'] == 'c': segment['contents'] = segment['contents'].center(segment['width']) # We need to yield a copy of the segment, or else mode-dependent # segment contents can’t be cached correctly e.g. when caching # non-current window contents for vim statuslines yield segment.copy() except Exception as e: self.pl.exception('Failed to compute segment: {0}', str(e)) fallback = get_fallback_segment() fallback.update(side=side) yield fallback
def _log(self, attr, msg, *args, **kwargs): prefix = kwargs.get('prefix') or self.prefix prefix = self.ext + ((':' + prefix) if prefix else '') if args or kwargs: msg = msg.format(*args, **kwargs) msg = prefix + ':' + safe_unicode(msg) key = attr + ':' + prefix if msg != self.last_msgs.get(key): getattr(self.logger, attr)(msg) self.last_msgs[key] = msg
def render(self, *args, **kwargs): '''Update/create renderer if needed and pass all arguments further to ``self.renderer.render()``. ''' try: self.update_renderer() return self.renderer.render(*args, **kwargs) except Exception as e: exc = e try: self.exception('Failed to render: {0}', str(e)) except Exception as e: exc = e return FailedUnicode(safe_unicode(exc))
def render_above_lines(self, *args, **kwargs): '''Like .render(), but for ``self.renderer.render_above_lines()`` ''' try: self.update_renderer() for line in self.renderer.render_above_lines(*args, **kwargs): yield line except Exception as e: exc = e try: self.exception('Failed to render: {0}', str(e)) except Exception as e: exc = e yield FailedUnicode(safe_unicode(exc))
def force_update(self, *args, **kwargs): '''Force a segment to update itself. ''' try: self.update_renderer() return self.renderer.force_update(*args, **kwargs) except Exception as e: exc = e try: self.exception('Failed to force segment update: {0}', str(e)) except Exception as e: exc = e ret = FailedUnicode(safe_unicode(exc)) if kwargs.get('output_width', False): ret = ret, len(ret) return ret
def render(self, *args, **kwargs): '''Update/create renderer if needed and pass all arguments further to ``self.renderer.render()``. ''' try: self.update_renderer() return self.renderer.render(*args, **kwargs) except Exception as e: exc = e try: self.exception('Failed to render: {0}', str(e)) except Exception as e: exc = e ret = FailedUnicode(safe_unicode(exc)) if kwargs.get('output_width', False): ret = ret, len(ret) return ret
def render(self, *args, **kwargs): '''Update/create renderer if needed and pass all arguments further to ``self.renderer.render()``. ''' try: self.update_renderer() return self.renderer.render(*args, **kwargs) except Exception as e: try: self.exception('Failed to render: {0}', str(e)) except Exception as e: # Updates e variable to new value, masking previous one. # Normally it is the same exception (due to raise in case pl is # unset), but it may also show error in logger. Note that latter # is not logged by logger for obvious reasons, thus this also # prevents us from seeing logger traceback. pass return FailedUnicode(safe_unicode(e))
def render_above_lines(self, *args, **kwargs): """Like .render(), but for ``self.renderer.render_above_lines()`` """ try: self.update_renderer() for line in self.renderer.render_above_lines(*args, **kwargs): yield line except Exception as e: try: self.exception("Failed to render: {0}", str(e)) except Exception as e: # Updates e variable to new value, masking previous one. # Normally it is the same exception (due to raise in case pl is # unset), but it may also show error in logger. Note that latter # is not logged by logger for obvious reasons, thus this also # prevents us from seeing logger traceback. pass yield FailedUnicode(safe_unicode(e))
def render_above_lines(self, *args, **kwargs): '''Like .render(), but for ``self.renderer.render_above_lines()`` ''' try: self.update_renderer() for line in self.renderer.render_above_lines(*args, **kwargs): yield line except Exception as e: try: self.exception('Failed to render: {0}', str(e)) except Exception as e: # Updates e variable to new value, masking previous one. # Normally it is the same exception (due to raise in case pl is # unset), but it may also show error in logger. Note that latter # is not logged by logger for obvious reasons, thus this also # prevents us from seeing logger traceback. pass yield FailedUnicode(safe_unicode(e))
def test_safe_unicode(self): self.assertStringsIdentical('abc', plu.safe_unicode('abc')) self.assertStringsIdentical('abc', plu.safe_unicode(b'abc')) self.assertStringsIdentical('«»', plu.safe_unicode(b'\xc2\xab\xc2\xbb')) with replace_attr(plu, 'get_preferred_output_encoding', lambda: 'latin1'): self.assertStringsIdentical('ÿ', plu.safe_unicode(b'\xFF')) self.assertStringsIdentical('None', plu.safe_unicode(None)) class FailingStr(object): def __str__(self): raise NotImplementedError('Fail!') self.assertStringsIdentical('Fail!', plu.safe_unicode(FailingStr()))