(self, lookup_view, _prefix, *args, **kwargs)
| 753 | return self._reverse_with_prefix(lookup_view, "", *args, **kwargs) |
| 754 | |
| 755 | def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs): |
| 756 | if args and kwargs: |
| 757 | raise ValueError("Don't mix *args and **kwargs in call to reverse()!") |
| 758 | |
| 759 | if not self._populated: |
| 760 | self._populate() |
| 761 | |
| 762 | possibilities = self.reverse_dict.getlist(lookup_view) |
| 763 | |
| 764 | for possibility, pattern, defaults, converters in possibilities: |
| 765 | for result, params in possibility: |
| 766 | if args: |
| 767 | if len(args) != len(params): |
| 768 | continue |
| 769 | candidate_subs = dict(zip(params, args)) |
| 770 | else: |
| 771 | if set(kwargs).symmetric_difference(params).difference(defaults): |
| 772 | continue |
| 773 | matches = True |
| 774 | for k, v in defaults.items(): |
| 775 | if k in params: |
| 776 | continue |
| 777 | if kwargs.get(k, v) != v: |
| 778 | matches = False |
| 779 | break |
| 780 | if not matches: |
| 781 | continue |
| 782 | candidate_subs = kwargs |
| 783 | # Convert the candidate subs to text using Converter.to_url(). |
| 784 | text_candidate_subs = {} |
| 785 | match = True |
| 786 | for k, v in candidate_subs.items(): |
| 787 | if k in converters: |
| 788 | try: |
| 789 | text_candidate_subs[k] = converters[k].to_url(v) |
| 790 | except ValueError: |
| 791 | match = False |
| 792 | break |
| 793 | else: |
| 794 | text_candidate_subs[k] = str(v) |
| 795 | if not match: |
| 796 | continue |
| 797 | # WSGI provides decoded URLs, without %xx escapes, and the URL |
| 798 | # resolver operates on such URLs. First substitute arguments |
| 799 | # without quoting to build a decoded URL and look for a match. |
| 800 | # Then, if we have a match, redo the substitution with quoted |
| 801 | # arguments in order to return a properly encoded URL. |
| 802 | candidate_pat = _prefix.replace("%", "%%") + result |
| 803 | if re.search( |
| 804 | "^%s%s" % (re.escape(_prefix), pattern), |
| 805 | candidate_pat % text_candidate_subs, |
| 806 | ): |
| 807 | # safe characters from `pchar` definition of RFC 3986 |
| 808 | url = quote( |
| 809 | candidate_pat % text_candidate_subs, |
| 810 | safe=RFC3986_SUBDELIMS + "/~:@", |
| 811 | ) |
| 812 | # Don't allow construction of scheme relative urls. |
no test coverage detected