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

Make builtins.property generic #90320

Closed
sobolevn opened this issue Dec 23, 2021 · 8 comments
Closed

Make builtins.property generic #90320

sobolevn opened this issue Dec 23, 2021 · 8 comments
Labels
3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@sobolevn
Copy link
Member

BPO 46162
Nosy @gvanrossum, @serhiy-storchaka, @sobolevn, @Fidget-Spinner, @AlexWaygood, @cdce8p
PRs
  • bpo-46162: make property generic #30238
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2022-01-11.08:24:39.222>
    created_at = <Date 2021-12-23.09:50:25.750>
    labels = ['type-bug', 'library', '3.11']
    title = 'Make `builtins.property` generic'
    updated_at = <Date 2022-01-11.08:24:39.221>
    user = 'https://github.com/sobolevn'

    bugs.python.org fields:

    activity = <Date 2022-01-11.08:24:39.221>
    actor = 'sobolevn'
    assignee = 'none'
    closed = True
    closed_date = <Date 2022-01-11.08:24:39.222>
    closer = 'sobolevn'
    components = ['Library (Lib)']
    creation = <Date 2021-12-23.09:50:25.750>
    creator = 'sobolevn'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 46162
    keywords = ['patch']
    message_count = 8.0
    messages = ['409080', '409081', '409099', '409127', '409129', '409160', '410268', '410278']
    nosy_count = 6.0
    nosy_names = ['gvanrossum', 'serhiy.storchaka', 'sobolevn', 'kj', 'AlexWaygood', 'cdce8p']
    pr_nums = ['30238']
    priority = 'normal'
    resolution = 'rejected'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue46162'
    versions = ['Python 3.11']

    @sobolevn
    Copy link
    Member Author

    Original discussion in typing bug tracker: python/typing#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 PEP-585

    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?

    @sobolevn sobolevn added 3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Dec 23, 2021
    @sobolevn
    Copy link
    Member Author

    One more question about PEP-585: it does not specify property. Do we need to update it?

    @gvanrossum
    Copy link
    Member

    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 (python/typing#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.)

    @sobolevn
    Copy link
    Member Author

    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 (python/typing#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: python/typing#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 propertys when get_type_hints() is used. There's nothing we can do here: it is not related to propertys being generic in any way.

    Here's how it works before my patch:

    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 python/typing#594 (comment)

    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:

    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 python/typing#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!

    @serhiy-storchaka
    Copy link
    Member

    Does it mean that property[GetType, SetType] will be required and MyPy will complain if the raw property decorator be used?

    @sobolevn
    Copy link
    Member Author

    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)

    @gvanrossum
    Copy link
    Member

    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?

    @sobolevn
    Copy link
    Member Author

    Looks like no one showed much interest in it :(
    So, yeah, closing it is probably the best idea.

    Thanks everyone!

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.11 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants