Skip to content

Cannot do inspection when using StructMeta #941

Closed

Description

@korlaz

Description

It seems inspection is not possible when using StructMeta.

The following error is returned when calling msgspec.structs.fields:

TypeError: Must be called with a struct type or instance
from msgspec import StructMeta, Struct

# Custom metaclass with kw_only_default parameter
class KwOnlyMeta(StructMeta):
    _kw_only_default_settings = {}
    
    def __new__(mcls, name, bases, namespace, **kwargs):
        # Store and inherit kw_only_default
        kw_only_default = kwargs.pop('kw_only_default', None)
        if kw_only_default is None:
            for base in bases:
                if base.__name__ in mcls._kw_only_default_settings:
                    kw_only_default = mcls._kw_only_default_settings[base.__name__]
                    break
        else:
            mcls._kw_only_default_settings[name] = kw_only_default
            
        # Apply kw_only_default if kw_only not specified
        if 'kw_only' not in kwargs and kw_only_default is not None:
            kwargs['kw_only'] = kw_only_default
            
        return super().__new__(mcls, name, bases, namespace, **kwargs)

# Base model requiring keyword arguments
class BaseModel(metaclass=KwOnlyMeta, kw_only_default=True):
    pass

# Child class inherits kw_only=True
class User(BaseModel):
    name: str
    age: int


msgspec.structs.fields(User)

If you construct the class using msgspec.Struct, this is working fine

Activity

  1. korlaz commented on Nov 17, 2025

    @korlaz
    Author

    Same thing for msgspec.structs.asdict(User):

    TypeError: `struct` must be a `msgspec.Struct`
    

    Different output for msgspec.inspect.type_info(User):
    With StructMeta:

    CustomType(cls=<class '__main__.User'>)
    

    Without:

    StructType(cls=<class '__main__.User'>, fields=(Field(name='name', encode_name='name', type=StrType(min_length=None, max_length=None, pattern=None), required=True, default=NODEFAULT, default_factory=NODEFAULT), Field(name='age', encode_name='age', type=IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None), required=True, default=NODEFAULT, default_factory=NODEFAULT)), tag_field=None, tag=None, array_like=False, forbid_unknown_fields=False)
    
  2. provinzkraut commented on Nov 22, 2025

    @provinzkraut
    Member

    @korlaz doing msgspec.structs.asdict(User) isn't supposed to work, and it wouldn't work with a subclass of Struct either, as asdict only works on instances.

    I've checked and asdict works as expected with StructMeta-based classes. Can you confirm this was just an error in your report, or are you actually facing another bug there?

  3. korlaz commented on Nov 22, 2025

    @korlaz
    Author

    Thanks for this quick PR ! Forget about my 2nd comment, there is no issue with msgspec.structs.asdict.
    Was the issue msgspec.inspect.type_info(User)taken into account as well ?

  4. provinzkraut commented on Nov 22, 2025

    @provinzkraut
    Member

    Was the issue msgspec.inspect.type_info(User)taken into account as well ?

    Yes it was!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions