diff -r 87b81b7df7f0 Lib/pathlib.py --- a/Lib/pathlib.py Mon Dec 16 20:22:37 2013 +0100 +++ b/Lib/pathlib.py Mon Dec 16 23:45:44 2013 +0200 @@ -68,17 +68,18 @@ else: if rel and rel != '.': parsed.append(sys.intern(rel)) - if drv or root: - if not drv: - # If no drive is present, try to find one in the previous - # parts. This makes the result of parsing e.g. - # ("C:", "/", "a") reasonably intuitive. - for part in it: - drv = self.splitroot(part)[0] - if drv: - break + if drv: break - if drv or root: + if root: + # If no drive is present, try to find one in the previous + # parts. This makes the result of parsing e.g. + # ("C:", "/", "a") reasonably intuitive. + for part in it: + drv = self.splitroot(part)[0] + if drv: + break + break + if root or drv: parsed.append(drv + root) parsed.reverse() return drv, root, parsed @@ -116,7 +117,6 @@ set(chr(x) for x in range(ord('a'), ord('z') + 1)) | set(chr(x) for x in range(ord('A'), ord('Z') + 1)) ) - ext_namespace_prefix = '\\\\?\\' reserved_names = ( {'CON', 'PRN', 'AUX', 'NUL'} | @@ -184,15 +184,12 @@ # Means fallback on absolute return None - def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix): - prefix = '' - if s.startswith(ext_prefix): - prefix = s[:4] - s = s[4:] - if s.startswith('UNC\\'): - prefix += s[:3] - s = '\\' + s[3:] - return prefix, s + def _split_extended_path(self, s): + if s[:4] == '\\\\?\\': + if s[4:8] == 'UNC\\': + return '\\\\?\\UNC', '\\\\' + s[8:] + return '\\\\?\\', s[4:] + return '', s def _ext_to_normal(self, s): # Turn back an extended path into a normal DOS-like path @@ -205,7 +202,7 @@ # not considered reserved by Windows. if not parts: return False - if parts[0].startswith('\\\\'): + if parts[0][:2] == '\\\\': # UNC paths are never reserved return False return parts[-1].partition('.')[0].upper() in self.reserved_names @@ -523,13 +520,13 @@ self._parts = path._parts def __len__(self): - if self._drv or self._root: + if self._root or self._drv: return len(self._parts) - 1 else: return len(self._parts) def __getitem__(self, idx): - if idx < 0 or idx >= len(self): + if not (0 <= idx < len(self)): raise IndexError(idx) return self._pathcls._from_parsed_parts(self._drv, self._root, self._parts[:-idx - 1]) @@ -607,7 +604,7 @@ @classmethod def _format_parsed_parts(cls, drv, root, parts): - if drv or root: + if root or drv: return drv + root + cls._flavour.join(parts[1:]) else: return cls._flavour.join(parts) @@ -635,8 +632,7 @@ def as_posix(self): """Return the string representation of the path with forward (/) slashes.""" - f = self._flavour - return str(self).replace(f.sep, '/') + return str(self).replace(self._flavour.sep, '/') def __bytes__(self): """Return the bytes representation of the path. This is only @@ -705,14 +701,15 @@ @property def anchor(self): """The concatenation of the drive and root, or ''.""" - anchor = self._drv + self._root - return anchor + return self._drv + self._root @property def name(self): """The final path component, if any.""" parts = self._parts - if len(parts) == (1 if (self._drv or self._root) else 0): + if not parts: + return '' + if (self._root or self._drv) and len(parts) == 1: return '' return parts[-1] @@ -730,7 +727,7 @@ def suffixes(self): """A list of the final component's suffixes, if any.""" name = self.name - if name.endswith('.'): + if not name or name[-1] == '.': return [] name = name.lstrip('.') return ['.' + suffix for suffix in name.split('.')[1:]] @@ -780,23 +777,17 @@ parts = self._parts drv = self._drv root = self._root - if drv or root: - if root: - abs_parts = [drv, root] + parts[1:] - else: - abs_parts = [drv] + parts[1:] + if root: + abs_parts = [drv, root] + parts[1:] else: abs_parts = parts to_drv, to_root, to_parts = self._parse_args(other) - if to_drv or to_root: - if to_root: - to_abs_parts = [to_drv, to_root] + to_parts[1:] - else: - to_abs_parts = [to_drv] + to_parts[1:] + if to_root: + to_abs_parts = [to_drv, to_root] + to_parts[1:] else: to_abs_parts = to_parts n = len(to_abs_parts) - if n == 0 and (drv or root) or abs_parts[:n] != to_abs_parts: + if not n and (root or drv) or abs_parts[:n] != to_abs_parts: formatted = self._format_parsed_parts(to_drv, to_root, to_parts) raise ValueError("{!r} does not start with {!r}" .format(str(self), str(formatted))) @@ -834,7 +825,7 @@ drv = self._drv root = self._root parts = self._parts - if len(parts) == 1 and (drv or root): + if (root or drv) and len(parts) == 1: return self return self._from_parsed_parts(drv, root, parts[:-1]) @@ -869,14 +860,15 @@ if root and root != cf(self._root): return False parts = self._cparts - if drv or root: + if root or drv: if len(pat_parts) != len(parts): return False pat_parts = pat_parts[1:] elif len(pat_parts) > len(parts): return False + match = fnmatch.fnmatchcase for part, pat in zip(reversed(parts), reversed(pat_parts)): - if not fnmatch.fnmatchcase(part, pat): + if not match(part, pat): return False return True @@ -979,7 +971,7 @@ """ pattern = self._flavour.casefold(pattern) drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) - if drv or root: + if root or drv: raise NotImplementedError("Non-relative patterns are unsupported") selector = _make_selector(tuple(pattern_parts)) for p in selector.select_from(self): @@ -991,7 +983,7 @@ """ pattern = self._flavour.casefold(pattern) drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) - if drv or root: + if root or drv: raise NotImplementedError("Non-relative patterns are unsupported") selector = _make_selector(("**",) + tuple(pattern_parts)) for p in selector.select_from(self):