# HG changeset patch # User Mads Kiilerich # Date 1687897904 -7200 # Node ID b9eb65a1ec140ccecd51e0b456de6e0e56e63c82 # Parent f173c2c2328916a88bff1daf6ac4a8d886454d6a extensions: address ast deprecations introduced in Python 3.12 Tests would fail with: .../mercurial/extensions.py:910: DeprecationWarning: ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead if isinstance(a, ast.Str): .../mercurial/extensions.py:912: DeprecationWarning: ast.Bytes is deprecated and will be removed in Python 3.14; use ast.Constant instead elif isinstance(a, ast.Bytes): .../mercurial/extensions.py:913: DeprecationWarning: Attribute s is deprecated and will be removed in Python 3.14; use value instead name = a.s diff -r f173c2c23289 -r b9eb65a1ec14 mercurial/extensions.py --- a/mercurial/extensions.py Tue Jun 27 08:39:12 2023 +0200 +++ b/mercurial/extensions.py Tue Jun 27 22:31:44 2023 +0200 @@ -885,16 +885,31 @@ with open(path, b'rb') as src: root = ast.parse(src.read(), path) cmdtable = {} + + # Python 3.12 started removing Bytes and Str and deprecate harder + use_constant = 'Bytes' not in vars(ast) + for node in _walkcommand(root): if not node.args: continue a = node.args[0] - if isinstance(a, ast.Str): - name = pycompat.sysbytes(a.s) - elif isinstance(a, ast.Bytes): - name = a.s - else: - continue + if use_constant: # Valid since Python 3.8 + if isinstance(a, ast.Constant): + if isinstance(a.value, str): + name = pycompat.sysbytes(a.value) + elif isinstance(a.value, bytes): + name = a.value + else: + continue + else: + continue + else: # Valid until 3.11 + if isinstance(a, ast.Str): + name = pycompat.sysbytes(a.s) + elif isinstance(a, ast.Bytes): + name = a.s + else: + continue cmdtable[name] = (None, [], b'') return cmdtable