Skip to content

upstream(pydantic): no public export for ModelMetaclass #140

Open

Description

@cdwilson

Tracks upstream friction in Pydantic. The explanation lives in the docs; this issue is the unit of work.

Explanation: No public export for ModelMetaclass — the limitation, why it matters to an ODM, the workaround tinydantic carries, and the change that would remove it. That section is written to be read standalone by an upstream maintainer, so it doubles as the ready-to-send proposal if we ever file this.

Reproduction

Upstream only — no tinydantic import.

import pydantic
from pydantic import BaseModel

print("type(BaseModel):        ", type(BaseModel).__module__ + "." + type(BaseModel).__name__)
print("pydantic.ModelMetaclass:", getattr(pydantic, "ModelMetaclass", "not exported"))

Run with python repro.py.

Actual output:

type(BaseModel):         pydantic._internal._model_construction.ModelMetaclass
pydantic.ModelMetaclass: not exported

A library that must run at class-creation time has to subclass this metaclass, and there is no supported name for it. tinydantic resolves it as type(BaseModel) at runtime and imports the private path only under TYPE_CHECKING, so nothing private is imported by an installed tinydantic — but the type-checking import still names an unsupported module path.

Expected: a public re-export, e.g. pydantic.ModelMetaclass, that the type-checking import can name.

Environment: pydantic 2.13.4, Python 3.10.20, macOS. Run 2026-08-13.

What tinydantic carries today

A TYPE_CHECKING-only import of pydantic._internal._model_construction.ModelMetaclass. tinydantic must run at class-creation time — to capture database=/table_name= class keywords, resolve __tinydantic_config__, and detect shadowed fields — which requires subclassing BaseModel's metaclass, and Pydantic exports no public name for it.

Exposure is limited: the runtime branch resolves the same class as type(BaseModel), so no Pydantic internal is imported at runtime and moving the module would not break an installed tinydantic.

Upstream status

Not filed. No draft prepared.

What would close this

A public re-export such as pydantic.ModelMetaclass, so the type-checking import can name a supported path — or a maintainer decision to carry the workaround indefinitely.

Assisted-by: Claude:claude-opus-5

Activity

  1. added
    enhancementNew feature or request
    upstreamTracks a defect or request in an upstream dependency
    ai-assistedCreated or investigated with help from an AI agent
    on Aug 13, 2026
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

    ai-assistedCreated or investigated with help from an AI agentenhancementNew feature or requestupstreamTracks a defect or request in an upstream dependency

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions