diff options
Diffstat (limited to 'lbup/_path.py')
-rw-r--r-- | lbup/_path.py | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/lbup/_path.py b/lbup/_path.py new file mode 100644 index 0000000..26c67f8 --- /dev/null +++ b/lbup/_path.py @@ -0,0 +1,57 @@ +class AbsPath: + _components = None + + def __init__(self, path = None, components = None): + if path is not None and components is not None: + raise ValueError('Both path and components provided') + + if path is not None: + if isinstance(path, str): + path = path.encode('utf-8') + if len(path) < 1 or not path.startswith(b'/'): + raise ValueError('Path does not look like valid absolute path', path) + components = list(filter(lambda x: len(x) > 0 and x != b'.', path[1:].split(b'/'))) + if b'..' in components: + raise ValueError('Parent references are not allowed', path) + + self._components = components + + def __bytes__(self): + return self.path + def __repr__(self): + return self.path.decode('utf-8', errors = 'backslashreplace') + + def __contains__(self, item): + c = self.components + ci = item.components + if len(ci) >= len(c) and ci[:len(c)] == c: + return True + return False + + def __eq__(self, other): + return self.components == other.components + + def __len__(self): + return len(self.components) + + @property + def path(self): + return b'/' + b'/'.join(self.components) + + @property + def components(self): + """ + Return a list of path components. + + Note that root does not count as a component, so a path of b'/' returns + an empty list. + """ + return self._components + + def reparent(self, src, dst): + if not self in src: + raise ValueError('Path not in parent', self, src) + tail = self.components[len(src):] + return AbsPath(components = dst.components + tail) + +ROOT = AbsPath('/') |