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 — functools.singledispatch doesn't verify annotation is on FIRST parameter · Issue #84644 · python/cpython

functools.singledispatch doesn't verify annotation is on FIRST parameter #84644

New issue
Copy link
New issue
Copy link
Open
Open
functools.singledispatch doesn't verify annotation is on FIRST parameter#84644
Copy link
Labels
3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

Dutcho
mannequin
opened on May 1, 2020
Issue body actions
BPO 40464
Nosy @rhettinger, @ambv, @Dutcho, @FFY00, @VismantasD, @AlexWaygood
PRs
  • bpo-40464: fix return annotation being used as the arg annotation in singledispatch #19871
  • 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 2020-05-01.07:04:01.217>
    labels = ['type-bug', 'library', '3.9', '3.10', '3.11']
    title = "functools.singledispatch doesn't verify annotation is on FIRST parameter"
    updated_at = <Date 2021-11-09.22:47:09.886>
    user = 'https://github.com/Dutcho'

    bugs.python.org fields:

    activity = <Date 2021-11-09.22:47:09.886>
    actor = 'AlexWaygood'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2020-05-01.07:04:01.217>
    creator = 'Dutcho'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 40464
    keywords = ['patch']
    message_count = 4.0
    messages = ['367824', '368079', '368095', '406062']
    nosy_count = 6.0
    nosy_names = ['rhettinger', 'lukasz.langa', 'Dutcho', 'FFY00', 'bim_bam', 'AlexWaygood']
    pr_nums = ['19871']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue40464'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    Linked PRs

    • gh-84644: Don't single-dispatch on return types #140255
    • gh-84644: Fix singledispatch annotation parsing #143465

    Activity

    Next
    1. Dutcho commented on May 1, 2020

      @Dutcho
      Dutchomannequin
      on May 1, 2020
      MannequinAuthor
      More actions

      From Python 3.7, functools.singledispatch makes the register() attribute of the generic function infer the type of the first argument automatically for functions annotated with types. That's great for DRY.
      However, in 3.7 and 3.8, no check is made that the first parameter of the registered function is actually annotated; any annotation suffices, even the return one.

      Example:

      >>> @functools.singledispatch
      ... def func(arg):...
      >>> @func.register
      ... def _int(arg) -> int:...
      >>> @func.register
      ... def _str(arg) -> str:...
      

      No errors happen, although the return type, not arg, is annotated.
      This results in:

      >>> func.registry
      mappingproxy({<class 'object'>: <function func>, <class 'int'>: <function _int>, <class 'str'>: <function _str>})
      

      Obviously, that doesn't dispatch correctly.

      Note that un-annotated functions *are* caught:

      >>> @func.register
      ... def _no_annotation(arg): ...
      Traceback (most recent call last):
      ...
      TypeError: Invalid first argument to `register()`: <function _no_annotation at 0x000001D769A43D30>. Use either `@register(some_class)` or plain `@register` on an annotated function.
      
    2. Dutcho
      added
      3.7 (EOL)end of lifeend of life
      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 May 1, 2020
    3. Dutcho commented on May 4, 2020

      @Dutcho
      Dutchomannequin
      on May 4, 2020
      MannequinAuthor
      More actions

      I'm afraid my "even return" was interpreted in #19871 as "only return", while as stated "any annotation" suffices. To rephrase:
      If the *first* parameter of the registered function isn't annotated, any non-first annotation suffices for registering, but will not dispatch correctly.
      Example:

      >>> @functools.singledispatch
      ... def func(arg, x):...
      >>> @func.register
      ... def _int(arg, x:int):...
      >>> @func.register
      ... def _str(arg, x:str):...
      

      No errors happen, although parameter x is annotated, not the first parameter arg. So func() will dispatch on the type of arg according to the annotation of x.
      So I'm afraid the PR solves the specific "return" example case, but not the flagged general issue.

    4. FFY00 commented on May 5, 2020

      @FFY00
      FFY00
      on May 5, 2020
      Member
      More actions

      Right, forgot about that. We can get the first argument name from inspect.signature and then fetch it from the get_type_hints dictionary, I don't know a better way to do it.

    5. AlexWaygood commented on Nov 9, 2021

      @AlexWaygood
      AlexWaygood
      on Nov 9, 2021
      Member
      More actions

      Reproduced on 3.11.

    6. AlexWaygood
      added
      3.9 (EOL)end of lifeend of life
      3.10 (EOL)end of lifeend of life
      3.11only security fixesonly security fixes
      and removed
      3.7 (EOL)end of lifeend of life
      on Nov 9, 2021
    7. 7 remaining items

    8. ZeroIntensity
      added
      3.13only security fixesonly security fixes
      3.14bugs and security fixesbugs and security fixes
      3.15bugs and security fixesbugs and security fixes
      and removed
      3.9 (EOL)end of lifeend of life
      on Oct 17, 2025
    9. johnslavik
      added 3 commits that reference this issue on Jan 7, 2026

      Add precedent case for pythonGH-84644

      ec01821

      Fix pythonGH-84644 test

      57faa34

      Fix `TestSingleDispatch.test_method_signatures` to put annotations on…

      30a5245
    10. serhiy-storchaka
      added a commit that references this issue on Jan 11, 2026

      gh-127750: Fix annotations in singledispatchmethod signature tests (G…

      620a5b9
    11. miss-islington
      added 2 commits that reference this issue on Jan 11, 2026

      pythongh-127750: Fix annotations in singledispatchmethod signature te…

      9c7f1fc

      pythongh-127750: Fix annotations in singledispatchmethod signature te…

      c9eccc7
    12. serhiy-storchaka
      added 2 commits that reference this issue on Jan 11, 2026

      [3.13] gh-127750: Fix annotations in singledispatchmethod signature t…

      ea1ecf6

      [3.14] gh-127750: Fix annotations in singledispatchmethod signature t…

      ea26c88
    13. reidenong
      added a commit that references this issue on Jan 12, 2026

      pythongh-127750: Fix annotations in singledispatchmethod signature te…

      13c9f56
    14. thunder-coding
      added a commit that references this issue on Feb 15, 2026

      pythongh-127750: Fix annotations in singledispatchmethod signature te…

      5b0a063
    15. encukou
      added a commit that references this issue on Oct 21, 2026

      gh-84644: Deprecate singledispatch on return annotation (GH-143465)

      641ef0a
    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.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-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.