Ticket #12201: 12201-3.diff

File 12201-3.diff, 8.3 KB (added by Claude Paroz, 14 years ago)

Refreshed patch and test

  • django/core/management/commands/makemessages.py

    diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
    index 8c73d76..f02a3c8 100644
    a b def make_messages(locale=None, domain='django', verbosity='1', all=False,  
    220220                os.unlink(os.path.join(dirpath, thefile))
    221221            elif domain == 'django' and (file_ext == '.py' or file_ext in extensions):
    222222                thefile = file
     223                orig_file = os.path.join(dirpath, file)
    223224                if file_ext in extensions:
    224                     src = open(os.path.join(dirpath, file), "rU").read()
     225                    src = open(orig_file, "rU").read()
    225226                    thefile = '%s.py' % file
     227                    f = open(os.path.join(dirpath, thefile), "w")
    226228                    try:
    227                         f = open(os.path.join(dirpath, thefile), "w")
    228                         try:
    229                             f.write(templatize(src))
    230                         finally:
    231                             f.close()
    232                     except SyntaxError, msg:
    233                         msg = "%s (file: %s)" % (msg, os.path.join(dirpath, file))
    234                         raise SyntaxError(msg)
     229                        f.write(templatize(src, orig_file[2:]))
     230                    finally:
     231                        f.close()
    235232                if verbosity > 1:
    236233                    sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
    237234                cmd = (
    def make_messages(locale=None, domain='django', verbosity='1', all=False,  
    250247
    251248                if thefile != file:
    252249                    old = '#: '+os.path.join(dirpath, thefile)[2:]
    253                     new = '#: '+os.path.join(dirpath, file)[2:]
     250                    new = '#: '+orig_file[2:]
    254251                    msgs = msgs.replace(old, new)
    255252                if os.path.exists(potfile):
    256253                    # Strip the header
  • django/template/base.py

    diff --git a/django/template/base.py b/django/template/base.py
    index c6d646e..bd500d7 100644
    a b def compile_string(template_string, origin):  
    132132    else:
    133133        lexer_class, parser_class = Lexer, Parser
    134134    lexer = lexer_class(template_string, origin)
    135     parser = parser_class(lexer.tokenize())
     135    tokens = lexer.tokenize()
     136    tokens = zip(*tokens)
     137    if tokens:
     138        tokens = tokens[0]
     139    parser = parser_class(list(tokens))
    136140    return parser.parse()
    137141
    138142class Token(object):
    class Lexer(object):  
    164168    def __init__(self, template_string, origin):
    165169        self.template_string = template_string
    166170        self.origin = origin
     171        self.lineno = 1
    167172
    168173    def tokenize(self):
    169174        "Return a list of tokens from a given template_string."
    class Lexer(object):  
    171176        result = []
    172177        for bit in tag_re.split(self.template_string):
    173178            if bit:
    174                 result.append(self.create_token(bit, in_tag))
     179                result.append((self.create_token(bit, in_tag), self.lineno))
    175180            in_tag = not in_tag
    176181        return result
    177182
    class Lexer(object):  
    193198                token = Token(TOKEN_COMMENT, content)
    194199        else:
    195200            token = Token(TOKEN_TEXT, token_string)
     201        self.lineno += token_string.count('\n')
    196202        return token
    197203
    198204class Parser(object):
  • django/template/debug.py

    diff --git a/django/template/debug.py b/django/template/debug.py
    index a9e3c4f..21ff65e 100644
    a b class DebugLexer(Lexer):  
    1515        for match in tag_re.finditer(self.template_string):
    1616            start, end = match.span()
    1717            if start > upto:
    18                 result.append(self.create_token(self.template_string[upto:start], (upto, start), False))
     18                result.append((self.create_token(self.template_string[upto:start], (upto, start), False), None))
    1919                upto = start
    20             result.append(self.create_token(self.template_string[start:end], (start, end), True))
     20            result.append((self.create_token(self.template_string[start:end], (start, end), True), None))
    2121            upto = end
    2222        last_bit = self.template_string[upto:]
    2323        if last_bit:
    24             result.append(self.create_token(last_bit, (upto, upto + len(last_bit)), False))
     24            result.append((self.create_token(last_bit, (upto, upto + len(last_bit)), False), None))
    2525        return result
    2626
    2727    def create_token(self, token_string, source, in_tag):
  • django/utils/translation/__init__.py

    diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
    index 0e1b4f8..e3edb65 100644
    a b def to_locale(language):  
    104104def get_language_from_request(request):
    105105    return _trans.get_language_from_request(request)
    106106
    107 def templatize(src):
    108     return _trans.templatize(src)
     107def templatize(src, origin=None):
     108    return _trans.templatize(src, origin)
    109109
    110110def deactivate_all():
    111111    return _trans.deactivate_all()
  • django/utils/translation/trans_real.py

    diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
    index 832acc7..6dbe8e3 100644
    a b endblock_re = re.compile(r"""^\s*endblocktrans$""")  
    421421plural_re = re.compile(r"""^\s*plural$""")
    422422constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?'))\)""")
    423423
    424 def templatize(src):
     424def templatize(src, origin=None):
    425425    """
    426426    Turns a Django template into something that is understood by xgettext. It
    427427    does so by translating the Django translation tags into standard gettext
    def templatize(src):  
    435435    plural = []
    436436    incomment = False
    437437    comment = []
    438     for t in Lexer(src, None).tokenize():
     438    for t, lineno in Lexer(src, origin).tokenize():
    439439        if incomment:
    440440            if t.token_type == TOKEN_BLOCK and t.contents == 'endcomment':
    441441                out.write(' # %s' % ''.join(comment))
    def templatize(src):  
    465465                elif pluralmatch:
    466466                    inplural = True
    467467                else:
    468                     raise SyntaxError("Translation blocks must not include other block tags: %s" % t.contents)
     468                    filemsg = ''
     469                    if origin:
     470                        filemsg = 'file %s, ' % origin
     471                    raise SyntaxError("Translation blocks must not include other block tags: %s (%sline %d)" % (t.contents, filemsg, lineno))
    469472            elif t.token_type == TOKEN_VAR:
    470473                if inplural:
    471474                    plural.append('%%(%s)s' % t.contents)
  • tests/regressiontests/i18n/commands/extraction.py

    diff --git a/tests/regressiontests/i18n/commands/extraction.py b/tests/regressiontests/i18n/commands/extraction.py
    index 3e8d2d6..9061863 100644
    a b class BasicExtractorTests(ExtractorTests):  
    5959        self.assertMsgId('I think that 100%% is more that 50%% of anything.', po_contents)
    6060        self.assertMsgId('I think that 100%% is more that 50%% of %\(obj\)s.', po_contents)
    6161
     62    def test_extraction_error(self):
     63        os.chdir(self.test_dir)
     64        shutil.copyfile('./templates/template_with_error.txt', './templates/template_with_error.html')
     65        self.assertRaises(SyntaxError, management.call_command, 'makemessages', locale=LOCALE, verbosity=0)
     66        try:
     67            management.call_command('makemessages', locale=LOCALE, verbosity=0)
     68        except SyntaxError, e:
     69            self.assertEqual(str(e), 'Translation blocks must not include other block tags: blocktrans (file templates/template_with_error.html, line 3)')
     70        finally:
     71            os.remove('./templates/template_with_error.html')
     72            os.remove('./templates/template_with_error.html.py') # Waiting for #8536 to be fixed
     73
    6274
    6375class JavascriptExtractorTests(ExtractorTests):
    6476
  • new file tests/regressiontests/i18n/commands/templates/template_with_error.txt

    diff --git a/tests/regressiontests/i18n/commands/templates/template_with_error.txt b/tests/regressiontests/i18n/commands/templates/template_with_error.txt
    new file mode 100644
    index 0000000..c2b93bd
    - +  
     1{% load i18n %}
     2<p>This template contains an error (no endblocktrans)</p>
     3<p>{% blocktrans %}This should fail{% blocktrans %}</p>
Back to Top