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