Ejemplo n.º 1
0
def atom_rewrite(loc, name, number, strs, namedc, ellipsis, dict, is_dict,
                 is_gen, is_list, comp, yield_expr):
    if name:
        return ast.Name(name.value, ast.Load(), **loc @ name)

    if number:
        return ast.Num(eval(number.value), **loc @ number)

    if strs:
        return str_maker(*strs)

    if ellipsis:
        return ast.Ellipsis()

    if namedc:
        return ast.NameConstant(eval(namedc.value), **loc @ namedc)

    if is_dict:
        return dict or ex_ast.ExDict([], [], ast.Load(), **loc @ is_dict)

    if is_gen:
        if yield_expr:
            return yield_expr
        return comp(is_tuple=True) if comp else ast.Tuple([], ast.Load(), **
                                                          loc @ is_gen)

    if is_list:
        return comp(is_list=True) if comp else ast.List([], ast.Load(), **
                                                        loc @ is_list)

    raise TypeError
Ejemplo n.º 2
0
def value2pyliteral(val):  # noqa: C901
    """
    Transforms a python value into a literal in AST form.
    """
    if val is None:
        return ast.NameConstant(value=None)
    elif val is ...:
        return ast.Ellipsis()
    elif val is True:
        return ast.NameConstant(value=True)
    elif val is False:
        return ast.NameConstant(value=False)
    elif isinstance(val, int):
        return ast.Num(n=val)
    elif isinstance(val, float):
        return ast.Num(n=val)
    elif isinstance(val, str):
        return ast.Str(s=val)
    elif isinstance(val, bytes):
        return ast.Bytes(s=val)
    elif isinstance(val, tuple):
        return ast.Tuple(elts=[value2pyliteral(item) for item in val])
    elif isinstance(val, list):
        return ast.List(elts=[value2pyliteral(item) for item in val])
    elif isinstance(val, dict):
        return ast.Dict(
            # .keys() and .values() have been documented to return things in the
            # same order since Py2
            keys=[value2pyliteral(item) for item in val.keys()],
            values=[value2pyliteral(item) for item in val.values()],
        )
    elif isinstance(val, set):
        return ast.Set(elts=[value2pyliteral(item) for item in val])
    else:
        raise ValueError(f"Can't translate {val!r} into a literal")
Ejemplo n.º 3
0
    def test_deprecated_constant_nodes(self):
        self.assertAstEqualsSource(
            ast.Assign(targets=[ast.Name(id='spam')], value=ast.Num(3)),
            "spam = 3")

        self.assertAstEqualsSource(
            ast.Assign(targets=[ast.Name(id='spam')], value=ast.Num(-93)),
            "spam = -93")

        self.assertAstEqualsSource(
            ast.Assign(targets=[ast.Name(id='spam')], value=ast.Num(837.3888)),
            "spam = 837.3888")

        self.assertAstEqualsSource(
            ast.Assign(targets=[ast.Name(id='spam')], value=ast.Num(-0.9877)),
            "spam = -0.9877")

        self.assertAstEqualsSource(ast.Ellipsis(), "...")

        if sys.version_info >= (3, 0):
            self.assertAstEqualsSource(
                ast.Assign(targets=[ast.Name(id='spam')],
                           value=ast.Bytes(b"Bytes")), "spam = b'Bytes'")

        self.assertAstEqualsSource(
            ast.Assign(targets=[ast.Name(id='spam')], value=ast.Str("String")),
            "spam = 'String'")
Ejemplo n.º 4
0
 def ellipsis_word_visitor(node: concat.parse.EllipsisWordNode):
     """Converts a EllipsisWordNode to the Python expression `push(...)`."""
     load = ast.Load()
     ellipsis = ast.Ellipsis()
     push_func = ast.Name(id='push', ctx=load)
     py_node = ast.Call(func=push_func, args=[ellipsis], keywords=[])
     py_node.lineno, py_node.col_offset = node.location
     return py_node
Ejemplo n.º 5
0
 def visit_Constant(self, node):
     if isinstance(node.value, (bool, int, long, float, complex)):
         new_node = ast.Num(node.value)
     elif node.value is Ellipsis:
         new_node = ast.Ellipsis()
     else:
         new_node = ast.Str(node.value)
     ast.copy_location(new_node, node)
     return new_node
Ejemplo n.º 6
0
def make_unconcat_slice(axis, lower, upper):
    dims = []
    for i in range(axis):
        dims.append(ast.Slice(lower=None, upper=None, step=None))
    dims.append(ast.Slice(lower=lower, upper=upper, step=None))
    dims.append(ast.Ellipsis())

    ext_slice = ast.ExtSlice(dims=dims)

    return ext_slice
Ejemplo n.º 7
0
 def visit_Constant(self, node):
     if node.value is None:
         new_node = ast.NameConstant(node.value)
     elif node.value is Ellipsis:
         new_node = ast.Ellipsis()
     elif isinstance(node.value, bool):
         new_node = ast.NameConstant(node.value)
     elif isinstance(node.value, (int, float, complex)):
         new_node = ast.Num(node.value)
     elif isinstance(node.value, str):
         new_node = ast.Str(node.value)
     else:
         new_node = ast.Bytes(node.value)
     return ast.copy_location(new_node, node)
Ejemplo n.º 8
0
    def test__get_literal_value(self):
        new_context = context.Context()

        value = ast.Num(42)
        expected = value.n
        self.assertEqual(expected, new_context._get_literal_value(value))

        value = ast.Str('spam')
        expected = value.s
        self.assertEqual(expected, new_context._get_literal_value(value))

        value = ast.List([ast.Str('spam'), ast.Num(42)], ast.Load())
        expected = [ast.Str('spam').s, ast.Num(42).n]
        self.assertListEqual(expected, new_context._get_literal_value(value))

        value = ast.Tuple([ast.Str('spam'), ast.Num(42)], ast.Load())
        expected = (ast.Str('spam').s, ast.Num(42).n)
        self.assertTupleEqual(expected, new_context._get_literal_value(value))

        value = ast.Set([ast.Str('spam'), ast.Num(42)])
        expected = set([ast.Str('spam').s, ast.Num(42).n])
        self.assertSetEqual(expected, new_context._get_literal_value(value))

        value = ast.Dict(['spam', 'eggs'], [42, 'foo'])
        expected = dict(spam=42, eggs='foo')
        self.assertDictEqual(expected, new_context._get_literal_value(value))

        value = ast.Ellipsis()
        self.assertIsNone(new_context._get_literal_value(value))

        value = ast.Name('spam', ast.Load())
        expected = value.id
        self.assertEqual(expected, new_context._get_literal_value(value))

        if six.PY3:
            value = ast.NameConstant(True)
            expected = str(value.value)
            self.assertEqual(expected, new_context._get_literal_value(value))

        if six.PY3:
            value = ast.Bytes(b'spam')
            expected = value.s
            self.assertEqual(expected, new_context._get_literal_value(value))

        self.assertIsNone(new_context._get_literal_value(None))
Ejemplo n.º 9
0
def _annotation_for_value(value: object) -> Optional[ast.expr]:
    if value is None:
        return None
    name = type(value).__name__
    if isinstance(value, (dict, list, set, tuple)):
        ann_elem = _annotation_for_elements(value)
        if isinstance(value, dict):
            ann_value = _annotation_for_elements(value.values())
            if ann_value is None:
                ann_elem = None
            elif ann_elem is not None:
                ann_elem = ast.Tuple(elts=[ann_elem, ann_value])
        if ann_elem is not None:
            if name == 'tuple':
                ann_elem = ast.Tuple(elts=[ann_elem, ast.Ellipsis()])
            return ast.Subscript(value=ast.Name(id=name),
                                 slice=ast.Index(value=ann_elem))
    return ast.Name(id=name)
Ejemplo n.º 10
0
    def visit_AnnAssign(self, node: ast.AnnAssign) -> ast.Assign:
        # Here, we replace `x: A = a` with just `x = a`. In case there's no value,
        # we set the value to an `...`. E.g: `x: A` changes to `x = ...`.
        #
        # We need to be a little careful about ensuring that newly created nodes
        # get the line and column information copied to them. This helps us avoid
        # an extra pass over the AST with ast.fix_missing_locations()
        value = node.value
        if value is None:
            value = ast.Ellipsis()
            value.kind = None
            _copy_attrs(node, value)

        assign = ast.Assign(targets=[node.target],
                            value=value,
                            type_comment=None)

        _copy_attrs(node, assign)
        return assign
Ejemplo n.º 11
0
    def test_simple_types(self):
        # string, integer, float, force casting
        xml = Parser(self.get_xml("basic_types.xml"))
        module = xml.parse()
        code = compile(module, "<ast>", "exec")

        mymodule = ast.Module([
            ast.Expr(ast.Str("batuhan")),
            ast.Expr(ast.Num(15)),
            ast.Expr(ast.Num(15.5)),
            ast.Expr(ast.Str("13")),
            ast.Expr(ast.Ellipsis()),
            ast.Expr(ast.Bytes(bytes("a", "ASCII"))),
            ast.Expr(ast.Bytes(bytes("ş", "utf-8"))),
        ])
        ast.fix_missing_locations(mymodule)
        mycode = compile(mymodule, "<ast>", "exec")
        pprint(mymodule)

        self.assertEqual(code, mycode)
Ejemplo n.º 12
0
    def _maybe_inject_class_argument(hint_tree: ast.FunctionType,
                                     func_obj: Function) -> ast.FunctionType:
        """
        Inject `self` or `cls` args into a type comment to align with PEP 3107-style annotations.

        Because PEP 484 does not describe a method to provide partial function-level type comments,
        there is a potential for ambiguity in the context of both class methods and classmethods
        when aligning type comments to method arguments.

        These two class methods, for example, should lint equivalently:

            def bar(self, a):
                # type: (int) -> int
                ...

            def bar(self, a: int) -> int
                ...

        When this example type comment is parsed by `ast` and then matched with the method's
        arguments, it associates the `int` hint to `self` rather than `a`, so a dummy hint needs to
        be provided in situations where `self` or `class` are not hinted in the type comment in
        order to achieve equivalent linting results to PEP-3107 style annotations.

        A dummy `ast.Ellipses` constant is injected if the following criteria are met:
            1. The function node is either a class method or classmethod
            2. The number of hinted args is at least 1 less than the number of function args
        """
        if not func_obj.is_class_method:
            # Short circuit
            return hint_tree

        if func_obj.class_decorator_type != ClassDecoratorType.STATICMETHOD:
            if len(hint_tree.argtypes) < (len(func_obj.args) -
                                          1):  # Subtract 1 to skip return arg
                # Ignore mypy's objection to this assignment, Ellipsis subclasses expr so I'm not
                # sure how to make Mypy happy with this but I think it still makes semantic sense
                hint_tree.argtypes = [
                    ast.Ellipsis()
                ] + hint_tree.argtypes  # type: ignore[assignment, operator]  # noqa: E501

        return hint_tree
Ejemplo n.º 13
0
    def test__get_literal_value(self):
        new_context = context.Context()

        value = ast.Num(42)
        expected = value.n
        self.assertEqual(expected, new_context._get_literal_value(value))

        value = ast.Str("spam")
        expected = value.s
        self.assertEqual(expected, new_context._get_literal_value(value))

        value = ast.List([ast.Str("spam"), ast.Num(42)], ast.Load())
        expected = [ast.Str("spam").s, ast.Num(42).n]
        self.assertListEqual(expected, new_context._get_literal_value(value))

        value = ast.Tuple([ast.Str("spam"), ast.Num(42)], ast.Load())
        expected = (ast.Str("spam").s, ast.Num(42).n)
        self.assertTupleEqual(expected, new_context._get_literal_value(value))

        value = ast.Set([ast.Str("spam"), ast.Num(42)])
        expected = {ast.Str("spam").s, ast.Num(42).n}
        self.assertSetEqual(expected, new_context._get_literal_value(value))

        value = ast.Dict(["spam", "eggs"], [42, "foo"])
        expected = dict(spam=42, eggs="foo")
        self.assertDictEqual(expected, new_context._get_literal_value(value))

        value = ast.Ellipsis()
        self.assertIsNone(new_context._get_literal_value(value))

        value = ast.Name("spam", ast.Load())
        expected = value.id
        self.assertEqual(expected, new_context._get_literal_value(value))

        value = ast.Bytes(b"spam")
        expected = value.s
        self.assertEqual(expected, new_context._get_literal_value(value))

        self.assertIsNone(new_context._get_literal_value(None))
Ejemplo n.º 14
0
def as_ast(dct):
    """See https://docs.python.org/2/library/ast.html"""
    if dct['ast_type'] == "Module":
        return ast.Module(dct["body"])
    elif dct['ast_type'] == "Interactive":
        return ast.Interactive(dct["body"])
    elif dct['ast_type'] == "Expression":
        return ast.Expression(dct["body"])
    elif dct['ast_type'] == "Suite":
        return ast.Suite(dct["body"])
    elif dct['ast_type'] == "FunctionDef":
        return ast.FunctionDef(dct["name"], dct["args"], dct["body"],
                               dct["decorator_list"])
    elif dct['ast_type'] == "ClassDef":
        return ast.ClassDef(dct["name"], dct["bases"], dct["body"],
                            dct["decorator_list"])
    elif dct['ast_type'] == "Return":
        return ast.Return(dct["value"])
    elif dct['ast_type'] == "Delete":
        return ast.Delete(dct["targets"])
    elif dct['ast_type'] == "Assign":
        return ast.Assign(dct["targets"], dct["value"])
    elif dct['ast_type'] == "AugAssign":
        return ast.AugAssign(dct["target"], dct["op"], dct["value"])
    elif dct['ast_type'] == "Print":
        return ast.Print(dct["dest"], dct["values"], dct["nl"])
    elif dct['ast_type'] == "For":
        return ast.For(dct["target"], dct["iter"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "While":
        return ast.While(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "If":
        return ast.If(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "With":
        return ast.With(dct["context_expr"], dct["optional_vars"], dct["body"])
    elif dct['ast_type'] == "Raise":
        return ast.Raise(dct["type"], dct["inst"], dct["tback"])
    elif dct['ast_type'] == "TryExcept":
        return ast.TryExcept(dct["body"], dct["handlers"], dct["orelse"])
    elif dct['ast_type'] == "TryFinally":
        return ast.TryFinally(dct["body"], dct["finalbody"])
    elif dct['ast_type'] == "Assert":
        return ast.Assert(dct["test"], dct["msg"])
    elif dct['ast_type'] == "Import":
        return ast.Import(dct["names"])
    elif dct['ast_type'] == "ImportFrom":
        return ast.ImportFrom(dct["module"], dct["names"], dct["level"])
    elif dct['ast_type'] == "Exec":
        return ast.Exec(dct["body"], dct["globals"], dct["locals"])
    elif dct['ast_type'] == "Global":
        return ast.Global(dct["names"])
    elif dct['ast_type'] == "Expr":
        return ast.Expr(dct["value"])
    elif dct['ast_type'] == "Pass":
        return ast.Pass()
    elif dct['ast_type'] == "Break":
        return ast.Break()
    elif dct['ast_type'] == "Continue":
        return ast.Continue()
    elif dct['ast_type'] == "BoolOp":
        return ast.BoolOp(dct["op"], dct["values"])
    elif dct['ast_type'] == "BinOp":
        return ast.BinOp(dct["left"], dct["op"], dct["right"])
    elif dct['ast_type'] == "UnaryOp":
        return ast.UnaryOp(dct["op"], dct["operand"])
    elif dct['ast_type'] == "Lambda":
        return ast.Lambda(dct["args"], dct["body"])
    elif dct['ast_type'] == "IfExp":
        return ast.IfExp(dct["test"], dct["body"], dct["orelse"])
    elif dct['ast_type'] == "Dict":
        return ast.Dict(dct["keys"], dct["values"])
    elif dct['ast_type'] == "Set":
        return ast.Set(dct["elts"])
    elif dct['ast_type'] == "ListComp":
        return ast.ListComp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "SetComp":
        return ast.SetComp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "DictComp":
        return ast.DictComp(dct["key"], dct["value"], dct["generators"])
    elif dct['ast_type'] == "GeneratorExp":
        return ast.GeneratorExp(dct["elt"], dct["generators"])
    elif dct['ast_type'] == "Yield":
        return ast.Yield(dct["value"])
    elif dct['ast_type'] == "Compare":
        return ast.Compare(dct["left"], dct["ops"], dct["comparators"])
    elif dct['ast_type'] == "Call":
        return ast.Call(dct["func"], dct["args"], dct["keywords"],
                        dct["starargs"], dct["kwargs"])
    elif dct['ast_type'] == "Repr":
        return ast.Repr(dct["value"])
    elif dct['ast_type'] == "Num":
        return ast.Num(dct["n"])
    elif dct['ast_type'] == "Str":
        # Converting to ASCII
        return ast.Str(dct["s"].encode('ascii', 'ignore'))
    elif dct['ast_type'] == "Attribute":
        return ast.Attribute(dct["value"], dct["attr"], dct["ctx"])
    elif dct['ast_type'] == "Subscript":
        return ast.Subscript(dct["value"], dct["slice"], dct["ctx"])
    elif dct['ast_type'] == "Name":
        return ast.Name(dct["id"], dct["ctx"])
    elif dct['ast_type'] == "List":
        return ast.List(dct["elts"], dct["ctx"])
    elif dct['ast_type'] == "Tuple":
        return ast.Tuple(dct["elts"], dct["ctx"])
    elif dct['ast_type'] == "Load":
        return ast.Load()
    elif dct['ast_type'] == "Store":
        return ast.Store()
    elif dct['ast_type'] == "Del":
        return ast.Del()
    elif dct['ast_type'] == "AugLoad":
        return ast.AugLoad()
    elif dct['ast_type'] == "AugStore":
        return ast.AugStore()
    elif dct['ast_type'] == "Param":
        return ast.Param()
    elif dct['ast_type'] == "Ellipsis":
        return ast.Ellipsis()
    elif dct['ast_type'] == "Slice":
        return ast.Slice(dct["lower"], dct["upper"], dct["step"])
    elif dct['ast_type'] == "ExtSlice":
        return ast.ExtSlice(dct["dims"])
    elif dct['ast_type'] == "Index":
        return ast.Index(dct["value"])
    elif dct['ast_type'] == "And":
        return ast.And()
    elif dct['ast_type'] == "Or":
        return ast.Or()
    elif dct['ast_type'] == "Add":
        return ast.Add()
    elif dct['ast_type'] == "Sub":
        return ast.Sub()
    elif dct['ast_type'] == "Mult":
        return ast.Mult()
    elif dct['ast_type'] == "Div":
        return ast.Div()
    elif dct['ast_type'] == "Mod":
        return ast.Mod()
    elif dct['ast_type'] == "Pow":
        return ast.Pow()
    elif dct['ast_type'] == "LShift":
        return ast.LShift()
    elif dct['ast_type'] == "RShift":
        return ast.RShift()
    elif dct['ast_type'] == "BitOr":
        return ast.BitOr()
    elif dct['ast_type'] == "BitXor":
        return ast.BitXor()
    elif dct['ast_type'] == "BitAnd":
        return ast.BitAnd()
    elif dct['ast_type'] == "FloorDiv":
        return ast.FloorDiv()
    elif dct['ast_type'] == "Invert":
        return ast.Invert()
    elif dct['ast_type'] == "Not":
        return ast.Not()
    elif dct['ast_type'] == "UAdd":
        return ast.UAdd()
    elif dct['ast_type'] == "USub":
        return ast.USub()
    elif dct['ast_type'] == "Eq":
        return ast.Eq()
    elif dct['ast_type'] == "NotEq":
        return ast.NotEq()
    elif dct['ast_type'] == "Lt":
        return ast.Lt()
    elif dct['ast_type'] == "LtE":
        return ast.LtE()
    elif dct['ast_type'] == "Gt":
        return ast.Gt()
    elif dct['ast_type'] == "GtE":
        return ast.GtE()
    elif dct['ast_type'] == "Is":
        return ast.Is()
    elif dct['ast_type'] == "IsNot":
        return ast.IsNot()
    elif dct['ast_type'] == "In":
        return ast.In()
    elif dct['ast_type'] == "NotIn":
        return ast.NotIn()
    elif dct['ast_type'] == "comprehension":
        return ast.comprehension(dct["target"], dct["iter"], dct["ifs"])
    elif dct['ast_type'] == "ExceptHandler":
        return ast.ExceptHandler(dct["type"], dct["name"], dct["body"])
    elif dct['ast_type'] == "arguments":
        return ast.arguments(dct["args"], dct["vararg"], dct["kwarg"],
                             dct["defaults"])
    elif dct['ast_type'] == "keyword":
        return ast.keyword(dct["arg"], dct["value"])
    elif dct['ast_type'] == "alias":
        return ast.alias(dct["name"], dct["asname"])
    else:
        return dct
Ejemplo n.º 15
0
    def test_empty_init(self):
        # Jython 2.5.0 did not allow empty constructors for many ast node types
        # but CPython ast nodes do allow this.  For the moment, I don't see a
        # reason to allow construction of the super types (like ast.AST and
        # ast.stmt) as well as the op types that are implemented as enums in
        # Jython (like boolop), but I've left them in but commented out for
        # now.  We may need them in the future since CPython allows this, but
        # it may fall under implementation detail.

        #ast.AST()
        ast.Add()
        ast.And()
        ast.Assert()
        ast.Assign()
        ast.Attribute()
        ast.AugAssign()
        ast.AugLoad()
        ast.AugStore()
        ast.BinOp()
        ast.BitAnd()
        ast.BitOr()
        ast.BitXor()
        ast.BoolOp()
        ast.Break()
        ast.Call()
        ast.ClassDef()
        ast.Compare()
        ast.Continue()
        ast.Del()
        ast.Delete()
        ast.Dict()
        ast.Div()
        ast.Ellipsis()
        ast.Eq()
        ast.Exec()
        ast.Expr()
        ast.Expression()
        ast.ExtSlice()
        ast.FloorDiv()
        ast.For()
        ast.FunctionDef()
        ast.GeneratorExp()
        ast.Global()
        ast.Gt()
        ast.GtE()
        ast.If()
        ast.IfExp()
        ast.Import()
        ast.ImportFrom()
        ast.In()
        ast.Index()
        ast.Interactive()
        ast.Invert()
        ast.Is()
        ast.IsNot()
        ast.LShift()
        ast.Lambda()
        ast.List()
        ast.ListComp()
        ast.Load()
        ast.Lt()
        ast.LtE()
        ast.Mod()
        ast.Module()
        ast.Mult()
        ast.Name()
        ast.Not()
        ast.NotEq()
        ast.NotIn()
        ast.Num()
        ast.Or()
        ast.Param()
        ast.Pass()
        ast.Pow()
        ast.Print()
        ast.RShift()
        ast.Raise()
        ast.Repr()
        ast.Return()
        ast.Slice()
        ast.Store()
        ast.Str()
        ast.Sub()
        ast.Subscript()
        ast.Suite()
        ast.TryExcept()
        ast.TryFinally()
        ast.Tuple()
        ast.UAdd()
        ast.USub()
        ast.UnaryOp()
        ast.While()
        ast.With()
        ast.Yield()
        ast.alias()
        ast.arguments()
        #ast.boolop()
        #ast.cmpop()
        ast.comprehension()
        #ast.excepthandler()
        #ast.expr()
        #ast.expr_context()
        ast.keyword()
Ejemplo n.º 16
0
 def test_Ellipsis(self):
     self.verify(ast.Ellipsis(), '...')
Ejemplo n.º 17
0
 def p_atom11(self, p):
     ''' atom : ELLIPSIS '''
     p[0] = ast.Ellipsis()
Ejemplo n.º 18
0
def Ellipsis(draw) -> ast.Ellipsis:
    return ast.Ellipsis()
Ejemplo n.º 19
0
def generate_ellipsis(max_depth=None):
    return ast.Ellipsis()
Ejemplo n.º 20
0
def dynamize_node(node, ty, replacement_chance=.1):
    def lhts_elts(node):
        if isinstance(node, ast.Call):
            return node.args[0]
        elif isinstance(node, ast.Subscript):
            return node.slice.value

    def tuple_elts(node):
        if isinstance(node, ast.Tuple):
            return node.elts
        elif isinstance(node, ast.Call):
            return node.args
        elif isinstance(node, ast.Subscript):
            return node.slice.value.elts

    def dict_keys(node):
        if isinstance(node, ast.Call):
            return node.args[0]
        elif isinstance(node, ast.Subscript):
            return node.slice.value.elts[0]

    def dict_vals(node):
        if isinstance(node, ast.Call):
            return node.args[1]
        elif isinstance(node, ast.Subscript):
            return node.slice.value.elts[1]

    def fn_to(node):
        if isinstance(node, ast.Call):
            return node.args[1]
        elif isinstance(node, ast.Subscript):
            return node.slice.value.elts[1]

    def fn_args(node):
        if isinstance(node, ast.Call):
            return node.args[0].elts
        elif isinstance(node, ast.Subscript):
            return node.slice.value.elts[0].elts

    def struct_keys(node):
        return node.keys

    def struct_vals(node):
        return node.values

    if random.random() < replacement_chance:
        return weight(ty), dyn(node)
    elif any(
            isinstance(ty, cls)
            for cls in {retic_ast.List, retic_ast.HTuple, retic_ast.Set}):
        w, elts = dynamize_node(lhts_elts(node), ty.elts)
        if w > 0:
            if isinstance(ty, retic_ast.List):
                return w, fix_location(
                    ast.Subscript(value=ast.Name(id='List', ctx=ast.Load()),
                                  slice=ast.Index(value=elts),
                                  ctx=ast.Load()), node)
            elif isinstance(ty, retic_ast.Set):
                return w, fix_location(
                    ast.Subscript(value=ast.Name(id='Set', ctx=ast.Load()),
                                  slice=ast.Index(value=elts),
                                  ctx=ast.Load()), node)
            elif isinstance(ty, retic_ast.HTuple):
                return w, fix_location(
                    ast.Subscript(
                        value=ast.Name(id='Tuple', ctx=ast.Load()),
                        slice=ast.Index(value=ast.Tuple(
                            elts=[elts, ast.Ellipsis()], ctx=ast.Load())),
                        ctx=ast.Load()), node)
        else:
            return 0, node
    elif isinstance(ty, retic_ast.Tuple):
        ws, elts = zip(*[
            dynamize_node(elt, ty)
            for elt, ty in zip(tuple_elts(node), ty.elts)
        ])
        w = sum(ws)
        if w > 0:
            return w, fix_location(
                ast.Subscript(
                    value=ast.Name(id='Tuple', ctx=ast.Load()),
                    slice=ast.Index(
                        value=ast.Tuple(elts=list(elts), ctx=ast.Load())),
                    ctx=ast.Load()), node)
        else:
            return 0, node
    elif isinstance(ty, retic_ast.Dict):
        wk, keys = dynamize_node(dict_keys(node), ty.keys)
        wv, vals = dynamize_node(dict_vals(node), ty.values)
        if wk + wv > 0:
            return wk + wv, fix_location(
                ast.Subscript(
                    value=ast.Name(id='Dict', ctx=ast.Load()),
                    slice=ast.Index(
                        value=ast.Tuple(elts=[keys, vals], ctx=ast.Load())),
                    ctx=ast.Load()), node)
        else:
            return 0, node
    elif isinstance(ty, retic_ast.Function):
        wt, to = dynamize_node(fn_to(node), ty.to)
        if isinstance(ty.froms, retic_ast.PosAT):
            if len(fn_args(node)) > 0:
                was, args = zip(*[
                    dynamize_node(elt, ty)
                    for elt, ty in zip(fn_args(node), ty.froms.types)
                ])
                wa = sum(was)
            else:
                args = []
                wa = 0
            if wt + wa > 0:
                return wt + wa, fix_location(
                    ast.Subscript(
                        value=ast.Name(id='Callable', ctx=ast.Load()),
                        slice=ast.Index(value=ast.Tuple(
                            elts=[ast.List(elts=list(args), ctx=ast.Load), to],
                            ctx=ast.Load())),
                        ctx=ast.Load()), node)
            else:
                return 0, node
        else:
            assert isinstance(ty.froms, retic_ast.ArbAT)
            if wt > 0:
                return wt, fix_location(
                    ast.Subscript(
                        value=ast.Name(id='Callable', ctx=ast.Load()),
                        slice=ast.Index(value=ast.Tuple(
                            elts=[ast.Ellipsis(), to], ctx=ast.Load())),
                        ctx=ast.Load()), node)
            else:
                return 0, node
    elif isinstance(ty, retic_ast.Structural):
        mems = [(k, dynamize_node(v, ty.members[k.s]))
                for k, v in zip(struct_keys(node), struct_vals(node))]
        w = 0
        keys = []
        vals = []
        for k, (we, v) in mems:
            w += we
            keys.append(k)
            vals.append(v)
        if w > 0:
            return w, fix_location(ast.Dict(keys=keys, values=vals), node)
        else:
            return 0, node
    else:
        return 0, node
Ejemplo n.º 21
0
 def visit(self, node):
     if node is Ellipsis:
         node = ast.Ellipsis()
     result = super(TypeInferer, self).visit(node)
     return result
Ejemplo n.º 22
0
 def visitEllipsis(self, n, *args):
     return ast.Ellipsis()