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

Use information from .pyi files in .py files they describe #1238

Closed
WilsonPhooYK opened this issue May 6, 2021 · 9 comments
Closed

Use information from .pyi files in .py files they describe #1238

WilsonPhooYK opened this issue May 6, 2021 · 9 comments
Labels
enhancement New feature or request

Comments

@WilsonPhooYK
Copy link

image
image
It does not work when separating the type interface out into a .pyi file.

image
It works if I inlined it.

Not sure what I did wrong?

VS Code version: 1.56.0
Python: 3.9.5
Python Extension: 2021.4.765268190
Pylance: 2021.5.0

@github-actions github-actions bot added the triage label May 6, 2021
@judej judej added the enhancement New feature or request label May 6, 2021
@github-actions github-actions bot removed the triage label May 6, 2021
@jakebailey
Copy link
Member

At the moment this is intended; the py file only sees the types inside itself. Other modules who import my_function will get the definition from the pyi file, but we do no merging / association between a py file and its pyi file in this sense.

I do think there's something to improve here, though.

@WilsonPhooYK
Copy link
Author

image
Yes, it worked for the imported function. Let's hope it will get an update to reflect on the actual py file!

@erictraut
Copy link
Contributor

@WilsonPhooYK, I think you have a misunderstanding of how type stub files are meant to work in Python. They are not like ".h" (header) files in C or C++. Instead, they're meant as a way to document a library's public contract in situations where the code for that library has no inline type annotations (for historical reasons, or because it's written in a language other than Python). They're the equivalent of ".d.ts" files in TypeScript, if you're familiar with that language.

If you are writing Python code and want to benefit from static type checking, you should add type annotations directly to your Python code. Type stubs are not necessary and will not work in this use case.

For more details about type stubs (including the problems they were designed to solve and how they work), please refer to PEP 484.

@WilsonPhooYK
Copy link
Author

Hi, pardon me if I misunderstood, but in reference to typescript, we certainly can do this.

test.d.tsx

export type TestType = (a: number, b: number) => number;

test.tsx

import { TestType } from './test.d';
const add:TestType = (a, b) => a + b;


add(1, 3)

Linter will show the definition correctly.
image

I am also raising this case as pycharm since to work as well, which gives me doubts on why VSCode was unable to do so.
image
test.pyi
image
test.py
image
image

@erictraut
Copy link
Contributor

The TypeScript example you provided is not a good comparison for a couple for reasons:

  1. This isn't how type declaration files are used in TypeScript. No one would define a ".d.tsx" and and ".tsx" file and import the former from the latter within the same project. A ".d.tsx" file is meant to describe a library's interface for consumers of that library. They are not meant to be consumed by the library implementation itself.
  2. You're explicitly importing the ".d.tsx" file by specifying "./test.d". As such, TypeScript is treating it like a regular ".tsx" file in this particular case, not as a type definition file.

In the Python case, you're expecting the type checker to read both the ".pyi" and ".py" file and somehow combine them, matching up unannotated symbols with annotated symbols.

I'm not sure what PyCharm is doing in this case, but this is not how other type checkers (e.g. mypy) operate, nor is it how ".pyi" files were intended to work as described in PEP 484. They are intended to be used as proxies for the implementation — a way for consumers of a library to understand the types that comprise the public interface contract for that library.

Is there a reason why you don't simply annotate the code in your ".py" file? Maintaining a separate ".pyi" file and trying to keep it in sync with the implementation sounds like a significant burden. If you provide annotations directly within your ".py" code, this will all work well.

@WilsonPhooYK
Copy link
Author

Thanks for the clarification. I am perfectly fine with inlining the annotations. I am just exploring the possibility of code splitting the annotations, although it is wrong to do so with the usage of .pyi files.

I am probably also confused by how pycharm works since that is the editor I am using before using vscode with pylance.

@jakebailey jakebailey mentioned this issue Aug 11, 2021
@jakebailey jakebailey changed the title .pyi stub files not working in vscode? Use information from .pyi files in .py files they describe Aug 19, 2021
@ewerybody
Copy link

I guess I'm beginning to get the whole picture and this is probably still the biggest issue I have left with all the typing stuff.
It looks so promising and I'd LOVE to use it! There is just so many "but"s and "if"s...

When I turn on strict Type Checking Mode I get SO many Problems listed .. well the counter on the tab just jumps directly to +1k ...

But even with the basic Type Checking Mode: You can't have proper typed suggestions on your objects unless writing the typing directly there BUT it would work on consuming modules. So IF you have the typing nicely tucked away in stubs you'd NEED to additionally type directly in your library code as well!. (Py2 compat is gone then but pfff ...) So having the stub file you'd need to manage 2 places for the typing. So get rid of the stub? But then why is there a functionality like Create stub files for module in the first place?

So I'll end up turning it off again 😑

@erictraut
Copy link
Contributor

erictraut commented Sep 9, 2021

"Create stub files for module" is meant to handle the case where someone other than the library author (a consumer of the library) wants to create stubs for an existing untyped library.

If you're the library author and your code is written in Python, you would add the type information directly to the code. You're absolutely correct that maintaining type stubs separately from the library code would be a huge burden, and I wouldn't recommend that approach. For more details, please refer to this guidance.

I would recommend starting with basic type checking mode. Strict mode is fine for new code bases, but it's very difficult to make an existing code base "strictly typed" without errors. I speak from experience here because it took me the better part of a year (in parallel with developing pyright) to get my team's 250K-line source Python source base to be strictly typed. Now that we've made that investment, the code is much more robust, and we can make changes (refactoring, etc.) with much higher confidence. It's a big investment, but one that's well worth it for a code base that you intend to maintain for an extended period of time.

@judej judej added the icebox label Sep 23, 2021
@judej judej removed the longterm label Mar 22, 2022
@judej
Copy link
Contributor

judej commented Apr 19, 2022

Closing old issue. If this is still a problem, please reopen with the information requested. thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants