#!/usr/bin/python
# -*- encoding: utf-8 -*-
from __future__ import with_statement
import os
import os.path
class ChangeDirectory(object):
"""
ChangeDirectory is a context manager that allowing
you to temporary change the working directory.
>>> import tempfile
>>> td = os.path.realpath(tempfile.mkdtemp())
>>> currentdirectory = os.getcwd()
>>> with ChangeDirectory(td) as cd:
... assert cd.current == td
... assert os.getcwd() == td
... assert cd.previous == currentdirectory
... assert os.path.normpath(os.path.join(cd.current, cd.relative)) == cd.previous
...
>>> assert os.getcwd() == currentdirectory
>>> with ChangeDirectory(td) as cd:
... os.mkdir('foo')
... with ChangeDirectory('foo') as cd2:
... assert cd2.previous == cd.current
... assert cd2.relative == '..'
... assert os.getcwd() == os.path.join(td, 'foo')
... assert os.getcwd() == td
... assert cd.current == td
... os.rmdir('foo')
...
>>> os.rmdir(td)
>>> with ChangeDirectory('.') as cd:
... assert cd.current == currentdirectory
... assert cd.current == cd.previous
... assert cd.relative == '.'
"""
def __init__(self, directory):
self._dir = directory
self._cwd = os.getcwd()
self._pwd = self._cwd
@property
def current(self):
return self._cwd
@property
def previous(self):
return self._pwd
@property
def relative(self):
c = self._cwd.split(os.path.sep)
p = self._pwd.split(os.path.sep)
l = min(len(c), len(p))
i = 0
while i < l and c[i] == p[i]:
i += 1
return os.path.normpath(os.path.join(*(['.'] + (['..'] * (len(c) - i)) + p[i:])))
def __enter__(self):
self._pwd = self._cwd
os.chdir(self._dir)
self._cwd = os.getcwd()
return self
def __exit__(self, *args):
os.chdir(self._pwd)
self._cwd = self._pwd
if __name__ == '__main__':
import doctest
doctest.testmod()