comparison mercurial/utils/resourceutil.py @ 52107:747a1370c598 stable

utils: fix resourceutil use of deprecated importlib.resources Some importlib functionality was deprecated in 3.11 . The documentation on https://docs.python.org/3.12/library/importlib.resources.html recommends using the new .files() API that was introduced in 3.9.
author Mads Kiilerich <mads@kiilerich.com>
date Mon, 22 Jul 2024 18:20:03 +0200
parents c5d6a66092e8
children b2e90465daf6
comparison
equal deleted inserted replaced
52106:c5d6a66092e8 52107:747a1370c598
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 os 11 import os
12 import sys 12 import sys
13
14 from typing import Iterator
13 15
14 from .. import pycompat 16 from .. import pycompat
15 17
16 18
17 def mainfrozen(): 19 def mainfrozen():
46 def _package_path(package): 48 def _package_path(package):
47 dirs = package.split(b".") 49 dirs = package.split(b".")
48 assert dirs[0] == b"mercurial" 50 assert dirs[0] == b"mercurial"
49 return os.path.join(_rootpath, *dirs[1:]) 51 return os.path.join(_rootpath, *dirs[1:])
50 52
53
51 else: 54 else:
52 datapath = os.path.dirname(os.path.dirname(pycompat.fsencode(__file__))) 55 datapath = os.path.dirname(os.path.dirname(pycompat.fsencode(__file__)))
53 _rootpath = os.path.dirname(datapath) 56 _rootpath = os.path.dirname(datapath)
54 57
55 def _package_path(package): 58 def _package_path(package):
60 # importlib.resources exists from Python 3.7; see fallback in except clause 63 # importlib.resources exists from Python 3.7; see fallback in except clause
61 # further down 64 # further down
62 from importlib import resources # pytype: disable=import-error 65 from importlib import resources # pytype: disable=import-error
63 66
64 # Force loading of the resources module 67 # Force loading of the resources module
65 if hasattr(resources, 'files'): 68 if hasattr(resources, 'files'): # Introduced in Python 3.9
66 resources.files # pytype: disable=module-attr 69 resources.files # pytype: disable=module-attr
67 else: 70 else:
68 resources.open_binary # pytype: disable=module-attr 71 resources.open_binary # pytype: disable=module-attr
69 72
70 # py2exe raises an AssertionError if uses importlib.resources 73 # py2exe raises an AssertionError if uses importlib.resources
91 path = pycompat.fsdecode(_package_path(package)) 94 path = pycompat.fsdecode(_package_path(package))
92 95
93 for p in os.listdir(path): 96 for p in os.listdir(path):
94 yield pycompat.fsencode(p) 97 yield pycompat.fsencode(p)
95 98
99
96 else: 100 else:
97 from .. import encoding 101 from .. import encoding
98 102
99 def open_resource(package, name): 103 def open_resource(package, name):
100 if hasattr(resources, 'files'): 104 if hasattr(resources, 'files'):
108 else: 112 else:
109 return resources.open_binary( # pytype: disable=module-attr 113 return resources.open_binary( # pytype: disable=module-attr
110 pycompat.sysstr(package), pycompat.sysstr(name) 114 pycompat.sysstr(package), pycompat.sysstr(name)
111 ) 115 )
112 116
113 def is_resource(package, name): 117 def is_resource(package: bytes, name: bytes) -> bool:
114 return resources.is_resource( # pytype: disable=module-attr 118 if hasattr(resources, 'files'): # Introduced in Python 3.9
115 pycompat.sysstr(package), encoding.strfromlocal(name) 119 return (
116 ) 120 resources.files(pycompat.sysstr(package))
121 .joinpath(encoding.strfromlocal(name))
122 .is_file()
123 )
124 else:
125 return resources.is_resource( # pytype: disable=module-attr
126 pycompat.sysstr(package), encoding.strfromlocal(name)
127 )
117 128
118 def contents(package): 129 def contents(package: bytes) -> "Iterator[bytes]":
119 # pytype: disable=module-attr 130 if hasattr(resources, 'files'): # Introduced in Python 3.9
120 for r in resources.contents(pycompat.sysstr(package)): 131 for path in resources.files(pycompat.sysstr(package)).iterdir():
121 # pytype: enable=module-attr 132 if path.is_file():
122 yield encoding.strtolocal(r) 133 yield encoding.strtolocal(path.name)
134 else:
135 # pytype: disable=module-attr
136 for r in resources.contents(pycompat.sysstr(package)):
137 # pytype: enable=module-attr
138 yield encoding.strtolocal(r)