Code

Opened 3 years ago

Closed 3 years ago

#16086 closed Uncategorized (invalid)

Unicode string used for module name when doing imports.

Reported by: grahamd Owned by: nobody
Component: Uncategorized Version: 1.3
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX:

Description

The equivalence of ASCII strings whether they be held as standard byte string or Unicode string means this in practice likely doesn't cause a problem, but Unicode strings are used for module names when performing module imports in certain cases.

Specifically, it seems that when importing template tag libraries named at the top of a template are imported, the constructed name of the module is passed as Unicode string.

Environment:


Request Method: GET
Request URL: http://django-3.example.com/admin/

Django Version: 1.3
Python Version: 2.6.1
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.admin',
 'xsllist']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/contrib/admin/sites.py" in wrapper
  214.                 return self.admin_view(view, cacheable)(*args, **kwargs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/utils/decorators.py" in _wrapped_view
  93.                     response = view_func(request, *args, **kwargs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/views/decorators/cache.py" in _wrapped_view_func
  79.         response = view_func(request, *args, **kwargs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/contrib/admin/sites.py" in inner
  196.                 return self.login(request)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/views/decorators/cache.py" in _wrapped_view_func
  79.         response = view_func(request, *args, **kwargs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/contrib/admin/sites.py" in login
  331.         return login(request, **defaults)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/utils/decorators.py" in _wrapped_view
  93.                     response = view_func(request, *args, **kwargs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/views/decorators/cache.py" in _wrapped_view_func
  79.         response = view_func(request, *args, **kwargs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/contrib/auth/views.py" in login
  69.                               context_instance=RequestContext(request, current_app=current_app))
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/shortcuts/__init__.py" in render_to_response
  20.     return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/loader.py" in render_to_string
  181.         t = get_template(template_name)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/loader.py" in get_template
  157.     template, origin = find_template(template_name)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/loader.py" in find_template
  134.             source, display_name = loader(name, dirs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/loader.py" in __call__
  42.         return self.load_template(template_name, template_dirs)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/loader.py" in load_template
  48.             template = get_template_from_string(source, origin, template_name)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/loader.py" in get_template_from_string
  168.     return Template(source, origin, name)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/base.py" in __init__
  108.         self.nodelist = compile_string(template_string, origin)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/base.py" in compile_string
  136.     return parser.parse()
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/base.py" in parse
  239.                     compiled_result = compile_func(self, token)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/loader_tags.py" in do_extends
  214.     nodelist = parser.parse()
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/base.py" in parse
  239.                     compiled_result = compile_func(self, token)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/loader_tags.py" in do_block
  192.     nodelist = parser.parse(('endblock', 'endblock %s' % block_name))
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/base.py" in parse
  239.                     compiled_result = compile_func(self, token)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/defaulttags.py" in load
  1050.                 lib = get_library(taglib)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/base.py" in get_library
  1007.             lib = import_library(taglib_module)
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/template/base.py" in import_library
  959.         if not module_has_submodule(app_module, taglib):
File "/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/utils/module_loading.py" in module_has_submodule
  15.         if finder.find_module(name):

Exception Type: TypeError at /admin/
Exception Value: find_module() argument 1 must be str, not unicode

At lowest level the locals being:

module_name	u'adminmedia'
name	u'django.templatetags.adminmedia'
finder	<topsecret.ImportHookFinder object at 0x10069e108>
package	<module 'django.templatetags' from '/Library/WebServer/Sites/django-3/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/templatetags/__init__.pyc'>

Only causing an issue in this case as the PEP 302 Importer, implemented in C code, was being overly strict in expecting a string object. The importer will be made to be more lenient and convert Unicode to string with default encoding.

So, reporting this only because it doesn't seem right that Unicode strings used when doing imports.

Attachments (0)

Change History (1)

comment:1 Changed 3 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

If I understand correctly, you have written a custom import hook, and you expect its find_module method to receive a str and not an unicode.

However, PEP 302 says nothing on this topic.

imp.find_module, the most similar function I could find in Python, happily accepts and basestr:

>>> import imp
>>> import sys
>>> sys.modules['imp']
<module 'imp' (built-in)>
>>> sys.modules[u'imp']
<module 'imp' (built-in)>
>>> imp.find_module('imp')
(None, 'imp', ('', '', 6))
>>> imp.find_module(u'imp')
(None, 'imp', ('', '', 6))

In my opinion, the fix belongs in your importer, not in Django.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.