You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Statement is unreachable when checking if Match[str].group(...) type is None #7363
Expected behaviour:
No error as the statement is reachable (and it's used when you run this code). I tried using Match[Optional[str]] to fix this but it's not valid argument for Match.
Another thing to note is that this code will not error if I'll just use Match without specifying type of string.
Python version:: 3.7.4 Mypy version: 0.730, occurs on master as well Mypy flags:--warn-unreachable
This is a legitimate bug/limitation in mypy. In short, what's happening is that the Match.group(...) function is currently defined in typeshed to only ever return a str or a byte, depending on whether you have a Match[str] or a Match[byte].
This is obviously incorrect, as you noted. And due to this incorrect annotation, the --warn-unreachable flag ends up assuming that the "if the group is None" branch will never be run.
We actually did experiment with having the return be an Optional, but it ended up causing regressions in various codebases we were testing on. E.g. some snippet of code was using a regex where there would always be N groups and so rightfully skipped the 'is this group None?' checks.
The reason why not specifying the type of the string works is because such a type is equivalent to doing Match[Any]. So, group() ends up also returning Any.
cc @ilevkivskyi, since we were just talking about this the other day. Maybe writing a plugin is the right approach after all? Doing re.compile(...).groups will at least get you the upper bound on the number of groups there'll be, and doing sre_parse.parse(...) seems to get us an AST of the regex we could perhaps try analyzing.
Activity
Michael0x2a commentedon Aug 18, 2019
This is a legitimate bug/limitation in mypy. In short, what's happening is that the
Match.group(...)function is currently defined in typeshed to only ever return a str or a byte, depending on whether you have aMatch[str]or aMatch[byte].This is obviously incorrect, as you noted. And due to this incorrect annotation, the
--warn-unreachableflag ends up assuming that the "if the group is None" branch will never be run.We actually did experiment with having the return be an Optional, but it ended up causing regressions in various codebases we were testing on. E.g. some snippet of code was using a regex where there would always be N groups and so rightfully skipped the 'is this group None?' checks.
The reason why not specifying the type of the string works is because such a type is equivalent to doing
Match[Any]. So,group()ends up also returning Any.cc @ilevkivskyi, since we were just talking about this the other day. Maybe writing a plugin is the right approach after all? Doing
re.compile(...).groupswill at least get you the upper bound on the number of groups there'll be, and doingsre_parse.parse(...)seems to get us an AST of the regex we could perhaps try analyzing.ilevkivskyi commentedon Aug 19, 2019
OK, it looks like we need some compromise here, possible plan is:
.group()and.group(0).group(n)when a plugin canAnyin other casesThis should:
--warn-unreachablestr/bytes@JelleZijlstra @srittau
Add plugin to infer more precise regex match types
Add plugin to infer more precise regex match types
AlexWaygood commentedon Mar 27, 2022
Typeshed improvements mean that this can no longer be reproduced in 0.920+