comparison genshi/filters/tests/i18n.py @ 916:872726bac135 experimental-py3k

add support for python 3 to genshi.filters: * minor changes to track encoding=None API change in core genshi modules. * renamed genshi/filters/tests/html.py to test_html.py to avoid clashes with Python 3 top-level html module when running tests subset. * did not rename genshi/filters/html.py. * i18n filters: * ugettext and friends are gone in Python 3 (and only gettext and friends exist and they now handle unicode) * Some \ line continuations inside doctests confused 2to3 and so were removed them. * Testing picked up a problem (already present in trunk) where Translator.__call__ could end up defining gettext as an endlessly recursive function. Noted with a TODO.
author hodgestar
date Sun, 24 Oct 2010 22:21:28 +0000
parents 85e4678337cf
children
comparison
equal deleted inserted replaced
915:9fafb35032a1 916:872726bac135
12 # history and logs, available at http://genshi.edgewall.org/log/. 12 # history and logs, available at http://genshi.edgewall.org/log/.
13 13
14 from datetime import datetime 14 from datetime import datetime
15 import doctest 15 import doctest
16 from gettext import NullTranslations 16 from gettext import NullTranslations
17 from StringIO import StringIO
18 import unittest 17 import unittest
19 18
20 from genshi.core import Attrs 19 from genshi.core import Attrs
21 from genshi.template import MarkupTemplate, Context 20 from genshi.template import MarkupTemplate, Context
22 from genshi.filters.i18n import Translator, extract 21 from genshi.filters.i18n import Translator, extract
23 from genshi.input import HTML 22 from genshi.input import HTML
23 from genshi.compat import IS_PYTHON2, StringIO
24 24
25 25
26 class DummyTranslations(NullTranslations): 26 class DummyTranslations(NullTranslations):
27 _domains = {} 27 _domains = {}
28 28
37 self._domains[domain] = translation 37 self._domains[domain] = translation
38 38
39 def _domain_call(self, func, domain, *args, **kwargs): 39 def _domain_call(self, func, domain, *args, **kwargs):
40 return getattr(self._domains.get(domain, self), func)(*args, **kwargs) 40 return getattr(self._domains.get(domain, self), func)(*args, **kwargs)
41 41
42 def ugettext(self, message): 42 if IS_PYTHON2:
43 missing = object() 43 def ugettext(self, message):
44 tmsg = self._catalog.get(message, missing) 44 missing = object()
45 if tmsg is missing: 45 tmsg = self._catalog.get(message, missing)
46 if self._fallback: 46 if tmsg is missing:
47 return self._fallback.ugettext(message) 47 if self._fallback:
48 return unicode(message) 48 return self._fallback.ugettext(message)
49 return tmsg 49 return unicode(message)
50 50 return tmsg
51 def dugettext(self, domain, message): 51 else:
52 return self._domain_call('ugettext', domain, message) 52 def gettext(self, message):
53 missing = object()
54 tmsg = self._catalog.get(message, missing)
55 if tmsg is missing:
56 if self._fallback:
57 return self._fallback.gettext(message)
58 return unicode(message)
59 return tmsg
60
61 if IS_PYTHON2:
62 def dugettext(self, domain, message):
63 return self._domain_call('ugettext', domain, message)
64 else:
65 def dgettext(self, domain, message):
66 return self._domain_call('gettext', domain, message)
53 67
54 def ungettext(self, msgid1, msgid2, n): 68 def ungettext(self, msgid1, msgid2, n):
55 try: 69 try:
56 return self._catalog[(msgid1, self.plural(n))] 70 return self._catalog[(msgid1, self.plural(n))]
57 except KeyError: 71 except KeyError:
60 if n == 1: 74 if n == 1:
61 return msgid1 75 return msgid1
62 else: 76 else:
63 return msgid2 77 return msgid2
64 78
65 def dungettext(self, domain, singular, plural, numeral): 79 if not IS_PYTHON2:
66 return self._domain_call('ungettext', domain, singular, plural, numeral) 80 ngettext = ungettext
81 del ungettext
82
83 if IS_PYTHON2:
84 def dungettext(self, domain, singular, plural, numeral):
85 return self._domain_call('ungettext', domain, singular, plural, numeral)
86 else:
87 def dngettext(self, domain, singular, plural, numeral):
88 return self._domain_call('ngettext', domain, singular, plural, numeral)
67 89
68 90
69 class TranslatorTestCase(unittest.TestCase): 91 class TranslatorTestCase(unittest.TestCase):
70 92
71 def test_translate_included_attribute_text(self): 93 def test_translate_included_attribute_text(self):
72 """ 94 """
73 Verify that translated attributes end up in a proper `Attrs` instance. 95 Verify that translated attributes end up in a proper `Attrs` instance.
74 """ 96 """
75 html = HTML("""<html> 97 html = HTML(u"""<html>
76 <span title="Foo"></span> 98 <span title="Foo"></span>
77 </html>""") 99 </html>""")
78 translator = Translator(lambda s: u"Voh") 100 translator = Translator(lambda s: u"Voh")
79 stream = list(html.filter(translator)) 101 stream = list(html.filter(translator))
80 kind, data, pos = stream[2] 102 kind, data, pos = stream[2]
216 </p> 238 </p>
217 </html>""") 239 </html>""")
218 gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]." 240 gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]."
219 translator = Translator(gettext) 241 translator = Translator(gettext)
220 translator.setup(tmpl) 242 translator.setup(tmpl)
221 self.assertEqual("""<html> 243 self.assertEqual(u"""<html>
222 <p>Für Details siehe bitte <a href="help.html">Hilfe</a>.</p> 244 <p>Für Details siehe bitte <a href="help.html">Hilfe</a>.</p>
223 </html>""", tmpl.generate().render()) 245 </html>""".encode('utf-8'), tmpl.generate().render(encoding='utf-8'))
224 246
225 def test_extract_i18n_msg_nonewline(self): 247 def test_extract_i18n_msg_nonewline(self):
226 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 248 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
227 xmlns:i18n="http://genshi.edgewall.org/i18n"> 249 xmlns:i18n="http://genshi.edgewall.org/i18n">
228 <p i18n:msg="">Please see <a href="help.html">Help</a></p> 250 <p i18n:msg="">Please see <a href="help.html">Help</a></p>
239 <p i18n:msg="">Please see <a href="help.html">Help</a></p> 261 <p i18n:msg="">Please see <a href="help.html">Help</a></p>
240 </html>""") 262 </html>""")
241 gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]" 263 gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]"
242 translator = Translator(gettext) 264 translator = Translator(gettext)
243 translator.setup(tmpl) 265 translator.setup(tmpl)
244 self.assertEqual("""<html> 266 self.assertEqual(u"""<html>
245 <p>Für Details siehe bitte <a href="help.html">Hilfe</a></p> 267 <p>Für Details siehe bitte <a href="help.html">Hilfe</a></p>
246 </html>""", tmpl.generate().render()) 268 </html>""", tmpl.generate().render())
247 269
248 def test_extract_i18n_msg_elt_nonewline(self): 270 def test_extract_i18n_msg_elt_nonewline(self):
249 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 271 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
262 <i18n:msg>Please see <a href="help.html">Help</a></i18n:msg> 284 <i18n:msg>Please see <a href="help.html">Help</a></i18n:msg>
263 </html>""") 285 </html>""")
264 gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]" 286 gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]"
265 translator = Translator(gettext) 287 translator = Translator(gettext)
266 translator.setup(tmpl) 288 translator.setup(tmpl)
267 self.assertEqual("""<html> 289 self.assertEqual(u"""<html>
268 Für Details siehe bitte <a href="help.html">Hilfe</a> 290 Für Details siehe bitte <a href="help.html">Hilfe</a>
269 </html>""", tmpl.generate().render()) 291 </html>""".encode('utf-8'), tmpl.generate().render(encoding='utf-8'))
270 292
271 def test_extract_i18n_msg_with_attributes(self): 293 def test_extract_i18n_msg_with_attributes(self):
272 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 294 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
273 xmlns:i18n="http://genshi.edgewall.org/i18n"> 295 xmlns:i18n="http://genshi.edgewall.org/i18n">
274 <p i18n:msg="" title="A helpful paragraph"> 296 <p i18n:msg="" title="A helpful paragraph">
392 </p> 414 </p>
393 </html>""") 415 </html>""")
394 gettext = lambda s: u"Für Details siehe bitte [1:[2:Hilfeseite]]." 416 gettext = lambda s: u"Für Details siehe bitte [1:[2:Hilfeseite]]."
395 translator = Translator(gettext) 417 translator = Translator(gettext)
396 translator.setup(tmpl) 418 translator.setup(tmpl)
397 self.assertEqual("""<html> 419 self.assertEqual(u"""<html>
398 <p>Für Details siehe bitte <a href="help.html"><em>Hilfeseite</em></a>.</p> 420 <p>Für Details siehe bitte <a href="help.html"><em>Hilfeseite</em></a>.</p>
399 </html>""", tmpl.generate().render()) 421 </html>""", tmpl.generate().render())
400 422
401 def test_extract_i18n_msg_label_with_nested_input(self): 423 def test_extract_i18n_msg_label_with_nested_input(self):
402 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 424 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
447 </p> 469 </p>
448 </html>""") 470 </html>""")
449 gettext = lambda s: u"[1:] Einträge pro Seite anzeigen." 471 gettext = lambda s: u"[1:] Einträge pro Seite anzeigen."
450 translator = Translator(gettext) 472 translator = Translator(gettext)
451 translator.setup(tmpl) 473 translator.setup(tmpl)
452 self.assertEqual("""<html> 474 self.assertEqual(u"""<html>
453 <p><input type="text" name="num"/> Einträge pro Seite anzeigen.</p> 475 <p><input type="text" name="num"/> Einträge pro Seite anzeigen.</p>
454 </html>""", tmpl.generate().render()) 476 </html>""", tmpl.generate().render())
455 477
456 def test_extract_i18n_msg_multiple(self): 478 def test_extract_i18n_msg_multiple(self):
457 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 479 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
474 </p> 496 </p>
475 </html>""") 497 </html>""")
476 gettext = lambda s: u"Für [2:Details] siehe bitte [1:Hilfe]." 498 gettext = lambda s: u"Für [2:Details] siehe bitte [1:Hilfe]."
477 translator = Translator(gettext) 499 translator = Translator(gettext)
478 translator.setup(tmpl) 500 translator.setup(tmpl)
479 self.assertEqual("""<html> 501 self.assertEqual(u"""<html>
480 <p>Für <em>Details</em> siehe bitte <a href="help.html">Hilfe</a>.</p> 502 <p>Für <em>Details</em> siehe bitte <a href="help.html">Hilfe</a>.</p>
481 </html>""", tmpl.generate().render()) 503 </html>""", tmpl.generate().render())
482 504
483 def test_extract_i18n_msg_multiple_empty(self): 505 def test_extract_i18n_msg_multiple_empty(self):
484 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 506 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
498 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 520 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
499 xmlns:i18n="http://genshi.edgewall.org/i18n"> 521 xmlns:i18n="http://genshi.edgewall.org/i18n">
500 <p i18n:msg=""> 522 <p i18n:msg="">
501 Show me <input type="text" name="num" /> entries per page, starting at page <input type="text" name="num" />. 523 Show me <input type="text" name="num" /> entries per page, starting at page <input type="text" name="num" />.
502 </p> 524 </p>
503 </html>""") 525 </html>""", encoding='utf-8')
504 gettext = lambda s: u"[1:] Einträge pro Seite, beginnend auf Seite [2:]." 526 gettext = lambda s: u"[1:] Einträge pro Seite, beginnend auf Seite [2:]."
505 translator = Translator(gettext) 527 translator = Translator(gettext)
506 translator.setup(tmpl) 528 translator.setup(tmpl)
507 self.assertEqual("""<html> 529 self.assertEqual(u"""<html>
508 <p><input type="text" name="num"/> Eintr\xc3\xa4ge pro Seite, beginnend auf Seite <input type="text" name="num"/>.</p> 530 <p><input type="text" name="num"/> Eintr\u00E4ge pro Seite, beginnend auf Seite <input type="text" name="num"/>.</p>
509 </html>""", tmpl.generate().render()) 531 </html>""".encode('utf-8'), tmpl.generate().render(encoding='utf-8'))
510 532
511 def test_extract_i18n_msg_with_param(self): 533 def test_extract_i18n_msg_with_param(self):
512 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 534 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
513 xmlns:i18n="http://genshi.edgewall.org/i18n"> 535 xmlns:i18n="http://genshi.edgewall.org/i18n">
514 <p i18n:msg="name"> 536 <p i18n:msg="name">
543 </p> 565 </p>
544 </html>""") 566 </html>""")
545 gettext = lambda s: u"%(name)s, sei gegrüßt!" 567 gettext = lambda s: u"%(name)s, sei gegrüßt!"
546 translator = Translator(gettext) 568 translator = Translator(gettext)
547 translator.setup(tmpl) 569 translator.setup(tmpl)
548 self.assertEqual("""<html> 570 self.assertEqual(u"""<html>
549 <p>Jim, sei gegrüßt!</p> 571 <p>Jim, sei gegrüßt!</p>
550 </html>""", tmpl.generate(user=dict(name='Jim')).render()) 572 </html>""", tmpl.generate(user=dict(name='Jim')).render())
551 573
552 def test_translate_i18n_msg_with_attribute_param(self): 574 def test_translate_i18n_msg_with_attribute_param(self):
553 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 575 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
557 </p> 579 </p>
558 </html>""") 580 </html>""")
559 gettext = lambda s: u"Sei gegrüßt, [1:Alter]!" 581 gettext = lambda s: u"Sei gegrüßt, [1:Alter]!"
560 translator = Translator(gettext) 582 translator = Translator(gettext)
561 translator.setup(tmpl) 583 translator.setup(tmpl)
562 self.assertEqual("""<html> 584 self.assertEqual(u"""<html>
563 <p>Sei gegrüßt, <a href="#42">Alter</a>!</p> 585 <p>Sei gegrüßt, <a href="#42">Alter</a>!</p>
564 </html>""", tmpl.generate(anchor='42').render()) 586 </html>""", tmpl.generate(anchor='42').render())
565 587
566 def test_extract_i18n_msg_with_two_params(self): 588 def test_extract_i18n_msg_with_two_params(self):
567 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 589 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
615 </p> 637 </p>
616 </html>""") 638 </html>""")
617 gettext = lambda s: u"[1:] Einträge pro Seite anzeigen." 639 gettext = lambda s: u"[1:] Einträge pro Seite anzeigen."
618 translator = Translator(gettext) 640 translator = Translator(gettext)
619 translator.setup(tmpl) 641 translator.setup(tmpl)
620 self.assertEqual("""<html> 642 self.assertEqual(u"""<html>
621 <p><input type="text" name="num" value="x"/> Einträge pro Seite anzeigen.</p> 643 <p><input type="text" name="num" value="x"/> Einträge pro Seite anzeigen.</p>
622 </html>""", tmpl.generate().render()) 644 </html>""", tmpl.generate().render())
623 645
624 def test_extract_i18n_msg_with_comment(self): 646 def test_extract_i18n_msg_with_comment(self):
625 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 647 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
674 'Foo': 'Voh', 696 'Foo': 'Voh',
675 'Foo bar': u'Voh bär' 697 'Foo bar': u'Voh bär'
676 })) 698 }))
677 tmpl.filters.insert(0, translator) 699 tmpl.filters.insert(0, translator)
678 tmpl.add_directives(Translator.NAMESPACE, translator) 700 tmpl.add_directives(Translator.NAMESPACE, translator)
679 self.assertEqual("""<html> 701 self.assertEqual(u"""<html>
680 <p title="Voh bär">Voh</p> 702 <p title="Voh bär">Voh</p>
681 </html>""", tmpl.generate().render()) 703 </html>""", tmpl.generate().render())
682 704
683 def test_translate_i18n_msg_and_py_strip_directives(self): 705 def test_translate_i18n_msg_and_py_strip_directives(self):
684 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 706 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
718 translations = DummyTranslations({ 740 translations = DummyTranslations({
719 'Changed %(date)s ago by %(author)s': u'Modificado à %(date)s por %(author)s' 741 'Changed %(date)s ago by %(author)s': u'Modificado à %(date)s por %(author)s'
720 }) 742 })
721 translator = Translator(translations) 743 translator = Translator(translations)
722 translator.setup(tmpl) 744 translator.setup(tmpl)
723 self.assertEqual("""<html> 745 self.assertEqual(u"""<html>
724 Modificado à um dia por Pedro 746 Modificado à um dia por Pedro
725 </html>""", tmpl.generate(date='um dia', author="Pedro").render()) 747 </html>""".encode('utf-8'), tmpl.generate(date='um dia', author="Pedro").render(encoding='utf-8'))
726 748
727 749
728 def test_i18n_msg_ticket_251_extract(self): 750 def test_i18n_msg_ticket_251_extract(self):
729 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 751 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
730 xmlns:i18n="http://genshi.edgewall.org/i18n"> 752 xmlns:i18n="http://genshi.edgewall.org/i18n">
747 u'[1:[2:Translation\\[\xa00\xa0\\]]: [3:One coin]]': 769 u'[1:[2:Translation\\[\xa00\xa0\\]]: [3:One coin]]':
748 u'[1:[2:Trandução\\[\xa00\xa0\\]]: [3:Uma moeda]]' 770 u'[1:[2:Trandução\\[\xa00\xa0\\]]: [3:Uma moeda]]'
749 }) 771 })
750 translator = Translator(translations) 772 translator = Translator(translations)
751 translator.setup(tmpl) 773 translator.setup(tmpl)
752 self.assertEqual("""<html> 774 self.assertEqual(u"""<html>
753 <p><tt><b>Trandução[ 0 ]</b>: <em>Uma moeda</em></tt></p> 775 <p><tt><b>Trandução[ 0 ]</b>: <em>Uma moeda</em></tt></p>
754 </html>""", tmpl.generate().render()) 776 </html>""".encode('utf-8'), tmpl.generate().render(encoding='utf-8'))
755 777
756 def test_extract_i18n_msg_with_other_directives_nested(self): 778 def test_extract_i18n_msg_with_other_directives_nested(self):
757 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 779 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
758 xmlns:i18n="http://genshi.edgewall.org/i18n"> 780 xmlns:i18n="http://genshi.edgewall.org/i18n">
759 <p i18n:msg="" py:with="q = quote_plus(message[:80])">Before you do that, though, please first try 781 <p i18n:msg="" py:with="q = quote_plus(message[:80])">Before you do that, though, please first try
809 translator.setup(tmpl) 831 translator.setup(tmpl)
810 messages = list(translator.extract(tmpl.stream)) 832 messages = list(translator.extract(tmpl.stream))
811 self.assertEqual(1, len(messages)) 833 self.assertEqual(1, len(messages))
812 ctx = Context() 834 ctx = Context()
813 ctx.push({'trac': {'homepage': 'http://trac.edgewall.org/'}}) 835 ctx.push({'trac': {'homepage': 'http://trac.edgewall.org/'}})
814 self.assertEqual("""<html> 836 self.assertEqual(u"""<html>
815 <p>Antes de o fazer, porém, 837 <p>Antes de o fazer, porém,
816 <strong>por favor tente <a href="http://trac.edgewall.org/search?ticket=yes&amp;noquickjump=1&amp;q=q">procurar</a> 838 <strong>por favor tente <a href="http://trac.edgewall.org/search?ticket=yes&amp;noquickjump=1&amp;q=q">procurar</a>
817 por problemas semelhantes</strong>, uma vez que é muito provável que este problema 839 por problemas semelhantes</strong>, uma vez que é muito provável que este problema
818 já tenha sido reportado anteriormente. Para questões relativas à instalação 840 já tenha sido reportado anteriormente. Para questões relativas à instalação
819 e configuração do Trac, por favor tente a 841 e configuração do Trac, por favor tente a
844 self.assertEqual( 866 self.assertEqual(
845 '[1:Note:] This repository is defined in\n ' 867 '[1:Note:] This repository is defined in\n '
846 '[2:[3:trac.ini]]\n and cannot be edited on this page.', 868 '[2:[3:trac.ini]]\n and cannot be edited on this page.',
847 messages[0][2] 869 messages[0][2]
848 ) 870 )
849 self.assertEqual("""<html> 871 self.assertEqual(u"""<html>
850 <p class="hint"><strong>Nota:</strong> Este repositório está definido em 872 <p class="hint"><strong>Nota:</strong> Este repositório está definido em
851 <code><a href="href.wiki(TracIni)">trac.ini</a></code> 873 <code><a href="href.wiki(TracIni)">trac.ini</a></code>
852 e não pode ser editado nesta página.</p> 874 e não pode ser editado nesta página.</p>
853 </html>""", tmpl.generate(editable=False).render()) 875 </html>""".encode('utf-8'), tmpl.generate(editable=False).render(encoding='utf-8'))
854 876
855 def test_extract_i18n_msg_with_py_strip(self): 877 def test_extract_i18n_msg_with_py_strip(self):
856 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 878 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
857 xmlns:i18n="http://genshi.edgewall.org/i18n"> 879 xmlns:i18n="http://genshi.edgewall.org/i18n">
858 <p i18n:msg="" py:strip=""> 880 <p i18n:msg="" py:strip="">
1769 def callback(template): 1791 def callback(template):
1770 translator.setup(template) 1792 translator.setup(template)
1771 loader = TemplateLoader([dirname], callback=callback) 1793 loader = TemplateLoader([dirname], callback=callback)
1772 tmpl = loader.load('tmpl10.html') 1794 tmpl = loader.load('tmpl10.html')
1773 1795
1796 if IS_PYTHON2:
1797 dgettext = translations.dugettext
1798 else:
1799 dgettext = translations.dgettext
1800
1774 self.assertEqual("""<html> 1801 self.assertEqual("""<html>
1775 <div>Included tmpl0</div> 1802 <div>Included tmpl0</div>
1776 <p title="foo_Bar 0">foo_Bar 0</p> 1803 <p title="foo_Bar 0">foo_Bar 0</p>
1777 <p title="bar_Bar">bar_Bar</p> 1804 <p title="bar_Bar">bar_Bar</p>
1778 <p title="Voh">Voh 0</p> 1805 <p title="Voh">Voh 0</p>
1795 <p title="bar_Bar">bar_Bar</p> 1822 <p title="bar_Bar">bar_Bar</p>
1796 <p title="Voh">Voh 3</p> 1823 <p title="Voh">Voh 3</p>
1797 <p title="Voh">Voh 3</p> 1824 <p title="Voh">Voh 3</p>
1798 <p title="Voh">Voh 3</p> 1825 <p title="Voh">Voh 3</p>
1799 </html>""", tmpl.generate(idx=-1, 1826 </html>""", tmpl.generate(idx=-1,
1800 dg=translations.dugettext).render()) 1827 dg=dgettext).render())
1801 finally: 1828 finally:
1802 shutil.rmtree(dirname) 1829 shutil.rmtree(dirname)
1803 1830
1804 1831
1805 class ExtractTestCase(unittest.TestCase): 1832 class ExtractTestCase(unittest.TestCase):
Copyright (C) 2012-2017 Edgewall Software