def __call__(self): if self._single_condition: return _evaluate_condition_func(self._single_condition) if len(self._kwargs) > 1: raise Exception("Only one key value pair allowed") key, val = list(self._kwargs.items())[0] if not hasattr(config(), key): return False if getattr(config(), key) is val: # pylint: disable=R1703 return True return False
def test_expressions(self): with fake_config(a="b"): expression = or_(Exp(a="b"), Exp(b="c")) self.assertTrue(expression()) delattr(config(), "a") self.assertFalse(expression())
def test_config_already_initialized(self): namespace = Namespace() namespace.tmp = "tmp" initialize_config(namespace) with self.assertRaises(ConfigAlreadyInitializedException): initialize_config(Namespace()) self.assertEqual(namespace, config())
def test_config(self): namespace = Namespace() namespace.tmp1 = "val1" namespace.tmp2 = 2 initialize_config(namespace) conf = config() self.assertEqual(conf.tmp1, "val1") self.assertEqual(conf.tmp2, 2)
def test_destroy_config(self): initialize_config(Namespace()) conf = config() with self.assertRaises(AttributeError): conf.tmp destroy_config() parser2 = ArgumentParser() parser2.add_argument("--tmp5", type=str) parser2.add_argument("--tmp6", type=int) cli_args3 = ["--tmp5", "val5", "--tmp6", "6"] args3 = parser2.parse_args(cli_args3) initialize_config(args3) conf3 = config() self.assertNotEqual(conf3, conf) self.assertEqual(conf3.tmp5, "val5") self.assertEqual(conf3.tmp6, 6) with self.assertRaises(AttributeError): config().tmp1 with self.assertRaises(AttributeError): config().tmp2
def test_single_exp(self): @condition(Exp(a="b")) def tmp(): return "returned" initialize_config(Namespace()) conf = config() conf._allow_overriding = True conf.a = "b" self.assertTrue(tmp() == "returned") conf.a = "c" self.assertIsNone(tmp())
def _evaluate_condition_func( single_condition: Callable[[object], bool]) -> bool: """ Evaluates a condition function based on the state of the global config. """ try: conf_value = single_condition(config()) except Exception as exc: # pylint: disable=W0703 raise ConditionRaisedException from exc if _check_is_bool(conf_value): return conf_value raise ConditionDidNotReturnBooleansException( "The condition did not return a valid boolean!")
def argument_filler(*args: Any, **kwargs: Any) -> Callable: """ Wrapper around the original function. This function checks if arguments of the original function have the same name as attributes of the global config. If the arguments to be filled have been set explicitly in the fill_args function only the corresponding arguments are checked. If arguments are declared a arguments to be filled but are not present in the global config object it is still possible to provide them as keyword argument on function execution. If the corresponding arguments are not filled from the config and not provided on function execution an exception is raised. """ for name, _ in sig.parameters.items(): if name in args_to_be_filled or len(args_to_be_filled) == 0: try: value = getattr(config(), name) except AttributeError: value = _UNSET_VALUE filled_kwargs[name] = value if len(args) > 0: raise OnlyKeywordArgumentsAllowedException( (f"Only keyword arguments are allowed when executing a " f"function defined with the {fill_args.__name__} " f"decorator.")) filled_kwargs.update(kwargs) for name, value in filled_kwargs.items(): if value is _UNSET_VALUE: raise IllegalStateException( f"\n\tArgument {name} was not present in the global \n\t" f"config and was not provided as keyword argument when \n\t" f"the function {func} was executed. Please make sure \n\t" f"needed arguments are either provided within the config \n\t" f"or when running a {fill_args.__name__}-decorated function." ) return func(**filled_kwargs)
def test_subparser_condition_wrong_order(self): parser = ArgumentParser() subparsers = parser.add_subparsers(dest="command") parser_sub1 = subparsers.add_parser('sub1') parser_sub1.add_argument('--sub1-tmp', type=int) parser_sub2 = subparsers.add_parser('sub2') parser_sub2.add_argument('--sub2-tmp', type=int) args = parser.parse_args(["sub1", "--sub1-tmp", "1"]) initialize_config(args) self.assertEqual(config().sub1_tmp, 1) @condition( and_(Exp(lambda c: c.sub2_tmp == 2), Exp(lambda c: c.command == "sub2"))) def tmp1(): return "returned" with self.assertRaises(ConditionRaisedException): tmp1()
def test_subparser_condition_right_order(self): parser = ArgumentParser() subparsers = parser.add_subparsers(dest="command") parser_sub1 = subparsers.add_parser('sub1') parser_sub1.add_argument('--sub1-tmp', type=int) parser_sub2 = subparsers.add_parser('sub2') parser_sub2.add_argument('--sub2-tmp', type=int) args = parser.parse_args(["sub1", "--sub1-tmp", "1"]) initialize_config(args) self.assertEqual(config().sub1_tmp, 1) @condition( and_(Exp(lambda c: c.command == "sub2"), Exp(lambda c: c.sub2_tmp == 2))) def tmp2(): return "returned" with self.assertNotRaises(AttributeError): tmp2() self.assertIsNone(tmp2())
from pyppy.args import fill_args from pyppy.config import initialize_config, config initialize_config() config().debug = True @fill_args() def debug_log(debug, message): if debug: return f"debugging: {message}" assert debug_log(message="useful logs") == "debugging: useful logs" config().debug = False assert not debug_log(message="useful logs")
from pyppy.conditions import condition, Exp, and_ import types from pyppy.config import initialize_config, config args = types.SimpleNamespace() args.log_level = "WARN" args.specific_log_level = "LEVEL_1" initialize_config(args) @condition( and_( Exp(log_level="WARN"), Exp(specific_log_level="LEVEL_1") ) ) def log_warn_level_1(): return "WARNING LEVEL 1" assert log_warn_level_1() == "WARNING LEVEL 1" config().log_level = "INFO" assert not log_warn_level_1()
def debug_log(): if config().debug: return "debugging"
from pyppy.conditions import Exp, condition from pyppy.config import initialize_config, config import types args = types.SimpleNamespace() args.debug = False initialize_config(args) @condition(Exp(debug=True)) def debug_log(): return "hello" assert not debug_log() config().debug = True assert debug_log() == "hello"
from pyppy.conditions import Exp, condition from pyppy.config import initialize_config, config import types args = types.SimpleNamespace() args.log_level = "WARN_LEVEL_1" initialize_config(args) @condition(Exp(lambda config: config.log_level.startswith("WARN"))) def log_warn(): return "WARNING" assert log_warn() == "WARNING" config().log_level = "INFO_LEVEL_2" assert not log_warn()