Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/flask/json/__init__.py: 29%

62 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:35 +0000

1from __future__ import annotations 

2 

3import json as _json 

4import typing as t 

5 

6from jinja2.utils import htmlsafe_json_dumps as _jinja_htmlsafe_dumps 

7 

8from ..globals import current_app 

9from .provider import _default 

10 

11if t.TYPE_CHECKING: # pragma: no cover 

12 from ..app import Flask 

13 from ..wrappers import Response 

14 

15 

16class JSONEncoder(_json.JSONEncoder): 

17 """The default JSON encoder. Handles extra types compared to the 

18 built-in :class:`json.JSONEncoder`. 

19 

20 - :class:`datetime.datetime` and :class:`datetime.date` are 

21 serialized to :rfc:`822` strings. This is the same as the HTTP 

22 date format. 

23 - :class:`decimal.Decimal` is serialized to a string. 

24 - :class:`uuid.UUID` is serialized to a string. 

25 - :class:`dataclasses.dataclass` is passed to 

26 :func:`dataclasses.asdict`. 

27 - :class:`~markupsafe.Markup` (or any object with a ``__html__`` 

28 method) will call the ``__html__`` method to get a string. 

29 

30 Assign a subclass of this to :attr:`flask.Flask.json_encoder` or 

31 :attr:`flask.Blueprint.json_encoder` to override the default. 

32 

33 .. deprecated:: 2.2 

34 Will be removed in Flask 2.3. Use ``app.json`` instead. 

35 """ 

36 

37 def __init__(self, **kwargs) -> None: 

38 import warnings 

39 

40 warnings.warn( 

41 "'JSONEncoder' is deprecated and will be removed in" 

42 " Flask 2.3. Use 'Flask.json' to provide an alternate" 

43 " JSON implementation instead.", 

44 DeprecationWarning, 

45 stacklevel=3, 

46 ) 

47 super().__init__(**kwargs) 

48 

49 def default(self, o: t.Any) -> t.Any: 

50 """Convert ``o`` to a JSON serializable type. See 

51 :meth:`json.JSONEncoder.default`. Python does not support 

52 overriding how basic types like ``str`` or ``list`` are 

53 serialized, they are handled before this method. 

54 """ 

55 return _default(o) 

56 

57 

58class JSONDecoder(_json.JSONDecoder): 

59 """The default JSON decoder. 

60 

61 This does not change any behavior from the built-in 

62 :class:`json.JSONDecoder`. 

63 

64 Assign a subclass of this to :attr:`flask.Flask.json_decoder` or 

65 :attr:`flask.Blueprint.json_decoder` to override the default. 

66 

67 .. deprecated:: 2.2 

68 Will be removed in Flask 2.3. Use ``app.json`` instead. 

69 """ 

70 

71 def __init__(self, **kwargs) -> None: 

72 import warnings 

73 

74 warnings.warn( 

75 "'JSONDecoder' is deprecated and will be removed in" 

76 " Flask 2.3. Use 'Flask.json' to provide an alternate" 

77 " JSON implementation instead.", 

78 DeprecationWarning, 

79 stacklevel=3, 

80 ) 

81 super().__init__(**kwargs) 

82 

83 

84def dumps(obj: t.Any, *, app: Flask | None = None, **kwargs: t.Any) -> str: 

85 """Serialize data as JSON. 

86 

87 If :data:`~flask.current_app` is available, it will use its 

88 :meth:`app.json.dumps() <flask.json.provider.JSONProvider.dumps>` 

89 method, otherwise it will use :func:`json.dumps`. 

90 

91 :param obj: The data to serialize. 

92 :param kwargs: Arguments passed to the ``dumps`` implementation. 

93 

94 .. versionchanged:: 2.2 

95 Calls ``current_app.json.dumps``, allowing an app to override 

96 the behavior. 

97 

98 .. versionchanged:: 2.2 

99 The ``app`` parameter will be removed in Flask 2.3. 

100 

101 .. versionchanged:: 2.0.2 

102 :class:`decimal.Decimal` is supported by converting to a string. 

103 

104 .. versionchanged:: 2.0 

105 ``encoding`` will be removed in Flask 2.1. 

106 

107 .. versionchanged:: 1.0.3 

108 ``app`` can be passed directly, rather than requiring an app 

109 context for configuration. 

110 """ 

111 if app is not None: 

112 import warnings 

113 

114 warnings.warn( 

115 "The 'app' parameter is deprecated and will be removed in" 

116 " Flask 2.3. Call 'app.json.dumps' directly instead.", 

117 DeprecationWarning, 

118 stacklevel=2, 

119 ) 

120 else: 

121 app = current_app 

122 

123 if app: 

124 return app.json.dumps(obj, **kwargs) 

125 

126 kwargs.setdefault("default", _default) 

127 return _json.dumps(obj, **kwargs) 

128 

129 

130def dump( 

131 obj: t.Any, fp: t.IO[str], *, app: Flask | None = None, **kwargs: t.Any 

132) -> None: 

133 """Serialize data as JSON and write to a file. 

134 

135 If :data:`~flask.current_app` is available, it will use its 

136 :meth:`app.json.dump() <flask.json.provider.JSONProvider.dump>` 

137 method, otherwise it will use :func:`json.dump`. 

138 

139 :param obj: The data to serialize. 

140 :param fp: A file opened for writing text. Should use the UTF-8 

141 encoding to be valid JSON. 

142 :param kwargs: Arguments passed to the ``dump`` implementation. 

143 

144 .. versionchanged:: 2.2 

145 Calls ``current_app.json.dump``, allowing an app to override 

146 the behavior. 

147 

148 .. versionchanged:: 2.2 

149 The ``app`` parameter will be removed in Flask 2.3. 

150 

151 .. versionchanged:: 2.0 

152 Writing to a binary file, and the ``encoding`` argument, will be 

153 removed in Flask 2.1. 

154 """ 

155 if app is not None: 

156 import warnings 

157 

158 warnings.warn( 

159 "The 'app' parameter is deprecated and will be removed in" 

160 " Flask 2.3. Call 'app.json.dump' directly instead.", 

161 DeprecationWarning, 

162 stacklevel=2, 

163 ) 

164 else: 

165 app = current_app 

166 

167 if app: 

168 app.json.dump(obj, fp, **kwargs) 

169 else: 

170 kwargs.setdefault("default", _default) 

171 _json.dump(obj, fp, **kwargs) 

172 

173 

174def loads(s: str | bytes, *, app: Flask | None = None, **kwargs: t.Any) -> t.Any: 

175 """Deserialize data as JSON. 

176 

177 If :data:`~flask.current_app` is available, it will use its 

178 :meth:`app.json.loads() <flask.json.provider.JSONProvider.loads>` 

179 method, otherwise it will use :func:`json.loads`. 

180 

181 :param s: Text or UTF-8 bytes. 

182 :param kwargs: Arguments passed to the ``loads`` implementation. 

183 

184 .. versionchanged:: 2.2 

185 Calls ``current_app.json.loads``, allowing an app to override 

186 the behavior. 

187 

188 .. versionchanged:: 2.2 

189 The ``app`` parameter will be removed in Flask 2.3. 

190 

191 .. versionchanged:: 2.0 

192 ``encoding`` will be removed in Flask 2.1. The data must be a 

193 string or UTF-8 bytes. 

194 

195 .. versionchanged:: 1.0.3 

196 ``app`` can be passed directly, rather than requiring an app 

197 context for configuration. 

198 """ 

199 if app is not None: 

200 import warnings 

201 

202 warnings.warn( 

203 "The 'app' parameter is deprecated and will be removed in" 

204 " Flask 2.3. Call 'app.json.loads' directly instead.", 

205 DeprecationWarning, 

206 stacklevel=2, 

207 ) 

208 else: 

209 app = current_app 

210 

211 if app: 

212 return app.json.loads(s, **kwargs) 

213 

214 return _json.loads(s, **kwargs) 

215 

216 

217def load(fp: t.IO[t.AnyStr], *, app: Flask | None = None, **kwargs: t.Any) -> t.Any: 

218 """Deserialize data as JSON read from a file. 

219 

220 If :data:`~flask.current_app` is available, it will use its 

221 :meth:`app.json.load() <flask.json.provider.JSONProvider.load>` 

222 method, otherwise it will use :func:`json.load`. 

223 

224 :param fp: A file opened for reading text or UTF-8 bytes. 

225 :param kwargs: Arguments passed to the ``load`` implementation. 

226 

227 .. versionchanged:: 2.2 

228 Calls ``current_app.json.load``, allowing an app to override 

229 the behavior. 

230 

231 .. versionchanged:: 2.2 

232 The ``app`` parameter will be removed in Flask 2.3. 

233 

234 .. versionchanged:: 2.0 

235 ``encoding`` will be removed in Flask 2.1. The file must be text 

236 mode, or binary mode with UTF-8 bytes. 

237 """ 

238 if app is not None: 

239 import warnings 

240 

241 warnings.warn( 

242 "The 'app' parameter is deprecated and will be removed in" 

243 " Flask 2.3. Call 'app.json.load' directly instead.", 

244 DeprecationWarning, 

245 stacklevel=2, 

246 ) 

247 else: 

248 app = current_app 

249 

250 if app: 

251 return app.json.load(fp, **kwargs) 

252 

253 return _json.load(fp, **kwargs) 

254 

255 

256def htmlsafe_dumps(obj: t.Any, **kwargs: t.Any) -> str: 

257 """Serialize an object to a string of JSON with :func:`dumps`, then 

258 replace HTML-unsafe characters with Unicode escapes and mark the 

259 result safe with :class:`~markupsafe.Markup`. 

260 

261 This is available in templates as the ``|tojson`` filter. 

262 

263 The returned string is safe to render in HTML documents and 

264 ``<script>`` tags. The exception is in HTML attributes that are 

265 double quoted; either use single quotes or the ``|forceescape`` 

266 filter. 

267 

268 .. deprecated:: 2.2 

269 Will be removed in Flask 2.3. This is built-in to Jinja now. 

270 

271 .. versionchanged:: 2.0 

272 Uses :func:`jinja2.utils.htmlsafe_json_dumps`. The returned 

273 value is marked safe by wrapping in :class:`~markupsafe.Markup`. 

274 

275 .. versionchanged:: 0.10 

276 Single quotes are escaped, making this safe to use in HTML, 

277 ``<script>`` tags, and single-quoted attributes without further 

278 escaping. 

279 """ 

280 import warnings 

281 

282 warnings.warn( 

283 "'htmlsafe_dumps' is deprecated and will be removed in Flask" 

284 " 2.3. Use 'jinja2.utils.htmlsafe_json_dumps' instead.", 

285 DeprecationWarning, 

286 stacklevel=2, 

287 ) 

288 return _jinja_htmlsafe_dumps(obj, dumps=dumps, **kwargs) 

289 

290 

291def htmlsafe_dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: 

292 """Serialize an object to JSON written to a file object, replacing 

293 HTML-unsafe characters with Unicode escapes. See 

294 :func:`htmlsafe_dumps` and :func:`dumps`. 

295 

296 .. deprecated:: 2.2 

297 Will be removed in Flask 2.3. 

298 """ 

299 import warnings 

300 

301 warnings.warn( 

302 "'htmlsafe_dump' is deprecated and will be removed in Flask" 

303 " 2.3. Use 'jinja2.utils.htmlsafe_json_dumps' instead.", 

304 DeprecationWarning, 

305 stacklevel=2, 

306 ) 

307 fp.write(htmlsafe_dumps(obj, **kwargs)) 

308 

309 

310def jsonify(*args: t.Any, **kwargs: t.Any) -> Response: 

311 """Serialize the given arguments as JSON, and return a 

312 :class:`~flask.Response` object with the ``application/json`` 

313 mimetype. A dict or list returned from a view will be converted to a 

314 JSON response automatically without needing to call this. 

315 

316 This requires an active request or application context, and calls 

317 :meth:`app.json.response() <flask.json.provider.JSONProvider.response>`. 

318 

319 In debug mode, the output is formatted with indentation to make it 

320 easier to read. This may also be controlled by the provider. 

321 

322 Either positional or keyword arguments can be given, not both. 

323 If no arguments are given, ``None`` is serialized. 

324 

325 :param args: A single value to serialize, or multiple values to 

326 treat as a list to serialize. 

327 :param kwargs: Treat as a dict to serialize. 

328 

329 .. versionchanged:: 2.2 

330 Calls ``current_app.json.response``, allowing an app to override 

331 the behavior. 

332 

333 .. versionchanged:: 2.0.2 

334 :class:`decimal.Decimal` is supported by converting to a string. 

335 

336 .. versionchanged:: 0.11 

337 Added support for serializing top-level arrays. This was a 

338 security risk in ancient browsers. See :ref:`security-json`. 

339 

340 .. versionadded:: 0.2 

341 """ 

342 return current_app.json.response(*args, **kwargs)