def describeStats(stats, stream, title=None, details=True, totals=True, gettext=None):
from . import state<EOL>modeStringLut = dict((<EOL>(constants.SYNCTYPE_TWO_WAY,             '<STR_LIT>'),<EOL>(constants.SYNCTYPE_SLOW_SYNC,           '<STR_LIT>'),<EOL>(constants.SYNCTYPE_ONE_WAY_FROM_CLIENT, '<STR_LIT>'),<EOL>(constants.SYNCTYPE_REFRESH_FROM_CLIENT, '<STR_LIT>'),<EOL>(constants.SYNCTYPE_ONE_WAY_FROM_SERVER, '<STR_LIT>'),<EOL>(constants.SYNCTYPE_REFRESH_FROM_SERVER, '<STR_LIT>'),<EOL>))<EOL>if gettext is not None:<EOL><INDENT>_ = gettext<EOL><DEDENT>else:<EOL><INDENT>_ = lambda s: s<EOL><DEDENT>wSrc  = len(_('<STR_LIT>'))<EOL>wMode = len(_('<STR_LIT>'))<EOL>wCon  = len(_('<STR_LIT>'))<EOL>wCol  = len(_('<STR_LIT>'))<EOL>wMrg  = len(_('<STR_LIT>'))<EOL>wHereAdd = wPeerAdd = len(_('<STR_LIT>'))<EOL>wHereMod = wPeerMod = len(_('<STR_LIT>'))<EOL>wHereDel = wPeerDel = len(_('<STR_LIT>'))<EOL>wHereErr = wPeerErr = len(_('<STR_LIT>'))<EOL>totLoc = <NUM_LIT:0><EOL>totRem = <NUM_LIT:0><EOL>totErr = <NUM_LIT:0><EOL>totCol = <NUM_LIT:0><EOL>totMrg = <NUM_LIT:0><EOL>for key in stats.keys():<EOL><INDENT>wSrc  = max(wSrc, len(key))<EOL>wMode = max(wMode, len(modeStringLut.get(stats[key].mode)))<EOL>wCol  = max(wCol, len(num2str(stats[key].conflicts)))<EOL>wMrg  = max(wMrg, len(num2str(stats[key].merged)))<EOL>wHereAdd = max(wHereAdd, len(num2str(stats[key].hereAdd)))<EOL>wPeerAdd = max(wPeerAdd, len(num2str(stats[key].peerAdd)))<EOL>wHereMod = max(wHereMod, len(num2str(stats[key].hereMod)))<EOL>wPeerMod = max(wPeerMod, len(num2str(stats[key].peerMod)))<EOL>wHereDel = max(wHereDel, len(num2str(stats[key].hereDel)))<EOL>wPeerDel = max(wPeerDel, len(num2str(stats[key].peerDel)))<EOL>wHereErr = max(wHereErr, len(num2str(stats[key].hereErr)))<EOL>wPeerErr = max(wPeerErr, len(num2str(stats[key].peerErr)))<EOL>totLoc += stats[key].hereAdd + stats[key].hereMod + stats[key].hereDel<EOL>totRem += stats[key].peerAdd + stats[key].peerMod + stats[key].peerDel<EOL>totErr += stats[key].hereErr + stats[key].peerErr<EOL>totCol += stats[key].conflicts<EOL>totMrg += stats[key].merged<EOL><DEDENT>if wCon > wCol + <NUM_LIT:3> + wMrg:<EOL><INDENT>diff = wCon - ( wCol + <NUM_LIT:3> + wMrg )<EOL>wCol += diff / <NUM_LIT:2><EOL>wMrg = wCon - <NUM_LIT:3> - wCol<EOL><DEDENT>else:<EOL><INDENT>wCon = wCol + <NUM_LIT:3> + wMrg<EOL><DEDENT>if details:<EOL><INDENT>tWid = ( wSrc + <NUM_LIT:3> + wMode + <NUM_LIT:3><EOL>+ wHereAdd + wHereMod + wHereDel + wHereErr + <NUM_LIT:9> + <NUM_LIT:3><EOL>+ wPeerAdd + wPeerMod + wPeerDel + wPeerErr + <NUM_LIT:9> + <NUM_LIT:3><EOL>+ wCon )<EOL><DEDENT>else:<EOL><INDENT>if title is None:<EOL><INDENT>tWid = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>tWid = len(title)<EOL><DEDENT><DEDENT>if totals:<EOL><INDENT>sumlist = []<EOL>for val, singular, plural in [<EOL>(totLoc, _('<STR_LIT>'), _('<STR_LIT>')),<EOL>(totRem, _('<STR_LIT>'), _('<STR_LIT>')),<EOL>(totErr, _('<STR_LIT:error>'), _('<STR_LIT>')),<EOL>]:<EOL><INDENT>if val == <NUM_LIT:1>:<EOL><INDENT>sumlist.append(num2str(val) + '<STR_LIT:U+0020>' + singular)<EOL><DEDENT>elif val > <NUM_LIT:1>:<EOL><INDENT>sumlist.append(num2str(val) + '<STR_LIT:U+0020>' + plural)<EOL><DEDENT><DEDENT>if len(sumlist) <= <NUM_LIT:0>:<EOL><INDENT>sumlist = _('<STR_LIT>')<EOL><DEDENT>elif len(sumlist) == <NUM_LIT:1>:<EOL><INDENT>sumlist = sumlist[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>sumlist = '<STR_LIT:U+002CU+0020>'.join(sumlist[:-<NUM_LIT:1>]) + '<STR_LIT:U+0020>' + _('<STR_LIT>') + '<STR_LIT:U+0020>' + sumlist[-<NUM_LIT:1>]<EOL><DEDENT>if totMrg > <NUM_LIT:0> or totCol > <NUM_LIT:0>:<EOL><INDENT>sumlist += '<STR_LIT>'<EOL>if totMrg == <NUM_LIT:1>:<EOL><INDENT>sumlist += num2str(totMrg) + '<STR_LIT:U+0020>' + _('<STR_LIT>')<EOL><DEDENT>elif totMrg > <NUM_LIT:1>:<EOL><INDENT>sumlist += num2str(totMrg) + '<STR_LIT:U+0020>' + _('<STR_LIT>')<EOL><DEDENT>if totMrg > <NUM_LIT:0> and totCol > <NUM_LIT:0>:<EOL><INDENT>sumlist += '<STR_LIT:U+0020>' + _('<STR_LIT>') + '<STR_LIT:U+0020>'<EOL><DEDENT>if totCol == <NUM_LIT:1>:<EOL><INDENT>sumlist += num2str(totCol) + '<STR_LIT:U+0020>' + _('<STR_LIT>')<EOL><DEDENT>elif totCol > <NUM_LIT:1>:<EOL><INDENT>sumlist += num2str(totCol) + '<STR_LIT:U+0020>' + _('<STR_LIT>')<EOL><DEDENT><DEDENT>sumlist += '<STR_LIT:.>'<EOL>if len(sumlist) > tWid:<EOL><INDENT>wSrc += len(sumlist) - tWid<EOL>tWid = len(sumlist)<EOL><DEDENT><DEDENT>if title is not None:<EOL><INDENT>stream.write('<STR_LIT>' + '<STR_LIT:->' * tWid + '<STR_LIT>')<EOL>stream.write('<STR_LIT>'.format(title, w=tWid))<EOL>stream.write('<STR_LIT>')<EOL><DEDENT>hline = '<STR_LIT>'+ '<STR_LIT:->' * wSrc+ '<STR_LIT>'+ '<STR_LIT:->' * wMode+ '<STR_LIT>'+ '<STR_LIT:->' * ( wHereAdd + wHereMod + wHereDel + wHereErr + <NUM_LIT:9> )+ '<STR_LIT>'+ '<STR_LIT:->' * ( wPeerAdd + wPeerMod + wPeerDel + wPeerErr + <NUM_LIT:9> )+ '<STR_LIT>'+ '<STR_LIT:->' * wCon+ '<STR_LIT>'<EOL>if details:<EOL><INDENT>stream.write(hline)<EOL>stream.write('<STR_LIT>' + '<STR_LIT:U+0020>' * wSrc)<EOL>stream.write('<STR_LIT>' + '<STR_LIT:U+0020>' * wMode)<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=( wHereAdd + wHereMod + wHereDel + wHereErr + <NUM_LIT:9> )))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=( wPeerAdd + wPeerMod + wPeerDel + wPeerErr + <NUM_LIT:9> )))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wCon))<EOL>stream.write('<STR_LIT>')<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wSrc))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wMode))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wHereAdd))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wHereMod))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wHereDel))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wHereErr))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wPeerAdd))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wPeerMod))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wPeerDel))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wPeerErr))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wCol))<EOL>stream.write('<STR_LIT>'.format(_('<STR_LIT>'), w=wMrg))<EOL>stream.write('<STR_LIT>')<EOL>hsline = '<STR_LIT>' + '<STR_LIT:->' * wSrc+ '<STR_LIT>' + '<STR_LIT:->' * wMode+ '<STR_LIT>' + '<STR_LIT:->' * wHereAdd+ '<STR_LIT>' + '<STR_LIT:->' * wHereMod+ '<STR_LIT>' + '<STR_LIT:->' * wHereDel+ '<STR_LIT>' + '<STR_LIT:->' * wHereErr+ '<STR_LIT>' + '<STR_LIT:->' * wPeerAdd+ '<STR_LIT>' + '<STR_LIT:->' * wPeerMod+ '<STR_LIT>' + '<STR_LIT:->' * wPeerDel+ '<STR_LIT>' + '<STR_LIT:->' * wPeerErr+ '<STR_LIT>' + '<STR_LIT:->' * wCol+ '<STR_LIT>' + '<STR_LIT:->' * wMrg+ '<STR_LIT>'<EOL>stream.write(hsline)<EOL>def numcol(val, wid):<EOL><INDENT>if val == <NUM_LIT:0>:<EOL><INDENT>return '<STR_LIT>'.format('<STR_LIT:->', w=wid)<EOL><DEDENT>return '<STR_LIT>'.format(num2str(val), w=wid)<EOL><DEDENT>for key in sorted(stats.keys(), key=lambda k: str(k).lower()):<EOL><INDENT>stream.write('<STR_LIT>'.format(key, w=wSrc))<EOL>stream.write('<STR_LIT>'.format(modeStringLut.get(stats[key].mode), w=wMode))<EOL>stream.write(numcol(stats[key].hereAdd, wHereAdd))<EOL>stream.write(numcol(stats[key].hereMod, wHereMod))<EOL>stream.write(numcol(stats[key].hereDel, wHereDel))<EOL>stream.write(numcol(stats[key].hereErr, wHereErr))<EOL>stream.write(numcol(stats[key].peerAdd, wPeerAdd))<EOL>stream.write(numcol(stats[key].peerMod, wPeerMod))<EOL>stream.write(numcol(stats[key].peerDel, wPeerDel))<EOL>stream.write(numcol(stats[key].peerErr, wPeerErr))<EOL>stream.write(numcol(stats[key].conflicts, wCol))<EOL>stream.write(numcol(stats[key].merged, wMrg))<EOL>stream.write('<STR_LIT>')<EOL><DEDENT>stream.write(hsline)<EOL><DEDENT>if totals:<EOL><INDENT>if title is None and not details:<EOL><INDENT>stream.write('<STR_LIT>' + '<STR_LIT:->' * tWid + '<STR_LIT>')<EOL><DEDENT>stream.write('<STR_LIT>'.format(sumlist, w=tWid))<EOL>stream.write('<STR_LIT>')<EOL>stream.write('<STR_LIT>' + '<STR_LIT:->' * tWid + '<STR_LIT>')<EOL><DEDENT>return<EOL>
Renders an ASCII-table of the synchronization statistics `stats`,
example output:

.. code-block::

  +----------------------------------------------------------------------------------+
  |                                      TITLE                                       |
  +----------+------+-------------------------+--------------------------+-----------+
  |          |      |          Local          |          Remote          | Conflicts |
  |   Source | Mode |  Add  | Mod | Del | Err |   Add  | Mod | Del | Err | Col | Mrg |
  +----------+------+-------+-----+-----+-----+--------+-----+-----+-----+-----+-----+
  | contacts |  <=  |   -   |  -  |  -  |  -  | 10,387 |  -  |  -  |  -  |  -  |  -  |
  |     note |  SS  | 1,308 |  -  |   2 |  -  |    -   |  -  |  -  |  -  |  -  |  -  |
  +----------+------+-------+-----+-----+-----+--------+-----+-----+-----+-----+-----+
  |                  1,310 local changes and 10,387 remote changes.                  |
  +----------------------------------------------------------------------------------+

:Parameters:

stats : dict

  The synchronization stats returned by a call to Adapter.sync().

stream : file-like-object

  An output file-like object that has at least a `write()` method,
  e.g. ``sys.stdout`` can be used.

title : str, optional, default: null

  A title placed at the top of the table -- if omitted (the default),
  then no title is rendered.

details : bool, optional, default: true

  If truthy, a per-datastore listing of changes will be displayed
  (as in the above example).

totals : bool, optional, default: true

  If truthy, a summary of all changes will be displayed (as in the
  above example).

gettext : callable, optional, @DEPRECATED(0.2.0), default: null

  A `gettext.gettext` compatible callable used for translating
  localized content (such as number formatting, etc.).

  NOTE: this parameter is deprecated, and will be replaced with
  a generalized i18n solution.