Skip to content
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

[red-knot] Descriptor protocol #15966

Open
Tracked by #14164
sharkdp opened this issue Feb 5, 2025 · 2 comments
Open
Tracked by #14164

[red-knot] Descriptor protocol #15966

sharkdp opened this issue Feb 5, 2025 · 2 comments
Labels
red-knot Multi-file analysis & type inference

Comments

@sharkdp
Copy link
Contributor

sharkdp commented Feb 5, 2025

We need to understand the descriptor protocol in order to infer proper types for attribute accesses like in this simple example:

from typing import Literal

class Ten:
    def __get__(self, instance: object, owner: type | None = None) -> Literal[10]:
        return 10

    def __set__(self, instance: object, value: Literal[10]) -> None:
        pass

class C:
    ten = Ten()

c = C()

# TODO: this should be `Literal[10]`
reveal_type(c.ten)  # revealed: Unknown | Ten

# TODO: This should `Literal[10]`
reveal_type(C.ten)  # revealed: Unknown | Ten

# These are fine:
c.ten = 10
C.ten = 10

# TODO: Both of these should be errors
c.ten = 11
C.ten = 11

References: Python Documentation: Descriptor Guide

part of: #14164

@sharkdp sharkdp changed the title Implement the descriptor protocol [red-knot] Descriptor protocol Feb 5, 2025
@sharkdp sharkdp added the red-knot Multi-file analysis & type inference label Feb 5, 2025
@carljm
Copy link
Contributor

carljm commented Feb 5, 2025

An important case to consider here that isn't shown in the example in summary is where the value argument to __set__ does not have the same type as the return type of __get__, meaning we need to use a different type for type-checking assignments to the attribute than we use for inferring the type of an attribute access.

@sharkdp
Copy link
Contributor Author

sharkdp commented Feb 5, 2025

where the value argument to __set__ does not have the same type as the return type of __get__

Yes, thanks. This is already covered in the provisional tests (#15972).

sharkdp added a commit that referenced this issue Feb 5, 2025
## Summary

This is a first step towards creating a test suite for
[descriptors](https://docs.python.org/3/howto/descriptor.html). It does
not (yet) aim to be exhaustive.

relevant ticket: #15966 

## Test Plan

Compared desired behavior with the runtime behavior and the behavior of
existing type checkers.

---------

Co-authored-by: Mike Perlov <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
red-knot Multi-file analysis & type inference
Projects
None yet
Development

No branches or pull requests

2 participants