Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Accepting an iterable of strings, but NOT a plain string #2028

Unanswered
Dr-Irv asked this question in Q&A
Discussion options

In pandas, we have methods that can accept iterables of strings, but not a plain string. From useful_types, there is the SequenceNotStr type that is a sequence that doesn't include plain strings. But how can we do the same for iterables? I thought of doing something like this:

Example:

from typing import Iterable, overload, NoReturn
@overload
def func(s: str) -> NoReturn: ...
@overload
def func(s: Iterable[str]) -> list[str]: ...
def func(s: Iterable[str]) -> list[str]:
 if isinstance(s, str):
 raise Exception("plain string not accepted")
 else:
 x = [v for v in s]
 return x
# reveal_type(func("abc"))
func("abc")
v = 3 + 4
func({"a": 1, "b": 2})

This code will raise an exception as expected. If I uncomment the reveal_type() line, the type is revealed as NoReturn or Never by pyright and mypy, respectively. But pyright and mypy don't say that the line with v = 3 + 4 is unreachable.

Ideally, the type checker would show that func("abc") is an invalid call. How do we accomplish that?

You must be logged in to vote

Replies: 2 comments 3 replies

Comment options

Linking #256 for related discussion

You must be logged in to vote
0 replies
Comment options

But pyright and mypy don't say that the line with v = 3 + 4 is unreachable.

I think this may be a configuration issue. mypy-playground, pyright-playground

One caveat is that they only raise the unreachable on the next line, not on the line that produces the Never, which can lead to subtle false negatives. For example, if you have a return func("abc") in the last line of some function.

See: python/mypy#15821

You must be logged in to vote
3 replies
Comment options

I think this may be a configuration issue.

Yes, for pyright it is, and that's a new parameter as of a week ago. IMHO, the result of NoReturn in a case like this should be flagged differently. It should be "that's an invalid call". It's not about reachability - it's that you passed an incorrect parameter and the code will never return.

Take this simple example:

def foo() -> NoReturn:
 raise NotImplementedError
foo()

Shouldn't the type checker say that foo() is problematic because it has a result of NoReturn. (Note: I realize this might be the topic of a different discussion).

Comment options

A function signature with a NoReturn return type doesn't mean that the call is invalid. It means that it's valid but control will not return to the caller after the call. Refer to this section of the typing spec for details.

What you're looking for is a way to mark the overload as an error condition, which would require a new mechanism and an update to the existing overload call evaluation specification. There has been some discussion of this previously, but no one has driven a concrete proposal.

Comment options

There has been some discussion of this previously, but no one has driven a concrete proposal.

I added an idea there - maybe it will get some traction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /