<s> import os <EOL> import sys <EOL> import ast <EOL> from . loaders import EnvFileConfigurationLoader , IniFileConfigurationLoader , EnvVarConfigurationLoader <EOL> from . exceptions import InvalidConfigurationFile , InvalidPath , InvalidConfigurationCast , UnknownConfiguration <EOL> from . casts import Boolean , Option , List , Tuple <EOL> MAGIC_FRAME_DEPTH = <NUM_LIT:3> <EOL> class ConfigurationDiscovery ( object ) : <EOL> default_filetypes = ( EnvFileConfigurationLoader , IniFileConfigurationLoader ) <EOL> def __init__ ( self , starting_path , filetypes = None , root_path = "<STR_LIT:/>" ) : <EOL> """<STR_LIT>""" <EOL> self . starting_path = os . path . realpath ( os . path . abspath ( starting_path ) ) <EOL> self . root_path = os . path . realpath ( root_path ) <EOL> if not self . starting_path . startswith ( self . root_path ) : <EOL> raise InvalidPath ( '<STR_LIT>' ) <EOL> if filetypes is None : <EOL> filetypes = self . default_filetypes <EOL> self . filetypes = filetypes <EOL> self . _config_files = None <EOL> def _scan_path ( self , path ) : <EOL> config_files = [ ] <EOL> for file_type in self . filetypes : <EOL> for filename in file_type . get_filenames ( path ) : <EOL> try : <EOL> config_files . append ( file_type ( filename ) ) <EOL> except InvalidConfigurationFile : <EOL> continue <EOL> return config_files <EOL> def _discover ( self ) : <EOL> self . _config_files = [ ] <EOL> path = self . starting_path <EOL> while not self . _config_files : <EOL> if os . path . isdir ( path ) : <EOL> self . _config_files += self . _scan_path ( path ) <EOL> if path == self . root_path : <EOL> break <EOL> path = os . path . dirname ( path ) <EOL> @ property <EOL> def config_files ( self ) : <EOL> if self . _config_files is None : <EOL> self . _discover ( ) <EOL> return self . _config_files <EOL> class Configuration ( object ) : <EOL> boolean = Boolean ( ) <EOL> list = List ( ) <EOL> tuple = Tuple ( ) <EOL> option = Option <EOL> eval = staticmethod ( ast . literal_eval ) <EOL> def __init__ ( self , configs = None , starting_path = None , root_path = "<STR_LIT:/>" ) : <EOL> if configs is None : <EOL> configs = [ EnvVarConfigurationLoader ( ) ] <EOL> self . configurations = configs <EOL> self . starting_path = starting_path <EOL> self . root_path = root_path <EOL> self . _initialized = False <EOL> @ staticmethod <EOL> def _caller_path ( ) : <EOL> frame = sys . _getframe ( MAGIC_FRAME_DEPTH ) <EOL> path = os . path . dirname ( frame . f_code . co_filename ) <EOL> return path <EOL> def _init_configs ( self ) : <EOL> if self . _initialized : <EOL> return <EOL> if self . starting_path is None : <EOL> self . starting_path = self . _caller_path ( ) <EOL> discovery = ConfigurationDiscovery ( self . starting_path , root_path = self . root_path ) <EOL> self . configurations . extend ( discovery . config_files ) <EOL> self . _initialized = True <EOL> def __call__ ( self , item , cast = lambda v : v , ** kwargs ) : <EOL> if not callable ( cast ) : <EOL> raise InvalidConfigurationCast ( "<STR_LIT>" ) <EOL> self . _init_configs ( ) <EOL> for configuration in self . configurations : <EOL> try : <EOL> return cast ( configuration [ item ] ) <EOL> except KeyError : <EOL> continue <EOL> if '<STR_LIT:default>' not in kwargs : <EOL> raise UnknownConfiguration ( "<STR_LIT>" . format ( item ) ) <EOL> return cast ( kwargs [ "<STR_LIT:default>" ] ) </s>
