Add `types`-mod to `.msg._exts.dec_type_union()`

Such that decoded output equivalent to `str|None` can actually be
unpacked from a `type_names = ['str', 'NoneType]` without just
ignoring the null-type entry.. Previously, the loop would fall through
silently ignoring the `None` -> `NoneType` string representation mapped
by `.enc_type_union()` and the output union would be incorrect.

Deats,
- include the stdlib's `types` in the lookup loop, obvi changing the
  output var's name to `_types` to not collide.
- add output checking versus input `type_names` such that we raise
  a value-error with a case specific `report: str` when either,
  * the output `_types: list[Type]` is empty,
  * the `len(_types) != len(type_names)`.
pld_dec_refinements
Tyler Goodlet 2025-09-25 18:23:44 -04:00
parent 6b3cc72e5c
commit 7d947d3776
1 changed files with 29 additions and 15 deletions

View File

@ -33,9 +33,7 @@ converters,
|_ https://jcristharif.com/msgspec/changelog.html |_ https://jcristharif.com/msgspec/changelog.html
''' '''
from types import ( import types
ModuleType,
)
import typing import typing
from typing import ( from typing import (
Type, Type,
@ -44,35 +42,51 @@ from typing import (
def dec_type_union( def dec_type_union(
type_names: list[str], type_names: list[str],
mods: list[ModuleType] = [] mods: list[types.ModuleType] = []
) -> Type|Union[Type]: ) -> Type|Union[Type]:
''' '''
Look up types by name, compile into a list and then create and Look up types by name, compile into a list and then create and
return a `typing.Union` from the full set. return a `typing.Union` from the full set.
''' '''
# import importlib _types: list[Type] = []
types: list[Type] = []
for type_name in type_names: for type_name in type_names:
for mod in [ for mod in [
typing, typing,
# importlib.import_module(__name__), types,
] + mods: ] + mods:
if type_ref := getattr( if type_ref := getattr(
mod, mod,
type_name, type_name,
False, False,
): ):
types.append(type_ref) _types.append(type_ref)
break
# special case handling only.. report: str = ''
# ipc_pld_spec: Union[Type] = eval( if not _types:
# pld_spec_str, report: str = 'No type-instances could be resolved from `type_names` ??\n'
# {}, # globals
# {'typing': typing}, # locals
# )
return Union[*types] elif len(type_names) != len(_types):
report: str = (
f'Some type-instances could not be resolved from `type_names` ??\n'
f'_types: {_types!r}\n'
)
if report:
raise ValueError(
report
+
f'type_names: {type_names!r}\n'
)
if not _types:
raise ValueError(
f'No type-instance could be resolved from `type_names` ??\n'
f'type_names: {type_names!r}\n'
)
return Union[*_types]
def enc_type_union( def enc_type_union(