1import os
2import sys
3
4try:
5    from functools import wraps
6except ImportError:
7    # only needed for Python 2.4
8    def wraps(_):
9        def _wraps(func):
10            return func
11        return _wraps
12
13__unittest = True
14
15
16def _relpath_nt(path, start=os.path.curdir):
17    """Return a relative version of a path"""
18
19    if not path:
20        raise ValueError("no path specified")
21    start_list = os.path.abspath(start).split(os.path.sep)
22    path_list = os.path.abspath(path).split(os.path.sep)
23    if start_list[0].lower() != path_list[0].lower():
24        unc_path, rest = os.path.splitunc(path)
25        unc_start, rest = os.path.splitunc(start)
26        if bool(unc_path) ^ bool(unc_start):
27            raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
28                             % (path, start))
29        else:
30            raise ValueError("path is on drive %s, start on drive %s"
31                             % (path_list[0], start_list[0]))
32    # Work out how much of the filepath is shared by start and path.
33    for i in range(min(len(start_list), len(path_list))):
34        if start_list[i].lower() != path_list[i].lower():
35            break
36    else:
37        i += 1
38
39    rel_list = [os.path.pardir] * (len(start_list) - i) + path_list[i:]
40    if not rel_list:
41        return os.path.curdir
42    return os.path.join(*rel_list)
43
44# default to posixpath definition
45
46
47def _relpath_posix(path, start=os.path.curdir):
48    """Return a relative version of a path"""
49
50    if not path:
51        raise ValueError("no path specified")
52
53    start_list = os.path.abspath(start).split(os.path.sep)
54    path_list = os.path.abspath(path).split(os.path.sep)
55
56    # Work out how much of the filepath is shared by start and path.
57    i = len(os.path.commonprefix([start_list, path_list]))
58
59    rel_list = [os.path.pardir] * (len(start_list) - i) + path_list[i:]
60    if not rel_list:
61        return os.path.curdir
62    return os.path.join(*rel_list)
63
64if os.path is sys.modules.get('ntpath'):
65    relpath = _relpath_nt
66else:
67    relpath = _relpath_posix
68