def test_literal_type(self): literal = self.get_call('1.0') assert isinstance(literal, tree.Literal) assert type(parser_utils.safe_literal_eval(literal.value)) == float literal = self.get_call('1') assert isinstance(literal, tree.Literal) assert type(parser_utils.safe_literal_eval(literal.value)) == int literal = self.get_call('"hello"') assert isinstance(literal, tree.Literal) assert parser_utils.safe_literal_eval(literal.value) == 'hello'
def test_name_and_call_positions(self): name = self.get_call('name\nsomething_else') assert name.value == 'name' assert name.start_pos == (1, 0) assert name.end_pos == (1, 4) leaf = self.get_call('1.0\n') assert leaf.value == '1.0' assert parser_utils.safe_literal_eval(leaf.value) == 1.0 assert leaf.start_pos == (1, 0) assert leaf.end_pos == (1, 3)
def test_quoted_strings(self): string_tokens = [ 'u"test"', 'u"""test"""', 'U"""test"""', "u'''test'''", "U'''test'''", ] for s in string_tokens: module = parse('''a = %s\n''' % s) simple_stmt = module.children[0] expr_stmt = simple_stmt.children[0] assert len(expr_stmt.children) == 3 string_tok = expr_stmt.children[2] assert string_tok.type == 'string' assert string_tok.value == s assert safe_literal_eval(string_tok.value) == 'test'
def safe_literal_eval(inference_state, value): return parser_utils.safe_literal_eval(value)
def safe_literal_eval(evaluator, value): return parser_utils.safe_literal_eval(value)
def eval_atom(context, atom): """ Basically to process ``atom`` nodes. The parser sometimes doesn't generate the node (because it has just one child). In that case an atom might be a name or a literal as well. """ if atom.type == 'name': # This is the first global lookup. stmt = tree.search_ancestor(atom, 'expr_stmt', 'lambdef') or atom if stmt.type == 'lambdef': stmt = atom return context.py__getattribute__(name_or_str=atom, position=stmt.start_pos, search_global=True) elif isinstance(atom, tree.Literal): string = parser_utils.safe_literal_eval(atom.value) return ContextSet(compiled.create(context.evaluator, string)) else: c = atom.children if c[0].type == 'string': # Will be one string. context_set = eval_atom(context, c[0]) for string in c[1:]: right = eval_atom(context, string) context_set = _eval_comparison(context.evaluator, context, context_set, '+', right) return context_set # Parentheses without commas are not tuples. elif c[0] == '(' and not len(c) == 2 \ and not(c[1].type == 'testlist_comp' and len(c[1].children) > 1): return context.eval_node(c[1]) try: comp_for = c[1].children[1] except (IndexError, AttributeError): pass else: if comp_for == ':': # Dict comprehensions have a colon at the 3rd index. try: comp_for = c[1].children[3] except IndexError: pass if comp_for.type == 'comp_for': return ContextSet( iterable.Comprehension.from_atom(context.evaluator, context, atom)) # It's a dict/list/tuple literal. array_node = c[1] try: array_node_c = array_node.children except AttributeError: array_node_c = [] if c[0] == '{' and (array_node == '}' or ':' in array_node_c): context = iterable.DictLiteralContext(context.evaluator, context, atom) else: context = iterable.SequenceLiteralContext(context.evaluator, context, atom) return ContextSet(context)
def eval_atom(self, context, atom): """ Basically to process ``atom`` nodes. The parser sometimes doesn't generate the node (because it has just one child). In that case an atom might be a name or a literal as well. """ if atom.type == 'name': # This is the first global lookup. stmt = tree.search_ancestor( atom, 'expr_stmt', 'lambdef' ) or atom if stmt.type == 'lambdef': stmt = atom return context.py__getattribute__( name_or_str=atom, position=stmt.start_pos, search_global=True ) elif isinstance(atom, tree.Literal): string = parser_utils.safe_literal_eval(atom.value) return set([compiled.create(self, string)]) else: c = atom.children if c[0].type == 'string': # Will be one string. types = self.eval_atom(context, c[0]) for string in c[1:]: right = self.eval_atom(context, string) types = precedence.calculate(self, context, types, '+', right) return types # Parentheses without commas are not tuples. elif c[0] == '(' and not len(c) == 2 \ and not(c[1].type == 'testlist_comp' and len(c[1].children) > 1): return self.eval_element(context, c[1]) try: comp_for = c[1].children[1] except (IndexError, AttributeError): pass else: if comp_for == ':': # Dict comprehensions have a colon at the 3rd index. try: comp_for = c[1].children[3] except IndexError: pass if comp_for.type == 'comp_for': return set([iterable.Comprehension.from_atom(self, context, atom)]) # It's a dict/list/tuple literal. array_node = c[1] try: array_node_c = array_node.children except AttributeError: array_node_c = [] if c[0] == '{' and (array_node == '}' or ':' in array_node_c): context = iterable.DictLiteralContext(self, context, atom) else: context = iterable.SequenceLiteralContext(self, context, atom) return set([context])
def eval_atom(self, context, atom): """ Basically to process ``atom`` nodes. The parser sometimes doesn't generate the node (because it has just one child). In that case an atom might be a name or a literal as well. """ if atom.type == 'name': # This is the first global lookup. stmt = atom.get_definition() if stmt.type == 'comp_for': stmt = tree.search_ancestor(stmt, ('expr_stmt', 'lambdef', 'funcdef', 'classdef')) if stmt is None or stmt.type != 'expr_stmt': # We only need to adjust the start_pos for statements, because # there the name cannot be used. stmt = atom return context.py__getattribute__( name_or_str=atom, position=stmt.start_pos, search_global=True ) elif isinstance(atom, tree.Literal): string = parser_utils.safe_literal_eval(atom.value) return set([compiled.create(self, string)]) else: c = atom.children if c[0].type == 'string': # Will be one string. types = self.eval_atom(context, c[0]) for string in c[1:]: right = self.eval_atom(context, string) types = precedence.calculate(self, context, types, '+', right) return types # Parentheses without commas are not tuples. elif c[0] == '(' and not len(c) == 2 \ and not(c[1].type == 'testlist_comp' and len(c[1].children) > 1): return self.eval_element(context, c[1]) try: comp_for = c[1].children[1] except (IndexError, AttributeError): pass else: if comp_for == ':': # Dict comprehensions have a colon at the 3rd index. try: comp_for = c[1].children[3] except IndexError: pass if comp_for.type == 'comp_for': return set([iterable.Comprehension.from_atom(self, context, atom)]) # It's a dict/list/tuple literal. array_node = c[1] try: array_node_c = array_node.children except AttributeError: array_node_c = [] if c[0] == '{' and (array_node == '}' or ':' in array_node_c): context = iterable.DictLiteralContext(self, context, atom) else: context = iterable.SequenceLiteralContext(self, context, atom) return set([context])