This commit is contained in:
2025-05-22 21:22:15 +02:00
parent 3d57f842f9
commit 97cb9c8703
156 changed files with 1205 additions and 6603 deletions

View File

@@ -167,4 +167,4 @@ def jsonify(*args: t.Any, **kwargs: t.Any) -> Response:
.. versionadded:: 0.2
"""
return current_app.json.response(*args, **kwargs)
return current_app.json.response(*args, **kwargs) # type: ignore[return-value]

View File

@@ -11,8 +11,9 @@ from datetime import date
from werkzeug.http import http_date
if t.TYPE_CHECKING: # pragma: no cover
from ..app import Flask
from ..wrappers import Response
from werkzeug.sansio.response import Response
from ..sansio.app import App
class JSONProvider:
@@ -34,8 +35,8 @@ class JSONProvider:
.. versionadded:: 2.2
"""
def __init__(self, app: Flask) -> None:
self._app = weakref.proxy(app)
def __init__(self, app: App) -> None:
self._app: App = weakref.proxy(app)
def dumps(self, obj: t.Any, **kwargs: t.Any) -> str:
"""Serialize data as JSON.
@@ -134,9 +135,7 @@ class DefaultJSONProvider(JSONProvider):
method) will call the ``__html__`` method to get a string.
"""
default: t.Callable[[t.Any], t.Any] = staticmethod(
_default
) # type: ignore[assignment]
default: t.Callable[[t.Any], t.Any] = staticmethod(_default) # type: ignore[assignment]
"""Apply this function to any object that :meth:`json.dumps` does
not know how to serialize. It should return a valid JSON type or
raise a ``TypeError``.

View File

@@ -61,9 +61,9 @@ class JSONTag:
__slots__ = ("serializer",)
#: The tag to mark the serialized object with. If ``None``, this tag is
#: The tag to mark the serialized object with. If empty, this tag is
#: only used as an intermediate step during tagging.
key: str | None = None
key: str = ""
def __init__(self, serializer: TaggedJSONSerializer) -> None:
"""Create a tagger for the given serializer."""
@@ -83,7 +83,7 @@ class JSONTag:
will already be removed."""
raise NotImplementedError
def tag(self, value: t.Any) -> t.Any:
def tag(self, value: t.Any) -> dict[str, t.Any]:
"""Convert the value to a valid JSON type and add the tag structure
around it."""
return {self.key: self.to_json(value)}
@@ -274,7 +274,7 @@ class TaggedJSONSerializer:
tag = tag_class(self)
key = tag.key
if key is not None:
if key:
if not force and key in self.tags:
raise KeyError(f"Tag '{key}' is already registered.")
@@ -285,7 +285,7 @@ class TaggedJSONSerializer:
else:
self.order.insert(index, tag)
def tag(self, value: t.Any) -> dict[str, t.Any]:
def tag(self, value: t.Any) -> t.Any:
"""Convert a value to a tagged representation if necessary."""
for tag in self.order:
if tag.check(value):
@@ -305,10 +305,22 @@ class TaggedJSONSerializer:
return self.tags[key].to_python(value[key])
def _untag_scan(self, value: t.Any) -> t.Any:
if isinstance(value, dict):
# untag each item recursively
value = {k: self._untag_scan(v) for k, v in value.items()}
# untag the dict itself
value = self.untag(value)
elif isinstance(value, list):
# untag each item recursively
value = [self._untag_scan(item) for item in value]
return value
def dumps(self, value: t.Any) -> str:
"""Tag the value and dump it to a compact JSON string."""
return dumps(self.tag(value), separators=(",", ":"))
def loads(self, value: str) -> t.Any:
"""Load data from a JSON string and deserialized any tagged objects."""
return loads(value, object_hook=self.untag)
return self._untag_scan(loads(value))