-
Notifications
You must be signed in to change notification settings - Fork 192
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
Apply type annotations from a stub. #265
Conversation
Codecov Report
@@ Coverage Diff @@
## master #265 +/- ##
==========================================
+ Coverage 93.88% 93.93% +0.04%
==========================================
Files 214 216 +2
Lines 20818 21140 +322
==========================================
+ Hits 19546 19857 +311
- Misses 1272 1283 +11
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for submitting this!
The goal is to use this in Pyre and MonkeyType.
@carljm Can you take a look to see if this takes care the need from MonkeyType as well?
|
@@ -153,3 +153,5 @@ inside codemods. As of now, the list includes the following helpers. | |||
:exclude-members: CONTEXT_KEY, visit_Module, leave_ImportFrom, leave_Module | |||
.. autoclass:: libcst.codemod.visitors.RemoveImportsVisitor | |||
:exclude-members: CONTEXT_KEY, METADATA_DEPENDENCIES, visit_Module, leave_ImportFrom, leave_Import | |||
.. autoclass:: libcst.codemod.visitors.ApplyTypeAnnotationsVisitor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jimmylai is there a reason these aren't alphabetized?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we basically just add them sequentially when we add new visitors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just flagged a couple of lines that might be under-tested. If there is good coverage around them, I'm happy with this. Will let Jimmy give the approve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for working on all the changes. The test suite looks really good.
Just found the implementation can be simplified a lot by reusing AddImportsVisitor
.
@@ -153,3 +153,5 @@ inside codemods. As of now, the list includes the following helpers. | |||
:exclude-members: CONTEXT_KEY, visit_Module, leave_ImportFrom, leave_Module | |||
.. autoclass:: libcst.codemod.visitors.RemoveImportsVisitor | |||
:exclude-members: CONTEXT_KEY, METADATA_DEPENDENCIES, visit_Module, leave_ImportFrom, leave_Import | |||
.. autoclass:: libcst.codemod.visitors.ApplyTypeAnnotationsVisitor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we basically just add them sequentially when we add new visitors.
a9294b3
to
8ffd760
Compare
Note: I discovered a couple of edge cases regarding imports with the same name, which I'll address in a follow-up PR. |
# Keep the existing `import A` instead of using `from A import B`. | ||
( | ||
""" | ||
import bar | ||
|
||
def foo() -> bar.Baz: ... | ||
""", | ||
""" | ||
import bar | ||
|
||
def foo(): | ||
return returns_baz() | ||
""", | ||
""" | ||
import bar | ||
|
||
def foo() -> bar.Baz: | ||
return returns_baz() | ||
""", | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm keeping the use of GatherImports
to get and check against the imports that already exist in the source module, because otherwise it adds an extra import from bar import Baz
and makes the return type of foo
be Baz
.
if self.is_generated: | ||
return original_node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@generated
is FB specific logic which is not generic.
Our CLI includes the option to skip generated file.
Line 481 in c21ae59
"--include-generated", action="store_true", help="Codemod generated files." |
Lines 657 to 659 in c21ae59
"generated_code_marker": _StrSerializer( | |
"String that LibCST should look for in code which indicates " | |
+ "that the module is generated code." |
We should probably reuse those existing logic or at least make the current implementation configurable (e.g. add skip_generated: bool = True
parameter to add_stub_to_context
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I removed our ad hoc handling since it looks like your tool already supports it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than the comments, looks great!
Look forward to the follow up edge case fixes.
Basically move the apply_annotations code from Pyre. Make it a ContextAwareTransformer named ApplyTypeAnnotationsVisitor. Use GatherImportsVisitor to collect imports. Add a static method `add_stub_to_context` so that users can schedule a stub whose types are to be applied later. Use `assertCodemod` and `data_provider` in the tests. Add documentation. Remove fixmes.
Basically move the
apply_annotations
code from Pyre. I had discussed this with Jimmy Lai. The main motivation for moving it to libcst is that the code deals purely with libcst concepts likeCSTVisitor
andCSTTransformer
and we want to use it in two separate projects: Pyre and MonkeyType.This is not implemented as a normal Codemod because, instead of working on just one module, it works on two modules: the stub module from which to collect annotations and the source module to which to apply the annotations.
Summary
Test Plan
Added the tests as well.