#18091 closed Bug (fixed)
Non-ASCII templates break `django-admin.py startproject --template=TEMPLATE`
| Reported by: | Antti Kaihola | Owned by: | nobody |
|---|---|---|---|
| Component: | Core (Management commands) | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Clo74, Florian Apolloner, tomas.ehrlich@… | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
If a file in a project template for manage.py startproject --template=TEMPLATE
- has non-ASCII characters in its contents, and
- is named with one of the extensions given in the
--extension=argument,
a UnicodeDecodeError is raised:
$ django-admin.py startproject --template=mytemplate myproject
Traceback (most recent call last):
File "/django/django/bin/django-admin.py", line 5, in <module>
management.execute_from_command_line()
File "django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "django/core/management/__init__.py", line 381, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "django/core/management/base.py", line 195, in run_from_argv
self.execute(*args, **options.__dict__)
File "django/core/management/base.py", line 231, in execute
output = self.handle(*args, **options)
File "django/core/management/commands/startproject.py", line 31, in handle
super(Command, self).handle('project', project_name, target, **options)
File "django/core/management/templates.py", line 161, in handle
new_file.write(content.encode('UTF-8'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 113: ordinal not in range(128)
The content of the template file is read from the disk as a bytestring (line 156) and run through the Django template engine, which outputs the rendered text as a Unicode object (line 159). The Unicode object is then attempted to be written in to a file without encoding it first (line 161).
Files whose extension isn't included in --extension= are read from the disk, not run through the template engine and written back to the destination without any decoding or encoding. For this reason, those files are handled without problems even if they have non-ASCII content.
Attachments (2)
Change History (12)
by , 14 years ago
| Attachment: | 18091-startproject-non-ascii-templates.diff added |
|---|
comment:1 by , 14 years ago
| Summary: | Non-ASCII templates break `manage.py startproject --template=TEMPLATE` → Non-ASCII templates break `django-admin.py startproject --template=TEMPLATE` |
|---|
I accidentally copy-pasted the traceback from a run with a patched Django source tree. This is the correct traceback:
$ django-admin.py startproject --template=project_template g2dt /tmp/g2dt
Traceback (most recent call last):
File "/django/django/bin/django-admin.py", line 5, in <module>
management.execute_from_command_line()
File "django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "django/core/management/__init__.py", line 381, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "django/core/management/base.py", line 195, in run_from_argv
self.execute(*args, **options.__dict__)
File "django/core/management/base.py", line 231, in execute
output = self.handle(*args, **options)
File "django/core/management/commands/startproject.py", line 31, in handle
super(Command, self).handle('project', project_name, target, **options)
File "django/core/management/templates.py", line 161, in handle
new_file.write(content)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 75: ordinal not in range(128)
by , 14 years ago
| Attachment: | 18091-startproject-non-ascii-templates.2.diff added |
|---|
Added a non-ASCII template to the startproject tests
comment:2 by , 13 years ago
| Patch needs improvement: | set |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
Using codecs.open would be better here, instead of encoding it by hand.
comment:3 by , 13 years ago
| Cc: | added |
|---|---|
| Triage Stage: | Accepted → Ready for checkin |
Another try with the help of the codecs library.
See https://github.com/django/django/pull/245/
It added the unit test case from akaihola.
comment:4 by , 13 years ago
| Triage Stage: | Ready for checkin → Accepted |
|---|
Please do not set Ready for checkin for your own patches.
comment:5 by , 13 years ago
The patch in the current form causes the following test failures for me:
florian@apollo13:~/sources/django.git/tests$ PYTHONPATH=.. ./runtests.py --settings=test_sqlite admin_scripts
Creating test database for alias 'default'...
Creating test database for alias 'other'...
.....................................................................................................................................FF......F...F.
======================================================================
FAIL: test_custom_project_template (regressiontests.admin_scripts.tests.StartProject)
Make sure the startproject management command is able to use a different project template
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/florian/sources/django.git/tests/regressiontests/admin_scripts/tests.py", line 1444, in test_custom_project_template
self.assertNoOutput(err)
File "/home/florian/sources/django.git/tests/regressiontests/admin_scripts/tests.py", line 159, in assertNoOutput
self.assertEqual(len(stream), 0, "Stream should be empty: actually contains '%s'" % stream)
AssertionError: Stream should be empty: actually contains 'UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 47: ordinal not in range(128)
'
======================================================================
FAIL: test_custom_project_template_context_variables (regressiontests.admin_scripts.tests.StartProject)
Make sure template context variables are rendered with proper values
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/florian/sources/django.git/tests/regressiontests/admin_scripts/tests.py", line 1537, in test_custom_project_template_context_variables
self.assertNoOutput(err)
File "/home/florian/sources/django.git/tests/regressiontests/admin_scripts/tests.py", line 159, in assertNoOutput
self.assertEqual(len(stream), 0, "Stream should be empty: actually contains '%s'" % stream)
AssertionError: Stream should be empty: actually contains 'UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 47: ordinal not in range(128)
'
======================================================================
FAIL: test_no_escaping_of_project_variables (regressiontests.admin_scripts.tests.StartProject)
Make sure template context variables are not html escaped
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/florian/sources/django.git/tests/regressiontests/admin_scripts/tests.py", line 1554, in test_no_escaping_of_project_variables
self.assertNoOutput(err)
File "/home/florian/sources/django.git/tests/regressiontests/admin_scripts/tests.py", line 159, in assertNoOutput
self.assertEqual(len(stream), 0, "Stream should be empty: actually contains '%s'" % stream)
AssertionError: Stream should be empty: actually contains 'UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 47: ordinal not in range(128)
'
======================================================================
FAIL: test_template_dir_with_trailing_slash (regressiontests.admin_scripts.tests.StartProject)
Ticket 17475: Template dir passed has a trailing path separator
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/florian/sources/django.git/tests/regressiontests/admin_scripts/tests.py", line 1456, in test_template_dir_with_trailing_slash
self.assertNoOutput(err)
File "/home/florian/sources/django.git/tests/regressiontests/admin_scripts/tests.py", line 159, in assertNoOutput
self.assertEqual(len(stream), 0, "Stream should be empty: actually contains '%s'" % stream)
AssertionError: Stream should be empty: actually contains 'UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 47: ordinal not in range(128)
'
----------------------------------------------------------------------
Ran 147 tests in 22.055s
FAILED (failures=4)
Destroying test database for alias 'default'...
Destroying test database for alias 'other'...
Please reopen a pull request once those are fixed, Thx!
comment:6 by , 13 years ago
| Cc: | added |
|---|
comment:7 by , 13 years ago
| Cc: | added |
|---|---|
| Patch needs improvement: | unset |
Tests fixed, https://github.com/django/django/pull/298
comment:8 by , 13 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Avoid UnicodeDecodeError by encoding template engine output in UTF-8