Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I describe a special return type for a subclass? #6512

Closed
alippai opened this issue Oct 3, 2024 · 3 comments
Closed

How do I describe a special return type for a subclass? #6512

alippai opened this issue Oct 3, 2024 · 3 comments
Assignees

Comments

@alippai
Copy link

alippai commented Oct 3, 2024

Pylance gives me: Overload 1 for "myfunc" overlaps overload 2 and returns an incompatible type Pylance[reportOverlappingOverload] for the below snippet:

from datetime import date, datetime
from typing import overload, Any

@overload
def myfunc(param: datetime) -> int:
    ...

@overload
def myfunc(param: date) -> str:
    ...

def myfunc(param: date) -> Any:
    if isinstance(param, datetime):
        return 5
    else:
        return "asd"
@github-actions github-actions bot added the needs repro Issue has not been reproduced yet label Oct 3, 2024
@erictraut
Copy link
Contributor

erictraut commented Oct 3, 2024

Pyright (the type checker that pylance is built upon) is working correctly here. It's telling you that you've defined two overloads that "overlap". That means the same set of arguments can match both overloads, but the return types are incompatible. This makes it possible for a call to result in an incorrect type. Consider the following.

def as_date(v: datetime) -> date:
    return v

x = myfunc(as_date(datetime(1, 2, 3)))
reveal_type(x)  # Statically evaluated as "str", but returns "int" at runtime

If you're not concerned about this potential "unsoundness", you can suppress the error with a # type: ignore or # pyright: ignore[reportOverlappingOverload] comment. If you don't want to see any errors in this category, you can disable the reportOverlappingOverload check in your project.

If this is your code and you're able to modify it, you may want to consider redesigning it to avoid this fragility. I don't know how this function is intended to be used, so I can't offer any more specific suggestions.

If you're interested in learning more about overloads and what it means for them to be "overlapping", you might be interested in reading the draft chapter that I recently wrote and submitted for inclusion in the Python typing spec.

@alippai
Copy link
Author

alippai commented Oct 3, 2024

Thanks, Eric.
I’m happy to change the typing and overloads of the function, but I can’t change the behavior.

The key is that it returns different type based on if the parameter is date or datetime. As the datetime is a subclass of date, I struggle to describe the return typing.

So I’d do “if param type is a special subclass (datetime) then return int, if the parameter type is anything else from the date class (eg date itself) then return string”. In python I can’t write a typing like “date except datetime” to make it non-overlapping, but I don’t know how to pass pylance (and mypy)

@erictraut
Copy link
Contributor

The Python type system doesn't allow you to express date except datetime. When you use the name of a class in a type annotation, that annotation represents the set of all values that are instances of the specified class and subclasses thereof. So if I hand you a value that is described by the annotation date, you cannot say whether that object is a datetime instance without doing runtime introspection on that object. It's best to avoid creating functions / APIs that have this sort of behavior. I realize that it's not always possible to avoid this — especially for existing APIs.

If you're not able to change the design of this function, then you'll need to live with the unsoundness. You can suppress the error if you don't want to see it.

@StellaHuang95 StellaHuang95 added by design and removed needs repro Issue has not been reproduced yet labels Oct 3, 2024
alippai added a commit to alippai/pandas-stubs that referenced this issue Oct 13, 2024
alippai added a commit to alippai/pandas-stubs that referenced this issue Oct 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants