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