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
This commit is contained in:
parent
5a7af25c7a
commit
23f69af454
|
@ -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
|
||||
f = open(os.path.join(dirpath, thefile), "w")
|
||||
try:
|
||||
f = open(os.path.join(dirpath, thefile), "w")
|
||||
try:
|
||||
f.write(templatize(src))
|
||||
finally:
|
||||
f.close()
|
||||
except SyntaxError, msg:
|
||||
msg = "%s (file: %s)" % (msg, os.path.join(dirpath, file))
|
||||
raise SyntaxError(msg)
|
||||
f.write(templatize(src, orig_file[2:]))
|
||||
finally:
|
||||
f.close()
|
||||
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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{% load i18n %}
|
||||
<p>This template contains an error (no endblocktrans)</p>
|
||||
<p>{% blocktrans %}This should fail{% blocktrans %}</p>
|
Loading…
Reference in New Issue