diff --git a/msgspec/__init__.py b/msgspec/__init__.py index 421e4311..95079e7d 100644 --- a/msgspec/__init__.py +++ b/msgspec/__init__.py @@ -6,6 +6,7 @@ MsgspecError, Raw, Struct, + StructMeta, UnsetType, UNSET, NODEFAULT, diff --git a/msgspec/__init__.pyi b/msgspec/__init__.pyi index 4d2d8744..ec3f121c 100644 --- a/msgspec/__init__.pyi +++ b/msgspec/__init__.pyi @@ -73,6 +73,43 @@ class Struct: self, ) -> Iterable[Union[Any, Tuple[Any], Tuple[str, Any], Tuple[str, Any, Any]]]: ... +class StructMeta(type): + __struct_fields__: ClassVar[Tuple[str, ...]] + __struct_defaults__: ClassVar[Tuple[Any, ...]] + __struct_encode_fields__: ClassVar[Tuple[str, ...]] + __match_args__: ClassVar[Tuple[str, ...]] + @property + def __signature__(self) -> inspect.Signature: ... + @property + def __struct_config__(self) -> structs.StructConfig: ... + def __new__( + cls, + name: str, + bases: Tuple[type, ...], + namespace: Dict[str, Any], + *, + tag_field: Optional[str] = None, + tag: Union[None, bool, str, int, Callable[[str], Union[str, int]]] = None, + rename: Union[ + None, + Literal["lower", "upper", "camel", "pascal", "kebab"], + Callable[[str], Optional[str]], + Mapping[str, str], + ] = None, + omit_defaults: bool = False, + forbid_unknown_fields: bool = False, + frozen: bool = False, + eq: bool = True, + order: bool = False, + kw_only: bool = False, + repr_omit_defaults: bool = False, + array_like: bool = False, + gc: bool = True, + weakref: bool = False, + dict: bool = False, + cache_hash: bool = False, + ) -> StructMeta: ... + def defstruct( name: str, fields: Iterable[Union[str, Tuple[str, type], Tuple[str, type, Any]]], diff --git a/msgspec/_core.c b/msgspec/_core.c index 147ad95a..cddd83e6 100644 --- a/msgspec/_core.c +++ b/msgspec/_core.c @@ -7146,7 +7146,7 @@ static PyTypeObject StructMetaType = { .tp_name = "msgspec._core.StructMeta", .tp_basicsize = sizeof(StructMetaObject), .tp_itemsize = 0, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_TYPE_SUBCLASS | Py_TPFLAGS_HAVE_GC | _Py_TPFLAGS_HAVE_VECTORCALL, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS | Py_TPFLAGS_HAVE_GC | _Py_TPFLAGS_HAVE_VECTORCALL, .tp_new = StructMeta_new, .tp_dealloc = (destructor) StructMeta_dealloc, .tp_clear = (inquiry) StructMeta_clear, @@ -22049,6 +22049,9 @@ PyInit__core(void) Py_INCREF(&StructConfig_Type); if (PyModule_AddObject(m, "StructConfig", (PyObject *)&StructConfig_Type) < 0) return NULL; + Py_INCREF(&StructMetaType); + if (PyModule_AddObject(m, "StructMeta", (PyObject *)&StructMetaType) < 0) + return NULL; Py_INCREF(&Ext_Type); if (PyModule_AddObject(m, "Ext", (PyObject *)&Ext_Type) < 0) return NULL;