##// END OF EJS Templates
utils: avoid using internal _imp.is_frozen()...
Mads Kiilerich -
r52643:c87c56ad default
parent child Browse files
Show More
@@ -1,138 +1,142 b''
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 import _imp
12 11 import os
13 12 import sys
14 13 import typing
15 14
16 15 from .. import pycompat
17 16
18 17
19 18 if typing.TYPE_CHECKING:
20 19 from typing import (
21 20 BinaryIO,
22 21 Iterator,
23 22 )
24 23
25 24
26 25 def mainfrozen():
27 26 """return True if we are a frozen executable.
28 27
29 28 The code supports py2exe (most common, Windows only) and tools/freeze
30 29 (portable, not much used).
31 30 """
32 31 return (
33 32 hasattr(sys, "frozen") # new py2exe
34 33 or hasattr(sys, "importers") # old py2exe
35 or _imp.is_frozen("__main__") # tools/freeze
34 or getattr(
35 getattr(sys.modules.get('__main__'), '__spec__', None),
36 'origin',
37 None,
38 )
39 == 'frozen' # tools/freeze
36 40 )
37 41
38 42
39 43 # the location of data files matching the source code
40 44 if mainfrozen() and getattr(sys, "frozen", None) != "macosx_app":
41 45 # executable version (py2exe) doesn't support __file__
42 46 datapath = os.path.dirname(pycompat.sysexecutable)
43 47 _rootpath = datapath
44 48
45 49 # The installers store the files outside of library.zip, like
46 50 # C:\Program Files\Mercurial\defaultrc\*.rc. This strips the
47 51 # leading "mercurial." off of the package name, so that these
48 52 # pseudo resources are found in their directory next to the
49 53 # executable.
50 54 def _package_path(package: bytes) -> bytes:
51 55 dirs = package.split(b".")
52 56 assert dirs[0] == b"mercurial"
53 57 return os.path.join(_rootpath, *dirs[1:])
54 58
55 59 else:
56 60 datapath = os.path.dirname(os.path.dirname(pycompat.fsencode(__file__)))
57 61 _rootpath = os.path.dirname(datapath)
58 62
59 63 def _package_path(package: bytes) -> bytes:
60 64 return os.path.join(_rootpath, *package.split(b"."))
61 65
62 66
63 67 try:
64 68 # importlib.resources exists from Python 3.7; see fallback in except clause
65 69 # further down
66 70 from importlib import resources # pytype: disable=import-error
67 71
68 72 # Force loading of the resources module
69 73 if hasattr(resources, 'files'): # Introduced in Python 3.9
70 74 resources.files # pytype: disable=module-attr
71 75 else:
72 76 resources.open_binary # pytype: disable=module-attr
73 77
74 78 # py2exe raises an AssertionError if uses importlib.resources
75 79 if getattr(sys, "frozen", None) in ("console_exe", "windows_exe"):
76 80 raise ImportError
77 81
78 82 except (ImportError, AttributeError):
79 83 # importlib.resources was not found (almost definitely because we're on a
80 84 # Python version before 3.7)
81 85
82 86 def open_resource(package: bytes, name: bytes) -> "BinaryIO":
83 87 path = os.path.join(_package_path(package), name)
84 88 return open(path, "rb")
85 89
86 90 def is_resource(package: bytes, name: bytes) -> bool:
87 91 path = os.path.join(_package_path(package), name)
88 92
89 93 try:
90 94 return os.path.isfile(pycompat.fsdecode(path))
91 95 except (IOError, OSError):
92 96 return False
93 97
94 98 def contents(package: bytes) -> "Iterator[bytes]":
95 99 path = pycompat.fsdecode(_package_path(package))
96 100
97 101 for p in os.listdir(path):
98 102 yield pycompat.fsencode(p)
99 103
100 104 else:
101 105 from .. import encoding
102 106
103 107 def open_resource(package: bytes, name: bytes) -> "BinaryIO":
104 108 if hasattr(resources, 'files'):
105 109 return (
106 110 resources.files( # pytype: disable=module-attr
107 111 pycompat.sysstr(package)
108 112 )
109 113 .joinpath(pycompat.sysstr(name))
110 114 .open('rb')
111 115 )
112 116 else:
113 117 return resources.open_binary( # pytype: disable=module-attr
114 118 pycompat.sysstr(package), pycompat.sysstr(name)
115 119 )
116 120
117 121 def is_resource(package: bytes, name: bytes) -> bool:
118 122 if hasattr(resources, 'files'): # Introduced in Python 3.9
119 123 return (
120 124 resources.files(pycompat.sysstr(package))
121 125 .joinpath(encoding.strfromlocal(name))
122 126 .is_file()
123 127 )
124 128 else:
125 129 return resources.is_resource( # pytype: disable=module-attr
126 130 pycompat.sysstr(package), encoding.strfromlocal(name)
127 131 )
128 132
129 133 def contents(package: bytes) -> "Iterator[bytes]":
130 134 if hasattr(resources, 'files'): # Introduced in Python 3.9
131 135 for path in resources.files(pycompat.sysstr(package)).iterdir():
132 136 if path.is_file():
133 137 yield encoding.strtolocal(path.name)
134 138 else:
135 139 # pytype: disable=module-attr
136 140 for r in resources.contents(pycompat.sysstr(package)):
137 141 # pytype: enable=module-attr
138 142 yield encoding.strtolocal(r)
General Comments 0
You need to be logged in to leave comments. Login now