def decorator(f): import inspect # The path is relative to the file the caller is defined in. module = inspect.getmodule(f) test_path = Path(module.__file__) nt_path = test_path.parent / relpath raw_params = nt.load(nt_path) raw_args = set.union(*(set(x) for x in raw_params)) - {'id'} # Make sure there aren't any missing/extra parameters: for params in raw_params: missing = raw_args - set(params) if missing: missing_str = ', '.join(f"'{x}'" for x in missing) raise ValueError( f"{nt_path}: {f.__name__}: missing parameter(s) {missing_str}" ) args = list(raw_args) params = [ pytest.param(*(x[k] for k in args), id=x.get('id', None)) for x in raw_params ] return parametrize(args, params)(f)
def load(self, path="default.conf"): self.clear() with open(process_path(path)) as f: config = conf_provider.load(f) if config is not None: self.update(config) object.__setattr__(self, "dirty", False)
def create_models(design_folder, output_folder): for f in [f for f in listdir(design_folder) if isfile(join(design_folder, f)) and f[-3:] == '.nt' and f[:5] == 'model']: models = nt.load(join(design_folder, f), 'dict') for model in models: create_model_file(output_folder, model) for k in models[model]: if k == 'fields': create_properties(output_folder, model, models[model][k])
import nestedtext as nt from voluptuous import Schema, Coerce, Invalid from inform import fatal, full_stop from pprint import pprint schema = Schema({ 'debug': Coerce(bool), 'secret_key': str, 'allowed_hosts': [str], 'database': { 'engine': str, 'host': str, 'port': Coerce(int), 'user': str, }, 'webmaster_email': str, }) try: keymap = {} raw = nt.load('deploy.nt', keymap=keymap) config = schema(raw) except nt.NestedTextError as e: e.terminate() except Invalid as e: kind = 'key' if 'key' in e.msg else 'value' loc = keymap[tuple(e.path)] fatal(full_stop(e.msg), culprit=e.path, codicil=loc.as_line(kind)) pprint(config)
def get_db_engine(design_folder): settings = nt.load(os.path.join(design_folder, 'settings.nt'), 'dict') if 'db_engine' in settings: return settings['db_engine'] return None
def load_io(content, _): io = StringIO(content) return lambda: nt.load(io), None
def factory(): with open(p) as f: return nt.load(f)
def load_path_no_ext(p): return lambda: nt.load(p), str(p)
def load_path(p): return lambda: nt.load(p), str(p)
def load_str(p): return lambda: nt.load(str(p)), str(p)
def test_load_api_errors(): with pytest.raises(FileNotFoundError): nt.load('does_not_exist.nt') with pytest.raises(TypeError): nt.load(['path_1.nt', 'path_2.nt'])
def test_all(case: nt_test_api.TestCase): if case.id in skip_testcases: pytest.skip(skip_testcases[case.id]) if "load" in case.case: load_in_path = case.case["load"]["in"]["path"] if case.id in skip_load_testcases: logger.warning("Skipping load check for %s: %s", case.id, skip_load_testcases[case.id]) elif "out" in case.case["load"]: logger.info("Checking successful load") expected = case.case["load"]["out"]["data"] with open(load_in_path, "r", encoding="utf-8") as f: actual = nt.load(f) assert actual == expected # Debug info. logger.debug("Loaded %s", load_in_path) with open(load_in_path, "r", encoding="utf-8") as f: logger.debug("\n%s", f.read()) logger.debug("%s", json.dumps(actual)) # Check loads() function too. with open(load_in_path, "r", encoding="utf-8") as f: actual2 = nt.loads(f.read()) assert actual2 == expected elif "err" in case.case["load"]: logger.info("Checking load error")
value = settings[value[1:].strip()] return value if isinstance(value, dict): return {k: expand_settings(v) for k, v in value.items()} if isinstance(value, list): return [expand_settings(v) for v in value] raise NotImplementedError(value) try: # Read settings config_filepath = Path('postmortem.nt') if config_filepath.exists(): # load from file settings = nt.load(config_filepath) # expand references settings = expand_settings(settings) # check settings and transform to desired types settings = schema(settings) # show the resulting settings pprint(settings) except nt.NestedTextError as e: e.report() except Invalid as e: print(f"ERROR: {', '.join(str(p) for p in e.path)}: {e.msg}")
#!/usr/bin/env python3 import nestedtext as nt from pydantic import BaseModel, EmailStr from typing import List from pprint import pprint class Database(BaseModel): engine: str host: str port: int user: str class Config(BaseModel): debug: bool secret_key: str allowed_hosts: List[str] database: Database webmaster_email: EmailStr obj = nt.load('deploy.nt') config = Config.parse_obj(obj) pprint(config.dict())
#!/usr/bin/env python3 import nestedtext as nt from voluptuous import Schema, Coerce from pprint import pprint schema = Schema({ 'debug': Coerce(bool), 'secret_key': str, 'allowed_hosts': [str], 'database': { 'engine': str, 'host': str, 'port': Coerce(int), 'user': str, }, 'webmaster_email': str, }) raw = nt.load('deploy.nt') config = schema(raw) pprint(config)
def _do_load_with_linenos(path): import nestedtext as nt keymap = {} return nt.load(path, keymap=keymap), keymap