Skip to content

Regression: descriptors don't work on protocols #19262

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
eltoder opened this issue Jun 9, 2025 · 6 comments
Closed

Regression: descriptors don't work on protocols #19262

eltoder opened this issue Jun 9, 2025 · 6 comments
Labels
bug mypy got something wrong topic-descriptors Properties, class vs. instance attributes topic-protocols

Comments

@eltoder
Copy link

eltoder commented Jun 9, 2025

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
@eltoder eltoder added the bug mypy got something wrong label Jun 9, 2025
@brianschubert brianschubert added topic-protocols topic-descriptors Properties, class vs. instance attributes labels Jun 9, 2025
@brianschubert
Copy link
Collaborator

Thanks! Closing as duplicate of #19054

@brianschubert
Copy link
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

@eltoder
Copy link
Author

eltoder commented Jun 9, 2025

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

@brianschubert
Copy link
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

@eltoder
Copy link
Author

eltoder commented Jun 9, 2025

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

@eltoder
Copy link
Author

eltoder commented Jun 9, 2025

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
Labels
bug mypy got something wrong topic-descriptors Properties, class vs. instance attributes topic-protocols
Projects
None yet
Development

No branches or pull requests

2 participants