Split a pathname into drive/UNC sharepoint and relative path specifiers. Returns a 2-tuple (drive_or_unc, path); either part may be empty. If you assign result = splitdrive(p) It is always true that: result[0] + result[1] == p If the path contained a drive l
(p)
| 152 | # colon) and the path specification. |
| 153 | # It is always true that drivespec + pathspec == p |
| 154 | def splitdrive(p): |
| 155 | """Split a pathname into drive/UNC sharepoint and relative path specifiers. |
| 156 | Returns a 2-tuple (drive_or_unc, path); either part may be empty. |
| 157 | |
| 158 | If you assign |
| 159 | result = splitdrive(p) |
| 160 | It is always true that: |
| 161 | result[0] + result[1] == p |
| 162 | |
| 163 | If the path contained a drive letter, drive_or_unc will contain everything |
| 164 | up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir") |
| 165 | |
| 166 | If the path contained a UNC path, the drive_or_unc will contain the host name |
| 167 | and share up to but not including the fourth directory separator character. |
| 168 | e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir") |
| 169 | |
| 170 | Paths cannot contain both a drive letter and a UNC path. |
| 171 | |
| 172 | """ |
| 173 | p = os.fspath(p) |
| 174 | if len(p) >= 2: |
| 175 | if isinstance(p, bytes): |
| 176 | sep = b'\\' |
| 177 | altsep = b'/' |
| 178 | colon = b':' |
| 179 | unc_prefix = b'\\\\?\\UNC\\' |
| 180 | else: |
| 181 | sep = '\\' |
| 182 | altsep = '/' |
| 183 | colon = ':' |
| 184 | unc_prefix = '\\\\?\\UNC\\' |
| 185 | normp = p.replace(altsep, sep) |
| 186 | if normp[0:2] == sep * 2: |
| 187 | # UNC drives, e.g. \\server\share or \\?\UNC\server\share |
| 188 | # Device drives, e.g. \\.\device or \\?\device |
| 189 | start = 8 if normp[:8].upper() == unc_prefix else 2 |
| 190 | index = normp.find(sep, start) |
| 191 | if index == -1: |
| 192 | return p, p[:0] |
| 193 | index2 = normp.find(sep, index + 1) |
| 194 | if index2 == -1: |
| 195 | return p, p[:0] |
| 196 | return p[:index2], p[index2:] |
| 197 | if normp[1:2] == colon: |
| 198 | # Drive-letter drives, e.g. X: |
| 199 | return p[:2], p[2:] |
| 200 | return p[:0], p |
| 201 | |
| 202 | |
| 203 | # Split a path in head (everything up to the last '/') and tail (the |