Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-mashumaro for
openSUSE:Factory checked in at 2026-05-29 18:11:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-mashumaro (Old)
and /work/SRC/openSUSE:Factory/.python-mashumaro.new.1937 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-mashumaro"
Fri May 29 18:11:42 2026 rev:10 rq:1355846 version:3.22
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-mashumaro/python-mashumaro.changes
2026-05-11 17:09:52.283722526 +0200
+++
/work/SRC/openSUSE:Factory/.python-mashumaro.new.1937/python-mashumaro.changes
2026-05-29 18:13:32.514469789 +0200
@@ -1,0 +2,9 @@
+Fri May 29 05:56:37 UTC 2026 - Johannes Kastl
<[email protected]>
+
+- update to 3.22:
+ * Added support for using Annotated[..., JSONSchema(...)] in JSON
+ Schema generation (#326)
+ * Added new fields contentEncoding, contentMediaType,
+ contentSchema to JSONSchema (#326)
+
+-------------------------------------------------------------------
Old:
----
mashumaro-3.21.tar.gz
New:
----
mashumaro-3.22.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-mashumaro.spec ++++++
--- /var/tmp/diff_new_pack.E1iKbD/_old 2026-05-29 18:13:33.226499374 +0200
+++ /var/tmp/diff_new_pack.E1iKbD/_new 2026-05-29 18:13:33.226499374 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-mashumaro
-Version: 3.21
+Version: 3.22
Release: 0
Summary: Fast and well tested serialization library
License: Apache-2.0
++++++ mashumaro-3.21.tar.gz -> mashumaro-3.22.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mashumaro-3.21/README.md new/mashumaro-3.22/README.md
--- old/mashumaro-3.21/README.md 2026-05-07 18:26:24.000000000 +0200
+++ new/mashumaro-3.22/README.md 2026-05-26 13:09:20.000000000 +0200
@@ -3073,6 +3073,78 @@
```
</details>
+For more complex field-level schema customization, `Annotated` can also be
+used with a `JSONSchema` instance. In that case, explicitly set schema
+attributes are applied on top of the automatically generated schema. This is
+especially useful for content-related keywords such as `contentEncoding`,
+`contentMediaType`, and `contentSchema`:
+
+```python
+from dataclasses import dataclass
+from typing import Annotated
+
+from mashumaro.jsonschema import build_json_schema
+from mashumaro.jsonschema.models import JSONSchema, JSONSchemaInstanceType
+
+
+@dataclass
+class Upload:
+ file: Annotated[
+ bytes,
+ JSONSchema(
+ contentEncoding="base64",
+ contentMediaType="application/pdf",
+ ),
+ ]
+ metadata: Annotated[
+ str,
+ JSONSchema(
+ contentMediaType="application/json",
+ contentSchema=JSONSchema(
+ type=JSONSchemaInstanceType.OBJECT,
+ ),
+ ),
+ ]
+
+
+print(build_json_schema(Upload).to_json())
+```
+
+<details>
+<summary>Click to show the result</summary>
+
+```json
+{
+ "type": "object",
+ "title": "Upload",
+ "properties": {
+ "file": {
+ "type": "string",
+ "format": "base64",
+ "contentEncoding": "base64",
+ "contentMediaType": "application/pdf"
+ },
+ "metadata": {
+ "type": "string",
+ "contentMediaType": "application/json",
+ "contentSchema": {
+ "type": "object"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "file",
+ "metadata"
+ ]
+}
+```
+</details>
+
+This overlay mechanism is intended for regular schema keywords. Structural
+keywords such as `$schema`, `$ref`, and `$defs` are not applied from
+`Annotated[..., JSONSchema(...)]`.
+
The
[`$schema`](https://json-schema.org/draft/2020-12/json-schema-core.html#name-the-schema-keyword)
keyword can be added by setting `with_dialect_uri` to True:
@@ -3466,8 +3538,13 @@
### Extending JSON Schema
-Using a `Config` class it is possible to override some parts of the schema.
-Currently, you can do the following:
+For field-level schema customization, prefer using
+`Annotated[..., JSONSchema(...)]` as shown above. It keeps schema overrides
+close to the field type and is the recommended way to add extra keywords such
+as `description`, `contentMediaType`, or `contentSchema`.
+
+Using a `Config` class is still useful when you need to override schema parts
+at the dataclass level. Currently, you can do the following:
* override some field schemas using the "properties" key
* change `additionalProperties` using the "additionalProperties" key
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mashumaro-3.21/mashumaro/core/meta/code/builder.py
new/mashumaro-3.22/mashumaro/core/meta/code/builder.py
--- old/mashumaro-3.21/mashumaro/core/meta/code/builder.py 2026-05-07
18:26:24.000000000 +0200
+++ new/mashumaro-3.22/mashumaro/core/meta/code/builder.py 2026-05-26
13:09:20.000000000 +0200
@@ -10,11 +10,9 @@
# noinspection PyProtectedMember
from dataclasses import _FIELDS # type: ignore
-from dataclasses import MISSING, Field, is_dataclass
+from dataclasses import KW_ONLY, MISSING, Field, is_dataclass
from functools import lru_cache
-from dataclasses import KW_ONLY
-
import typing_extensions
from mashumaro.config import (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mashumaro-3.21/mashumaro/jsonschema/models.py
new/mashumaro-3.22/mashumaro/jsonschema/models.py
--- old/mashumaro-3.21/mashumaro/jsonschema/models.py 2026-05-07
18:26:24.000000000 +0200
+++ new/mashumaro-3.22/mashumaro/jsonschema/models.py 2026-05-26
13:09:20.000000000 +0200
@@ -154,6 +154,10 @@
minProperties: int | None = None
required: list[str] | None = None
dependentRequired: dict[str, set[str]] | None = None
+ # A Vocabulary for the Contents of String-Encoded Data
+ contentEncoding: str | None = None
+ contentMediaType: str | None = None
+ contentSchema: "JSONSchema | None" = None
class Config(BaseConfig):
omit_none = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mashumaro-3.21/mashumaro/jsonschema/schema.py
new/mashumaro-3.22/mashumaro/jsonschema/schema.py
--- old/mashumaro-3.21/mashumaro/jsonschema/schema.py 2026-05-07
18:26:24.000000000 +0200
+++ new/mashumaro-3.22/mashumaro/jsonschema/schema.py 2026-05-26
13:09:20.000000000 +0200
@@ -277,6 +277,8 @@
if with_dialect_uri:
schema.schema = ctx.dialect.uri
break
+ if schema is not None:
+ apply_schema_annotations(instance, schema)
for plugin in ctx.plugins:
try:
new_schema = plugin.get_schema(instance, ctx, schema)
@@ -299,6 +301,23 @@
return schema
+def apply_schema_annotations(
+ instance: Instance, schema: JSONSchema
+) -> JSONSchema:
+ for annotation in instance.annotations:
+ if isinstance(annotation, JSONSchema):
+ annotation_dict = replace(annotation).to_dict()
+ for key in annotation_dict.keys():
+ if key in ("$schema", "$ref", "$defs"):
+ continue
+ if key in ("const", "default"):
+ value = annotation_dict[key]
+ else:
+ value = getattr(annotation, key)
+ setattr(schema, key, value)
+ return schema
+
+
def _default(
f_type: Type | None, f_value: Any, config_cls: Type[BaseConfig]
) -> Any:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/mashumaro-3.21/pyproject.toml
new/mashumaro-3.22/pyproject.toml
--- old/mashumaro-3.21/pyproject.toml 2026-05-07 18:26:24.000000000 +0200
+++ new/mashumaro-3.22/pyproject.toml 2026-05-26 13:09:20.000000000 +0200
@@ -4,7 +4,7 @@
[project]
name = "mashumaro"
-version = "3.21"
+version = "3.22"
license = "Apache-2.0"
description = "Fast and well tested serialization library"
readme = "README.md"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/mashumaro-3.21/tests/test_jsonschema/test_jsonschema_generation.py
new/mashumaro-3.22/tests/test_jsonschema/test_jsonschema_generation.py
--- old/mashumaro-3.21/tests/test_jsonschema/test_jsonschema_generation.py
2026-05-07 18:26:24.000000000 +0200
+++ new/mashumaro-3.22/tests/test_jsonschema/test_jsonschema_generation.py
2026-05-26 13:09:20.000000000 +0200
@@ -1543,3 +1543,121 @@
additionalProperties=False,
required=["no_default"],
)
+
+
+def test_jsonschema_annotation_overlay_for_content_keywords():
+ assert build_json_schema(
+ Annotated[
+ bytes,
+ JSONSchema(contentEncoding="base64", contentMediaType="image/png"),
+ ]
+ ) == JSONSchema(
+ type=JSONSchemaInstanceType.STRING,
+ format=JSONSchemaInstanceFormatExtension.BASE64,
+ contentEncoding="base64",
+ contentMediaType="image/png",
+ )
+
+
+def test_jsonschema_annotation_overlay_for_content_schema():
+ payload_schema = JSONObjectSchema(
+ properties={"value": JSONSchema(type=JSONSchemaInstanceType.INTEGER)},
+ additionalProperties=False,
+ required=["value"],
+ )
+
+ assert build_json_schema(
+ Annotated[
+ str,
+ JSONSchema(
+ contentMediaType="application/json",
+ contentSchema=payload_schema,
+ ),
+ ]
+ ) == JSONSchema(
+ type=JSONSchemaInstanceType.STRING,
+ contentMediaType="application/json",
+ contentSchema=payload_schema,
+ )
+
+
+def test_jsonschema_annotation_overlay_combines_with_constraints():
+ assert build_json_schema(
+ Annotated[
+ str,
+ MinLength(1),
+ JSONSchema(
+ contentMediaType="text/plain", description="Request body"
+ ),
+ ]
+ ) == JSONSchema(
+ type=JSONSchemaInstanceType.STRING,
+ minLength=1,
+ contentMediaType="text/plain",
+ description="Request body",
+ )
+
+
+def test_jsonschema_annotation_overlay_preserves_serialized_none_values():
+ assert build_json_schema(
+ Annotated[str, JSONSchema(const=None, default=None)]
+ ) == JSONSchema(
+ type=JSONSchemaInstanceType.STRING, const=None, default=None
+ )
+
+
+def test_jsonschema_annotation_overlay_for_dataclass_field():
+ @dataclass
+ class Upload:
+ file: Annotated[
+ bytes,
+ JSONSchema(
+ contentEncoding="base64", contentMediaType="application/pdf"
+ ),
+ ]
+
+ assert build_json_schema(Upload) == JSONObjectSchema(
+ title="Upload",
+ properties={
+ "file": JSONSchema(
+ type=JSONSchemaInstanceType.STRING,
+ format=JSONSchemaInstanceFormatExtension.BASE64,
+ contentEncoding="base64",
+ contentMediaType="application/pdf",
+ )
+ },
+ additionalProperties=False,
+ required=["file"],
+ )
+
+
+def test_jsonschema_annotation_overlay_last_wins():
+ assert build_json_schema(
+ Annotated[
+ str,
+ JSONSchema(description="First description"),
+ JSONSchema(description="Second description"),
+ ]
+ ) == JSONSchema(
+ type=JSONSchemaInstanceType.STRING, description="Second description"
+ )
+
+
+def test_jsonschema_annotation_overlay_ignores_structural_keywords():
+ assert build_json_schema(
+ Annotated[
+ str,
+ JSONSchema(
+ schema="https://json-schema.org/draft/2020-12/schema",
+ reference="#/$defs/UploadedFile",
+ definitions={
+ "UploadedFile": JSONSchema(
+ type=JSONSchemaInstanceType.STRING
+ )
+ },
+ description="Plain string",
+ ),
+ ]
+ ) == JSONSchema(
+ type=JSONSchemaInstanceType.STRING, description="Plain string"
+ )