Skip to content

Commit

Permalink
Port pyre fixes (#651)
Browse files Browse the repository at this point in the history
* Port facebook/pyre-check@c3b44cb

* Port facebook/pyre-check@138c97c

* Test harness for the next commit

* Port facebook/pyre-check@2cdc4ba

* Test harness for next commit

* Port facebook/pyre-check@71c5da8

* Remove no-longer-used import
  • Loading branch information
stroxler authored Feb 18, 2022
1 parent bb6d150 commit e8c8457
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 25 deletions.
44 changes: 19 additions & 25 deletions libcst/codemod/visitors/_apply_type_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from libcst.codemod._visitor import ContextAwareTransformer
from libcst.codemod.visitors._add_imports import AddImportsVisitor
from libcst.codemod.visitors._gather_imports import GatherImportsVisitor
from libcst.codemod.visitors._imports import ImportItem
from libcst.helpers import get_full_name_for_node
from libcst.metadata import PositionProvider, QualifiedNameProvider

Expand Down Expand Up @@ -312,7 +311,7 @@ def record_typevar(
) -> None:
# pyre-ignore current_assign is never None here
name = get_full_name_for_node(self.current_assign.targets[0].target)
if name:
if name is not None:
# pyre-ignore current_assign is never None here
self.annotations.typevars[name] = self.current_assign
self._handle_qualification_and_should_qualify("typing.TypeVar")
Expand Down Expand Up @@ -530,10 +529,12 @@ class ApplyTypeAnnotationsVisitor(ContextAwareTransformer):
This is one of the transforms that is available automatically to you when
running a codemod. To use it in this manner, import
:class:`~libcst.codemod.visitors.ApplyTypeAnnotationsVisitor` and then call the static
:meth:`~libcst.codemod.visitors.ApplyTypeAnnotationsVisitor.store_stub_in_context` method,
giving it the current context (found as ``self.context`` for all subclasses of
:class:`~libcst.codemod.Codemod`), the stub module from which you wish to add annotations.
:class:`~libcst.codemod.visitors.ApplyTypeAnnotationsVisitor` and then call
the static
:meth:`~libcst.codemod.visitors.ApplyTypeAnnotationsVisitor.store_stub_in_context`
method, giving it the current context (found as ``self.context`` for all
subclasses of :class:`~libcst.codemod.Codemod`), the stub module from which
you wish to add annotations.
For example, you can store the type annotation ``int`` for ``x`` using::
Expand All @@ -550,7 +551,8 @@ class ApplyTypeAnnotationsVisitor(ContextAwareTransformer):
x: int = 1
If the function or attribute already has a type annotation, it will not be overwritten.
If the function or attribute already has a type annotation, it will not be
overwritten.
To overwrite existing annotations when applying annotations from a stub,
use the keyword argument ``overwrite_existing_annotations=True`` when
Expand Down Expand Up @@ -662,20 +664,12 @@ def transform_module_impl(
cst.MetadataWrapper(stub).visit(visitor)
self.annotations.update(visitor.annotations)

tree_with_imports = AddImportsVisitor(
context=self.context,
imports=(
[
ImportItem(
"__future__",
"annotations",
None,
)
]
if self.use_future_annotations
else ()
),
).transform_module(tree)
if self.use_future_annotations:
AddImportsVisitor.add_needed_import(
self.context, "__future__", "annotations"
)
tree_with_imports = AddImportsVisitor(self.context).transform_module(tree)

tree_with_changes = tree_with_imports.visit(self)

# don't modify the imports if we didn't actually add any type information
Expand Down Expand Up @@ -735,7 +729,7 @@ def _annotate_single_target(
for element in only_target.elements:
value = element.value
name = get_full_name_for_node(value)
if name:
if name is not None and name != "_":
self._add_to_toplevel_annotations(name)
elif isinstance(only_target, (cst.Subscript)):
pass
Expand Down Expand Up @@ -828,7 +822,7 @@ def update_annotation(
annotated_parameters.append(parameter)
return annotated_parameters

return annotations.parameters.with_changes(
return updated_node.params.with_changes(
params=update_annotation(
updated_node.params.params,
annotations.parameters.params,
Expand Down Expand Up @@ -1024,7 +1018,7 @@ def record_typevar(
) -> None:
# pyre-ignore current_assign is never None here
name = get_full_name_for_node(self.current_assign.targets[0].target)
if name:
if name is not None:
# Preserve the whole node, even though we currently just use the
# name, so that we can match bounds and variance at some point and
# determine if two typevars with the same name are indeed the same.
Expand All @@ -1046,7 +1040,7 @@ def leave_Assign(
target = assign.target
if isinstance(target, (cst.Name, cst.Attribute)):
name = get_full_name_for_node(target)
if name is not None:
if name is not None and name != "_":
# Add separate top-level annotations for `a = b = 1`
# as `a: int` and `b: int`.
self._add_to_toplevel_annotations(name)
Expand Down
48 changes: 48 additions & 0 deletions libcst/codemod/visitors/tests/test_apply_type_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,29 @@ def run_test_case_with_flags(
x2: Optional[T2] = None
""",
),
"splitting_multi_assigns": (
"""
a: str = ...
x: int = ...
y: int = ...
_: str = ...
z: str = ...
""",
"""
a = 'a'
x, y = 1, 2
_, z = 'hello world'.split()
""",
"""
x: int
y: int
z: str
a: str = 'a'
x, y = 1, 2
_, z = 'hello world'.split()
""",
),
}
)
def test_annotate_globals(self, stub: str, before: str, after: str) -> None:
Expand Down Expand Up @@ -468,6 +491,31 @@ async def async_with_decorators(r: Request, b: bool) -> HttpResponse:
return respond(r, b)
""",
),
"with_variadic_arguments": (
"""
def incomplete_stubs_with_stars(
x: int,
*args,
**kwargs,
) -> None: ...
""",
"""
def incomplete_stubs_with_stars(
x,
*args: P.args,
**kwargs: P.kwargs,
):
pass
""",
"""
def incomplete_stubs_with_stars(
x: int,
*args: P.args,
**kwargs: P.kwargs,
) -> None:
pass
""",
),
# test cases named with the REQUIRES_PREEXISTING prefix are verifying
# that certain special cases work if the stub and the existing code
# happen to align well, but none of these cases are guaranteed to work
Expand Down

0 comments on commit e8c8457

Please sign in to comment.