def evaluate_current_attribute(cursor_offset, line, namespace=None): """Safely evaluates the expression having an attributed accesssed""" # this function runs user code in case of custom descriptors, # so could fail in any way obj = evaluate_current_expression(cursor_offset, line, namespace) attr = line_properties.current_expression_attribute(cursor_offset, line) if attr is None: raise EvaluationError("No attribute found to look up") try: return getattr(obj, attr.word) except AttributeError: raise EvaluationError("can't lookup attribute %s on %r" % (attr.word, obj))
def evaluate_current_attribute(cursor_offset, line, namespace=None): """Safely evaluates the expression having an attributed accesssed""" # this function runs user code in case of custom descriptors, # so could fail in any way obj = evaluate_current_expression(cursor_offset, line, namespace) attr = line_properties.current_expression_attribute(cursor_offset, line) if attr is None: raise EvaluationError("No attribute found to look up") try: return getattr(obj, attr.word) except AttributeError: raise EvaluationError( "can't lookup attribute %s on %r" % (attr.word, obj))
def evaluate_current_expression(cursor_offset, line, namespace=None): """ Return evaluated expression to the right of the dot of current attribute. Only evaluates builtin objects, and do any attribute lookup. """ # Builds asts from with increasing numbers of characters back from cursor. # Find the biggest valid ast. # Once our attribute access is found, return its .value subtree if namespace is None: namespace = {} # in case attribute is blank, e.g. foo.| -> foo.xxx| temp_line = line[:cursor_offset] + 'xxx' + line[cursor_offset:] temp_cursor = cursor_offset + 3 temp_attribute = line_properties.current_expression_attribute( temp_cursor, temp_line) if temp_attribute is None: raise EvaluationError("No current attribute") attr_before_cursor = temp_line[temp_attribute.start:temp_cursor] def parse_trees(cursor_offset, line): for i in range(cursor_offset - 1, -1, -1): try: tree = ast.parse(line[i:cursor_offset]) yield tree except SyntaxError: continue largest_ast = None for tree in parse_trees(temp_cursor, temp_line): attribute_access = find_attribute_with_name(tree, attr_before_cursor) if attribute_access: largest_ast = attribute_access.value if largest_ast is None: raise EvaluationError( "Corresponding ASTs to right of cursor are invalid") try: return simple_eval(largest_ast, namespace) except ValueError: raise EvaluationError("Could not safely evaluate")
def locate(self, current_offset, line): return lineparts.current_expression_attribute(current_offset, line)