8000 [question] Overload with return type depending on an optional argument · Issue #5621 · python/mypy · GitHub
[go: up one dir, main page]

Ski 8000 p to content
[question] Overload with return type depending on an optional argument #5621
Closed
@zero323

Description

@zero323

i am working on annotation for a 3rd package. For simplicity let's say we have a function like this one:

def foo(x=0, f=None):
    return f(x) if f else x + 1

I would like to express, that the return type of the function is

  • int if f is missing.
  • The same as f return type otherwise.

So conceptually I would like to see something like this:

from typing import Callable, TypeVar, overload

T = TypeVar("T")

@overload
def foo(x: int = ..., f: Callable[[int], T]) -> T: ...
@overload
def foo(x: int = ...) -> int: ...

Of course, it is not valid, as non-default argument follows default argument. Similarly (as imprecise as it would be) we cannot use the following

from typing import Callable, TypeVar
from typing import overload

T = TypeVar("T")

@overload
def foo(x: int = ..., f: Callable[[int], T] = ...) -> T: ...
@overload
def foo(x: int = ...) -> int: ...

because the optional argument, makes the first signature broader than the second one.

A workaround is to split the first signature into two separate cases:

from typing import Callable, TypeVar
from typing import overload

T = TypeVar("T")

@overload
def foo(x: int, f: Callable[[int], T] = ...) -> T: ...
@overload
def foo(f: Callable[[int], T] = ...) -> T: ...
@overload
def foo(x: int = ...) -> int: ...

but it doesn't scale when the number of preceding optional arguments grows:

def bar(x=0,  y=0, z=0, f=None):
     return f(x + y + z) if f else x + y + z + 1

Is there any other solution here?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0