Skip to content

Commit ceb01c1

Browse files
authored
Narrow none_member in JSON schema union handling (#1121)
Follow-up to #1028. #1028 introduced `none_member: mi.Type | None` in the union branch of `_json_schema.py` and guarded the `self.to_schema(none_member)` calls with a separate `has_none` boolean. mypy can't narrow `none_member` through the flag, so it errors: ``` _json_schema.py:363: error: Argument 1 to "to_schema" of "_SchemaGenerator" has incompatible type "Type | None"; expected "Type" [arg-type] ``` This is not caught by current CI because the msgspec source is not type-checked there (only `tests/typing` is); #1116 (adding stubtest) is what surfaces it. Fixing it here so #1116 can go green. The fix drops the redundant `has_none` flag and checks `none_member is not None` at the call sites, which gives mypy the narrowing. No runtime behavior change (`has_none` and `none_member` were always set together): `tests/unit/test_schema.py` still passes (115), and stubtest with mypy 2.2.0 is clean. Co-authored-by: Siyet <[email protected]>
1 parent e1c6f23 commit ceb01c1

1 file changed

Lines changed: 4 additions & 6 deletions

File tree

‎src/msgspec/_json_schema.py‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,6 @@ def to_schema(self, t: mi.Type, check_ref: bool = True) -> dict[str, Any]:
330330
elif isinstance(t, mi.UnionType):
331331
structs = {}
332332
other = []
333-
has_none = False
334333
none_member = None
335334
tag_field = None
336335
for subtype in t.types:
@@ -341,7 +340,6 @@ def to_schema(self, t: mi.Type, check_ref: bool = True) -> dict[str, Any]:
341340
tag_field = real_type.tag_field
342341
structs[real_type.tag] = real_type
343342
elif isinstance(real_type, mi.NoneType):
344-
has_none = True
345343
none_member = subtype
346344
else:
347345
other.append(subtype)
@@ -359,21 +357,21 @@ def to_schema(self, t: mi.Type, check_ref: bool = True) -> dict[str, Any]:
359357
}
360358
if options:
361359
options.append(struct_schema)
362-
if has_none:
360+
if none_member is not None:
363361
options.append(self.to_schema(none_member))
364362
schema["anyOf"] = options
365-
elif has_none:
363+
elif none_member is not None:
366364
schema["anyOf"] = [struct_schema, self.to_schema(none_member)]
367365
else:
368366
schema.update(struct_schema)
369367
elif len(structs) == 1:
370368
_, subtype = structs.popitem()
371369
options.append(self.to_schema(subtype))
372-
if has_none:
370+
if none_member is not None:
373371
options.append(self.to_schema(none_member))
374372
schema["anyOf"] = options
375373
else:
376-
if has_none:
374+
if none_member is not None:
377375
options.append(self.to_schema(none_member))
378376
schema["anyOf"] = options
379377
elif isinstance(t, mi.LiteralType):

0 commit comments

Comments
 (0)