GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Problems caused by isinstance(list[int], type) returning True · Issue #89828 · python/cpython

Problems caused by isinstance(list[int], type) returning True #89828

New issue
Copy link
New issue
Copy link
Closed
Closed
Problems caused by isinstance(list[int], type) returning True#89828
Copy link
Labels
3.10 (EOL)end of lifeend of life3.11only security fixesonly security fixes3.9 (EOL)end of lifeend of lifestdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-typingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@serhiy-storchaka
serhiy-storchaka
opened on Oct 29, 2021
Issue body actions
BPO 45665
Nosy @gvanrossum, @serhiy-storchaka, @wyfo, @Fidget-Spinner, @AlexWaygood, @martinitus
Dependencies
  • bpo-40296: help(list[int]) fails
  • bpo-45438: inspect not capturing type annotations created by class_getitem
  • bpo-45662: Incorrect repr of InitVar of a type alias
  • bpo-45663: is_dataclass() does not work for dataclasses which are subclasses of types.GenericAlias
  • bpo-45664: resolve_bases() and new_class() do not work with type alias of a built-in type
  • bpo-46032: functools' singledispatch does not support GenericAlias
  • 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-10-29.08:27:43.950>
    labels = ['type-bug', 'library', '3.9', '3.10', '3.11']
    title = 'Problems caused by isinstance(list[int], type) returning True'
    updated_at = <Date 2022-01-06.16:58:47.655>
    user = 'https://github.com/serhiy-storchaka'

    bugs.python.org fields:

    activity = <Date 2022-01-06.16:58:47.655>
    actor = 'AlexWaygood'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2021-10-29.08:27:43.950>
    creator = 'serhiy.storchaka'
    dependencies = ['40296', '45438', '45662', '45663', '45664', '46032']
    files = []
    hgrepos = []
    issue_num = 45665
    keywords = []
    message_count = 17.0
    messages = ['405290', '405291', '405427', '405429', '408207', '409167', '409233', '409679', '409691', '409694', '409697', '409701', '409702', '409703', '409711', '409792', '409881']
    nosy_count = 6.0
    nosy_names = ['gvanrossum', 'serhiy.storchaka', 'joperez', 'kj', 'AlexWaygood', 'martinitus']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = None
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue45665'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    • help(list[int]) fails #84476
    • inspect not capturing type annotations created by __class_getitem__ #89601
    • Incorrect repr of InitVar of a type alias #89825
    • is_dataclass() does not work for dataclasses which are subclasses of types.GenericAlias #89826
    • resolve_bases() and new_class() do not work with type alias of a built-in type #89827
    • functools' singledispatch does not support GenericAlias #90190
    • Enum does not work if member is an instance of types.GenericAlias #93847

    Activity

    Next
    1. serhiy-storchaka commented on Oct 29, 2021

      @serhiy-storchaka
      serhiy-storchaka
      on Oct 29, 2021
      MemberAuthor
      More actions

      This is a meta-issue for problems caused by isinstance(list[int]) returning True.

      See also discussion in bpo-45438.

    2. serhiy-storchaka
      added
      3.9 (EOL)end of lifeend of life
      3.10 (EOL)end of lifeend of life
      3.11only security fixesonly security fixes
      stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
      on Oct 29, 2021
    3. serhiy-storchaka commented on Oct 29, 2021

      @serhiy-storchaka
      serhiy-storchaka
      on Oct 29, 2021
      MemberAuthor
      More actions

      isinstance(x, type) returns True for instances of types.GenericAlias (like list[int]). While it may help in some cases related to typing, in many unrelated cases it causes problems if the value which is not a type passes checks for types.

      Also, isinstance(x, type) been not equal to issubclass(type(x), type) can cause other problems. No matter what the result should be, it should be consistent.

      There are many occurrences of isinstance(..., type) in the code.

      $ find Lib -name '*.py' \! -path '*/test*' -exec egrep 'isinstance.*,
      type\)' '{}' + | wc -l
      55

      And all of them can potentially be broken if pass a types.GenericAlias instance. Many of them are safe, but every case should be analyzed.

    4. serhiy-storchaka
      changed the title [-]Problems caused by isinstance(list[int]) returning True[/-] [+]Problems caused by isinstance(list[int], type) returning True[/+] on Oct 29, 2021
    5. serhiy-storchaka
      changed the title [-]Problems caused by isinstance(list[int]) returning True[/-] [+]Problems caused by isinstance(list[int], type) returning True[/+] on Oct 29, 2021
    6. martinitus commented on Nov 1, 2021

      @martinitus
      martinitusmannequin
      on Nov 1, 2021
      Mannequin
      More actions

      One thing that probably should be considered in this context:

      isinstance(arg, type) == issubclass(type(arg), type)

      Holds True for arg in (Optional[X], Union[X, Y]). Both sides evaluate to False. (v3.10.0)

      While I still think both sides evaluating to True would be more intuitive, this supports the proposed change.

      Small test snippet:

      from typing import Dict, List, Set, Tuple, Optional, Union
      
      import pytest
      
      
      @pytest.mark.parametrize('arg', [
          list, List[int], list[int],
          dict, Dict[str, int], dict[str, int],
          set, Set[int], set[int],
          tuple, Tuple[str, int], tuple[str, int],
          Optional[int],
          Union[int, str]
      ])
      def test_invariant(arg):
          same = isinstance(arg, type) == issubclass(type(arg), type)
          result = "Check" if same else "Failed"
          print(f"\n{result}: Testing: {arg=} with {type(arg)=}: {isinstance(arg, type)=} <> {issubclass(type(arg), type)=}")
          assert same
      
      

      Any other commonly used annotations that could be added to the checklist?

    7. 12 remaining items

    8. pablogsal commented on Jan 5, 2022

      @pablogsal
      pablogsal
      on Jan 5, 2022
      Member
      More actions

      Gentle ping, as the next alpha will be release soon

    9. AlexWaygood commented on Jan 6, 2022

      @AlexWaygood
      AlexWaygood
      on Jan 6, 2022
      Member
      More actions

      We will still allow instantiating e.g. list[int], right?

      I certainly hope so! That would be a much more breaking change if we were to change that, and I can't personally see any benefit to doing so.

    10. ezio-melotti
      transferred this issue fromon Apr 10, 2022
    11. AlexWaygood
      added
      topic-typing
      on Apr 13, 2022
    12. serhiy-storchaka
      added a commit that references this issue on Jun 12, 2022

      pythongh-89828: Do not relay the __class__ attribute in GenericAlias

      2c3e4d1
    13. serhiy-storchaka commented on Jun 12, 2022

      @serhiy-storchaka
      serhiy-storchaka
      on Jun 12, 2022
      MemberAuthor
      More actions

      The cause what that list[int].__class__ returned type instead of types.GenericAlias.

      I suppose also that there may be problems caused by relaying other dunder methods. There is a list of exceptions, but it is not complete. typing._GenericAlias in general does not relay dunder methods (except __name__ and __qualname__).

    14. serhiy-storchaka
      added a commit that references this issue on Jun 18, 2022

      gh-89828: Do not relay the __class__ attribute in GenericAlias (#93754)

      f9433ff
    15. miss-islington
      added 2 commits that reference this issue on Jun 18, 2022

      pythongh-89828: Do not relay the __class__ attribute in GenericAlias (p…

      257f48c

      gh-89828: Do not relay the __class__ attribute in GenericAlias (GH-93754

      579e985
    16. serhiy-storchaka
      added a commit that references this issue on Jun 26, 2022

      Revert 30935 defer bpo45162 to 312 (#94285)

      1ffde3e
    17. johnslavik commented on Jan 17, 2023

      @johnslavik
      johnslavik
      on Jan 17, 2023
      Member
      More actions

      At this point I'd like to report the following inconsistency between C PyType_Check(t) and Python's isinstance(t, type) that I've noticed. I don't know if it's fixed at the moment, just so that it doesn't get lost:

      from abc import ABCMeta  # the C implementation is required for this snippet
      
      class MyABC(metaclass=ABCMeta):
          pass
      
      t = list[int]
      isinstance(t, type) and issubclass(t, MyABC)

      causing the following error:

      Traceback (most recent call last):
        File "...", line 9, in <module>
          isinstance(t, type) and issubclass(t, MyABC)
        File "/usr/lib/python3.10/abc.py", line 123, in __subclasscheck__
          return _abc_subclasscheck(cls, subclass)
      TypeError: issubclass() arg 1 must be a class
      

      But if we change abc import to _py_abc,

      from _py_abc import ABCMeta  # Python implementation
      
      class MyABC(metaclass=ABCMeta):
         pass
      
      t = list[int]
      isinstance(t, type) and issubclass(t, MyABC)

      the above absolutely does not produce any error.
      This is of course clearly a GenericAlias-related problem.

    18. gvanrossum commented on Jan 18, 2023

      @gvanrossum
      gvanrossum
      on Jan 18, 2023
      Member
      More actions

      At this point I'd like to report the following inconsistency between C PyType_Check(t) and Python's isinstance(t, type) that I've noticed. I don't know if it's fixed at the moment, just so that it doesn't get lost:
      [...]

      What Python version? The most recent version where I can repro that error is 3.10. The fix appears to be in 3.11 and on main (3.12 alpha).

    19. johnslavik commented on Jan 19, 2023

      @johnslavik
      johnslavik
      on Jan 19, 2023
      Member
      More actions

      Oh, right. Yes, it was 3.10, like in the traceback.
      Sorry for not specifying the version and not checking if the bug is not already fixed in versions >3.10.
      Also sorry for causing unnecessary chaos.
      Thanks and good luck!

    20. serhiy-storchaka commented on Jan 19, 2023

      @serhiy-storchaka
      serhiy-storchaka
      on Jan 19, 2023
      MemberAuthor
      More actions

      There is not much that we can do with this in 3.10. The workaround in the user code is:

      isinstance(t, type) and not isinstance(t, types.GenericAlias) and issubclass(t, MyABC)

      The middle check is not needed in 3.11+.

      I think this issue can now be closed. I have not found other sites in the stdlib with user visible differences.

      But I have found an interesting difference in the behavior of issubclass(), which should rarely affect user code: #101162.

    21. serhiy-storchaka
      closed this as completedon Jan 19, 2023
    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 lifeend of life3.11only security fixesonly security fixes3.9 (EOL)end of lifeend of lifestdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-typingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        You are visitor 01402503 — GeezerVison does not store the pages you look up.
        Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.