Ejemplo n.º 1
0
    def leave_SubscriptElement(self, original_node: cst.SubscriptElement,
                               updated_node: cst.SubscriptElement):
        if self.type_annot_visited and self.parametric_type_annot_visited:
            if match.matches(
                    original_node,
                    match.SubscriptElement(slice=match.Index(
                        value=match.Subscript()))):
                q_name, _ = self.__get_qualified_name(
                    original_node.slice.value.value)
                if q_name is not None:
                    return updated_node.with_changes(slice=cst.Index(
                        value=cst.Subscript(
                            value=self.__name2annotation(q_name).annotation,
                            slice=updated_node.slice.value.slice)))
            elif match.matches(
                    original_node,
                    match.SubscriptElement(slice=match.Index(
                        value=match.Ellipsis()))):
                # TODO: Should the original node be returned?!
                return updated_node.with_changes(slice=cst.Index(
                    value=cst.Ellipsis()))
            elif match.matches(
                    original_node,
                    match.SubscriptElement(slice=match.Index(
                        value=match.SimpleString(value=match.DoNotCare())))):
                return updated_node.with_changes(slice=cst.Index(
                    value=updated_node.slice.value))
            elif match.matches(
                    original_node,
                    match.SubscriptElement(slice=match.Index(value=match.Name(
                        value='None')))):
                return original_node
            elif match.matches(
                    original_node,
                    match.SubscriptElement(slice=match.Index(
                        value=match.List()))):
                return updated_node.with_changes(slice=cst.Index(
                    value=updated_node.slice.value))
            else:
                q_name, _ = self.__get_qualified_name(
                    original_node.slice.value)
                if q_name is not None:
                    return updated_node.with_changes(slice=cst.Index(
                        value=self.__name2annotation(q_name).annotation))

        return original_node
 def contains_union_with_none(self, node: cst.Annotation) -> bool:
     return m.matches(
         node,
         m.Annotation(
             m.Subscript(
                 value=m.Name("Union"),
                 slice=m.OneOf(
                     [
                         m.SubscriptElement(m.Index()),
                         m.SubscriptElement(m.Index(m.Name("None"))),
                     ],
                     [
                         m.SubscriptElement(m.Index(m.Name("None"))),
                         m.SubscriptElement(m.Index()),
                     ],
                 ),
             )),
     )
Ejemplo n.º 3
0
 def leave_Annotation(self, original_node: cst.Annotation) -> None:
     if self.contains_union_with_none(original_node):
         scope = self.get_metadata(cst.metadata.ScopeProvider, original_node, None)
         nones = 0
         indexes = []
         replacement = None
         if scope is not None and "Optional" in scope:
             for s in cst.ensure_type(original_node.annotation, cst.Subscript).slice:
                 if m.matches(s, m.SubscriptElement(m.Index(m.Name("None")))):
                     nones += 1
                 else:
                     indexes.append(s.slice)
             if not (nones > 1) and len(indexes) == 1:
                 replacement = original_node.with_changes(
                     annotation=cst.Subscript(
                         value=cst.Name("Optional"),
                         slice=(cst.SubscriptElement(indexes[0]),),
                     )
                 )
                 # TODO(T57106602) refactor lint replacement once extract exists
         self.report(original_node, replacement=replacement)
Ejemplo n.º 4
0
 def _is_awaitable_callable(annotation: str) -> bool:
     if not (annotation.startswith("typing.Callable")
             or annotation.startswith("typing.ClassMethod")
             or annotation.startswith("StaticMethod")):
         # Exit early if this is not even a `typing.Callable` annotation.
         return False
     try:
         # Wrap this in a try-except since the type annotation may not be parse-able as a module.
         # If it is not parse-able, we know it's not what we are looking for anyway, so return `False`.
         parsed_ann = cst.parse_module(annotation)
     except Exception:
         return False
     # If passed annotation does not match the expected annotation structure for a `typing.Callable` with
     # typing.Coroutine as the return type, matched_callable_ann will simply be `None`.
     # The expected structure of an awaitable callable annotation from Pyre is: typing.Callable()[[...], typing.Coroutine[...]]
     matched_callable_ann: Optional[Dict[str, Union[
         Sequence[cst.CSTNode], cst.CSTNode]]] = m.extract(
             parsed_ann,
             m.Module(body=[
                 m.SimpleStatementLine(body=[
                     m.Expr(value=m.Subscript(slice=[
                         m.SubscriptElement(),
                         m.SubscriptElement(slice=m.Index(value=m.Subscript(
                             value=m.SaveMatchedNode(
                                 m.Attribute(),
                                 "base_return_type",
                             )))),
                     ], ))
                 ]),
             ]),
         )
     if (matched_callable_ann is not None
             and "base_return_type" in matched_callable_ann):
         base_return_type = get_full_name_for_node(
             cst.ensure_type(matched_callable_ann["base_return_type"],
                             cst.CSTNode))
         return (base_return_type is not None
                 and base_return_type == "typing.Coroutine")
     return False
Ejemplo n.º 5
0
    def obf_slice(self, sub_slice: Union[cst.Index, cst.Slice,
                                         List[cst.SubscriptElement]]):

        if m.matches(sub_slice, m.Index()):
            sub_slice = self.obf_universal(sub_slice.value)

        elif m.matches(sub_slice, m.Slice()):

            sub_slice = cst.ensure_type(sub_slice, cst.Slice)
            sub_slice = sub_slice.with_changes(
                lower=self.obf_universal(sub_slice.lower),
                upper=self.obf_universal(sub_slice.upper),
                step=self.obf_universal(sub_slice.step))

        elif m.matches(sub_slice, m.SubscriptElement()):
            sub_slice = cst.ensure_type(sub_slice, cst.SubscriptElement)
            sub_slice = sub_slice.with_changes(
                slice=self.obf_universal(sub_slice.slice))

        else:
            pass
            # print(f"NOT IMPLEMENTED obf_slice")

        return sub_slice
Ejemplo n.º 6
0
 def _deprecated_visitor(self, node: cst.ExtSlice) -> None:
     if m.matches(node, m.ExtSlice(m.Index(m.Integer("2")))):
         self.calls.add("called")