Join a base URL and a possibly relative URL to form an absolute interpretation of the latter.
(base, url, allow_fragments=True)
| 537 | return _coerce_result(url) |
| 538 | |
| 539 | def urljoin(base, url, allow_fragments=True): |
| 540 | """Join a base URL and a possibly relative URL to form an absolute |
| 541 | interpretation of the latter.""" |
| 542 | if not base: |
| 543 | return url |
| 544 | if not url: |
| 545 | return base |
| 546 | |
| 547 | base, url, _coerce_result = _coerce_args(base, url) |
| 548 | bscheme, bnetloc, bpath, bparams, bquery, bfragment = \ |
| 549 | urlparse(base, '', allow_fragments) |
| 550 | scheme, netloc, path, params, query, fragment = \ |
| 551 | urlparse(url, bscheme, allow_fragments) |
| 552 | |
| 553 | if scheme != bscheme or scheme not in uses_relative: |
| 554 | return _coerce_result(url) |
| 555 | if scheme in uses_netloc: |
| 556 | if netloc: |
| 557 | return _coerce_result(urlunparse((scheme, netloc, path, |
| 558 | params, query, fragment))) |
| 559 | netloc = bnetloc |
| 560 | |
| 561 | if not path and not params: |
| 562 | path = bpath |
| 563 | params = bparams |
| 564 | if not query: |
| 565 | query = bquery |
| 566 | return _coerce_result(urlunparse((scheme, netloc, path, |
| 567 | params, query, fragment))) |
| 568 | |
| 569 | base_parts = bpath.split('/') |
| 570 | if base_parts[-1] != '': |
| 571 | # the last item is not a directory, so will not be taken into account |
| 572 | # in resolving the relative path |
| 573 | del base_parts[-1] |
| 574 | |
| 575 | # for rfc3986, ignore all base path should the first character be root. |
| 576 | if path[:1] == '/': |
| 577 | segments = path.split('/') |
| 578 | else: |
| 579 | segments = base_parts + path.split('/') |
| 580 | # filter out elements that would cause redundant slashes on re-joining |
| 581 | # the resolved_path |
| 582 | segments[1:-1] = filter(None, segments[1:-1]) |
| 583 | |
| 584 | resolved_path = [] |
| 585 | |
| 586 | for seg in segments: |
| 587 | if seg == '..': |
| 588 | try: |
| 589 | resolved_path.pop() |
| 590 | except IndexError: |
| 591 | # ignore any .. segments that would otherwise cause an IndexError |
| 592 | # when popped from resolved_path if resolving for rfc3986 |
| 593 | pass |
| 594 | elif seg == '.': |
| 595 | continue |
| 596 | else: |
no test coverage detected