FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Top / function argument level ClassVar should not be allowed during `get_type_hints()` · Issue #89446 · python/cpython · GitHub

Repository navigation

Top / function argument level ClassVar should not be allowed during get_type_hints() #89446

Closed

Description

BPO 45283
Nosy @gvanrossum, @ambv, @sobolevn, @Fidget-Spinner
PRs
  • bpo-45283: Run _type_check on get_type_hints() #28563
  • 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 = None
    created_at = <Date 2021-09-24.13:44:07.559>
    labels = ['type-bug', 'library', '3.9', '3.10', '3.11']
    title = 'Top / function argument level ClassVar should not be allowed during `get_type_hints()`'
    updated_at = <Date 2021-09-26.17:09:09.780>
    user = 'https://github.com/sobolevn'

    bugs.python.org fields:

    activity = <Date 2021-09-26.17:09:09.780>
    actor = 'lukasz.langa'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2021-09-24.13:44:07.559>
    creator = 'sobolevn'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 45283
    keywords = ['patch']
    message_count = 7.0
    messages = ['402563', '402628', '402631', '402636', '402640', '402641', '402671']
    nosy_count = 4.0
    nosy_names = ['gvanrossum', 'lukasz.langa', 'sobolevn', 'kj']
    pr_nums = ['28563']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue45283'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    Activity

    1. sobolevn commented on Sep 24, 2021

      MemberAuthor

      This code currently does not raise any issues:

      # contents of `ex.py`
      from typing import ClassVar
      
      a: ClassVar[int] = 1
      def b(c: ClassVar[int]): ...

      And then:

      1. Module: python -c 'import ex; from typing import get_type_hints; print(get_type_hints(ex))'
      2. Function argument: python -c 'import ex; from typing import get_type_hints; print(get_type_hints(ex.b))'

      It should not be allowed. Currently, the same with from __future__ import annotations does correctly raise TypeError: typing.ClassVar[int] is not valid as type argument

      Related: #28279

      I will send a PR with the fix shortly.

    2. added
      3.11only security fixes
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      on Sep 24, 2021
    3. gvanrossum commented on Sep 25, 2021

      Member

      Hm. IMO it is up to static type checkers to reject bad use of types. The runtime should be relaxed so type checkers can develop new features assigning new semantics to such constructs.

    4. Fidget-Spinner commented on Sep 25, 2021

      Member

      This makes get_type_hints quite opinionated and backwards incompatible. The first line the docs says "This is often the same as obj.annotations".

      I also agree with Guido. FYI, we've tried to reduce usage of _type_check in new features since version 3.10. We've found that they make typing_extensions operability with typing worse. For example, the whole of PEP-612 in typing_extensions required lots of hacks to work with typing's Callable.

      If you're really vouching for this change. We probably need a 2 major version deprecation period (with warnings telling the user their current type hints are invalid) *plus* asking typing-sig/python-dev if the runtime type hints users will be affected. See PEP-387 for more info.

      On the other hand, we now have a less-opinionated alternative to get_type_hints with inspect.get_annotations, but it can't do as much (like resolving ForwardRef).

    5. sobolevn commented on Sep 25, 2021

      MemberAuthor

      Just to bring in some context for this discussion: #28279

      We have dicussed in the PR above that current implementation depends on existing of __future__ import of annotations.

      With from __future__ import annotations:

      1. Top level class var will be raise TypeError
      2. Final and ClassVar function arguments will raise TypeError
      3. Annotations like x: 1 will raise TypeError: Forward references must evaluate to types. Got 1.

      Without from __future import annotationsit accepts all the cases above.

      I share two opposite views on this change:

      1. By adding the same _type_check logic we can reduce the inconsitency between two versions. It would be easier for users to migrate from one version to another.
      2. By adding this feature, we would more aggresively force some specific semantics for builtin types. Which can possibly be problematic, for example I've tried to add Final annotations to function arguments in my own type checker. It is something current semantics does not support. Moreover, it can cause incompatibility to existing users.

      My opinion is that consitency is more important here. Because I received quite a lot of bug reports from users involving different behavior with / without __future__ import of annotations.

      But, I understand that it is not up to me to decide :)

    6. Fidget-Spinner commented on Sep 25, 2021

      Member
      1. By adding the same _type_check logic we can reduce the inconsistency between two versions. It would be easier for users to migrate from one version to another.

      That's definitely a plus. But please consider this hypothetical scenario:

      • Let's say some typing code has _type_check in 3.8
      • In 3.12, we decide to give type hinting with ints (like x: 1) some meaning (this has been proposed before in typing-sig).
      • The new construct arrives in 3.12. We backport to typing_extensions, which must support 3.8's typing module.
      • Now the new addition to 3.12 typing_extensions doesn't work with 3.8 typing because of _type_check, and we need to hack around it.
      • The hacks may eventually lead to real behavioral inconsistencies between typing_extensions and typing.

      If this sounds familiar, that's because something similar has already happened! Callable and Generic had too strict checking in typing (requiring Callable's args to be a tuple of types always) before 3.10. So typing_extensions doesn't support the full PEP-612 syntax :( https://github.com/python/typing/tree/master/typing_extensions#other-notes-and-limitations.

      Stricter runtime type checking makes growing the typing syntax harder. For the newer types, we try to defer checking to 3rd-party libraries.

      Because I received quite a lot of bug reports from users involving different behavior with / without __future__ import of annotations.

      Your perspective as a runtime typing library dev is very valuable. Thank you for your feedback! IMO, from __future__ import annotations becoming the default in 3.11 is still undecided. It was yanked from 3.10 for breaking pydantic and FastAPI, and I doubt it will land in 3.11 for the same reasons. It seems the current consensus is to use that import for code with purely static typing, and not use it with runtime typing libraries.

    7. sobolevn commented on Sep 25, 2021

      MemberAuthor

      Thank you, Ken Jin! Very clear explanation!

      It seems the current consensus is to use that import for code with purely static typing, and not use it with runtime typing libraries.

      Is it an official position? Or just a common usage pattern?
      What can we do to make this more widely known?

      Maybe we can formulate something like "When to use: raw, string, future annotations" in the typing docs (https://docs.python.org/3/library/typing.html)?

    8. ambv commented on Sep 26, 2021

      Contributor

      Is it an official position?

      No, we need to decide what will happen to PEP-563 and PEP-649 in Python 3.11.

    9. transferred this issue fromon Apr 10, 2022
    10. AlexWaygood commented on Apr 14, 2022

      Member

      The consensus on this issue is that stricter runtime type-checking in get_type_hints (at least for ClassVar, probably also in general) would be undesirable, and the linked PR has been closed. I am therefore closing this issue.

    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

      3.10 (EOL)end of life3.11only security fixes3.9 (EOL)end of lifestdlibStandard Library Python modules in the Lib/ directorytopic-typingtype-bugAn unexpected behavior, bug, or error

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions


        Back | FazBrowse Home | New Git URL