text: # vim:fileencoding=utf-8:noet
  from __future__ import (unicode_literals, division, absolute_import, print_function)
  
  import sys
  import pdb
  
  from powerline.pdb import PDBPowerline
  from powerline.lib.encoding import get_preferred_output_encoding
  from powerline.lib.unicode import unicode
  
  
  if sys.version_info < (3,):
  	# XXX The below classes make code compatible with PDBpp which uses pyrepl
  	#     which does not expect unicode or something above ASCII. They are 
  	#     completely not needed if pdbpp is not used, but that’s not always the 
  	#     case.
  	class PowerlineRenderBytesResult(bytes):
  		def __new__(cls, s, encoding=None):
  			encoding = encoding or s.encoding
  			if isinstance(s, PowerlineRenderResult):
  				return s.encode(encoding)
  			self = bytes.__new__(cls, s.encode(encoding) if isinstance(s, unicode) else s)
  			self.encoding = encoding
  			return self
  
  		for meth in (
  			'__contains__',
  			'partition', 'rpartition',
  			'split', 'rsplit',
  			'count', 'join',
  		):
  			exec((
  				'def {0}(self, *args):\n'
  				'	if any((isinstance(arg, unicode) for arg in args)):\n'
  				'		return self.__unicode__().{0}(*args)\n'
  				'	else:\n'
  				'		return bytes.{0}(self, *args)'
  			).format(meth))
  
  		for meth in (
  			'find', 'rfind',
  			'index', 'rindex',
  		):
  			exec((
  				'def {0}(self, *args):\n'
  				'	if any((isinstance(arg, unicode) for arg in args)):\n'
  				'		args = [arg.encode(self.encoding) if isinstance(arg, unicode) else arg for arg in args]\n'
  				'	return bytes.{0}(self, *args)'
  			).format(meth))
  
  		def __len__(self):
  			return len(self.decode(self.encoding))
  
  		def __getitem__(self, *args):
  			return PowerlineRenderBytesResult(bytes.__getitem__(self, *args), encoding=self.encoding)
  
  		def __getslice__(self, *args):
  			return PowerlineRenderBytesResult(bytes.__getslice__(self, *args), encoding=self.encoding)
  
  		@staticmethod
  		def add(encoding, *args):
  			if any((isinstance(arg, unicode) for arg in args)):
  				return PowerlineRenderResult(''.join((
  					arg
  					if isinstance(arg, unicode)
  					else arg.decode(encoding)
  					for arg in args
  				)), encoding)
  			else:
  				return PowerlineRenderBytesResult(b''.join(args), encoding=encoding)
  
  		def __add__(self, other):
  			return self.add(self.encoding, self, other)
  
  		def __radd__(self, other):
  			return self.add(self.encoding, other, self)
  
  		def __unicode__(self):
  			return PowerlineRenderResult(self)
  
  	class PowerlineRenderResult(unicode):
  		def __new__(cls, s, encoding=None):
  			encoding = (
  				encoding
  				or getattr(s, 'encoding', None)
  				or get_preferred_output_encoding()
  			)
  			if isinstance(s, unicode):
  				self = unicode.__new__(cls, s)
  			else:
  				self = unicode.__new__(cls, s, encoding, 'replace')
  			self.encoding = encoding
  			return self
  
  		def __str__(self):
  			return PowerlineRenderBytesResult(self)
  
  		def __getitem__(self, *args):
  			return PowerlineRenderResult(unicode.__getitem__(self, *args))
  
  		def __getslice__(self, *args):
  			return PowerlineRenderResult(unicode.__getslice__(self, *args))
  
  		@staticmethod
  		def add(encoding, *args):
  			return PowerlineRenderResult(''.join((
  				arg
  				if isinstance(arg, unicode)
  				else arg.decode(encoding)
  				for arg in args
  			)), encoding)
  
  		def __add__(self, other):
  			return self.add(self.encoding, self, other)
  
  		def __radd__(self, other):
  			return self.add(self.encoding, other, self)
  
  		def encode(self, *args, **kwargs):
  			return PowerlineRenderBytesResult(unicode.encode(self, *args, **kwargs), args[0])
  else:
  	PowerlineRenderResult = str
  
  
  def use_powerline_prompt(cls):
  	'''Decorator that installs powerline prompt to the class
  
  	:param pdb.Pdb cls:
  		Class that should be decorated.
  
  	:return:
  		``cls`` argument or a class derived from it. Latter is used to turn 
  		old-style classes into new-style classes.
  	'''
  	@property
  	def prompt(self):
  		try:
  			powerline = self.powerline
  		except AttributeError:
  			powerline = PDBPowerline()
  			powerline.setup(self)
  			self.powerline = powerline
  		return PowerlineRenderResult(powerline.render(side='left'))
  
  	@prompt.setter
  	def prompt(self, _):
  		pass
  
  	@prompt.deleter
  	def prompt(self):
  		pass
  
  	if not hasattr(cls, '__class__'):
  		# Old-style class: make it new-style or @property will not work.
  		old_cls = cls
  
  		class cls(cls, object):
  			__module__ = cls.__module__
  			__doc__ = cls.__doc__
  
  		cls.__name__ = old_cls.__name__
  
  	cls.prompt = prompt
  
  	return cls
  
  
  def main():
  	'''Run module as a script
  
  	Uses :py:func:`pdb.main` function directly, but prior to that it mocks 
  	:py:class:`pdb.Pdb` class with powerline-specific class instance.
  	'''
  	orig_pdb = pdb.Pdb
  
  	@use_powerline_prompt
  	class Pdb(pdb.Pdb, object):
  		def __init__(self):
  			orig_pdb.__init__(self)
  
  	pdb.Pdb = Pdb
  
  	return pdb.main()
  