"""Thin wrapper around the dependency so we can maintain some stability while being ableto swap implementations (e.g. replace `tomlkit`_ with `toml`_).`tomlkit`_ is preferred because it supports comments... _tomlkit: https://github.com/sdispater/tomlkit.. _toml: https://github.com/uiri/toml"""fromtypingimportAny,List,MutableMapping,NewType,Tuple,TypeVar,Union,castimporttomlkitTOMLMapping=NewType("TOMLMapping",MutableMapping)"""Abstraction on the value returned by :obj:`loads`.This kind of object ideally should present a dict-like interface and be able to preservethe formatting and comments of the original TOML file."""T=TypeVar("T")
[docs]defloads(text:str)->TOMLMapping:"""Parse a string containing TOML into a dict-like object, preserving style somehow. """returnTOMLMapping(cast(MutableMapping,tomlkit.loads(text)))
[docs]defdumps(obj:Union[TOMLMapping,dict])->str:# and do not change the object# TODO: If/when tomlkit allows serialising arbitrary Mapping objects, replace union# with Mapping"""Serialize a dict-like object into a TOML str, If the object was generated via :obj:`loads`, then the style will be preserved. """returntomlkit.dumps(obj)# type: ignore[arg-type]
# TODO: Once tomlkit improves dumps' type hints, remove type ignore comment
[docs]defsetdefault(obj:MutableMapping,key:str,value:T)->T:# TODO: Use recursive type for obj, when available in mypy, and remove type: ignore"""tomlkit seems to be tricky to use together with setdefault, this function is a workaround for that. When ``key`` is string containing ``'.'``, it will perform a nested setdefault. """keys=key.split(".")items:List[Tuple[str,Any]]=list(zip(keys,[{}]*len(keys)))items[-1]=(keys[-1],value)last=objforkey,valueinitems:ifkeynotinlast:last[key]=valuelast=last[key]# type: ignorereturncast(T,last)