def run(args: List[str]) -> int: """ Run the program. :arg args: A list of command line arguments. Typically :python:`sys.argv`. :returns: A program return code. 0 for success, integers for any errors. These are documented in :func:`main`. """ flog = mlog.fields(func='run') flog.fields(raw_args=args).info('Enter') program_name = os.path.basename(args[0]) try: args: argparse.Namespace = parse_args(program_name, args[1:]) except InvalidArgumentError as e: print(e) return 2 cfg = load_config(args.config_file) flog.fields(config=cfg).info('Config loaded') context_data = app_context.create_contexts(args=args, cfg=cfg) with app_context.app_and_lib_context(context_data) as (app_ctx, dummy_): twiggy.dict_config(app_ctx.logging_cfg.dict()) flog.debug('Set logging config') return ARGS_MAP[args.command]()
def run(self): """ Run the program. This is the main entrypoint to the magnate client """ # Create the statedir if it doesn't exist if not os.path.exists(self.cfg['state_dir']): os.makedirs(self.cfg['state_dir']) twiggy.dict_config(self.cfg['logging']) # Base data attributes self._load_data_definitions() ui_plugins = load('magnate.ui', subclasses=UserInterface) for UIClass in ui_plugins: #pylint: disable=invalid-name if UIClass.__module__.startswith('magnate.ui.{}'.format( self.cfg['ui_plugin'])): break else: print('Unknown user ui: {}'.format(self.cfg['ui_plugin'])) return 1 # Try using uvloop instead of the asyncio event loop if self.cfg['use_uvloop']: try: import uvloop except Exception: print( 'Could not import uvloop. Falling back on asyncio event loop' ) try: asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) except Exception: print( 'Could not set uvloop to be the event loop. Falling back on asyncio event loop' ) loop = asyncio.get_event_loop() self.pubpen = PubPen(loop) self._setup_markets() self.dispatcher = Dispatcher(self, self.markets) # UIClass is always available because we'd have already returned (via # the for-else) if UIClass was not defined try: user_interface = UIClass(self.pubpen, self.cfg['ui_args']) # pylint: disable=undefined-loop-variable return user_interface.run() except Exception as e: mlog.trace('error').error( 'Exception raised while running the user interface') raise
def test_dict_config_incremental_true(mocker): def return_how_called(*args, **kwargs): return (args, kwargs) cfg = copy.deepcopy(VALID_CONFIG) del cfg['emitters']['some'] cfg['incremental'] = True add_emitters = mocker.patch('twiggy.add_emitters') mocker.patch('twiggy.emitters') emitters_dict_clear = mocker.patch('twiggy.emitters.clear') mocker.patch('twiggy.filters.names', return_how_called) twiggy.dict_config(cfg) assert emitters_dict_clear.call_args_list == [] assert len(add_emitters.call_args_list) == 1 assert len(add_emitters.call_args_list[0][0]) == 1 cfg = copy.deepcopy(VALID_CONFIG) del cfg['emitters']['all'] cfg['incremental'] = True twiggy.dict_config(cfg) assert emitters_dict_clear.call_args_list == [] assert len(add_emitters.call_args_list) == 2 assert len(add_emitters.call_args_list[0][0]) == 1 assert len(add_emitters.call_args_list[1][0]) == 1 # call_args_list is nested like this: [call(positional_args(first_emitter)),] # We expect to have called add_emitters twice with one positional arg each time all_emitter = add_emitters.call_args_list[0][0][0] some_emitter = add_emitters.call_args_list[1][0][0] assert all_emitter[0] == 'all' assert all_emitter[1] == twiggy.levels.DEBUG assert all_emitter[2] is None assert isinstance(all_emitter[3], twiggy.outputs.StreamOutput) assert all_emitter[3]._format == twiggy.formats.line_format assert all_emitter[3].stream == 'testing1' assert some_emitter[0] == 'some' assert some_emitter[1] == twiggy.levels.WARNING assert some_emitter[2] == [(('a', 'b'), {}), (('c', 'd'), {})] assert isinstance(some_emitter[3], twiggy.outputs.StreamOutput) assert some_emitter[3]._format == twiggy.formats.shell_format assert some_emitter[3].stream == 'testing2'
def test_dict_config_incremental_false_contents(mocker): def return_how_called(*args, **kwargs): return (args, kwargs) cfg = copy.deepcopy(VALID_CONFIG) del cfg['emitters']['some'] add_emitters = mocker.patch('twiggy.add_emitters') mocker.patch('twiggy.emitters') emitters_dict_clear = mocker.patch('twiggy.emitters.clear') mocker.patch('twiggy.filters.names', return_how_called) twiggy.dict_config(cfg) assert emitters_dict_clear.call_args_list == [mocker.call()] assert len(add_emitters.call_args_list) == 1 assert len(add_emitters.call_args_list[0][0]) == 1 the_emitter = add_emitters.call_args_list[0][0][0] assert the_emitter[0] == 'all' assert the_emitter[1] == twiggy.levels.DEBUG assert the_emitter[2] is None assert isinstance(the_emitter[3], twiggy.outputs.StreamOutput) assert the_emitter[3]._format == twiggy.formats.line_format assert the_emitter[3].stream == 'testing1' cfg = copy.deepcopy(VALID_CONFIG) del cfg['emitters']['all'] twiggy.dict_config(cfg) # Note: This does not check that the clear call happens before the add_emitters call. # The test_dict_config_incremental_false_order() check takes care of that. assert emitters_dict_clear.call_args_list == [mocker.call(), mocker.call()] assert len(add_emitters.call_args_list) == 2 assert len(add_emitters.call_args_list[1][0]) == 1 the_emitter = add_emitters.call_args_list[1][0][0] assert the_emitter[0] == 'some' assert the_emitter[1] == twiggy.levels.WARNING assert the_emitter[2] == [(('a', 'b'), {}), (('c', 'd'), {})] assert isinstance(the_emitter[3], twiggy.outputs.StreamOutput) assert the_emitter[3]._format == twiggy.formats.shell_format assert the_emitter[3].stream == 'testing2'
def test_dict_config_incremental_false_order(mocker): """ With incremental=false it is important that the dictionary is cleared before the emitter is added. We'll do this by testing the emitters dict instead of a mock """ cfg = copy.deepcopy(VALID_CONFIG) del cfg['emitters']['some'] twiggy.dict_config(cfg) assert len(twiggy.emitters) == 1 assert 'all' in twiggy.emitters cfg = copy.deepcopy(VALID_CONFIG) del cfg['emitters']['all'] twiggy.dict_config(cfg) assert len(twiggy.emitters) == 1 assert 'some' in twiggy.emitters
def test_dict_config_valid(mocker): def return_how_called(*args, **kwargs): return (args, kwargs) cfg = copy.deepcopy(VALID_CONFIG) add_emitters = mocker.patch('twiggy.add_emitters') mocker.patch('twiggy.emitters') emitters_dict_clear = mocker.patch('twiggy.emitters.clear') mocker.patch('twiggy.filters.names', return_how_called) twiggy.dict_config(cfg) assert emitters_dict_clear.call_args_list == [mocker.call()] assert len(add_emitters.call_args_list) == 1 assert len(add_emitters.call_args_list[0][0]) == 2 # call_args_list is nested like this: [call(positional_args(first_emitter)),] # We expect to have called add_emitters once with two positional args which are # themselves tuples if add_emitters.call_args_list[0][0][0][0] == 'all': all_emitter = add_emitters.call_args_list[0][0][0] some_emitter = add_emitters.call_args_list[0][0][1] else: some_emitter = add_emitters.call_args_list[0][0][0] all_emitter = add_emitters.call_args_list[0][0][1] assert all_emitter[0] == 'all' assert all_emitter[1] == twiggy.levels.DEBUG assert all_emitter[2] is None assert isinstance(all_emitter[3], twiggy.outputs.StreamOutput) assert all_emitter[3]._format == twiggy.formats.line_format assert all_emitter[3].stream == 'testing1' assert some_emitter[0] == 'some' assert some_emitter[1] == twiggy.levels.WARNING assert some_emitter[2] == [(('a', 'b'), {}), (('c', 'd'), {})] assert isinstance(some_emitter[3], twiggy.outputs.StreamOutput) assert some_emitter[3]._format == twiggy.formats.shell_format assert some_emitter[3].stream == 'testing2'
def test_twiggy_smoketest(self, mocker): cfg = c._read_config(tuple()) m = mocker.mock_open() mocker.patch('builtins.open', m) twiggy.dict_config(cfg['logging'])
def test_dict_config_invalid(internal_log): with pytest.raises(ValueError) as excinfo: twiggy.dict_config({}) assert excinfo.value.message == "Config dict must contain a 'version' key"