Commit 23f69af4 authored by Ramiro Morales's avatar Ramiro Morales
Browse files

Fixed #12201 -- Added a lineno attibute to template Token so e.g. we can...

Fixed #12201 -- Added a lineno attibute to template Token so e.g. we can report line numbers in errors during i18n literals extraction. Thanks madewulf for the report and Claude Paroz for the patch.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@14813 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 5a7af25c
Loading
Loading
Loading
Loading
+7 −10
Original line number Diff line number Diff line
@@ -220,18 +220,15 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,
                os.unlink(os.path.join(dirpath, thefile))
            elif domain == 'django' and (file_ext == '.py' or file_ext in extensions):
                thefile = file
                orig_file = os.path.join(dirpath, file)
                if file_ext in extensions:
                    src = open(os.path.join(dirpath, file), "rU").read()
                    src = open(orig_file, "rU").read()
                    thefile = '%s.py' % file
                    try:
                    f = open(os.path.join(dirpath, thefile), "w")
                    try:
                            f.write(templatize(src))
                        f.write(templatize(src, orig_file[2:]))
                    finally:
                        f.close()
                    except SyntaxError, msg:
                        msg = "%s (file: %s)" % (msg, os.path.join(dirpath, file))
                        raise SyntaxError(msg)
                if verbosity > 1:
                    sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
                cmd = (
@@ -250,7 +247,7 @@ def make_messages(locale=None, domain='django', verbosity='1', all=False,

                if thefile != file:
                    old = '#: '+os.path.join(dirpath, thefile)[2:]
                    new = '#: '+os.path.join(dirpath, file)[2:]
                    new = '#: '+orig_file[2:]
                    msgs = msgs.replace(old, new)
                if os.path.exists(potfile):
                    # Strip the header
+4 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ class Token(object):
    def __init__(self, token_type, contents):
        # token_type must be TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK or TOKEN_COMMENT.
        self.token_type, self.contents = token_type, contents
        self.lineno = None

    def __str__(self):
        return '<%s token: "%s...">' % \
@@ -164,6 +165,7 @@ class Lexer(object):
    def __init__(self, template_string, origin):
        self.template_string = template_string
        self.origin = origin
        self.lineno = 1

    def tokenize(self):
        "Return a list of tokens from a given template_string."
@@ -193,6 +195,8 @@ class Lexer(object):
                token = Token(TOKEN_COMMENT, content)
        else:
            token = Token(TOKEN_TEXT, token_string)
        token.lineno = self.lineno
        self.lineno += token_string.count('\n')
        return token

class Parser(object):
+2 −2
Original line number Diff line number Diff line
@@ -104,8 +104,8 @@ def to_locale(language):
def get_language_from_request(request):
    return _trans.get_language_from_request(request)

def templatize(src):
    return _trans.templatize(src)
def templatize(src, origin=None):
    return _trans.templatize(src, origin)

def deactivate_all():
    return _trans.deactivate_all()
+6 −3
Original line number Diff line number Diff line
@@ -421,7 +421,7 @@ endblock_re = re.compile(r"""^\s*endblocktrans$""")
plural_re = re.compile(r"""^\s*plural$""")
constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?'))\)""")

def templatize(src):
def templatize(src, origin=None):
    """
    Turns a Django template into something that is understood by xgettext. It
    does so by translating the Django translation tags into standard gettext
@@ -435,7 +435,7 @@ def templatize(src):
    plural = []
    incomment = False
    comment = []
    for t in Lexer(src, None).tokenize():
    for t in Lexer(src, origin).tokenize():
        if incomment:
            if t.token_type == TOKEN_BLOCK and t.contents == 'endcomment':
                out.write(' # %s' % ''.join(comment))
@@ -465,7 +465,10 @@ def templatize(src):
                elif pluralmatch:
                    inplural = True
                else:
                    raise SyntaxError("Translation blocks must not include other block tags: %s" % t.contents)
                    filemsg = ''
                    if origin:
                        filemsg = 'file %s, ' % origin
                    raise SyntaxError("Translation blocks must not include other block tags: %s (%sline %d)" % (t.contents, filemsg, t.lineno))
            elif t.token_type == TOKEN_VAR:
                if inplural:
                    plural.append('%%(%s)s' % t.contents)
+12 −0
Original line number Diff line number Diff line
@@ -59,6 +59,18 @@ class BasicExtractorTests(ExtractorTests):
        self.assertMsgId('I think that 100%% is more that 50%% of anything.', po_contents)
        self.assertMsgId('I think that 100%% is more that 50%% of %\(obj\)s.', po_contents)

    def test_extraction_error(self):
        os.chdir(self.test_dir)
        shutil.copyfile('./templates/template_with_error.txt', './templates/template_with_error.html')
        self.assertRaises(SyntaxError, management.call_command, 'makemessages', locale=LOCALE, verbosity=0)
        try:
            management.call_command('makemessages', locale=LOCALE, verbosity=0)
        except SyntaxError, e:
            self.assertEqual(str(e), 'Translation blocks must not include other block tags: blocktrans (file templates/template_with_error.html, line 3)')
        finally:
            os.remove('./templates/template_with_error.html')
            os.remove('./templates/template_with_error.html.py') # Waiting for #8536 to be fixed


class JavascriptExtractorTests(ExtractorTests):

Loading