Ticket #20757: patch_commit_86a42e712a0e.patch
File patch_commit_86a42e712a0e.patch, 7.1 KB (added by , 11 years ago) |
---|
-
django/core/urlresolvers.py
diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py index b7017e47b91115db23f2406d0b4a825ca55a272a..f599cf83ddf2ec19e5ea4b8a8b19bce2adba595a 100644
a b from threading import local 13 13 14 14 from django.http import Http404 15 15 from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist 16 from django.utils.datastructures import MultiValueDict 16 from django.utils.datastructures import MultiValueDict, NameIndexedIterable 17 17 from django.utils.encoding import force_str, force_text, iri_to_uri 18 18 from django.utils.functional import memoize, lazy 19 19 from django.utils.http import urlquote … … class RegexURLPattern(LocaleRegexProvider): 229 229 self._callback = get_callable(self._callback_str) 230 230 return self._callback 231 231 232 233 class URLEntry(NameIndexedIterable): 234 state_class = tuple 235 keys = ('urlbits', 'p_pattern', 'pattern.default') 236 237 def __repr__(self): 238 return "<URLEntry: %s>" % self.state.__repr__() 239 240 241 class URLBit(NameIndexedIterable): 242 state_class = tuple 243 keys = ('format', 'argument_names') 244 245 def __repr__(self): 246 return "<URLBit: %s>" % self.state.__repr__() 247 248 232 249 class RegexURLResolver(LocaleRegexProvider): 233 250 def __init__(self, regex, urlconf_name, default_kwargs=None, app_name=None, namespace=None): 234 251 LocaleRegexProvider.__init__(self, regex) … … class RegexURLResolver(LocaleRegexProvider): 269 286 if pattern.app_name: 270 287 apps.setdefault(pattern.app_name, []).append(pattern.namespace) 271 288 else: 272 parent = normalize(pattern.regex.pattern)289 parent = [URLBit(*p) for p in normalize(pattern.regex.pattern)] 273 290 for name in pattern.reverse_dict: 274 291 for matches, pat, defaults in pattern.reverse_dict.getlist(name): 275 292 new_matches = [] 276 293 for piece, p_args in parent: 277 new_matches.extend([ (piece + suffix, p_args + args) for (suffix, args) in matches])278 lookups.appendlist(name, (new_matches, p_pattern + pat, dict(defaults, **pattern.default_kwargs)))294 new_matches.extend([URLBit(piece + suffix, p_args + args) for (suffix, args) in matches]) 295 lookups.appendlist(name, URLEntry(new_matches, p_pattern + pat, dict(defaults, **pattern.default_kwargs))) 279 296 for namespace, (prefix, sub_pattern) in pattern.namespace_dict.items(): 280 297 namespaces[namespace] = (p_pattern + prefix, sub_pattern) 281 298 for app_name, namespace_list in pattern.app_dict.items(): 282 299 apps.setdefault(app_name, []).extend(namespace_list) 283 300 else: 284 bits = normalize(p_pattern)285 lookups.appendlist(pattern.callback, (bits, p_pattern, pattern.default_args))301 bits = [URLBit(*p) for p in normalize(p_pattern)] 302 lookups.appendlist(pattern.callback, URLEntry(bits, p_pattern, pattern.default_args)) 286 303 if pattern.name is not None: 287 lookups.appendlist(pattern.name, (bits, p_pattern, pattern.default_args))304 lookups.appendlist(pattern.name, URLEntry(bits, p_pattern, pattern.default_args)) 288 305 self._reverse_dict[language_code] = lookups 289 306 self._namespace_dict[language_code] = namespaces 290 307 self._app_dict[language_code] = apps … … def is_valid_path(path, urlconf=None): 574 591 return True 575 592 except Resolver404: 576 593 return False 594 595 def get_urlformat(urlname): 596 """ 597 Given a URL name, returns the URL as a string suitable for string.format. 598 599 Example:: 600 601 urlpatterns = patterns('', 602 url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url2"), 603 ) 604 605 >>> get_urlformat('named-url2') 606 '/extra/%(extra)s/' 607 """ 608 urlconf = get_urlconf() 609 resolver = get_resolver(urlconf) 610 urlbit = resolver.reverse_dict[urlname].urlbits[0] 611 return "%s%s" % (get_script_prefix(), urlbit.format) -
django/utils/datastructures.py
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index 3b1638392c08bf5fed640cdea67d5559a971a584..56bfd54a31f725c49ec7d2b1182eb17a156cb32d 100644
a b class DictWrapper(dict): 496 496 if use_func: 497 497 return self.func(value) 498 498 return value 499 500 501 class NameIndexedIterable(object): 502 """ 503 An Iterable (most likely a list or tuple), whose indexes can be referred 504 by name. 505 """ 506 state_class = list 507 keys = list() 508 509 def __init__(self, *args, **kwargs): 510 updated_args = list(args) 511 for i, keyword in enumerate(self.keys): 512 if keyword in kwargs: 513 updated_args[i] = kwargs[keyword] 514 else: 515 break 516 self.state = self.state_class(updated_args) 517 super(NameIndexedIterable, self).__init__() 518 519 def __getitem__(self, index): 520 if index < len(self.state): 521 return self.state[index] 522 else: 523 raise IndexError 524 525 def __setitem__(self, index, value): 526 if index < len(self.state): 527 self.state[index] = value 528 else: 529 raise IndexError 530 531 def __getattr__(self, attr): 532 if attr in self.keys: 533 return self.state[self.keys.index(attr)] 534 return super(NameIndexedIterable, self).__getattr__(attr) 535 536 def __setattr__(self, attr, value): 537 if attr in self.keys: 538 self.state[self.keys.index(attr)] = value 539 return super(NameIndexedIterable, self).__setattr__(attr, value) 540 541 def __repr__(self): 542 return self.state.__repr__() -
tests/urlpatterns_reverse/tests.py
diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index 222ebe053b1362afca1c9962cc2b4e3fbc908b55..e265e7659e26bc305cd93a23f7491a3721a72965 100644
a b from django.conf import settings 9 9 from django.contrib.auth.models import User 10 10 from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist 11 11 from django.core.urlresolvers import (reverse, resolve, get_callable, 12 get_resolver, NoReverseMatch, Resolver404, ResolverMatch, RegexURLResolver,13 RegexURL Pattern)12 get_resolver, get_urlformat, NoReverseMatch, Resolver404, ResolverMatch, 13 RegexURLResolver, RegexURLPattern) 14 14 from django.http import HttpRequest, HttpResponseRedirect, HttpResponsePermanentRedirect 15 15 from django.shortcuts import redirect 16 16 from django.test import TestCase … … class ViewLoadingTests(TestCase): 644 644 self.assertRaises(AttributeError, get_callable, 645 645 'urlpatterns_reverse.views_broken.i_am_broken') 646 646 647 648 class URLObjects(TestCase): 649 urls = 'urlpatterns_reverse.named_urls' 650 651 def test_URL_objects(self): 652 format = get_urlformat('named-url2') 653 self.assertEqual(format, '/extra/%(extra)s/')