Coverage for multiurl.py: 30%

59 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-06-07 15:55 +0200

1from __future__ import unicode_literals 

2 

3try: 

4 from django import urls as urlresolvers 

5 from django.urls.resolvers import RegexPattern 

6except ImportError: 

7 # Fallbacks and mocks for Django 1.* 

8 from django.core import urlresolvers 

9 

10 urlresolvers.URLResolver = urlresolvers.RegexURLResolver 

11 

12 def RegexPattern(pattern): 

13 return pattern 

14 

15 

16class ContinueResolving(Exception): 

17 pass 

18 

19 

20def multiurl(*urls, **kwargs): 

21 exceptions = kwargs.get('catch', (ContinueResolving,)) 

22 return MultiRegexURLResolver(urls, exceptions) 

23 

24 

25class MultiRegexURLResolver(urlresolvers.URLResolver): 

26 def __init__(self, urls, exceptions): 

27 super(MultiRegexURLResolver, self).__init__(RegexPattern(''), None) 

28 self._urls = urls 

29 self._exceptions = exceptions 

30 

31 @property 

32 def url_patterns(self): 

33 return self._urls 

34 

35 def resolve(self, path): 

36 tried = [] 

37 matched = [] 

38 patterns_matched = [] 

39 

40 # This is a simplified version of RegexURLResolver. It doesn't 

41 # support a regex prefix, and it doesn't need to handle include(), 

42 # so it's simplier, but otherwise this is mostly a copy/paste. 

43 for pattern in self.url_patterns: 

44 sub_match = pattern.resolve(path) 

45 if sub_match: 

46 # Here's the part that's different: instead of returning the 

47 # first match, build up a list of all matches. 

48 rm = urlresolvers.ResolverMatch(sub_match.func, sub_match.args, sub_match.kwargs, sub_match.url_name) 

49 matched.append(rm) 

50 patterns_matched.append([pattern]) 

51 tried.append([pattern]) 

52 if matched: 

53 return MultiResolverMatch(matched, self._exceptions, patterns_matched, path) 

54 raise urlresolvers.Resolver404({'tried': tried, 'path': path}) 

55 

56 

57class MultiResolverMatch(object): 

58 def __init__(self, matches, exceptions, patterns_matched, path, route='', tried=None): 

59 self.matches = matches 

60 self.exceptions = exceptions 

61 self.patterns_matched = patterns_matched 

62 self.path = path 

63 self.route = route 

64 self.tried = tried 

65 

66 # Attributes to emulate ResolverMatch 

67 self.kwargs = {} 

68 self.args = () 

69 self.url_name = None 

70 self.app_names = [] 

71 self.app_name = None 

72 self.namespaces = [] 

73 

74 @property 

75 def func(self): 

76 def multiview(request): 

77 for i, match in enumerate(self.matches): 

78 try: 

79 return match.func(request, *match.args, **match.kwargs) 

80 except self.exceptions: 

81 continue 

82 raise urlresolvers.Resolver404({'tried': self.patterns_matched, 'path': self.path}) 

83 multiview.multi_resolver_match = self 

84 return multiview