mirror of
https://chromium.googlesource.com/chromium/tools/depot_tools.git
synced 2026-01-11 02:31:29 +00:00
Replace deprecated ast types with ast.Constant
ast.Str et al. have been deprecated since Py3.8 and have been completely removed in 3.14. Replace their usage with ast.Constant. This change should not have any functional impact, since according to [1]: > Changed in version 3.8: Class ast.Constant is now used for > all constants. > Deprecated since version 3.8: Old classes ast.Num, ast.Str, > [...] instantiating them will return an instance of a > different class. [1] https://docs.python.org/3/library/ast.html Bug: 40283283 Change-Id: I0ed8ef3910f921483bff118976f516c5a935e0fc Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/7228507 Reviewed-by: Gavin Mak <gavinmak@google.com> Reviewed-by: Yiwei Zhang <yiwzhang@google.com> Commit-Queue: jj <jj@chromium.org>
This commit is contained in:
@@ -101,6 +101,24 @@ def _NodeDictSchema(dict_schema):
|
|||||||
return validate
|
return validate
|
||||||
|
|
||||||
|
|
||||||
|
def _IsConstant(node):
|
||||||
|
return isinstance(node, ast.Constant)
|
||||||
|
|
||||||
|
|
||||||
|
def _IsStringConstant(node):
|
||||||
|
return _IsConstant(node) and isinstance(node.value, str)
|
||||||
|
|
||||||
|
|
||||||
|
def _IsNameConstant(node):
|
||||||
|
return _IsConstant(node) \
|
||||||
|
and isinstance(node.value, (bool, type(None)))
|
||||||
|
|
||||||
|
|
||||||
|
def _IsNumericConstant(node):
|
||||||
|
return _IsConstant(node) \
|
||||||
|
and isinstance(node.value, (int, float, complex)) \
|
||||||
|
and not isinstance(node.value, bool)
|
||||||
|
|
||||||
# See https://github.com/keleshev/schema for docs how to configure schema.
|
# See https://github.com/keleshev/schema for docs how to configure schema.
|
||||||
_GCLIENT_DEPS_SCHEMA = _NodeDictSchema({
|
_GCLIENT_DEPS_SCHEMA = _NodeDictSchema({
|
||||||
schema.Optional(str):
|
schema.Optional(str):
|
||||||
@@ -316,18 +334,18 @@ def _gclient_eval(node_or_string, filename='<unknown>', vars_dict=None):
|
|||||||
node_or_string = node_or_string.body
|
node_or_string = node_or_string.body
|
||||||
|
|
||||||
def _convert(node):
|
def _convert(node):
|
||||||
if isinstance(node, ast.Str):
|
if _IsStringConstant(node):
|
||||||
if vars_dict is None:
|
if vars_dict is None:
|
||||||
return node.s
|
return node.value
|
||||||
try:
|
try:
|
||||||
return node.s.format(**vars_dict)
|
return node.value.format(**vars_dict)
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
raise KeyError(
|
raise KeyError(
|
||||||
'%s was used as a variable, but was not declared in the vars dict '
|
'%s was used as a variable, but was not declared in the vars dict '
|
||||||
'(file %r, line %s)' %
|
'(file %r, line %s)' %
|
||||||
(e.args[0], filename, getattr(node, 'lineno', '<unknown>')))
|
(e.args[0], filename, getattr(node, 'lineno', '<unknown>')))
|
||||||
elif isinstance(node, ast.Num):
|
elif _IsNameConstant(node) or _IsNumericConstant(node):
|
||||||
return node.n
|
return node.value
|
||||||
elif isinstance(node, ast.Tuple):
|
elif isinstance(node, ast.Tuple):
|
||||||
return tuple(map(_convert, node.elts))
|
return tuple(map(_convert, node.elts))
|
||||||
elif isinstance(node, ast.List):
|
elif isinstance(node, ast.List):
|
||||||
@@ -349,9 +367,6 @@ def _gclient_eval(node_or_string, filename='<unknown>', vars_dict=None):
|
|||||||
'invalid name %r (file %r, line %s)' %
|
'invalid name %r (file %r, line %s)' %
|
||||||
(node.id, filename, getattr(node, 'lineno', '<unknown>')))
|
(node.id, filename, getattr(node, 'lineno', '<unknown>')))
|
||||||
return _allowed_names[node.id]
|
return _allowed_names[node.id]
|
||||||
elif not sys.version_info[:2] < (3, 4) and isinstance(
|
|
||||||
node, ast.NameConstant): # Since Python 3.4
|
|
||||||
return node.value
|
|
||||||
elif isinstance(node, ast.Call):
|
elif isinstance(node, ast.Call):
|
||||||
if (not isinstance(node.func, ast.Name)
|
if (not isinstance(node.func, ast.Name)
|
||||||
or (node.func.id not in ('Str', 'Var'))):
|
or (node.func.id not in ('Str', 'Var'))):
|
||||||
@@ -366,8 +381,8 @@ def _gclient_eval(node_or_string, filename='<unknown>', vars_dict=None):
|
|||||||
'<unknown>')))
|
'<unknown>')))
|
||||||
|
|
||||||
if node.func.id == 'Str':
|
if node.func.id == 'Str':
|
||||||
if isinstance(node.args[0], ast.Str):
|
if _IsStringConstant(node.args[0]):
|
||||||
return ConstantString(node.args[0].s)
|
return ConstantString(node.args[0].value)
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Passed a non-string to Str() (file %r, line%s)' %
|
'Passed a non-string to Str() (file %r, line%s)' %
|
||||||
(filename, getattr(node, 'lineno', '<unknown>')))
|
(filename, getattr(node, 'lineno', '<unknown>')))
|
||||||
@@ -594,8 +609,8 @@ def EvaluateCondition(condition, variables, referenced_variables=None):
|
|||||||
main_node = main_node.body
|
main_node = main_node.body
|
||||||
|
|
||||||
def _convert(node, allow_tuple=False):
|
def _convert(node, allow_tuple=False):
|
||||||
if isinstance(node, ast.Str):
|
if _IsStringConstant(node):
|
||||||
return node.s
|
return node.value
|
||||||
|
|
||||||
if isinstance(node, ast.Tuple) and allow_tuple:
|
if isinstance(node, ast.Tuple) and allow_tuple:
|
||||||
return tuple(map(_convert, node.elts))
|
return tuple(map(_convert, node.elts))
|
||||||
@@ -627,8 +642,7 @@ def EvaluateCondition(condition, variables, referenced_variables=None):
|
|||||||
# be evaluated.
|
# be evaluated.
|
||||||
return node.id
|
return node.id
|
||||||
|
|
||||||
if not sys.version_info[:2] < (3, 4) and isinstance(
|
if _IsNameConstant(node):
|
||||||
node, ast.NameConstant): # Since Python 3.4
|
|
||||||
return node.value
|
return node.value
|
||||||
|
|
||||||
if isinstance(node, ast.BoolOp) and isinstance(node.op, ast.Or):
|
if isinstance(node, ast.BoolOp) and isinstance(node.op, ast.Or):
|
||||||
@@ -696,11 +710,11 @@ def _UpdateAstString(tokens, node, value):
|
|||||||
node = node.args[0]
|
node = node.args[0]
|
||||||
position = node.lineno, node.col_offset
|
position = node.lineno, node.col_offset
|
||||||
quote_char = ''
|
quote_char = ''
|
||||||
if isinstance(node, ast.Str):
|
if _IsStringConstant(node):
|
||||||
quote_char = tokens[position][1][0]
|
quote_char = tokens[position][1][0]
|
||||||
value = value.encode('unicode_escape').decode('utf-8')
|
value = value.encode('unicode_escape').decode('utf-8')
|
||||||
tokens[position][1] = quote_char + value + quote_char
|
tokens[position][1] = quote_char + value + quote_char
|
||||||
node.s = value
|
node.value = value
|
||||||
|
|
||||||
|
|
||||||
def _ShiftLinesInTokens(tokens, delta, start):
|
def _ShiftLinesInTokens(tokens, delta, start):
|
||||||
@@ -793,11 +807,11 @@ def SetVar(gclient_dict, var_name, value):
|
|||||||
|
|
||||||
def _GetVarName(node):
|
def _GetVarName(node):
|
||||||
if isinstance(node, ast.Call):
|
if isinstance(node, ast.Call):
|
||||||
return node.args[0].s
|
return node.args[0].value
|
||||||
|
|
||||||
if node.s.endswith('}'):
|
if node.value.endswith('}'):
|
||||||
last_brace = node.s.rfind('{')
|
last_brace = node.value.rfind('{')
|
||||||
return node.s[last_brace + 1:-1]
|
return node.value[last_brace + 1:-1]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -821,9 +835,9 @@ def SetGCS(gclient_dict, dep_name, new_objects):
|
|||||||
keys_to_update = ('object_name', 'sha256sum', 'size_bytes', 'generation')
|
keys_to_update = ('object_name', 'sha256sum', 'size_bytes', 'generation')
|
||||||
for index, object_node in enumerate(objects_node.elts):
|
for index, object_node in enumerate(objects_node.elts):
|
||||||
for key, value in zip(object_node.keys, object_node.values):
|
for key, value in zip(object_node.keys, object_node.values):
|
||||||
if key.s not in keys_to_update:
|
if key.value not in keys_to_update:
|
||||||
continue
|
continue
|
||||||
_UpdateAstString(tokens, value, new_objects[index][key.s])
|
_UpdateAstString(tokens, value, new_objects[index][key.value])
|
||||||
|
|
||||||
node.SetNode('objects', new_objects, objects_node)
|
node.SetNode('objects', new_objects, objects_node)
|
||||||
|
|
||||||
@@ -855,7 +869,7 @@ def SetCIPD(gclient_dict, dep_name, package_name, new_version):
|
|||||||
"The deps entry for %s:%s has no formatting information." %
|
"The deps entry for %s:%s has no formatting information." %
|
||||||
(dep_name, package_name))
|
(dep_name, package_name))
|
||||||
|
|
||||||
if not isinstance(node, ast.Call) and not isinstance(node, ast.Str):
|
if not isinstance(node, ast.Call) and not _IsStringConstant(node):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Unsupported dependency revision format. Please file a bug to the "
|
"Unsupported dependency revision format. Please file a bug to the "
|
||||||
"Infra>SDK component in crbug.com")
|
"Infra>SDK component in crbug.com")
|
||||||
@@ -880,15 +894,15 @@ def SetRevision(gclient_dict, dep_name, new_revision):
|
|||||||
if isinstance(node, ast.BinOp):
|
if isinstance(node, ast.BinOp):
|
||||||
node = node.right
|
node = node.right
|
||||||
|
|
||||||
if isinstance(node, ast.Str):
|
if _IsStringConstant(node):
|
||||||
token = _gclient_eval(tokens[node.lineno, node.col_offset][1])
|
token = _gclient_eval(tokens[node.lineno, node.col_offset][1])
|
||||||
if token != node.s:
|
if token != node.value:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Can\'t update value for %s. Multiline strings and implicitly '
|
'Can\'t update value for %s. Multiline strings and implicitly '
|
||||||
'concatenated strings are not supported.\n'
|
'concatenated strings are not supported.\n'
|
||||||
'Consider reformatting the DEPS file.' % dep_key)
|
'Consider reformatting the DEPS file.' % dep_key)
|
||||||
|
|
||||||
if not isinstance(node, ast.Call) and not isinstance(node, ast.Str):
|
if not isinstance(node, ast.Call) and not _IsStringConstant(node):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Unsupported dependency revision format. Please file a bug to the "
|
"Unsupported dependency revision format. Please file a bug to the "
|
||||||
"Infra>SDK component in crbug.com")
|
"Infra>SDK component in crbug.com")
|
||||||
@@ -897,15 +911,15 @@ def SetRevision(gclient_dict, dep_name, new_revision):
|
|||||||
if var_name is not None:
|
if var_name is not None:
|
||||||
SetVar(gclient_dict, var_name, new_revision)
|
SetVar(gclient_dict, var_name, new_revision)
|
||||||
else:
|
else:
|
||||||
if '@' in node.s:
|
if '@' in node.value:
|
||||||
# '@' is part of the last string, which we want to modify.
|
# '@' is part of the last string, which we want to modify.
|
||||||
# Discard whatever was after the '@' and put the new revision in
|
# Discard whatever was after the '@' and put the new revision in
|
||||||
# its place.
|
# its place.
|
||||||
new_revision = node.s.split('@')[0] + '@' + new_revision
|
new_revision = node.value.split('@')[0] + '@' + new_revision
|
||||||
elif '@' not in dep_dict[dep_key]:
|
elif '@' not in dep_dict[dep_key]:
|
||||||
# '@' is not part of the URL at all. This mean the dependency is
|
# '@' is not part of the URL at all. This mean the dependency is
|
||||||
# unpinned and we should pin it.
|
# unpinned and we should pin it.
|
||||||
new_revision = node.s + '@' + new_revision
|
new_revision = node.value + '@' + new_revision
|
||||||
_UpdateAstString(tokens, node, new_revision)
|
_UpdateAstString(tokens, node, new_revision)
|
||||||
dep_dict.SetNode(dep_key, new_revision, node)
|
dep_dict.SetNode(dep_key, new_revision, node)
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ class GClientEvalTest(unittest.TestCase):
|
|||||||
def test_str(self):
|
def test_str(self):
|
||||||
self.assertEqual('foo', gclient_eval._gclient_eval('"foo"'))
|
self.assertEqual('foo', gclient_eval._gclient_eval('"foo"'))
|
||||||
|
|
||||||
|
def test_num(self):
|
||||||
|
self.assertEqual(42, gclient_eval._gclient_eval('42'))
|
||||||
|
self.assertEqual(1024.0, gclient_eval._gclient_eval('1024.0'))
|
||||||
|
self.assertEqual(42j, gclient_eval._gclient_eval('42j'))
|
||||||
|
|
||||||
def test_tuple(self):
|
def test_tuple(self):
|
||||||
self.assertEqual(('a', 'b'), gclient_eval._gclient_eval('("a", "b")'))
|
self.assertEqual(('a', 'b'), gclient_eval._gclient_eval('("a", "b")'))
|
||||||
|
|
||||||
@@ -40,6 +45,7 @@ class GClientEvalTest(unittest.TestCase):
|
|||||||
self.assertEqual({'a': 'b'}, gclient_eval._gclient_eval('{"a": "b"}'))
|
self.assertEqual({'a': 'b'}, gclient_eval._gclient_eval('{"a": "b"}'))
|
||||||
|
|
||||||
def test_name_safe(self):
|
def test_name_safe(self):
|
||||||
|
self.assertEqual(None, gclient_eval._gclient_eval('None'))
|
||||||
self.assertEqual(True, gclient_eval._gclient_eval('True'))
|
self.assertEqual(True, gclient_eval._gclient_eval('True'))
|
||||||
|
|
||||||
def test_name_unsafe(self):
|
def test_name_unsafe(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user