Skip to content

invalid-inheritance error when a pydantic BaseModel extends a Protocol #5521

Closed

Description

@DetachHead

Describe the Bug

from typing import Protocol

from pydantic import BaseModel


class Foo(Protocol):
    a: int


class Bar(BaseModel, Foo):  # error: invalid-inheritance
    a: int = 1
Class `Bar` has metaclass `ModelMetaclass` from base class `BaseModel` which is not compatible with metaclass `_ProtocolMeta` from base class `Foo`

Sandbox Link

No response

(Only applicable for extension issues) IDE Information

No response

Activity

  1. shahhamdihassan commented on Nov 5, 2026

    @shahhamdihassan
    Contributor

    Thanks for the report! Python itself rejects this class with TypeError: metaclass conflict, since pydantic's ModelMetaclass and the _ProtocolMeta behind Protocol are unrelated subclasses of ABCMeta (sandbox), so I'm closing this as working as intended. Protocols are structural, though, so if you drop Foo from the bases, Bar is still accepted anywhere a Foo is expected.

  2. connernilsen commented on Nov 6, 2026

    @connernilsen
    Contributor

    I'm going to reopen this one for now and take it over, since I think there's probably a valid ask here, but I'm not sure what it is yet.

    @DetachHead, Hassan is right that it looks like it errors when run by a Python interpreter. Is there a different example you have where this would be a false positive?

  3. DetachHead commented on Nov 9, 2026

    @DetachHead
    ContributorAuthor

    wow, i had no idea this doesnt work at runtime... just another thing to add to the long list of everything wrong with Protocols in python

    the reason i never ran into this before is because pyright doesn't handle extending Protocols properly at all, so i had to use my extremely hacky @implements decorator instead. but that doesn't work in pyrefly due to #5536 and #1180

    i dont mind if you close this because it doesnt really seem fixable in pyrefly, unless we can have a separate pyrefly_extensions module with runtime fixes for some of these fundamentally broken typing features

  4. connernilsen commented on Nov 9, 2026

    @connernilsen
    Contributor

    wow, i had no idea this doesnt work at runtime... just another thing to add to DetachHead/basedpyright#294 (comment)

    another special casing situation to consider for protocols 🤣

    the reason i never ran into this before is because pyright doesn't handle extending Protocols properly at all, so i had to use my DetachHead/basedpyright#775 (comment). but that doesn't work in pyrefly due to #5536 and #1180

    wait, I never knew pyright didn't handle protocol at all, that's crazy! hopefully #5536 and #1180 will be fixed this week, and that it will support your @implements decorator. I'll put out a new release once it's landed

    i dont mind if you close this because it doesnt really seem fixable in pyrefly, unless we can have a separate pyrefly_extensions module with runtime fixes for some of these fundamentally broken typing features

    I may open a new issue or discussion post with possible ideas for things to include in a pyrefly_extensions module and add this in

    Edit: #5600 created

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

Metadata

Metadata

Assignees

Labels

pydanticIssues related to support for PydanticquestionFurther information is requestedtypechecking

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions