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):