This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Extend registering of single-dispatch functions to parametrized generic pseudo-types
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.7
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: Dutcho, levkivskyi, lukasz.langa
Priority: normal Keywords:

Created on 2018-08-25 12:38 by Dutcho, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg324063 - (view) Author: (Dutcho) Date: 2018-08-25 12:38
While issue #34498 signalled a break in Python 3.7 of legal Python 3.6 code that registers a single-dispatch function with a 'pseudo-type' like typing.Sequence, both Python 3.6 and Python 3.7 don't work with a 'parametrized pseudo-type' like typing.Sequence[int].
However, to fully benefit from Python 3.7's use of annotations for registering single-dispatch functions, these 'parametrized pseudo-types' should also be acceptable.

E.g. in Python 3.6:
$ py -3.6
Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from functools import singledispatch
>>> from typing import Iterable, Sequence, T
>>>
>>> @singledispatch
... def last(iterable: Iterable[T]) -> T:
...     for last in iterable:
...             pass
...     return 'slow', last
...
>>> @last.register(Sequence)
... def _(sequence: Sequence[T]) -> T:
...     return 'fast', sequence[-1]
...
>>> print(*last(iter([1, 2, 3])))
slow 3
>>> print(*last([1, 2, 3]))
fast 3

Note in Python 3.6 no match results if the 'parametrized pseudo-type' Sequence[T] is specified as argument to last.register() as isinstance(..., Sequence[T]) fails.

To fully benefit from Python 3.7's use of annotations for single-dispatch functions, it should
(1) accept 
>>> @last.register
... def _(sequence: Sequence[T]) -> T:
...     return 'fast', sequence[-1]
and (2) remove the T parameter of Sequence for matching when dispatching. I recognize this could potentially create a clash between e.g. Sequence[int] and Sequence[str]
msg324462 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-09-01 10:18
TBH, I don't like this idea. Consider this situation:

    @singledispatch
    def what(x: Iterable) -> None:
        print('general case')

    @what.register
    def _(x: Sequence[int]) -> None:
        print('special case')

    what(['is', 'going', 'on'])  # special case?

Even if you put in the docs that variables are erased etc. people will assume type arguments mean something unless rejected by `singledispatch`. The behaviour you propose can cause confusion.
msg324506 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2018-09-03 11:27
I agree with Ivan. This is a no go for parametrized pseudotypes.
History
Date User Action Args
2022-04-11 14:59:05adminsetgithub: 78680
2018-09-03 11:27:22lukasz.langasetstatus: open -> closed
resolution: wont fix
messages: + msg324506

stage: resolved
2018-09-01 10:18:13levkivskyisetnosy: + lukasz.langa
messages: + msg324462
2018-08-31 20:34:35levkivskyisetnosy: + levkivskyi
2018-08-25 12:38:48Dutchocreate