| 634 | |
| 635 | # Implementation details |
| 636 | def _origin_args_metadata(t): |
| 637 | # Strip wrappers (Annotated, NewType, Final) until we hit a concrete type |
| 638 | metadata = [] |
| 639 | while True: |
| 640 | try: |
| 641 | origin = _CONCRETE_TYPES.get(t) |
| 642 | except TypeError: |
| 643 | # t is not hashable |
| 644 | origin = None |
| 645 | |
| 646 | if origin is not None: |
| 647 | args = None |
| 648 | break |
| 649 | |
| 650 | origin = getattr(t, "__origin__", None) |
| 651 | if origin is not None: |
| 652 | if type(t) is _AnnotatedAlias: |
| 653 | metadata.extend(m for m in t.__metadata__ if type(m) is msgspec.Meta) |
| 654 | t = origin |
| 655 | elif origin == Final: |
| 656 | t = t.__args__[0] |
| 657 | elif type(origin) is _TypeAliasType: |
| 658 | t = origin.__value__[t.__args__] |
| 659 | else: |
| 660 | args = getattr(t, "__args__", None) |
| 661 | origin = _CONCRETE_TYPES.get(origin, origin) |
| 662 | break |
| 663 | else: |
| 664 | supertype = getattr(t, "__supertype__", None) |
| 665 | if supertype is not None: |
| 666 | t = supertype |
| 667 | elif type(t) is _TypeAliasType: |
| 668 | t = t.__value__ |
| 669 | else: |
| 670 | origin = t |
| 671 | args = None |
| 672 | break |
| 673 | |
| 674 | if type(origin) is _types_UnionType: |
| 675 | args = origin.__args__ |
| 676 | origin = Union |
| 677 | return origin, args, tuple(metadata) |
| 678 | |
| 679 | |
| 680 | def _is_enum(t): |