Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tomlkit/api.py: 59%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

109 statements  

1from __future__ import annotations 

2 

3import contextlib 

4import datetime as _datetime 

5 

6from collections.abc import Mapping 

7from typing import IO 

8from typing import Iterable 

9from typing import TypeVar 

10 

11from tomlkit._utils import parse_rfc3339 

12from tomlkit.container import Container 

13from tomlkit.exceptions import UnexpectedCharError 

14from tomlkit.items import CUSTOM_ENCODERS 

15from tomlkit.items import AoT 

16from tomlkit.items import Array 

17from tomlkit.items import Bool 

18from tomlkit.items import Comment 

19from tomlkit.items import Date 

20from tomlkit.items import DateTime 

21from tomlkit.items import DottedKey 

22from tomlkit.items import Encoder 

23from tomlkit.items import Float 

24from tomlkit.items import InlineTable 

25from tomlkit.items import Integer 

26from tomlkit.items import Item as _Item 

27from tomlkit.items import Key 

28from tomlkit.items import SingleKey 

29from tomlkit.items import String 

30from tomlkit.items import StringType as _StringType 

31from tomlkit.items import Table 

32from tomlkit.items import Time 

33from tomlkit.items import Trivia 

34from tomlkit.items import Whitespace 

35from tomlkit.items import item 

36from tomlkit.parser import Parser 

37from tomlkit.toml_document import TOMLDocument 

38 

39 

40def loads(string: str | bytes) -> TOMLDocument: 

41 """ 

42 Parses a string into a TOMLDocument. 

43 

44 Alias for parse(). 

45 """ 

46 return parse(string) 

47 

48 

49def dumps(data: Mapping, sort_keys: bool = False) -> str: 

50 """ 

51 Dumps a TOMLDocument into a string. 

52 """ 

53 if not isinstance(data, Container) and isinstance(data, Mapping): 

54 data = item(dict(data), _sort_keys=sort_keys) 

55 

56 try: 

57 # data should be a `Container` (and therefore implement `as_string`) 

58 # for all type safe invocations of this function 

59 return data.as_string() # type: ignore[attr-defined] 

60 except AttributeError as ex: 

61 msg = f"Expecting Mapping or TOML Container, {type(data)} given" 

62 raise TypeError(msg) from ex 

63 

64 

65def load(fp: IO[str] | IO[bytes]) -> TOMLDocument: 

66 """ 

67 Load toml document from a file-like object. 

68 """ 

69 return parse(fp.read()) 

70 

71 

72def dump(data: Mapping, fp: IO[str], *, sort_keys: bool = False) -> None: 

73 """ 

74 Dump a TOMLDocument into a writable file stream. 

75 

76 :param data: a dict-like object to dump 

77 :param sort_keys: if true, sort the keys in alphabetic order 

78 

79 :Example: 

80 

81 >>> with open("output.toml", "w") as fp: 

82 ... tomlkit.dump(data, fp) 

83 """ 

84 fp.write(dumps(data, sort_keys=sort_keys)) 

85 

86 

87def parse(string: str | bytes) -> TOMLDocument: 

88 """ 

89 Parses a string or bytes into a TOMLDocument. 

90 """ 

91 return Parser(string).parse() 

92 

93 

94def document() -> TOMLDocument: 

95 """ 

96 Returns a new TOMLDocument instance. 

97 """ 

98 return TOMLDocument() 

99 

100 

101# Items 

102def integer(raw: str | int) -> Integer: 

103 """Create an integer item from a number or string.""" 

104 return item(int(raw)) 

105 

106 

107def float_(raw: str | float) -> Float: 

108 """Create an float item from a number or string.""" 

109 return item(float(raw)) 

110 

111 

112def boolean(raw: str) -> Bool: 

113 """Turn `true` or `false` into a boolean item.""" 

114 return item(raw == "true") 

115 

116 

117def string( 

118 raw: str, 

119 *, 

120 literal: bool = False, 

121 multiline: bool = False, 

122 escape: bool = True, 

123) -> String: 

124 """Create a string item. 

125 

126 By default, this function will create *single line basic* strings, but 

127 boolean flags (e.g. ``literal=True`` and/or ``multiline=True``) 

128 can be used for personalization. 

129 

130 For more information, please check the spec: `<https://toml.io/en/v1.0.0#string>`__. 

131 

132 Common escaping rules will be applied for basic strings. 

133 This can be controlled by explicitly setting ``escape=False``. 

134 Please note that, if you disable escaping, you will have to make sure that 

135 the given strings don't contain any forbidden character or sequence. 

136 """ 

137 type_ = _StringType.select(literal, multiline) 

138 return String.from_raw(raw, type_, escape) 

139 

140 

141def date(raw: str) -> Date: 

142 """Create a TOML date.""" 

143 value = parse_rfc3339(raw) 

144 if not isinstance(value, _datetime.date): 

145 raise ValueError("date() only accepts date strings.") 

146 

147 return item(value) 

148 

149 

150def time(raw: str) -> Time: 

151 """Create a TOML time.""" 

152 value = parse_rfc3339(raw) 

153 if not isinstance(value, _datetime.time): 

154 raise ValueError("time() only accepts time strings.") 

155 

156 return item(value) 

157 

158 

159def datetime(raw: str) -> DateTime: 

160 """Create a TOML datetime.""" 

161 value = parse_rfc3339(raw) 

162 if not isinstance(value, _datetime.datetime): 

163 raise ValueError("datetime() only accepts datetime strings.") 

164 

165 return item(value) 

166 

167 

168def array(raw: str = "[]") -> Array: 

169 """Create an array item for its string representation. 

170 

171 :Example: 

172 

173 >>> array("[1, 2, 3]") # Create from a string 

174 [1, 2, 3] 

175 >>> a = array() 

176 >>> a.extend([1, 2, 3]) # Create from a list 

177 >>> a 

178 [1, 2, 3] 

179 """ 

180 return value(raw) 

181 

182 

183def table(is_super_table: bool | None = None) -> Table: 

184 """Create an empty table. 

185 

186 :param is_super_table: if true, the table is a super table 

187 

188 :Example: 

189 

190 >>> doc = document() 

191 >>> foo = table(True) 

192 >>> bar = table() 

193 >>> bar.update({'x': 1}) 

194 >>> foo.append('bar', bar) 

195 >>> doc.append('foo', foo) 

196 >>> print(doc.as_string()) 

197 [foo.bar] 

198 x = 1 

199 """ 

200 return Table(Container(), Trivia(), False, is_super_table) 

201 

202 

203def inline_table() -> InlineTable: 

204 """Create an inline table. 

205 

206 :Example: 

207 

208 >>> table = inline_table() 

209 >>> table.update({'x': 1, 'y': 2}) 

210 >>> print(table.as_string()) 

211 {x = 1, y = 2} 

212 """ 

213 return InlineTable(Container(), Trivia(), new=True) 

214 

215 

216def aot() -> AoT: 

217 """Create an array of table. 

218 

219 :Example: 

220 

221 >>> doc = document() 

222 >>> aot = aot() 

223 >>> aot.append(item({'x': 1})) 

224 >>> doc.append('foo', aot) 

225 >>> print(doc.as_string()) 

226 [[foo]] 

227 x = 1 

228 """ 

229 return AoT([]) 

230 

231 

232def key(k: str | Iterable[str]) -> Key: 

233 """Create a key from a string. When a list of string is given, 

234 it will create a dotted key. 

235 

236 :Example: 

237 

238 >>> doc = document() 

239 >>> doc.append(key('foo'), 1) 

240 >>> doc.append(key(['bar', 'baz']), 2) 

241 >>> print(doc.as_string()) 

242 foo = 1 

243 bar.baz = 2 

244 """ 

245 if isinstance(k, str): 

246 return SingleKey(k) 

247 return DottedKey([key(_k) for _k in k]) 

248 

249 

250def value(raw: str) -> _Item: 

251 """Parse a simple value from a string. 

252 

253 :Example: 

254 

255 >>> value("1") 

256 1 

257 >>> value("true") 

258 True 

259 >>> value("[1, 2, 3]") 

260 [1, 2, 3] 

261 """ 

262 parser = Parser(raw) 

263 v = parser._parse_value() 

264 if not parser.end(): 

265 raise parser.parse_error(UnexpectedCharError, char=parser._current) 

266 return v 

267 

268 

269def key_value(src: str) -> tuple[Key, _Item]: 

270 """Parse a key-value pair from a string. 

271 

272 :Example: 

273 

274 >>> key_value("foo = 1") 

275 (Key('foo'), 1) 

276 """ 

277 return Parser(src)._parse_key_value() 

278 

279 

280def ws(src: str) -> Whitespace: 

281 """Create a whitespace from a string.""" 

282 return Whitespace(src, fixed=True) 

283 

284 

285def nl() -> Whitespace: 

286 """Create a newline item.""" 

287 return ws("\n") 

288 

289 

290def comment(string: str) -> Comment: 

291 """Create a comment item.""" 

292 return Comment(Trivia(comment_ws=" ", comment="# " + string)) 

293 

294 

295E = TypeVar("E", bound=Encoder) 

296 

297 

298def register_encoder(encoder: E) -> E: 

299 """Add a custom encoder, which should be a function that will be called 

300 if the value can't otherwise be converted. It should takes a single value 

301 and return a TOMLKit item or raise a ``TypeError``. 

302 """ 

303 CUSTOM_ENCODERS.append(encoder) 

304 return encoder 

305 

306 

307def unregister_encoder(encoder: Encoder) -> None: 

308 """Unregister a custom encoder.""" 

309 with contextlib.suppress(ValueError): 

310 CUSTOM_ENCODERS.remove(encoder)