##// END OF EJS Templates
resourceutil: force filesystem access to resources when using py2exe...
Matt Harbison -
r49947:3e8134f7 default draft
parent child Browse files
Show More
@@ -1,104 +1,108
1 1 # resourceutil.py - utility for looking up resources
2 2 #
3 3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com>
4 4 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
5 5 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
6 6 #
7 7 # This software may be used and distributed according to the terms of the
8 8 # GNU General Public License version 2 or any later version.
9 9
10 10
11 11 import imp
12 12 import os
13 13 import sys
14 14
15 15 from .. import pycompat
16 16
17 17
18 18 def mainfrozen():
19 19 """return True if we are a frozen executable.
20 20
21 21 The code supports py2exe (most common, Windows only) and tools/freeze
22 22 (portable, not much used).
23 23 """
24 24 return (
25 25 pycompat.safehasattr(sys, "frozen") # new py2exe
26 26 or pycompat.safehasattr(sys, "importers") # old py2exe
27 27 or imp.is_frozen("__main__") # tools/freeze
28 28 )
29 29
30 30
31 31 # the location of data files matching the source code
32 32 if mainfrozen() and getattr(sys, "frozen", None) != "macosx_app":
33 33 # executable version (py2exe) doesn't support __file__
34 34 datapath = os.path.dirname(pycompat.sysexecutable)
35 35 _rootpath = datapath
36 36
37 37 # The installers store the files outside of library.zip, like
38 38 # C:\Program Files\Mercurial\defaultrc\*.rc. This strips the
39 39 # leading "mercurial." off of the package name, so that these
40 40 # pseudo resources are found in their directory next to the
41 41 # executable.
42 42 def _package_path(package):
43 43 dirs = package.split(b".")
44 44 assert dirs[0] == b"mercurial"
45 45 return os.path.join(_rootpath, *dirs[1:])
46 46
47 47
48 48 else:
49 49 datapath = os.path.dirname(os.path.dirname(pycompat.fsencode(__file__)))
50 50 _rootpath = os.path.dirname(datapath)
51 51
52 52 def _package_path(package):
53 53 return os.path.join(_rootpath, *package.split(b"."))
54 54
55 55
56 56 try:
57 57 # importlib.resources exists from Python 3.7; see fallback in except clause
58 58 # further down
59 59 from importlib import resources # pytype: disable=import-error
60 60
61 61 # Force loading of the resources module
62 62 resources.open_binary # pytype: disable=module-attr
63 63
64 # py2exe raises an AssertionError if uses importlib.resources
65 if getattr(sys, "frozen", None) in ("console_exe", "windows_exe"):
66 raise ImportError
67
64 68 except (ImportError, AttributeError):
65 69 # importlib.resources was not found (almost definitely because we're on a
66 70 # Python version before 3.7)
67 71
68 72 def open_resource(package, name):
69 73 path = os.path.join(_package_path(package), name)
70 74 return open(path, "rb")
71 75
72 76 def is_resource(package, name):
73 77 path = os.path.join(_package_path(package), name)
74 78
75 79 try:
76 80 return os.path.isfile(pycompat.fsdecode(path))
77 81 except (IOError, OSError):
78 82 return False
79 83
80 84 def contents(package):
81 85 path = pycompat.fsdecode(_package_path(package))
82 86
83 87 for p in os.listdir(path):
84 88 yield pycompat.fsencode(p)
85 89
86 90
87 91 else:
88 92 from .. import encoding
89 93
90 94 def open_resource(package, name):
91 95 return resources.open_binary( # pytype: disable=module-attr
92 96 pycompat.sysstr(package), pycompat.sysstr(name)
93 97 )
94 98
95 99 def is_resource(package, name):
96 100 return resources.is_resource( # pytype: disable=module-attr
97 101 pycompat.sysstr(package), encoding.strfromlocal(name)
98 102 )
99 103
100 104 def contents(package):
101 105 # pytype: disable=module-attr
102 106 for r in resources.contents(pycompat.sysstr(package)):
103 107 # pytype: enable=module-attr
104 108 yield encoding.strtolocal(r)
General Comments 0
You need to be logged in to leave comments. Login now