Mercurial > public > mercurial-scm > hg
comparison mercurial/extensions.py @ 50816:3ccef7902070
branching: merge stable into default
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Mon, 07 Aug 2023 11:08:00 +0200 |
parents | ee1617c04858 19108906abaf |
children | f75fd677cc05 |
comparison
equal
deleted
inserted
replaced
50807:5c3d07950bac | 50816:3ccef7902070 |
---|---|
7 | 7 |
8 | 8 |
9 import ast | 9 import ast |
10 import collections | 10 import collections |
11 import functools | 11 import functools |
12 import imp | 12 import importlib |
13 import inspect | 13 import inspect |
14 import os | 14 import os |
15 import sys | |
15 | 16 |
16 from .i18n import ( | 17 from .i18n import ( |
17 _, | 18 _, |
18 gettext, | 19 gettext, |
19 ) | 20 ) |
87 path = util.normpath(util.expandpath(path)) | 88 path = util.normpath(util.expandpath(path)) |
88 module_name = pycompat.fsdecode(module_name) | 89 module_name = pycompat.fsdecode(module_name) |
89 path = pycompat.fsdecode(path) | 90 path = pycompat.fsdecode(path) |
90 if os.path.isdir(path): | 91 if os.path.isdir(path): |
91 # module/__init__.py style | 92 # module/__init__.py style |
92 d, f = os.path.split(path) | 93 init_py_path = os.path.join(path, '__init__.py') |
93 fd, fpath, desc = imp.find_module(f, [d]) | 94 if not os.path.exists(init_py_path): |
94 # When https://github.com/python/typeshed/issues/3466 is fixed | 95 raise ImportError("No module named '%s'" % os.path.basename(path)) |
95 # and in a pytype release we can drop this disable. | 96 path = init_py_path |
96 return imp.load_module( | 97 |
97 module_name, fd, fpath, desc # pytype: disable=wrong-arg-types | 98 loader = importlib.machinery.SourceFileLoader(module_name, path) |
98 ) | 99 spec = importlib.util.spec_from_file_location(module_name, loader=loader) |
99 else: | 100 assert spec is not None # help Pytype |
100 try: | 101 module = importlib.util.module_from_spec(spec) |
101 return imp.load_source(module_name, path) | 102 sys.modules[module_name] = module |
102 except IOError as exc: | 103 spec.loader.exec_module(module) |
103 if not exc.filename: | 104 return module |
104 exc.filename = path # python does not fill this | |
105 raise | |
106 | 105 |
107 | 106 |
108 def _importh(name): | 107 def _importh(name): |
109 """import and return the <name> module""" | 108 """import and return the <name> module""" |
110 mod = __import__(pycompat.sysstr(name)) | 109 mod = __import__(pycompat.sysstr(name)) |
892 This may raise IOError or SyntaxError. | 891 This may raise IOError or SyntaxError. |
893 """ | 892 """ |
894 with open(path, b'rb') as src: | 893 with open(path, b'rb') as src: |
895 root = ast.parse(src.read(), path) | 894 root = ast.parse(src.read(), path) |
896 cmdtable = {} | 895 cmdtable = {} |
896 | |
897 # Python 3.12 started removing Bytes and Str and deprecate harder | |
898 use_constant = 'Bytes' not in vars(ast) | |
899 | |
897 for node in _walkcommand(root): | 900 for node in _walkcommand(root): |
898 if not node.args: | 901 if not node.args: |
899 continue | 902 continue |
900 a = node.args[0] | 903 a = node.args[0] |
901 if isinstance(a, ast.Str): | 904 if use_constant: # Valid since Python 3.8 |
902 name = pycompat.sysbytes(a.s) | 905 if isinstance(a, ast.Constant): |
903 elif isinstance(a, ast.Bytes): | 906 if isinstance(a.value, str): |
904 name = a.s | 907 name = pycompat.sysbytes(a.value) |
905 else: | 908 elif isinstance(a.value, bytes): |
906 continue | 909 name = a.value |
910 else: | |
911 continue | |
912 else: | |
913 continue | |
914 else: # Valid until 3.11 | |
915 if isinstance(a, ast.Str): | |
916 name = pycompat.sysbytes(a.s) | |
917 elif isinstance(a, ast.Bytes): | |
918 name = a.s | |
919 else: | |
920 continue | |
907 cmdtable[name] = (None, [], b'') | 921 cmdtable[name] = (None, [], b'') |
908 return cmdtable | 922 return cmdtable |
909 | 923 |
910 | 924 |
911 def _finddisabledcmd(ui, cmd, name, path, strict): | 925 def _finddisabledcmd(ui, cmd, name, path, strict): |