Skip to content

Regression: descriptors don't work on protocols #19262

Closed as duplicate
Closed as duplicate

Description

@eltoder

Descriptors don't work when used as attributes on Protocols. The same code works on a regular class. This worked for many years up to and including mypy 1.15, but stopped working in 1.16.

To Reproduce

https://mypy-play.net/?mypy=1.16.0&python=3.11&gist=e1f1bd3254690db213102de71f894854

from typing import Protocol, assert_type

class Desc:
    def __get__(self, obj, owner=None) -> int:
        return 1

class HasDesc(Protocol):
    a: Desc

obj: HasDesc
assert_type(obj.a, int)

Expected Behavior

This code should type-check. If works with mypy 1.15 or when HasDesc is not a protocol.

Actual Behavior

main.py:11: error: Expression is of type "Desc", not "int"  [assert-type]

Your Environment

  • Mypy version used: 1.16.0
  • Mypy command-line flags:
  • Python version used: 3.11

Activity

  1. brianschubert commented on Jun 9, 2025

    @brianschubert
    Collaborator

    Thanks! Closing as duplicate of #19054

  2. brianschubert commented on Jun 9, 2025

    @brianschubert
    Collaborator

    As a workaround, you can try annotating the protocol member as a ClassVar: https://mypy-play.net/?mypy=1.16.0&python=3.11&gist=9db8f68d93df061e745e4ce45c0daa5e

  3. eltoder commented on Jun 9, 2025

    @eltoder
    Author

    Good idea, but unfortunately this makes actual classes incompatible with the protocol: https://mypy-play.net/?mypy=1.16.0&python=3.11&gist=9321d98d479917bd489d5be8872a509b

  4. brianschubert commented on Jun 9, 2025

    @brianschubert
    Collaborator

    Mypy will accept it if you also annotate the class assignments as ClassVar, though I realize that could mean a lot of code churn: https://mypy-play.net/?mypy=1.16.0&python=3.11&gist=65196eafe5d72a12a5d7baadb2d5ace7

  5. eltoder commented on Jun 9, 2025

    @eltoder
    Author

    Yeah, I don't want to update all my classes to work-around something that will hopefully get fixed.

  6. eltoder commented on Jun 9, 2025

    @eltoder
    Author

    It's also pretty verbose and ugly. Your snippet is missing the type argument to ClassVar, so you lost typing on the actual class.

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions