Rev 6288: (gz) Add _PotExporter and other refactorings to export_pot module (Martin in file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/
Patch Queue Manager
pqm at pqm.ubuntu.com
Thu Nov 24 13:40:44 UTC 2011
At file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 6288 [merge]
revision-id: pqm at pqm.ubuntu.com-20111124134044-fxzjs2iro5obaax9
parent: pqm at pqm.ubuntu.com-20111124131551-u7xzxgto1p1yfz57
parent: martin.packman at canonical.com-20111121130048-tnw5gyty1b59qrpn
committer: Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2011-11-24 13:40:44 +0000
message:
(gz) Add _PotExporter and other refactorings to export_pot module (Martin
Packman)
modified:
bzrlib/export_pot.py bzrgettext-20110429104643-3wjy38532whc21yj-2
bzrlib/tests/test_export_pot.py test_export_pot.py-20110509102137-efovgz233s9uk2b2-1
=== modified file 'bzrlib/export_pot.py'
--- a/bzrlib/export_pot.py 2011-09-27 11:31:35 +0000
+++ b/bzrlib/export_pot.py 2011-11-21 13:00:48 +0000
@@ -18,6 +18,12 @@
# with Python under the Python License, which is GPL compatible.
"""Extract docstrings from Bazaar commands.
+
+This module only handles bzrlib objects that use strings not directly wrapped
+by a gettext() call. To generate a complete translation template file, this
+output needs to be combined with that of xgettext or a similar command for
+extracting those strings, as is done in the bzr Makefile. Sorting the output
+is also left to that stage of the process.
"""
import inspect
@@ -62,30 +68,39 @@
return s
-_FOUND_MSGID = None # set by entry function.
-
-def _poentry(outf, path, lineno, s, comment=None):
- if s in _FOUND_MSGID:
- return
- _FOUND_MSGID.add(s)
- if comment is None:
- comment = ''
- else:
- comment = "# %s\n" % comment
- mutter("Exporting msg %r at line %d in %r", s[:20], lineno, path)
- print >>outf, ('#: %s:%d\n' % (path, lineno) +
- comment+
- 'msgid %s\n' % _normalize(s) +
- 'msgstr ""\n')
-
-def _poentry_per_paragraph(outf, path, lineno, msgid, filter=lambda x: False):
- # TODO: How to split long help?
- paragraphs = msgid.split('\n\n')
- for p in paragraphs:
- if filter(p):
- continue
- _poentry(outf, path, lineno, p)
- lineno += p.count('\n') + 2
+class _PotExporter(object):
+ """Write message details to output stream in .pot file format"""
+
+ def __init__(self, outf):
+ self.outf = outf
+ self._msgids = set()
+
+ def poentry(self, path, lineno, s, comment=None):
+ if s in self._msgids:
+ return
+ self._msgids.add(s)
+ if comment is None:
+ comment = ''
+ else:
+ comment = "# %s\n" % comment
+ mutter("Exporting msg %r at line %d in %r", s[:20], lineno, path)
+ self.outf.write(
+ "#: {path}:{lineno}\n"
+ "{comment}"
+ "msgid {msg}\n"
+ "msgstr \"\"\n"
+ "\n".format(
+ path=path, lineno=lineno, comment=comment, msg=_normalize(s)))
+
+ def poentry_per_paragraph(self, path, lineno, msgid, include=None):
+ # TODO: How to split long help?
+ paragraphs = msgid.split('\n\n')
+ if include is not None:
+ paragraphs = filter(include, paragraphs)
+ for p in paragraphs:
+ self.poentry(path, lineno, p)
+ lineno += p.count('\n') + 2
+
_LAST_CACHE = _LAST_CACHED_SRC = None
@@ -106,7 +121,7 @@
_LAST_CACHE = offsets.copy()
return offsets
-def _standard_options(outf):
+def _standard_options(exporter):
from bzrlib.option import Option
src = inspect.findsource(Option)[0]
src = ''.join(src)
@@ -121,16 +136,16 @@
lineno = offsets.get(opt.title, 9999)
if lineno == 9999:
note(gettext("%r is not found in bzrlib/option.py") % opt.title)
- _poentry(outf, path, lineno, opt.title,
+ exporter.poentry(path, lineno, opt.title,
'title of %r option' % name)
if getattr(opt, 'help', None):
lineno = offsets.get(opt.help, 9999)
if lineno == 9999:
note(gettext("%r is not found in bzrlib/option.py") % opt.help)
- _poentry(outf, path, lineno, opt.help,
+ exporter.poentry(path, lineno, opt.help,
'help of %r option' % name)
-def _command_options(outf, path, cmd):
+def _command_options(exporter, path, cmd):
src, default_lineno = inspect.findsource(cmd.__class__)
offsets = _offsets_of_literal(''.join(src))
for opt in cmd.takes_options:
@@ -141,15 +156,15 @@
name = opt.name
if getattr(opt, 'title', None):
lineno = offsets.get(opt.title, default_lineno)
- _poentry(outf, path, lineno, opt.title,
+ exporter.poentry(path, lineno, opt.title,
'title of %r option of %r command' % (name, cmd.name()))
if getattr(opt, 'help', None):
lineno = offsets.get(opt.help, default_lineno)
- _poentry(outf, path, lineno, opt.help,
+ exporter.poentry(path, lineno, opt.help,
'help of %r option of %r command' % (name, cmd.name()))
-def _write_command_help(outf, cmd):
+def _write_command_help(exporter, cmd):
path = inspect.getfile(cmd.__class__)
if path.endswith('.pyc'):
path = path[:-1]
@@ -159,17 +174,17 @@
lineno = offsets[cmd.__doc__]
doc = inspect.getdoc(cmd)
- def filter(p):
+ def exclude_usage(p):
# ':Usage:' has special meaning in help topics.
# This is usage example of command and should not be translated.
- if p.splitlines()[0] == ':Usage:':
+ if p.splitlines()[0] != ':Usage:':
return True
- _poentry_per_paragraph(outf, path, lineno, doc, filter)
- _command_options(outf, path, cmd)
-
-
-def _command_helps(outf, plugin_name=None):
+ exporter.poentry_per_paragraph(path, lineno, doc, exclude_usage)
+ _command_options(exporter, path, cmd)
+
+
+def _command_helps(exporter, plugin_name=None):
"""Extract docstrings from path.
This respects the Bazaar cmdtable/table convention and will
@@ -186,7 +201,7 @@
# only export builtins if we are not exporting plugin commands
continue
note(gettext("Exporting messages from builtin command: %s"), cmd_name)
- _write_command_help(outf, command)
+ _write_command_help(exporter, command)
plugin_path = plugin.get_core_plugin_path()
core_plugins = glob(plugin_path + '/*/__init__.py')
@@ -206,10 +221,10 @@
continue
note(gettext("Exporting messages from plugin command: {0} in {1}").format(
cmd_name, command.plugin_name() ))
- _write_command_help(outf, command)
-
-
-def _error_messages(outf):
+ _write_command_help(exporter, command)
+
+
+def _error_messages(exporter):
"""Extract fmt string from bzrlib.errors."""
path = errors.__file__
if path.endswith('.pyc'):
@@ -230,35 +245,32 @@
fmt = getattr(klass, "_fmt", None)
if fmt:
note(gettext("Exporting message from error: %s"), name)
- _poentry(outf, 'bzrlib/errors.py',
+ exporter.poentry('bzrlib/errors.py',
offsets.get(fmt, 9999), fmt)
-def _help_topics(outf):
+def _help_topics(exporter):
topic_registry = help_topics.topic_registry
for key in topic_registry.keys():
doc = topic_registry.get(key)
if isinstance(doc, str):
- _poentry_per_paragraph(
- outf,
+ exporter.poentry_per_paragraph(
'dummy/help_topics/'+key+'/detail.txt',
1, doc)
elif callable(doc): # help topics from files
- _poentry_per_paragraph(
- outf,
+ exporter.poentry_per_paragraph(
'en/help_topics/'+key+'.txt',
1, doc(key))
summary = topic_registry.get_summary(key)
if summary is not None:
- _poentry(outf, 'dummy/help_topics/'+key+'/summary.txt',
+ exporter.poentry('dummy/help_topics/'+key+'/summary.txt',
1, summary)
def export_pot(outf, plugin=None):
- global _FOUND_MSGID
- _FOUND_MSGID = set()
+ exporter = _PotExporter(outf)
if plugin is None:
- _standard_options(outf)
- _command_helps(outf)
- _error_messages(outf)
- _help_topics(outf)
+ _standard_options(exporter)
+ _command_helps(exporter)
+ _error_messages(exporter)
+ _help_topics(exporter)
else:
- _command_helps(outf, plugin)
+ _command_helps(exporter, plugin)
=== modified file 'bzrlib/tests/test_export_pot.py'
--- a/bzrlib/tests/test_export_pot.py 2011-06-28 10:28:29 +0000
+++ b/bzrlib/tests/test_export_pot.py 2011-11-21 13:00:48 +0000
@@ -70,21 +70,20 @@
class PoEntryTestCase(tests.TestCase):
def setUp(self):
- self.overrideAttr(export_pot, '_FOUND_MSGID', set())
- self._outf = StringIO()
super(PoEntryTestCase, self).setUp()
+ self.exporter = export_pot._PotExporter(StringIO())
def check_output(self, expected):
self.assertEqual(
- self._outf.getvalue(),
+ self.exporter.outf.getvalue(),
textwrap.dedent(expected)
)
class TestPoEntry(PoEntryTestCase):
def test_simple(self):
- export_pot._poentry(self._outf, 'dummy', 1, "spam")
- export_pot._poentry(self._outf, 'dummy', 2, "ham", 'EGG')
+ self.exporter.poentry('dummy', 1, "spam")
+ self.exporter.poentry('dummy', 2, "ham", 'EGG')
self.check_output('''\
#: dummy:1
msgid "spam"
@@ -98,9 +97,9 @@
''')
def test_duplicate(self):
- export_pot._poentry(self._outf, 'dummy', 1, "spam")
+ self.exporter.poentry('dummy', 1, "spam")
# This should be ignored.
- export_pot._poentry(self._outf, 'dummy', 2, "spam", 'EGG')
+ self.exporter.poentry('dummy', 2, "spam", 'EGG')
self.check_output('''\
#: dummy:1
@@ -112,8 +111,7 @@
class TestPoentryPerPergraph(PoEntryTestCase):
def test_single(self):
- export_pot._poentry_per_paragraph(
- self._outf,
+ self.exporter.poentry_per_paragraph(
'dummy',
10,
'''foo\nbar\nbaz\n'''
@@ -128,8 +126,7 @@
''')
def test_multi(self):
- export_pot._poentry_per_paragraph(
- self._outf,
+ self.exporter.poentry_per_paragraph(
'dummy',
10,
'''spam\nham\negg\n\nSPAM\nHAM\nEGG\n'''
@@ -169,8 +166,8 @@
Blah Blah Blah
"""
- export_pot._write_command_help(self._outf, cmd_Demo())
- result = self._outf.getvalue()
+ export_pot._write_command_help(self.exporter, cmd_Demo())
+ result = self.exporter.outf.getvalue()
# We don't care about filename and lineno here.
result = re.sub(r'(?m)^#: [^\n]+\n', '', result)
More information about the bazaar-commits
mailing list