def basicTypeSpecialFunction(cv):
"""If you're in a number or string (which has no metadata), move up to the AST to make the special functions work."""
if isinstance(cv, SwapVector) or isinstance(cv, MoveVector):
return cv
if (cv.path[0] in [('n', 'Number'), ('s', 'String'), ('id', 'Name'), ('arg', 'Argument'),
('value', 'Name Constant'), ('s', 'Bytes'), ('name', 'Alias')]):
cvCopy = cv.deepcopy()
cv.oldSubtree = deepcopy(cvCopy.traverseTree(cv.start))
if cv.path[0] == ('n', 'Number'):
cv.newSubtree = ast.Num(cv.newSubtree)
elif cv.path[0] == ('s', 'String'):
cv.newSubtree = ast.Str(cv.newSubtree)
elif cv.path[0] == ('id', 'Name'):
cv.newSubtree = ast.Name(cv.newSubtree, cv.oldSubtree.ctx)
elif cv.path[0] == ('arg', 'Argument'):
cv.newSubtree = ast.arg(cv.newSubtree, cv.oldSubtree.annotation)
elif cv.path[0] == ('value', 'Name Constant'):
cv.newSubtree = ast.NameConstant(cv.newSubtree)
elif cv.path[0] == ('s', 'Bytes'):
cv.newSubtree = ast.Bytes(cv.newSubtree)
elif cv.path[0] == ('name', 'Alias'):
cv.newSubtree = ast.alias(cv.newSubtree, cv.oldSubtree.asname)
cv.path = cv.path[1:]
return cv
python类Bytes()的实例源码
def specialize_constant(node, value):
if value is None or isinstance(value, bool):
new_node = ast.NameConstant(value=value)
elif isinstance(value, (int, float, complex)):
new_node = ast.Num(n=value)
elif isinstance(value, str):
new_node = ast.Str(s=value)
elif isinstance(value, bytes):
new_node = ast.Bytes(s=value)
elif isinstance(value, tuple):
elts = [specialize_constant(node, elt) for elt in value]
new_node = ast.Tuple(elts=elts, ctx=ast.Load())
else:
raise ValueError("unknown constant: %r" % value)
fatoptimizer.tools.copy_lineno(node, new_node)
return new_node
def convert_to_value(item):
if isinstance(item, ast.Str):
return item.s
elif hasattr(ast, 'Bytes') and isinstance(item, ast.Bytes):
return item.s
elif isinstance(item, ast.Tuple):
return tuple(convert_to_value(i) for i in item.elts)
elif isinstance(item, ast.Num):
return item.n
elif isinstance(item, ast.Name):
result = VariableKey(item=item)
constants_lookup = {
'True': True,
'False': False,
'None': None,
}
return constants_lookup.get(
result.name,
result,
)
elif (not PY33) and isinstance(item, ast.NameConstant):
# None, True, False are nameconstants in python3, but names in 2
return item.value
else:
return UnhandledKeyType()
def convert_to_value(item):
if isinstance(item, ast.Str):
return item.s
elif hasattr(ast, 'Bytes') and isinstance(item, ast.Bytes):
return item.s
elif isinstance(item, ast.Tuple):
return tuple(convert_to_value(i) for i in item.elts)
elif isinstance(item, ast.Num):
return item.n
elif isinstance(item, ast.Name):
result = VariableKey(item=item)
constants_lookup = {
'True': True,
'False': False,
'None': None,
}
return constants_lookup.get(
result.name,
result,
)
elif (not PY33) and isinstance(item, ast.NameConstant):
# None, True, False are nameconstants in python3, but names in 2
return item.value
else:
return UnhandledKeyType()
def reify(kvalue, gen_sym):
value = kvalue.value
if value is True or value is False or value is None:
return ast.NameConstant(value=value), gen_sym, {}
elif type(value) == str:
return ast.Str(s=value), gen_sym, {}
elif type(value) == bytes:
return ast.Bytes(s=value), gen_sym, {}
elif type(value) in (int, float, complex):
return ast.Num(n=value), gen_sym, {}
else:
if kvalue.preferred_name is None:
name, gen_sym = gen_sym('temp')
else:
name = kvalue.preferred_name
return ast.Name(id=name, ctx=ast.Load()), gen_sym, {name: value}
def test_simple_reify():
check_reify(True, ast.NameConstant(value=True))
check_reify(False, ast.NameConstant(value=False))
check_reify(None, ast.NameConstant(value=None))
class Dummy(): pass
x = Dummy()
check_reify(
x, ast.Name(id='__peval_temp_1', ctx=ast.Load()),
expected_binding=dict(__peval_temp_1=x))
check_reify(
x, ast.Name(id='y', ctx=ast.Load()),
preferred_name='y', expected_binding=dict(y=x))
check_reify(1, ast.Num(n=1))
check_reify(2.3, ast.Num(n=2.3))
check_reify(3+4j, ast.Num(n=3+4j))
check_reify('abc', ast.Str(s='abc'))
s = bytes('abc', encoding='ascii')
check_reify(s, ast.Bytes(s=s))
def isConstant(x):
"""Determine whether the provided AST is a constant"""
return (type(x) in [ast.Num, ast.Str, ast.Bytes, ast.NameConstant])
def astFormat(x, gid=None):
"""Given a value, turn it into an AST if it's a constant; otherwise, leave it alone."""
if type(x) in [int, float, complex]:
return ast.Num(x)
elif type(x) == bool or x == None:
return ast.NameConstant(x)
elif type(x) == type:
types = { bool : "bool", int : "int", float : "float",
complex : "complex", str : "str", bytes : "bytes", unicode : "unicode",
list : "list", tuple : "tuple", dict : "dict" }
return ast.Name(types[x], ast.Load())
elif type(x) == str: # str or unicode
return ast.Str(x)
elif type(x) == bytes:
return ast.Bytes(x)
elif type(x) == list:
elts = [astFormat(val) for val in x]
return ast.List(elts, ast.Load())
elif type(x) == dict:
keys = []
vals = []
for key in x:
keys.append(astFormat(key))
vals.append(astFormat(x[key]))
return ast.Dict(keys, vals)
elif type(x) == tuple:
elts = [astFormat(val) for val in x]
return ast.Tuple(elts, ast.Load())
elif type(x) == set:
elts = [astFormat(val) for val in x]
if len(elts) == 0: # needs to be a call instead
return ast.Call(ast.Name("set", ast.Load()), [], [])
else:
return ast.Set(elts)
elif type(x) == slice:
return ast.Slice(astFormat(x.start), astFormat(x.stop), astFormat(x.step))
elif isinstance(x, ast.AST):
return x # Do not change if it's not constant!
else:
log("astTools\tastFormat\t" + str(type(x)) + "," + str(x),"bug")
return None
def basicFormat(x):
"""Given an AST, turn it into its value if it's constant; otherwise, leave it alone"""
if type(x) == ast.Num:
return x.n
elif type(x) == ast.NameConstant:
return x.value
elif type(x) == ast.Str:
return x.s
elif type(x) == ast.Bytes:
return x.s
return x # Do not change if it's not a constant!
def resolve_attr_id(node):
if isinstance(node, (ast.Attribute, ast.Subscript)):
value_id = None
if isinstance(node.value, (ast.Name, ast.Attribute, ast.Subscript)):
value_id = resolve_attr_id(node.value)
elif isinstance(node.value, ast.Call):
value_id = resolve_attr_id(node.value)
elif isinstance(node.value, ast.Str):
value_id = 'str'
elif isinstance(node.value, ast.Bytes):
value_id = 'bytes'
elif isinstance(node.value, (ast.List, ast.ListComp)):
value_id = 'list'
elif isinstance(node.value, ast.Tuple):
value_id = 'tuple'
elif isinstance(node.value, (ast.Set, ast.SetComp)):
value_id = 'set'
elif isinstance(node.value, (ast.Dict, ast.DictComp)):
value_id = 'dict'
else:
raise SyntaxError(
'unsupport type: {}'.format(ast.dump(node.value))
)
if isinstance(node, ast.Attribute):
return '{}.{}'.format(value_id, node.attr)
elif isinstance(node, ast.Subscript):
slice = None
if isinstance(node.slice.value, ast.Str):
slice = node.slice.value.s
elif isinstance(node.slice.value, ast.Num):
slice = node.slice.value.n
elif isinstance(node.slice.value, ast.Name):
slice = resolve_attr_id(node.slice.value)
return '{}[{}]'.format(value_id, slice)
elif isinstance(node, ast.Call):
return '{}()'.format(resolve_attr_id(node.func))
return node.id
def test__get_literal_value(self):
new_context = context.Context()
value = ast.Num(42)
expected = value.n
self.assertEqual(expected, new_context._get_literal_value(value))
value = ast.Str('spam')
expected = value.s
self.assertEqual(expected, new_context._get_literal_value(value))
value = ast.List([ast.Str('spam'), ast.Num(42)], ast.Load())
expected = [ast.Str('spam').s, ast.Num(42).n]
self.assertListEqual(expected, new_context._get_literal_value(value))
value = ast.Tuple([ast.Str('spam'), ast.Num(42)], ast.Load())
expected = (ast.Str('spam').s, ast.Num(42).n)
self.assertTupleEqual(expected, new_context._get_literal_value(value))
value = ast.Set([ast.Str('spam'), ast.Num(42)])
expected = set([ast.Str('spam').s, ast.Num(42).n])
self.assertSetEqual(expected, new_context._get_literal_value(value))
value = ast.Dict(['spam', 'eggs'], [42, 'foo'])
expected = dict(spam=42, eggs='foo')
self.assertDictEqual(expected, new_context._get_literal_value(value))
value = ast.Ellipsis()
self.assertIsNone(new_context._get_literal_value(value))
value = ast.Name('spam', ast.Load())
expected = value.id
self.assertEqual(expected, new_context._get_literal_value(value))
if six.PY3:
value = ast.NameConstant(True)
expected = str(value.value)
self.assertEqual(expected, new_context._get_literal_value(value))
if six.PY3:
value = ast.Bytes(b'spam')
expected = value.s
self.assertEqual(expected, new_context._get_literal_value(value))
self.assertIsNone(new_context._get_literal_value(None))
def infer(node, context, solver, from_call=False):
"""Infer the type of a given AST node"""
if isinstance(node, ast.Num):
return infer_numeric(node, solver)
elif isinstance(node, ast.Str):
return solver.z3_types.string
elif (sys.version_info[0] >= 3 and sys.version_info[1] >= 6 and
(isinstance(node, ast.FormattedValue) or isinstance(node, ast.JoinedStr))):
# Formatted strings were introduced in Python 3.6
return solver.z3_types.string
elif isinstance(node, ast.Bytes):
return solver.z3_types.bytes
elif isinstance(node, ast.List):
return infer_list(node, context, solver)
elif isinstance(node, ast.Dict):
return infer_dict(node, context, solver)
elif isinstance(node, ast.Tuple):
return infer_tuple(node, context, solver)
elif isinstance(node, ast.NameConstant):
return infer_name_constant(node, solver)
elif isinstance(node, ast.Set):
return infer_set(node, context, solver)
elif isinstance(node, ast.BinOp):
return infer_binary_operation(node, context, solver)
elif isinstance(node, ast.BoolOp):
return infer_boolean_operation(node, context, solver)
elif isinstance(node, ast.UnaryOp):
return infer_unary_operation(node, context, solver)
elif isinstance(node, ast.IfExp):
return infer_if_expression(node, context, solver)
elif isinstance(node, ast.Subscript):
return infer_subscript(node, context, solver)
elif sys.version_info[0] >= 3 and sys.version_info[1] >= 5 and isinstance(node, ast.Await):
# Await and Async were introduced in Python 3.5
return infer(node.value, context, solver)
elif isinstance(node, ast.Yield):
return infer(node.value, context, solver)
elif isinstance(node, ast.Compare):
return infer_compare(node, context, solver)
elif isinstance(node, ast.Name):
return infer_name(node, context)
elif isinstance(node, ast.ListComp):
return infer_sequence_comprehension(node, solver.z3_types.list, context, solver)
elif isinstance(node, ast.SetComp):
return infer_sequence_comprehension(node, solver.z3_types.set, context, solver)
elif isinstance(node, ast.DictComp):
return infer_dict_comprehension(node, context, solver)
elif isinstance(node, ast.Call):
return infer_func_call(node, context, solver)
elif isinstance(node, ast.Attribute):
return infer_attribute(node, context, from_call, solver)
elif isinstance(node, ast.Lambda):
return _infer_lambda(node, context, solver)
raise NotImplementedError("Inference for expression {} is not implemented yet.".format(type(node).__name__))