Fixed reverse URL lookup using functions when the original URL pattern was a

string. This is now just as fragile as it was prior to [5609], but works in a
few cases that people were relying on, apparently.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@5632 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-07-08 00:39:32 +00:00
parent 4c011e6f36
commit b6812f2d9d
2 changed files with 20 additions and 20 deletions

View File

@ -38,29 +38,27 @@ def get_callable(lookup_view, can_fail=False):
If can_fail is True, lookup_view might be a URL pattern label, so errors If can_fail is True, lookup_view might be a URL pattern label, so errors
during the import fail and the string is returned. during the import fail and the string is returned.
""" """
try: if not callable(lookup_view):
# Bail out early if lookup_view is not ASCII. This can't be a function. try:
lookup_view = lookup_view.encode('ascii') # Bail early for non-ASCII strings (they can't be functions).
lookup_view = lookup_view.encode('ascii')
if not callable(lookup_view):
mod_name, func_name = get_mod_func(lookup_view) mod_name, func_name = get_mod_func(lookup_view)
try: if func_name != '':
if func_name != '': lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name)
lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name) except (ImportError, AttributeError):
except (ImportError, AttributeError): if not can_fail:
if not can_fail: raise
raise except UnicodeEncodeError:
except UnicodeEncodeError: pass
pass
return lookup_view return lookup_view
get_callable = memoize(get_callable, _callable_cache) get_callable = memoize(get_callable, _callable_cache, 1)
def get_resolver(urlconf): def get_resolver(urlconf):
if urlconf is None: if urlconf is None:
from django.conf import settings from django.conf import settings
urlconf = settings.ROOT_URLCONF urlconf = settings.ROOT_URLCONF
return RegexURLResolver(r'^/', urlconf) return RegexURLResolver(r'^/', urlconf)
get_resolver = memoize(get_resolver, _resolver_cache) get_resolver = memoize(get_resolver, _resolver_cache, 1)
def get_mod_func(callback): def get_mod_func(callback):
# Converts 'django.views.news.stories.story_detail' to # Converts 'django.views.news.stories.story_detail' to

View File

@ -3,18 +3,20 @@ def curry(_curried_func, *args, **kwargs):
return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs)) return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
return _curried return _curried
def memoize(func, cache): def memoize(func, cache, num_args):
""" """
Wrap a function so that results for any argument tuple are stored in Wrap a function so that results for any argument tuple are stored in
'cache'. Note that the args to the function must be usable as dictionary 'cache'. Note that the args to the function must be usable as dictionary
keys. keys.
Only the first num_args are considered when creating the key.
""" """
def wrapper(*args): def wrapper(*args):
if args in cache: mem_args = args[:num_args]
return cache[args] if mem_args in cache:
return cache[mem_args]
result = func(*args) result = func(*args)
cache[args] = result cache[mem_args] = result
return result return result
return wrapper return wrapper