mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	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:
		| @@ -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> | ||||
		Reference in New Issue
	
	Block a user