This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Make `builtins.property` generic
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.11
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: AlexWaygood, cdce8p, gvanrossum, kj, serhiy.storchaka, sobolevn
Priority: normal Keywords: patch

Created on 2021-12-23 09:50 by sobolevn, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 30238 closed sobolevn, 2021-12-23 09:55
Messages (8)
msg409080 - (view) Author: Nikita Sobolev (sobolevn) * (Python triager) Date: 2021-12-23 09:50
Original discussion in `typing` bug tracker: https://github.com/python/typing/issues/985

Short description:
- `property[GetType, SetType]` is required for us to remove a lot of special casing from type-checkers and just use the primitive type
- In runtime it copies the same behavior `list` / `dict` / other primitive types have under PEP585

Open questions:
- I think that it is too late to backport this in 3.10. Am I right?
- I hope that `from __future__ import annotations` will just work for this new change. Is there anything I should do in scope of this PR? Is my assumption about `__future__` import is even correct in this context? Do I need to test that it works with `__future__ annotations`?
msg409081 - (view) Author: Nikita Sobolev (sobolevn) * (Python triager) Date: 2021-12-23 09:54
One more question about PEP585: it does not specify `property`. Do we need to update it?
msg409099 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2021-12-23 18:56
Yes, it is too late for 3.10 (but you can add it to typing_extensions). Also, PEP 585 is done, we don't update PEPs. Please do test with `from __future__ import annotations` -- you never know.

When this was first proposed (https://github.com/python/typing/issues/985) there were worries about backwards compatibility. Given how common property is, we need to make sure there are no problems with that. Can you address that? I don't see it in the original thread.

Also, since this requires type checkers to change, do we need a PEP?

Finally. Please keep discussion in this bpo issue, don't have long discussions on the PR. (Honestly I think it's too soon for a PR given that we don't seem to have agreement in the typing tracker discussion.)
msg409127 - (view) Author: Nikita Sobolev (sobolevn) * (Python triager) Date: 2021-12-24 07:36
Thanks, Guido!

> Yes, it is too late for 3.10 (but you can add it to typing_extensions). Also, PEP 585 is done, we don't update PEPs. 

Got it!

> Please do test with `from __future__ import annotations` -- you never know.

Done, PR is updated. Now we test that `property` works with future import.

> When this was first proposed (https://github.com/python/typing/issues/985) there were worries about backwards compatibility. Given how common property is, we need to make sure there are no problems with that. Can you address that? I don't see it in the original thread.

I guess you were thinking about this one: https://github.com/python/typing/issues/594

Here's a list of problem from the original thread:

## the returned value of property has no typing equivalent

Now there is: `property[G, S]`

## There is no consistency in how properties in classes work in comparison to normal variables or functions

Author points out that all python versions right now ignore `property`s when `get_type_hints()` is used. There's nothing we can do here: it is not related to `property`s being generic in any way.

Here's how it works before my patch:

```python
Python 3.10.0 (default, Nov  1 2021, 10:24:06) [Clang 11.0.0 (clang-1100.0.33.16)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import get_type_hints
>>> class Some:
...   @property
...   def a(self) -> int:
...     return 1
... 
>>> get_type_hints(Some)
{}
>>> get_type_hints(Some.a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/sobolev/.pyenv/versions/3.10.0/lib/python3.10/typing.py", line 1827, in get_type_hints
    raise TypeError('{!r} is not a module, class, method, '
TypeError: <property object at 0x102b7a7f0> is not a module, class, method, or function.
```

I've added a test case for my patch to make sure this behavior is not changed. And indeed, it works exactly the same as before.

I've also covered a part from https://github.com/python/typing/issues/594#issuecomment-627692188

Runtime introspection of `fget` / `fset` / `fdel` works the same as before. I've added a test case for this.

## Forward compat

Users of python<3.11 will have `property` with `[]` type syntax via `typing_extensions`.
I don't think it is going to be widely used, though.

> Also, since this requires type checkers to change, do we need a PEP?

I cannot speak for all type-checkers, but I know how it works in mypy. Mypy already supports descriptors. So, this example works:

```python
class Desc:
    def __get__(self, obj, typ) -> int: pass

class Some:
    a = Desc()

s = Some()
reveal_type(s.a)     # N: Revealed type is "builtins.int"
reveal_type(Some.a)  # N: Revealed type is "builtins.int"
```

The same just works for my `property` stub example from https://github.com/python/typing/issues/985

All in all, I don't think that we need a PEP for three reasons:
1. properties are already supported in all type checkers (with special casing), if it does not cause any trouble, existing behavior can be left untouched. Mypy has multiple problem with our special casing
2. Underlying mechanism - which are descriptors - is also supported
3. Change is relatively small, it does not add any new concepts

Feedback on this is welcome! Maybe I am missing something.

> Honestly I think it's too soon for a PR given that we don't seem to have agreement in the typing tracker discussion.

This PR is really small. It took me like 30 mins, but we have a reference now. 
We can close it anytime with no damage done!
msg409129 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-12-24 08:28
Does it mean that property[GetType, SetType] will be required and MyPy will complain if the raw property decorator be used?
msg409160 - (view) Author: Nikita Sobolev (sobolevn) * (Python triager) Date: 2021-12-24 22:40
Serhiy, no, we can infer that.

There are two general cases:

1. `x = property(x_get, x_set)`, it is just ideal
2. `@property x` and `@x.setter`, it is also inferable with a bit of special casing for the mutable type part (we mutate the type of `x` when adding a setter)
msg410268 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2022-01-11 01:17
Since the conclusion is that we can't do this without breaking backwards compatibility, should we just close this? Or is there still a compromise possible?
msg410278 - (view) Author: Nikita Sobolev (sobolevn) * (Python triager) Date: 2022-01-11 08:24
Looks like no one showed much interest in it :(
So, yeah, closing it is probably the best idea.

Thanks everyone!
History
Date User Action Args
2022-04-11 14:59:53adminsetgithub: 90320
2022-01-11 08:24:39sobolevnsetstatus: open -> closed
resolution: rejected
messages: + msg410278

stage: patch review -> resolved
2022-01-11 01:17:04gvanrossumsetmessages: + msg410268
2021-12-24 22:40:30sobolevnsetmessages: + msg409160
2021-12-24 21:42:50AlexWaygoodsetnosy: + AlexWaygood
2021-12-24 21:38:26cdce8psetnosy: + cdce8p
2021-12-24 08:28:03serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg409129
2021-12-24 07:36:42sobolevnsetmessages: + msg409127
2021-12-23 18:56:35gvanrossumsetmessages: + msg409099
2021-12-23 09:55:14sobolevnsetkeywords: + patch
stage: patch review
pull_requests: + pull_request28460
2021-12-23 09:54:02sobolevnsetmessages: + msg409081
2021-12-23 09:50:25sobolevncreate