Skip to content

Allow subclassing Any at runtime #91154

Description

@hauntsaninja
BPO 46998
Nosy @gvanrossum, @JelleZijlstra, @hauntsaninja, @Fidget-Spinner, @AlexWaygood
PRs
  • bpo-46998: Allow subclassing Any at runtime #31841
  • 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-04-05.02:35:58.785>
    created_at = <Date 2022-03-13.03:06:37.673>
    labels = ['library', '3.11']
    title = 'Allow subclassing Any at runtime'
    updated_at = <Date 2022-04-05.02:35:58.784>
    user = 'https://github.com/hauntsaninja'

    bugs.python.org fields:

    activity = <Date 2022-04-05.02:35:58.784>
    actor = 'JelleZijlstra'
    assignee = 'none'
    closed = True
    closed_date = <Date 2022-04-05.02:35:58.785>
    closer = 'JelleZijlstra'
    components = ['Library (Lib)']
    creation = <Date 2022-03-13.03:06:37.673>
    creator = 'hauntsaninja'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 46998
    keywords = ['patch']
    message_count = 3.0
    messages = ['415023', '416720', '416721']
    nosy_count = 5.0
    nosy_names = ['gvanrossum', 'JelleZijlstra', 'hauntsaninja', 'kj', 'AlexWaygood']
    pr_nums = ['31841']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = None
    url = 'https://bugs.python.org/issue46998'
    versions = ['Python 3.11']

    Activity

    1. hauntsaninja commented on Mar 13, 2022

      @hauntsaninja
      ContributorAuthor
    2. added
      3.11only security fixes
      stdlibStandard Library Python modules in the Lib/ directory
      on Mar 13, 2022
    3. JelleZijlstra commented on Apr 5, 2022

      @JelleZijlstra
      Member

      New changeset 5a4973e by Shantanu in branch 'main':
      bpo-46998: Allow subclassing Any at runtime (GH-31841)
      5a4973e

    4. JelleZijlstra commented on Apr 5, 2022

      @JelleZijlstra
      Member

      Thanks for the idea and patch!

    5. transferred this issue fromon Apr 10, 2022
    6. superbobry commented on Aug 1, 2023

      @superbobry

      I understand the rationale for this change, but it does complicate the type system in unspecified (and not fully understood ways). For example

      • What does it mean to subclass Any in a) a generic class b) a protocol c) a typing.NamedTuple d) a typing.TypedDict?
      • Are Any subclasses plain subtypes of Any? Does this question even make sense?
      • How do Any subclasses interact with Any? Are they consistent with Any? Are they consistent subtypes of Any?
      • etc

      I know it is too late to revert this in 3.11, but is there a chance we could revisit the decision to make Any subclassable and put together a deprecation plan, where this behavior ultimately is going away?

    7. JelleZijlstra commented on Aug 1, 2023

      @JelleZijlstra
      Member

      We can always decide to change our mind and deprecate this feature, but that's putting the cart before the horse. Type checkers must support Any as a base class (it will come up if you inherit from a class in an untyped library), so the concept needs to be part of the type system somehow. Formalizing what subclassing Any means could be useful, but existing type checkers manage without it.

    8. superbobry commented on Aug 1, 2023

      @superbobry

      Is there a better forum to continue this discussion?

      I'm not sure I understand why inheriting from Any is necessary in the type system. In my mind, inheriting from a class in an untyped library is very different. An untyped class is syntactically known to be a class, i.e. a static type, whereas Any is a gradual type.

    9. AlexWaygood commented on Aug 1, 2023

      @AlexWaygood
      Member

      Is there a better forum to continue this discussion?

      @superbobry I'm a little confused here, because this was a change to runtime behaviour, but your concern seems to be with whether type checkers should allow Any to be subclassed or not. Whether it's allowed at runtime or not is pretty tangential to that discussion -- there are lots of things that are allowed at runtime that aren't allowed by some or all type checkers, and that's how it should be. If you want to write a type checker that disallows Any from ever being subclassed, it's your right to do so (though it's not one that most type checkers have taken), but the decision we took here to change the runtime behaviour has little bearing on that.

      Nonetheless, if you do want to argue that we should standardise the behaviour of type checkers so that they always disallow subclassing Any, feel free to open an issue at https://github.com/python/typing or to start a thread on the typing-sig mailing list (https://mail.python.org/archives/list/typing-sig@python.org/).

    10. superbobry commented on Aug 2, 2023

      @superbobry

      Thanks for chiming in @AlexWaygood!

      My concern is that this change does not just affect the runtime behavior as type checkers will now observe Any subclasses in the source and will need to decide what to do with them.

      I will follow up on typing-sig@.

    11. kmoffett commented on Dec 7, 2023

      @kmoffett

      I just discovered this behavior change recently, when our codebase upgraded to python 3.11. I would have expected Any to perhaps be a GenericAlias whose __mro_entries__ method returns (object,) or something like that, no? That way, the "subclasses" of Any are still just subclasses of object.

      But also, an object can get the same behavior of inheriting from Any by implementing __getattr__ that returns Any, right? And I assume all the mock-like objects already do that, no?

    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.11only security fixesstdlibStandard Library Python modules in the Lib/ directory

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions