add fastyaml loader

pull/9918/head
Stone Tickle 3 years ago committed by Daniel Mensinger
parent 7528c69fcc
commit bfb12222c3
  1. 233
      docs/refman/loaderyaml.py
  2. 3
      docs/refman/main.py

@ -28,71 +28,130 @@ from .model import (
from mesonbuild import mlog
from mesonbuild import mesonlib
from strictyaml import Map, MapPattern, Optional, Str, Seq, Int, Bool, load, EmptyList, OrValidator
from pathlib import Path
import typing as T
d_named_object = {
'name': Str(),
'description': Str(),
}
d_feture_check = {
Optional('since', default=''): Str(),
Optional('deprecated', default=''): Str(),
}
s_posarg = Map({
**d_feture_check,
'description': Str(),
'type': Str(),
Optional('default', default=''): Str(),
})
s_varargs = Map({
**d_named_object, **d_feture_check,
'type': Str(),
Optional('min_varargs', default=-1): Int(),
Optional('max_varargs', default=-1): Int(),
})
s_kwarg = Map({
**d_feture_check,
'type': Str(),
'description': Str(),
Optional('required', default=False): Bool(),
Optional('default', default=''): Str(),
})
s_function = Map({
**d_named_object, **d_feture_check,
'returns': Str(),
Optional('notes', default=[]): OrValidator(Seq(Str()), EmptyList()),
Optional('warnings', default=[]): OrValidator(Seq(Str()), EmptyList()),
Optional('example', default=''): Str(),
Optional('posargs'): MapPattern(Str(), s_posarg),
Optional('optargs'): MapPattern(Str(), s_posarg),
Optional('varargs'): s_varargs,
Optional('posargs_inherit', default=''): Str(),
Optional('optargs_inherit', default=''): Str(),
Optional('varargs_inherit', default=''): Str(),
Optional('kwargs'): MapPattern(Str(), s_kwarg),
Optional('kwargs_inherit', default=[]): OrValidator(OrValidator(Seq(Str()), EmptyList()), Str()),
})
s_object = Map({
**d_named_object, **d_feture_check,
'long_name': Str(),
Optional('extends', default=''): Str(),
Optional('notes', default=[]): OrValidator(Seq(Str()), EmptyList()),
Optional('warnings', default=[]): OrValidator(Seq(Str()), EmptyList()),
Optional('example', default=''): Str(),
Optional('methods'): Seq(s_function),
Optional('is_container', default=False): Bool()
})
class Template:
d_feature_check: T.Dict[str, T.Any] = {}
s_posarg: T.Dict[str, T.Any] = {}
s_varargs: T.Dict[str, T.Any] = {}
s_kwarg: T.Dict[str, T.Any] = {}
s_function: T.Dict[str, T.Any] = {}
s_object: T.Dict[str, T.Any] = {}
class StrictTemplate(Template):
def __init__(self) -> None:
from strictyaml import Map, MapPattern, Optional, Str, Seq, Int, Bool, EmptyList, OrValidator
d_named_object = {
'name': Str(),
'description': Str(),
}
d_feture_check = {
Optional('since', default=''): Str(),
Optional('deprecated', default=''): Str(),
}
self.s_posarg = Map({
**d_feture_check,
'description': Str(),
'type': Str(),
Optional('default', default=''): Str(),
})
self.s_varargs = Map({
**d_named_object, **d_feture_check,
'type': Str(),
Optional('min_varargs', default=-1): Int(),
Optional('max_varargs', default=-1): Int(),
})
self.s_kwarg = Map({
**d_feture_check,
'type': Str(),
'description': Str(),
Optional('required', default=False): Bool(),
Optional('default', default=''): Str(),
})
self.s_function = Map({
**d_named_object, **d_feture_check,
'returns': Str(),
Optional('notes', default=[]): OrValidator(Seq(Str()), EmptyList()),
Optional('warnings', default=[]): OrValidator(Seq(Str()), EmptyList()),
Optional('example', default=''): Str(),
Optional('posargs'): MapPattern(Str(), self.s_posarg),
Optional('optargs'): MapPattern(Str(), self.s_posarg),
Optional('varargs'): self.s_varargs,
Optional('posargs_inherit', default=''): Str(),
Optional('optargs_inherit', default=''): Str(),
Optional('varargs_inherit', default=''): Str(),
Optional('kwargs'): MapPattern(Str(), self.s_kwarg),
Optional('kwargs_inherit', default=[]): OrValidator(OrValidator(Seq(Str()), EmptyList()), Str()),
})
self.s_object = Map({
**d_named_object, **d_feture_check,
'long_name': Str(),
Optional('extends', default=''): Str(),
Optional('notes', default=[]): OrValidator(Seq(Str()), EmptyList()),
Optional('warnings', default=[]): OrValidator(Seq(Str()), EmptyList()),
Optional('example', default=''): Str(),
Optional('methods'): Seq(self.s_function),
Optional('is_container', default=False): Bool()
})
class FastTemplate(Template):
d_feature_check: T.Dict[str, T.Any] = {
'since': '',
'deprecated': '',
}
s_posarg = {
**d_feature_check,
'default': '',
}
s_varargs: T.Dict[str, T.Any] = {
**d_feature_check,
'min_varargs': -1,
'max_varargs': -1,
}
s_kwarg = {
**d_feature_check,
'required': False,
'default': '',
}
s_function = {
**d_feature_check,
'notes': [],
'warnings': [],
'example': '',
'posargs': {},
'optargs': {},
'varargs': None,
'posargs_inherit': '',
'optargs_inherit': '',
'varargs_inherit': '',
'kwargs': {},
'kwargs_inherit': [],
}
s_object = {
**d_feature_check,
'extends': '',
'notes': [],
'warnings': [],
'example': '',
'methods': [],
'is_container': False,
}
class LoaderYAML(LoaderBase):
def __init__(self, yaml_dir: Path) -> None:
def __init__(self, yaml_dir: Path, strict: bool=True) -> None:
super().__init__()
self.yaml_dir = yaml_dir
self.func_dir = self.yaml_dir / 'functions'
@ -100,8 +159,37 @@ class LoaderYAML(LoaderBase):
self.objs_dir = self.yaml_dir / 'objects'
self.builtin_dir = self.yaml_dir / 'builtins'
self.modules_dir = self.yaml_dir / 'modules'
self.strict = strict
template: Template
if self.strict:
import strictyaml
def loader(file: str, template: T.Any, label: str) -> T.Dict:
r: T.Dict = strictyaml.load(file, template, label=label).data
return r
def _process_function_base(self, raw: T.OrderedDict, obj: T.Optional[Object] = None) -> Function:
self._load = loader
template = StrictTemplate()
else:
import yaml
from yaml import CLoader
def loader(file: str, template: T.Any, label: str) -> T.Dict:
return {**template, **yaml.load(file, Loader=CLoader)}
self._load = loader
template = FastTemplate()
self.template = template
def _fix_default(self, v: T.Dict) -> None:
if v["default"] is False:
v["default"] = "false"
elif v["default"] is True:
v["default"] = "true"
else:
v["default"] = str(v["default"])
def _process_function_base(self, raw: T.Dict, obj: T.Optional[Object] = None) -> Function:
# Handle arguments
posargs = raw.pop('posargs', {})
optargs = raw.pop('optargs', {})
@ -119,18 +207,29 @@ class LoaderYAML(LoaderBase):
kwargs_mapped: T.Dict[str, Kwarg] = {}
for k, v in posargs.items():
if not self.strict:
v = {**self.template.s_posarg, **v}
self._fix_default(v)
v['type'] = Type(v['type'])
posargs_mapped += [PosArg(name=k, **v)]
for k, v in optargs.items():
if not self.strict:
v = {**self.template.s_posarg, **v}
self._fix_default(v)
v['type'] = Type(v['type'])
optargs_mapped += [PosArg(name=k, **v)]
for k, v in kwargs.items():
if not self.strict:
v = {**self.template.s_kwarg, **v}
self._fix_default(v)
v['type'] = Type(v['type'])
kwargs_mapped[k] = Kwarg(name=k, **v)
if varargs is not None:
if not self.strict:
varargs = {**self.template.s_varargs, **varargs}
varargs['type'] = Type(varargs['type'])
varargs_mapped = VarArgs(**varargs)
@ -157,13 +256,13 @@ class LoaderYAML(LoaderBase):
def _load_function(self, path: Path, obj: T.Optional[Object] = None) -> Function:
path_label = path.relative_to(self.yaml_dir).as_posix()
mlog.log('Loading', mlog.bold(path_label))
raw = load(self.read_file(path), s_function, label=path_label).data
raw = self._load(self.read_file(path), self.template.s_function, label=path_label)
return self._process_function_base(raw)
def _load_object(self, obj_type: ObjectType, path: Path) -> Object:
path_label = path.relative_to(self.yaml_dir).as_posix()
mlog.log(f'Loading', mlog.bold(path_label))
raw = load(self.read_file(path), s_object, label=path_label).data
raw = self._load(self.read_file(path), self.template.s_object, label=path_label)
def as_methods(mlist: T.List[Function]) -> T.List[Method]:
res: T.List[Method] = []
@ -174,7 +273,13 @@ class LoaderYAML(LoaderBase):
methods = raw.pop('methods', [])
obj = Object(methods=[], obj_type=obj_type, **raw)
obj.methods = as_methods([self._process_function_base(x, obj) for x in methods])
methods = []
for x in methods:
if not self.strict:
x = {**self.template.s_function, **x}
methods += [self._process_function_base(x, obj)]
obj.methods = as_methods(methods)
return obj
def _load_module(self, path: Path) -> T.List[Object]:

@ -33,7 +33,7 @@ meson_root = Path(__file__).absolute().parents[2]
def main() -> int:
parser = argparse.ArgumentParser(description='Meson reference manual generator')
parser.add_argument('-l', '--loader', type=str, default='yaml', choices=['yaml', 'pickle'], help='Information loader backend')
parser.add_argument('-l', '--loader', type=str, default='yaml', choices=['yaml', 'fastyaml', 'pickle'], help='Information loader backend')
parser.add_argument('-g', '--generator', type=str, choices=['print', 'pickle', 'md', 'json', 'man'], required=True, help='Generator backend')
parser.add_argument('-s', '--sitemap', type=Path, default=meson_root / 'docs' / 'sitemap.txt', help='Path to the input sitemap.txt')
parser.add_argument('-o', '--out', type=Path, required=True, help='Output directory for generated files')
@ -49,6 +49,7 @@ def main() -> int:
loaders: T.Dict[str, T.Callable[[], LoaderBase]] = {
'yaml': lambda: LoaderYAML(args.input),
'fastyaml': lambda: LoaderYAML(args.input, strict=False),
'pickle': lambda: LoaderPickle(args.input),
}

Loading…
Cancel
Save