class RegexURLResolver(object): def __init__(self, regex, urlconf_name, default_kwargs=None): # regex is a string representing a regular expression. # urlconf_name is a string representing the module containing urlconfs. self.regex = re.compile(regex, re.UNICODE) self.urlconf_name = urlconf_name self.callback = None self.default_kwargs = default_kwargs or {} self._reverse_dict = MultiValueDict() def __repr__(self): return '<%s %s %s>' % (self.__class__.__name__, self.urlconf_name, self.regex.pattern) def _get_reverse_dict(self): if not self._reverse_dict and hasattr(self.urlconf_module, 'urlpatterns'): try: for pattern in reversed(self.urlconf_module.urlpatterns): p_pattern = pattern.regex.pattern if p_pattern.startswith('^'): p_pattern = p_pattern[1:] if isinstance(pattern, RegexURLResolver): parent = normalize(pattern.regex.pattern) for name in pattern.reverse_dict: for matches, pat in pattern.reverse_dict.getlist(name): new_matches = [] for piece, p_args in parent: new_matches.extend([(piece + suffix, p_args + args) for (suffix, args) in matches]) self._reverse_dict.appendlist(name, (new_matches, p_pattern + pat)) else: bits = normalize(p_pattern) self._reverse_dict.appendlist(pattern.callback, (bits, p_pattern)) self._reverse_dict.appendlist(pattern.name, (bits, p_pattern)) except: self._reverse_dict.clear() raise return self._reverse_dict reverse_dict = property(_get_reverse_dict) def resolve(self, path): tried = [] match = self.regex.search(path) if match: new_path = path[match.end():] for pattern in self.urlconf_module.urlpatterns: try: sub_match = pattern.resolve(new_path) except Resolver404, e: tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0]['tried']]) else: if sub_match: sub_match_dict = dict([(smart_str(k), v) for k, v in match.groupdict().items()]) sub_match_dict.update(self.default_kwargs) for k, v in sub_match[2].iteritems(): sub_match_dict[smart_str(k)] = v return sub_match[0], sub_match[1], sub_match_dict tried.append(pattern.regex.pattern) raise Resolver404, {'tried': tried, 'path': new_path}
def clear(self): self._assert_mutable() MultiValueDict.clear(self)