Return a relative version of a path
(path, start=None)
| 742 | supports_unicode_filenames = True |
| 743 | |
| 744 | def relpath(path, start=None): |
| 745 | """Return a relative version of a path""" |
| 746 | path = os.fspath(path) |
| 747 | if not path: |
| 748 | raise ValueError("no path specified") |
| 749 | |
| 750 | if isinstance(path, bytes): |
| 751 | sep = b'\\' |
| 752 | curdir = b'.' |
| 753 | pardir = b'..' |
| 754 | else: |
| 755 | sep = '\\' |
| 756 | curdir = '.' |
| 757 | pardir = '..' |
| 758 | |
| 759 | if start is None: |
| 760 | start = curdir |
| 761 | else: |
| 762 | start = os.fspath(start) |
| 763 | |
| 764 | try: |
| 765 | start_abs = abspath(start) |
| 766 | path_abs = abspath(path) |
| 767 | start_drive, _, start_rest = splitroot(start_abs) |
| 768 | path_drive, _, path_rest = splitroot(path_abs) |
| 769 | if normcase(start_drive) != normcase(path_drive): |
| 770 | raise ValueError("path is on mount %r, start on mount %r" % ( |
| 771 | path_drive, start_drive)) |
| 772 | |
| 773 | start_list = start_rest.split(sep) if start_rest else [] |
| 774 | path_list = path_rest.split(sep) if path_rest else [] |
| 775 | # Work out how much of the filepath is shared by start and path. |
| 776 | i = 0 |
| 777 | for e1, e2 in zip(start_list, path_list): |
| 778 | if normcase(e1) != normcase(e2): |
| 779 | break |
| 780 | i += 1 |
| 781 | |
| 782 | rel_list = [pardir] * (len(start_list)-i) + path_list[i:] |
| 783 | if not rel_list: |
| 784 | return curdir |
| 785 | return sep.join(rel_list) |
| 786 | except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning): |
| 787 | genericpath._check_arg_types('relpath', path, start) |
| 788 | raise |
| 789 | |
| 790 | |
| 791 | # Return the longest common sub-path of the iterable of paths given as input. |
no test coverage detected
searching dependent graphs…