<s> from __future__ import print_function , absolute_import <EOL> from types import ModuleType <EOL> import weakref <EOL> from . import ir <EOL> from . errors import ConstantInferenceError <EOL> class ConstantInference ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , interp ) : <EOL> self . _interp = weakref . proxy ( interp ) <EOL> self . _cache = { } <EOL> def infer_constant ( self , name ) : <EOL> """<STR_LIT>""" <EOL> if name not in self . _cache : <EOL> try : <EOL> self . _cache [ name ] = ( True , self . _do_infer ( name ) ) <EOL> except ConstantInferenceError as exc : <EOL> self . _cache [ name ] = ( False , ( exc . __class__ , exc . args ) ) <EOL> success , val = self . _cache [ name ] <EOL> if success : <EOL> return val <EOL> else : <EOL> exc , args = val <EOL> raise exc ( * args ) <EOL> def _fail ( self , val ) : <EOL> raise ConstantInferenceError ( <EOL> "<STR_LIT>" % ( val , ) ) <EOL> def _do_infer ( self , name ) : <EOL> if not isinstance ( name , str ) : <EOL> raise TypeError ( "<STR_LIT>" <EOL> % ( name , ) ) <EOL> try : <EOL> defn = self . _interp . get_definition ( name ) <EOL> except KeyError : <EOL> raise ConstantInferenceError ( <EOL> "<STR_LIT>" % ( name , ) ) <EOL> try : <EOL> const = defn . infer_constant ( ) <EOL> except ConstantInferenceError : <EOL> if isinstance ( defn , ir . Expr ) : <EOL> return self . _infer_expr ( defn ) <EOL> self . _fail ( defn ) <EOL> return const <EOL> def _infer_expr ( self , expr ) : <EOL> if expr . op == '<STR_LIT>' : <EOL> func = self . infer_constant ( expr . func . name ) <EOL> return self . _infer_call ( func , expr ) <EOL> elif expr . op == '<STR_LIT>' : <EOL> value = self . infer_constant ( expr . value . name ) <EOL> return self . _infer_getattr ( value , expr ) <EOL> elif expr . op == '<STR_LIT>' : <EOL> return [ self . infer_constant ( i . name ) for i in expr . items ] <EOL> elif expr . op == '<STR_LIT>' : <EOL> return tuple ( self . infer_constant ( i . name ) for i in expr . items ) <EOL> self . _fail ( expr ) <EOL> def _infer_call ( self , func , expr ) : <EOL> if expr . kws or expr . vararg : <EOL> self . _fail ( expr ) <EOL> if ( func in ( slice , ) or <EOL> ( isinstance ( func , type ) and issubclass ( func , BaseException ) ) ) : <EOL> args = [ self . infer_constant ( a . name ) for a in expr . args ] <EOL> return func ( * args ) <EOL> self . _fail ( expr ) <EOL> def _infer_getattr ( self , value , expr ) : <EOL> if isinstance ( value , ( ModuleType , type ) ) : <EOL> return getattr ( value , expr . attr ) <EOL> self . _fail ( expr ) </s>
