4 from __future__ import with_statement
13 import cStringIO as StringIO
18 @contextlib.contextmanager
19 def change_directory(directory):
20 previousDirectory = os.getcwd()
22 currentDirectory = os.getcwd()
25 yield previousDirectory, currentDirectory
27 os.chdir(previousDirectory)
30 @contextlib.contextmanager
31 def pickled(filename):
33 Here is an example usage:
34 with pickled("foo.db") as p:
35 p("users", list).append(["srid", "passwd", 23])
38 if os.path.isfile(filename):
39 data = pickle.load(open(filename))
43 def getter(item, factory):
47 data[item] = factory()
52 pickle.dump(data, open(filename, "w"))
55 @contextlib.contextmanager
56 def redirect(object_, attr, value):
59 ... with redirect(sys, 'stdout', open('stdout', 'w')):
62 >>> print "we're back"
65 orig = getattr(object_, attr)
66 setattr(object_, attr, value)
70 setattr(object_, attr, orig)
75 >>> pathsplit("/a/b/c")
77 >>> pathsplit("./plugins/builtins.ini")
78 ['.', 'plugins', 'builtins.ini']
80 pathParts = path.split(os.path.sep)
84 def commonpath(l1, l2, common=None):
86 >>> commonpath(pathsplit('/a/b/c/d'), pathsplit('/a/b/c1/d1'))
87 (['', 'a', 'b'], ['c', 'd'], ['c1', 'd1'])
88 >>> commonpath(pathsplit("./plugins/"), pathsplit("./plugins/builtins.ini"))
89 (['.', 'plugins'], [''], ['builtins.ini'])
90 >>> commonpath(pathsplit("./plugins/builtins"), pathsplit("./plugins"))
91 (['.', 'plugins'], ['builtins'], [])
99 for i, (leftDir, rightDir) in enumerate(zip(l1, l2)):
100 if leftDir != rightDir:
101 return l1[0:i], l1[i:], l2[i:]
103 if leftDir == rightDir:
105 return l1[0:i], l1[i:], l2[i:]
110 >>> relpath('/', '/')
112 >>> relpath('/a/b/c/d', '/')
114 >>> relpath('/a/b/c/d', '/a/b/c1/d1')
116 >>> relpath('/a/b/c/d', '/a/b/c1/d1/')
118 >>> relpath("./plugins/builtins", "./plugins")
120 >>> relpath("./plugins/", "./plugins/builtins.ini")
123 sourcePath = os.path.normpath(p1)
124 destPath = os.path.normpath(p2)
126 (common, sourceOnly, destOnly) = commonpath(pathsplit(sourcePath), pathsplit(destPath))
127 if len(sourceOnly) or len(destOnly):
128 relParts = itertools.chain(
129 (('..' + os.sep) * len(sourceOnly), ),
132 return os.path.join(*relParts)
137 class UTF8Recoder(object):
139 Iterator that reads an encoded stream and reencodes the input to UTF-8
141 def __init__(self, f, encoding):
142 self.reader = codecs.getreader(encoding)(f)
148 return self.reader.next().encode("utf-8")
151 class UnicodeReader(object):
153 A CSV reader which will iterate over lines in the CSV file "f",
154 which is encoded in the given encoding.
157 def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
158 f = UTF8Recoder(f, encoding)
159 self.reader = csv.reader(f, dialect=dialect, **kwds)
162 row = self.reader.next()
163 return [unicode(s, "utf-8") for s in row]
168 class UnicodeWriter(object):
170 A CSV writer which will write rows to CSV file "f",
171 which is encoded in the given encoding.
174 def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
175 # Redirect output to a queue
176 self.queue = StringIO.StringIO()
177 self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
179 self.encoder = codecs.getincrementalencoder(encoding)()
181 def writerow(self, row):
182 self.writer.writerow([s.encode("utf-8") for s in row])
183 # Fetch UTF-8 output from the queue ...
184 data = self.queue.getvalue()
185 data = data.decode("utf-8")
186 # ... and reencode it into the target encoding
187 data = self.encoder.encode(data)
188 # write to the target stream
189 self.stream.write(data)
191 self.queue.truncate(0)
193 def writerows(self, rows):
198 def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
199 # csv.py doesn't do Unicode; encode temporarily as UTF-8:
200 csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
201 dialect=dialect, **kwargs)
202 for row in csv_reader:
203 # decode UTF-8 back to Unicode, cell by cell:
204 yield [unicode(cell, 'utf-8') for cell in row]
207 def utf_8_encoder(unicode_csv_data):
208 for line in unicode_csv_data:
209 yield line.encode('utf-8')