Skip to content

Overloaded signature with LiteralString is seen as "broader or same" as str #18584

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

Closed
Avasam opened this issue Feb 1, 2025 · 1 comment
Closed
Labels
bug mypy got something wrong topic-overloads

Comments

@Avasam
Copy link
Contributor

Avasam commented Feb 1, 2025

Bug Report

(A clear and concise description of what the bug is.)

To Reproduce

import os
from typing import TYPE_CHECKING, overload

if TYPE_CHECKING:
    from _typeshed import StrPath
    from typing_extensions import LiteralString, reveal_type

@overload
def insert_before_extension(
    filename: LiteralString | os.PathLike[LiteralString], content: LiteralString
) -> LiteralString: ...
@overload
def insert_before_extension(filename: StrPath, content: str) -> str: ...
def insert_before_extension(filename: StrPath, content: str) -> str:
    """
    Given a filename and some content, insert the content just before
    the extension.

    >>> insert_before_extension('pages.pdf', '-old')
    'pages-old.pdf'
    """
    parts = list(os.path.splitext(filename))
    parts[1:1] = [content]
    return ''.join(parts)

a = insert_before_extension("", "")
reveal_type(a)
b = insert_before_extension(str(0), str(0))
reveal_type(b)

Expected Behavior

I expected mypy to see the overloads as being different so that a function passed literal inputs can propagate its output as also being literal (ie: not a user input). With a fallback to a regular str when the input isn't statically controlled.

Pyright supports this. Results from Pylance:

Type of "a" is "LiteralString"
Type of "b" is "str"

Actual Behavior
Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader [overload-cannot-match]
In both cases: Revealed type is "builtins.str"

Your Environment

  • Mypy version used: mypy 1.14.1 (compiled: yes)
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.12.6
@Avasam Avasam added the bug mypy got something wrong label Feb 1, 2025
@hamdanal
Copy link
Collaborator

hamdanal commented Feb 2, 2025

This is working as expected because mypy does not support PEP 675 yet.
mypy currently treats LiteralString as an alias to str, meaning both overloads in your example are the same, hence the error.

Duplicate of #12554

@hamdanal hamdanal closed this as completed Feb 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-overloads
Projects
None yet
Development

No branches or pull requests

3 participants