E.g. when you have opened __init__.py and working on main() it would automatically identify types of a, b, c and return types provided in the __init__.pyi. See snippet below.
__init__.py:
def main(a, b, c):
# Expression of type "Literal['5']" is incompatible with return type "int"
return "5"
__init__.pyi:
def main(a: int, b: int, c: int) -> int: ...
It would be great for
Reading code from codebases that have stubs. Currently they’re all just flooded with knowns Unknowns that are just defined in other files.
If needed they can be displayed similar to inlay type hints but not to be present in actual file.
Also can help maintaining those codebases - besides usual typing benefits, it will also make it harder for implementation signature and stub file signature to go out of sync.
It would create an option to have all typing benefits in your codebase and move all the overloads-monstrosity or other typing complexicity to a separate file to keep actual codebase cleaner.
I guess the main reason why packages provide type-hints only in stubs and not in the the actual .py files is the code simplicity and avoiding maintenance the same signatures twice.
Obvious cons are type checking performance (which sure could be crucial for live type checkers like Pyright that give you feedback immediately in the code editor) and growing complexing type hints resolution order…
This is not a FR for python, the language or the typing standards. You need to make this FR to pylance/pyright. Nothing in the general spec allows or disallows doing this.
I don’t see how any interesting discussion is going to happen here. Most counter arguments would probably be related to implementation difficultly, and this is definitely the wrong forum for discussing implementation details of one specific type checker.
This side (discuss.python.org) is primarily mean for discussions on CPyhon/the Python language and this subforum Typing is primarily meant for discussions on the spec and other cross-type-checker concerns - not of the specific details of one IDEs features.
While there is little harm, I also see little point. If you want to, discuss the proposal - I am not preventing you from doing that, just pointing out that raising it here will not lead to anything.
Your motivating example is actually also a good reason for why it’s not really a good idea to do this, what if the type checker emits a false positive in an implementation for your stub? This could happen for any number of reasons, often it’ll be related to inference behavior, since you won’t have any type hints in your implementation.
So the only way to rectify this, would be to start adding type: ignoretyping.cast and/or annotations within your implementation. And now you have your type information spread across two separate sources, for no particularly good reason.
Another good example of problematic interactions between regular python code and stubs are overloaded functions. The type checker will not know what the signature of the implementation should look like, since the stubs don’t contain a signature for the implementation. So you would need to add a signature in order to check the bodies of overloaded functions, but not others, high potential for confusion.
Type checking implementations using stubs just never was a use-case for stubs. Stubs are a trade-off, you get less static information out of them and they’re more difficult to maintain than inline hints, the benefit is, that they’re completely separate from your code, so they don’t cost you anything at runtime.
Merging stubs with their implementation is less trivial than it first may seem. If you ever tried to use something like merge-pyi you’d know that the results are often less than ideal and need a lot of manual fixing up, due to some of the issues i mentioned above and others.
Well, yes, but since this behaviour would be another inconsistency with all other type checkers, it raises a question if there’s a general consensus that new behaviour is actually desirable and useful enough for the community.
E.g. if it’s important enough, it’s possbiel that other type checkers might implement similar thing in the future and it’s worth going this direction earlier, or if it’s too much of a niche, then maybe it doesn’t worth deviating from general type checkers behaviour.
So the only way to rectify this, would be to start adding type: ignoretyping.cast and/or annotations within your implementation. And now you have your type information spread across two separate sources, for no particularly good reason.
That’s a good point - this feature is basically helping to keep code base clean for signatures but is motivating users to start including type hints (they were trying to avoid) in functions bodies to overcome false positives. So implementing such feature in type checker would require an option to switch it off to make sure things are not getting worse than they were before this feature was added.