Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1152)

Side by Side Diff: client/utils/zip_package.py

Issue 2093593002: luci-py: Making __file__ usage unicode safe. (Closed) Base URL: https://github.com/luci/luci-py.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « client/utils/oauth.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2013 The LUCI Authors. All rights reserved. 1 # Copyright 2013 The LUCI Authors. All rights reserved.
2 # Use of this source code is governed under the Apache License, Version 2.0 2 # Use of this source code is governed under the Apache License, Version 2.0
3 # that can be found in the LICENSE file. 3 # that can be found in the LICENSE file.
4 4
5 """Utilities to work with importable python zip packages.""" 5 """Utilities to work with importable python zip packages."""
6 6
7 import atexit 7 import atexit
8 import collections 8 import collections
9 import cStringIO as StringIO 9 import cStringIO as StringIO
10 import hashlib 10 import hashlib
(...skipping 15 matching lines...) Expand all
26 # Ignore precompiled python files since they depend on python version and we 26 # Ignore precompiled python files since they depend on python version and we
27 # don't want zip package to be version-depended. 27 # don't want zip package to be version-depended.
28 r'.*\.pyc$', 28 r'.*\.pyc$',
29 r'.*\.pyo$', 29 r'.*\.pyo$',
30 ) 30 )
31 31
32 32
33 # Temporary files extracted by extract_resource. Removed in atexit hook. 33 # Temporary files extracted by extract_resource. Removed in atexit hook.
34 _extracted_files = [] 34 _extracted_files = []
35 _extracted_files_lock = threading.Lock() 35 _extracted_files_lock = threading.Lock()
36 36
M-A Ruel 2016/06/23 13:09:54 add another empty line above.
mithro 2016/06/24 03:22:42 Done.
37 # Patch zipimport.zipimporter hook to accept unicode strings
38 def zipimporter_unicode(archivepath):
39 if isinstance(archivepath, unicode):
40 archivepath = archivepath.encode(sys.getfilesystemencoding())
41 return zipimport.zipimporter(archivepath)
42
43 for i, hook in enumerate(sys.path_hooks):
44 if hook is zipimport.zipimporter:
45 sys.path_hooks[i] = zipimporter_unicode
M-A Ruel 2016/06/23 13:09:54 sadness
mithro 2016/06/24 03:22:42 Yeah :( It works properly in Python 3...
46
37 47
38 class ZipPackageError(RuntimeError): 48 class ZipPackageError(RuntimeError):
39 """Failed to create a zip package.""" 49 """Failed to create a zip package."""
40 50
41 51
42 class ZipPackage(object): 52 class ZipPackage(object):
43 """A set of files that can be zipped to file on disk or into memory buffer. 53 """A set of files that can be zipped to file on disk or into memory buffer.
44 54
45 Usage: 55 Usage:
46 package = ZipPackage(root) 56 package = ZipPackage(root)
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 def get_main_script_path(): 241 def get_main_script_path():
232 """If running from zip returns path to a zip file, else path to __main__. 242 """If running from zip returns path to a zip file, else path to __main__.
233 243
234 Basically returns path to a file passed to python for execution 244 Basically returns path to a file passed to python for execution
235 as in 'python <main_script>' considering a case of executable zip package. 245 as in 'python <main_script>' considering a case of executable zip package.
236 246
237 Returns path relative to a current directory of when process was started. 247 Returns path relative to a current directory of when process was started.
238 """ 248 """
239 # If running from interactive console __file__ is not defined. 249 # If running from interactive console __file__ is not defined.
240 main = sys.modules['__main__'] 250 main = sys.modules['__main__']
241 return get_module_zip_archive(main) or getattr(main, '__file__', None) 251 path = get_module_zip_archive(main)
252 if path:
253 return path
254
255 path = getattr(main, '__file__', None)
256 if path:
257 return path.decode(sys.getfilesystemencoding())
242 258
243 259
244 def _write_temp_data(name, data, temp_dir): 260 def _write_temp_data(name, data, temp_dir):
245 """Writes content-addressed file in `temp_dir` if relevant.""" 261 """Writes content-addressed file in `temp_dir` if relevant."""
246 filename = '%s-%s' % (hashlib.sha1(data).hexdigest(), name) 262 filename = '%s-%s' % (hashlib.sha1(data).hexdigest(), name)
247 filepath = os.path.join(temp_dir, filename) 263 filepath = os.path.join(temp_dir, filename)
248 if os.path.isfile(filepath): 264 if os.path.isfile(filepath):
249 with open(filepath, 'rb') as f: 265 with open(filepath, 'rb') as f:
250 if f.read() == data: 266 if f.read() == data:
251 # It already exists. 267 # It already exists.
(...skipping 20 matching lines...) Expand all
272 package: is a python module object that represents a package. 288 package: is a python module object that represents a package.
273 resource: should be a relative filename, using '/'' as the path separator. 289 resource: should be a relative filename, using '/'' as the path separator.
274 temp_dir: if set, it will extra the file in this directory with the filename 290 temp_dir: if set, it will extra the file in this directory with the filename
275 being the hash of the content. Otherwise, it uses tempfile.mkstemp(). 291 being the hash of the content. Otherwise, it uses tempfile.mkstemp().
276 292
277 Raises ValueError if no such resource. 293 Raises ValueError if no such resource.
278 """ 294 """
279 # For regular non-zip packages just construct an absolute path. 295 # For regular non-zip packages just construct an absolute path.
280 if not is_zipped_module(package): 296 if not is_zipped_module(package):
281 # Package's __file__ attribute is always an absolute path. 297 # Package's __file__ attribute is always an absolute path.
282 path = os.path.join(os.path.dirname(package.__file__), 298 ppath = package.__file__.decode(sys.getfilesystemencoding())
299 path = os.path.join(os.path.dirname(ppath),
283 resource.replace('/', os.sep)) 300 resource.replace('/', os.sep))
284 if not os.path.exists(path): 301 if not os.path.exists(path):
285 raise ValueError('No such resource in %s: %s' % (package, resource)) 302 raise ValueError('No such resource in %s: %s' % (package, resource))
286 return path 303 return path
287 304
288 # For zipped packages extract the resource into a temp file. 305 # For zipped packages extract the resource into a temp file.
289 data = pkgutil.get_data(package.__name__, resource) 306 data = pkgutil.get_data(package.__name__, resource)
290 if data is None: 307 if data is None:
291 raise ValueError('No such resource in zipped %s: %s' % (package, resource)) 308 raise ValueError('No such resource in zipped %s: %s' % (package, resource))
292 309
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 h = hashlib.sha1() 353 h = hashlib.sha1()
337 with zipfile.ZipFile(get_main_script_path(), 'r') as z: 354 with zipfile.ZipFile(get_main_script_path(), 'r') as z:
338 for name in sorted(z.namelist()): 355 for name in sorted(z.namelist()):
339 with z.open(name) as f: 356 with z.open(name) as f:
340 h.update(str(len(name))) 357 h.update(str(len(name)))
341 h.update(name) 358 h.update(name)
342 content = f.read() 359 content = f.read()
343 h.update(str(len(content))) 360 h.update(str(len(content)))
344 h.update(content) 361 h.update(content)
345 return h.hexdigest() 362 return h.hexdigest()
OLDNEW
« no previous file with comments | « client/utils/oauth.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698