<s> """<STR_LIT>""" <EOL> import ast <EOL> import inspect <EOL> from six import string_types <EOL> from six . moves import builtins <EOL> import sys <EOL> import types <EOL> from bpython import line as line_properties <EOL> from bpython . _py3compat import py3 <EOL> from bpython . inspection import is_new_style , AttrCleaner <EOL> _string_type_nodes = ( ast . Str , ast . Bytes ) if py3 else ( ast . Str , ) <EOL> _numeric_types = ( int , float , complex ) + ( ( ) if py3 else ( long , ) ) <EOL> if hasattr ( ast , '<STR_LIT>' ) : <EOL> _name_type_nodes = ( ast . Name , ast . NameConstant ) <EOL> else : <EOL> _name_type_nodes = ( ast . Name , ) <EOL> class EvaluationError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> def safe_eval ( expr , namespace ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return eval ( expr , namespace ) <EOL> except ( NameError , AttributeError , SyntaxError ) : <EOL> raise EvaluationError <EOL> def simple_eval ( node_or_string , namespace = None ) : <EOL> """<STR_LIT>""" <EOL> if namespace is None : <EOL> namespace = { } <EOL> if isinstance ( node_or_string , string_types ) : <EOL> node_or_string = ast . parse ( node_or_string , mode = '<STR_LIT>' ) <EOL> if isinstance ( node_or_string , ast . Expression ) : <EOL> node_or_string = node_or_string . body <EOL> def _convert ( node ) : <EOL> if isinstance ( node , _string_type_nodes ) : <EOL> return node . s <EOL> elif isinstance ( node , ast . Num ) : <EOL> return node . n <EOL> elif isinstance ( node , ast . Tuple ) : <EOL> return tuple ( map ( _convert , node . elts ) ) <EOL> elif isinstance ( node , ast . List ) : <EOL> return list ( map ( _convert , node . elts ) ) <EOL> elif isinstance ( node , ast . Dict ) : <EOL> return dict ( ( _convert ( k ) , _convert ( v ) ) for k , v <EOL> in zip ( node . keys , node . values ) ) <EOL> elif isinstance ( node , _name_type_nodes ) : <EOL> try : <EOL> return namespace [ node . id ] <EOL> except KeyError : <EOL> try : <EOL> return getattr ( builtins , node . id ) <EOL> except AttributeError : <EOL> raise EvaluationError ( "<STR_LIT>" % node . id ) <EOL> elif ( isinstance ( node , ast . UnaryOp ) and <EOL> isinstance ( node . op , ( ast . UAdd , ast . USub ) ) ) : <EOL> operand = _convert ( node . operand ) <EOL> if not type ( operand ) in _numeric_types : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if isinstance ( node . op , ast . UAdd ) : <EOL> return + operand <EOL> else : <EOL> return - operand <EOL> elif ( isinstance ( node , ast . BinOp ) and <EOL> isinstance ( node . op , ( ast . Add , ast . Sub ) ) ) : <EOL> left = _convert ( node . left ) <EOL> right = _convert ( node . right ) <EOL> if not ( type ( left ) in _numeric_types and <EOL> type ( right ) in _numeric_types ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if isinstance ( node . op , ast . Add ) : <EOL> return left + right <EOL> else : <EOL> return left - right <EOL> elif ( isinstance ( node , ast . Subscript ) and <EOL> isinstance ( node . slice , ast . Index ) ) : <EOL> obj = _convert ( node . value ) <EOL> index = _convert ( node . slice . value ) <EOL> return safe_getitem ( obj , index ) <EOL> if isinstance ( node , ast . Attribute ) : <EOL> obj = _convert ( node . value ) <EOL> attr = node . attr <EOL> return safe_get_attribute ( obj , attr ) <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> return _convert ( node_or_string ) <EOL> def safe_getitem ( obj , index ) : <EOL> if type ( obj ) in ( list , tuple , dict , bytes ) + string_types : <EOL> try : <EOL> return obj [ index ] <EOL> except ( KeyError , IndexError ) : <EOL> raise EvaluationError ( "<STR_LIT>" % ( index , obj ) ) <EOL> raise ValueError ( '<STR_LIT>' % ( type ( obj ) , ) ) <EOL> def find_attribute_with_name ( node , name ) : <EOL> if isinstance ( node , ast . Attribute ) and node . attr == name : <EOL> return node <EOL> for item in ast . iter_child_nodes ( node ) : <EOL> r = find_attribute_with_name ( item , name ) <EOL> if r : <EOL> return r <EOL> def evaluate_current_expression ( cursor_offset , line , namespace = None ) : <EOL> """<STR_LIT>""" <EOL> if namespace is None : <EOL> namespace = { } <EOL> temp_line = line [ : cursor_offset ] + '<STR_LIT>' + line [ cursor_offset : ] <EOL> temp_cursor = cursor_offset + <NUM_LIT:3> <EOL> temp_attribute = line_properties . current_expression_attribute ( <EOL> temp_cursor , temp_line ) <EOL> if temp_attribute is None : <EOL> raise EvaluationError ( "<STR_LIT>" ) <EOL> attr_before_cursor = temp_line [ temp_attribute . start : temp_cursor ] <EOL> def parse_trees ( cursor_offset , line ) : <EOL> for i in range ( cursor_offset - <NUM_LIT:1> , - <NUM_LIT:1> , - <NUM_LIT:1> ) : <EOL> try : <EOL> tree = ast . parse ( line [ i : cursor_offset ] ) <EOL> yield tree <EOL> except SyntaxError : <EOL> continue <EOL> largest_ast = None <EOL> for tree in parse_trees ( temp_cursor , temp_line ) : <EOL> attribute_access = find_attribute_with_name ( tree , attr_before_cursor ) <EOL> if attribute_access : <EOL> largest_ast = attribute_access . value <EOL> if largest_ast is None : <EOL> raise EvaluationError ( <EOL> "<STR_LIT>" ) <EOL> try : <EOL> return simple_eval ( largest_ast , namespace ) <EOL> except ValueError : <EOL> raise EvaluationError ( "<STR_LIT>" ) <EOL> def evaluate_current_attribute ( cursor_offset , line , namespace = None ) : <EOL> """<STR_LIT>""" <EOL> obj = evaluate_current_expression ( cursor_offset , line , namespace ) <EOL> attr = line_properties . current_expression_attribute ( cursor_offset , line ) <EOL> if attr is None : <EOL> raise EvaluationError ( "<STR_LIT>" ) <EOL> try : <EOL> return getattr ( obj , attr . word ) <EOL> except AttributeError : <EOL> raise EvaluationError ( <EOL> "<STR_LIT>" % ( attr . word , obj ) ) <EOL> def safe_get_attribute ( obj , attr ) : <EOL> """<STR_LIT>""" <EOL> if is_new_style ( obj ) : <EOL> with AttrCleaner ( obj ) : <EOL> result = safe_get_attribute_new_style ( obj , attr ) <EOL> if isinstance ( result , member_descriptor ) : <EOL> return getattr ( obj , attr ) <EOL> return result <EOL> return getattr ( obj , attr ) <EOL> class _ClassWithSlots ( object ) : <EOL> __slots__ = [ '<STR_LIT:a>' ] <EOL> member_descriptor = type ( _ClassWithSlots . a ) <EOL> def safe_get_attribute_new_style ( obj , attr ) : <EOL> """<STR_LIT>""" <EOL> if not is_new_style ( obj ) : <EOL> raise ValueError ( "<STR_LIT>" % obj ) <EOL> to_look_through = ( obj . __mro__ <EOL> if inspect . isclass ( obj ) <EOL> else ( obj , ) + type ( obj ) . __mro__ ) <EOL> for cls in to_look_through : <EOL> if hasattr ( cls , '<STR_LIT>' ) and attr in cls . __dict__ : <EOL> return cls . __dict__ [ attr ] <EOL> raise AttributeError ( ) </s>
