[go: up one dir, main page]

Menu

[r41]: / Paths.py  Maximize  Restore  History

Download this file

126 lines (103 with data), 3.8 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import os
import os.path
import stat
class PathSet(object):
"""Represents an ordered set of unique normalized file paths.
The paths may be the subject to user (~) and variable ($) expansion.
This class fulfills the sequence contract (i.e. len(), x[], iterating etc.).
"""
def __init__(self, *args, **kwds):
"""Construct a set. Any number of either string-like objects or the sequences of
thereof is accepted.
The following keywords are recognized:
userExpand -- (default True)
varExpand -- (default True)
"""
self.paths = []
try:
self.varExpand = kwds["varExpand"]
except KeyError:
self.varExpand = True
try:
self.userExpand = kwds["userExpand"]
except KeyError:
self.userExpand = True
for x in args:
self.append(x)
def __iter__(self):
return self.paths.__iter__()
def __len__(self):
return len(self.paths)
def __str__(self):
paths = self.paths
if len(paths) > 1:
s = str(paths[0])
for x in paths[1:]:
s += ":" + str(x)
elif len(paths) > 0:
s = str(paths[0])
else:
s = ""
return s
def __contains__(self, path):
return self.adopt(path) in self.paths
def __getitem__(self, index):
return self.paths[index]
def __add__(self, other):
x = self.__class__()
x.append(self)
x.append(other)
return x
def __iadd__(self, other):
self.append(other)
return self
def adopt(self, path):
"""Validates the specified path and converts it to a form suitable for inclusion
into the set. Must either return the path or raise ValueError if an inappropriate
path was given.
"""
if self.userExpand and path.startswith("~"):
path = os.path.expanduser(path)
if self.varExpand and "$" in path:
path = os.path.expandvars(path)
path = os.path.normpath(path)
if path in self.paths:
raise ValueError
else:
return path
def append(self, arg):
if isinstance(arg, str):
try:
self.paths.append(self.adopt(arg))
except ValueError:
pass
else:
for x in arg:
self.append(str(x)) # WARNING : a recursive call, stay alert
class ValidPathSet(PathSet):
"""Represents the PathSet of the valid paths. The symbolic links are respected
and have the preference over the real directories they point to.
"""
def adopt(self, path):
path = super(ValidPathSet, self).adopt(path)
try:
st = os.stat(path)
for xst in self.stats:
if os.path.samestat(st, xst):
# FIXME : inefficiency
if os.path.islink(path) and not os.path.islink(
self.stats[xst]):
# In case of real path followed by the symlink to it
# the latter has the preference
self.paths[self.paths.index(self.stats[xst])] = path
del self.stats[xst]
self.stats[st] = path
# In all other cases the path is discarded
raise ValueError # To prevent the appending of the path
self.stats[st] = path
return path
except OSError:
raise ValueError
def __init__(self, *args, **kwds):
self.stats = {}
super(ValidPathSet, self).__init__(*args, **kwds)