Exemplo n.º 1
0
def _transform(path: str, code: str,
               target: CompilationTarget) -> Tuple[str, List[str]]:
    """Applies all transformation for passed target."""
    dependencies = []  # type: List[str]

    for transformer in transformers:
        tree = ast.parse(code, path)
        if transformer.target < target:
            continue

        try:
            result = transformer.transform(tree)
        except:
            raise TransformationError(path, transformer, dump(tree),
                                      format_exc())

        if not result.tree_changed:
            continue

        dependencies.extend(result.dependencies)

        try:
            code = unparse(tree)
        except:
            raise TransformationError(path, transformer, dump(tree),
                                      format_exc())

    return fix_code(code), dependencies
Exemplo n.º 2
0
    def dispatch_var_type(self, tree):
        code = horast.unparse(tree)
        stripped_code = code.strip()
        if stripped_code in PYTHON_FORTRAN_TYPE_PAIRS:
            type_name, precision = PYTHON_FORTRAN_TYPE_PAIRS[stripped_code]
            self.write(type_name)
            if precision is not None:
                self.write('*')
                self.write(str(precision))
        elif _match_array(tree):
            sli = tree.slice
            assert isinstance(sli,
                              typed_ast3.Index), typed_astunparse.dump(tree)
            assert isinstance(sli.value, typed_ast3.Tuple)
            assert len(sli.value.elts) in (2, 3), sli.value.elts
            elts = sli.value.elts
            self.dispatch_var_type(elts[1])
            self.write(', ')
            self.write('dimension(')

            if len(sli.value.elts) == 2:
                self.write(':')
            else:
                if not self._context_input_args:
                    self.dispatch(elts[2])
                else:
                    assert isinstance(elts[2], typed_ast3.Tuple)
                    _LOG.warning('coercing indices of %i dims to 0-based',
                                 len(elts[2].elts))
                    # _LOG.warning('coercing indices of %s in %s to 0-based', arg.arg, t.name)
                    tup_elts = []
                    for elt in elts[2].elts:
                        if isinstance(elt, typed_ast3.Num):
                            assert isinstance(elt.n, int)
                            upper = typed_ast3.Num(n=elt.n - 1)
                        else:
                            assert isinstance(elt, typed_ast3.Name)
                            upper = typed_ast3.BinOp(left=elt,
                                                     op=typed_ast3.Sub(),
                                                     right=typed_ast3.Num(n=1))
                        tup_elts.append(
                            typed_ast3.Slice(lower=typed_ast3.Num(n=0),
                                             upper=upper,
                                             step=None))
                    tup = typed_ast3.Tuple(elts=tup_elts,
                                           ctx=typed_ast3.Load())
                    self.dispatch(tup)

            self.write(')')
        elif _match_io(tree):
            self.write('integer')
        elif isinstance(tree, typed_ast3.Call) and isinstance(tree.func, typed_ast3.Name) \
                and tree.func.id == 'type':
            self.dispatch(tree)
        else:
            raise NotImplementedError('not yet implemented: {}'.format(
                typed_astunparse.dump(tree)))
Exemplo n.º 3
0
 def transform(transformer, before):
     tree = parse(before)
     try:
         transformer.transform(tree)
         return unparse(tree).strip()
     except:
         print('Before:')
         print(dump(parse(before)))
         print('After:')
         print(dump(tree))
         raise
Exemplo n.º 4
0
 def _NameConstant(self, t):
     if t.value is None:
         _LOG.info('possibly invalid Fortran in """%s"""', typed_astunparse.dump(t))
     self.write({
         None: 'none',
         False: '.false.',
         True: '.true.'}[t.value])
Exemplo n.º 5
0
 def _add_kind_info(self):
     if len(self.decorator_list) == 0:
         if len(self.args.args) == 0:
             self._kind = FunctionKind.Function
         else:
             first_arg = self.args.args[0].arg
             if first_arg == 'self':
                 if self.name == '__init__':
                     self._kind = FunctionKind.Constructor
                 else:
                     self._kind = FunctionKind.InstanceMethod
             else:
                 self._kind = FunctionKind.Function
     elif len(self.decorator_list) == 1:
         decorator = self.decorator_list[0]
         assert isinstance(decorator, ast_module.Name)
         self._kind = {
             'classmethod': FunctionKind.ClassMethod,
             'staticmethod': FunctionKind.StaticMethod}.get(
                 decorator.id, FunctionKind.Undetermined)
     else:
         raise NotImplementedError('no support for many decorators:\n{}'
                                   .format(self.decorator_list))
     if self._kind is FunctionKind.Undetermined:
         raise NotImplementedError('could not determine function kind:\n{}'
                                   .format(typed_astunparse.dump(self)))
Exemplo n.º 6
0
    def test_dump_files_comparison(self):
        """Print the same data as other existing modules."""
        for path in PATHS:
            with open(path, 'r', encoding='utf-8') as py_file:
                code = py_file.read()

            untyped_tree = ast.parse(source=code, filename=path)
            untyped_dump = astunparse.dump(untyped_tree)
            tested_untyped_dump = typed_astunparse.dump(untyped_tree)

            self.assertEqual(untyped_dump.splitlines(),
                             tested_untyped_dump.splitlines())

            typed_tree = typed_ast.ast3.parse(source=code, filename=path)
            bad_typed_dump = astunparse.dump(typed_tree)

            for annotate_fields in [True, False]:
                for include_attributes in [False, True]:
                    if include_attributes and not annotate_fields:
                        continue  # behaviour differs from typed_ast

                    with self.assertRaises(TypeError):
                        _ = typed_ast.ast3.dump(
                            untyped_tree,
                            annotate_fields=annotate_fields,
                            include_attributes=include_attributes)

                    typed_dump = typed_ast.ast3.dump(
                        typed_tree,
                        annotate_fields=annotate_fields,
                        include_attributes=include_attributes)
                    tested_typed_dump = _postprocess_dump(
                        typed_astunparse.dump(
                            typed_tree,
                            annotate_fields=annotate_fields,
                            include_attributes=include_attributes))

                    if include_attributes:
                        # because of https://github.com/python/typed_ast/issues/23
                        self.assertEqual(typed_dump.replace(' ', ''),
                                         tested_typed_dump.replace(' ', ''))
                        continue
                    self.assertNotEqual(untyped_dump, bad_typed_dump)
                    self.assertNotEqual(typed_dump, bad_typed_dump)
                    self.assertEqual(typed_dump, tested_typed_dump)
Exemplo n.º 7
0
 def _BinOp(self, t):
     if t.op.__class__.__name__ not in self.binop:
         raise NotImplementedError('not yet implemented: {}'.format(
             typed_astunparse.dump(t)))
     self.write('(')
     self.dispatch(t.left)
     self.write(' ' + self.binop[t.op.__class__.__name__] + ' ')
     self.dispatch(t.right)
     self.write(')')
Exemplo n.º 8
0
 def test_dump_examples(self):
     """Print ASTs of examples correctly."""
     for description, example in EXAMPLES.items():
         for mode in MODES:
             if example['trees'][mode] is None:
                 continue
             dump = typed_astunparse.dump(example['trees'][mode])
             _LOG.debug('%s', dump)
             dump = dump.replace('\n', '').replace(' ', '')
             self.assertEqual(dump, example['dumps'][mode], msg=(description, mode))
Exemplo n.º 9
0
 def test_generalize_examples(self):
     code_reader = CodeReader()
     parser = C99Parser()
     ast_generalizer = CAstGeneralizer()
     for path in EXAMPLES_C11_FILES:
         code = code_reader.read_file(path)
         tree = parser.parse(code, path)
         basic_check_c_ast(self, path, tree)
         tree = ast_generalizer.generalize(tree)
         basic_check_python_ast(self, path, tree)
         _LOG.debug('%s', typed_astunparse.dump(tree))
         _LOG.debug('%s', typed_astunparse.unparse(tree))
Exemplo n.º 10
0
 def test_dump_examples(self):
     """Print ASTs of examples correctly."""
     for description, example in EXAMPLES.items():
         for mode in MODES:
             if example['trees'][mode] is None:
                 continue
             dump = typed_astunparse.dump(example['trees'][mode])
             _LOG.debug('%s', dump)
             dump = dump.replace('\n', '').replace(' ', '')
             self.assertEqual(dump,
                              example['dumps'][mode],
                              msg=(description, mode))
Exemplo n.º 11
0
    def test_dump_files_comparison(self):
        """Print the same data as other existing modules."""
        for path in PATHS:
            with open(path, 'r', encoding='utf-8') as py_file:
                code = py_file.read()

            untyped_tree = ast.parse(source=code, filename=path)
            untyped_dump = astunparse.dump(untyped_tree)
            tested_untyped_dump = typed_astunparse.dump(untyped_tree)

            self.assertEqual(untyped_dump.splitlines(), tested_untyped_dump.splitlines())

            typed_tree = typed_ast.ast3.parse(source=code, filename=path)
            bad_typed_dump = astunparse.dump(typed_tree)

            for annotate_fields in [True, False]:
                for include_attributes in [False, True]:
                    if include_attributes and not annotate_fields:
                        continue  # behaviour differs from typed_ast

                    with self.assertRaises(TypeError):
                        _ = typed_ast.ast3.dump(
                            untyped_tree, annotate_fields=annotate_fields,
                            include_attributes=include_attributes)

                    typed_dump = typed_ast.ast3.dump(
                        typed_tree, annotate_fields=annotate_fields,
                        include_attributes=include_attributes)
                    tested_typed_dump = _postprocess_dump(typed_astunparse.dump(
                        typed_tree, annotate_fields=annotate_fields,
                        include_attributes=include_attributes))

                    if include_attributes:
                        # because of https://github.com/python/typed_ast/issues/23
                        self.assertEqual(
                            typed_dump.replace(' ', ''), tested_typed_dump.replace(' ', ''))
                        continue
                    self.assertNotEqual(untyped_dump, bad_typed_dump)
                    self.assertNotEqual(typed_dump, bad_typed_dump)
                    self.assertEqual(typed_dump, tested_typed_dump)
Exemplo n.º 12
0
 def test_generalize_examples(self, input_path):
     code_reader = CodeReader()
     code = code_reader.read_file(input_path)
     parser = CppParser()
     cpp_ast = parser.parse(code, input_path)
     basic_check_cpp_ast(self, input_path, cpp_ast)
     ast_generalizer = CppAstGeneralizer(scope={'path': input_path})
     with _TIME.measure('generalize.{}'.format(input_path.name.replace('.', '_'))) as timer:
         syntax = ast_generalizer.generalize(cpp_ast)
     basic_check_python_ast(self, input_path, syntax)
     _LOG.info('generalized "%s" in %fs', input_path, timer.elapsed)
     _LOG.debug('%s', typed_astunparse.dump(syntax))
     _LOG.debug('%s', typed_astunparse.unparse(syntax))
 def test_generalize_examples(self):
     code_reader = CodeReader()
     parser = CppParser()
     for path in EXAMPLES_CPP14_FILES:
         ast_generalizer = CppAstGeneralizer(scope={'path': path})
         code = code_reader.read_file(path)
         tree = parser.parse(code, path)
         basic_check_cpp_ast(self, path, tree)
         with self.subTest(path=path):
             tree = ast_generalizer.generalize(tree)
             basic_check_python_ast(self, path, tree)
             _LOG.debug('%s', typed_astunparse.dump(tree))
             _LOG.debug('%s', typed_astunparse.unparse(tree))
Exemplo n.º 14
0
    def test_many_dump_roundtrips(self):
        """Preserve ASTs after unparse(parse(...unparse(parse(dump(tree)))...))."""
        for description, example in EXAMPLES.items():
            for mode in MODES:
                if example['trees'][mode] is None:
                    continue

                dump = typed_astunparse.dump(example['trees'][mode])
                for _ in range(4):
                    tree = typed_ast.ast3.parse(source=dump, mode=mode)
                    dump = typed_astunparse.unparse(tree)
                    _LOG.debug('%s', dump)
                    clean_dump = dump.replace('\n', '').replace(' ', '')
                    self.assertEqual(clean_dump, example['dumps'][mode], msg=(description, mode))
Exemplo n.º 15
0
def transform(path: str, code: str, target: CompilationTarget) -> str:
    """Applies all transformation for passed target."""
    from ..exceptions import TransformationError

    for transformer in transformers:
        tree = ast.parse(code, path)
        if transformer.target >= target:
            transformer().visit(tree)
        try:
            code = unparse(tree)
        except:
            raise TransformationError(path, transformer, dump(tree),
                                      format_exc())

    return fix_code(code)
Exemplo n.º 16
0
    def test_many_dump_roundtrips(self):
        """Preserve ASTs after unparse(parse(...unparse(parse(dump(tree)))...))."""
        for description, example in EXAMPLES.items():
            for mode in MODES:
                if example['trees'][mode] is None:
                    continue

                dump = typed_astunparse.dump(example['trees'][mode])
                for _ in range(4):
                    tree = typed_ast.ast3.parse(source=dump, mode=mode)
                    dump = typed_astunparse.unparse(tree)
                    _LOG.debug('%s', dump)
                    clean_dump = dump.replace('\n', '').replace(' ', '')
                    self.assertEqual(clean_dump,
                                     example['dumps'][mode],
                                     msg=(description, mode))
Exemplo n.º 17
0
 def _keyword(self, t):
     if t.arg is None:
         raise NotImplementedError('not yet implemented: {}'.format(typed_astunparse.dump(t)))
     super()._keyword(t)
Exemplo n.º 18
0
    def test_inline_flash_subset_hydro(self):
        app_name = 'FLASH-SUBSET'
        if app_name not in _APPS_ROOT_PATHS and app_name in _APPS_OPTIONAL:
            self.skipTest('{} directory not found'.format(app_name))
        language = Language.find('Fortran')
        reader = CodeReader()
        parser = Parser.find(language)()
        ast_generalizer = AstGeneralizer.find(language)()
        f_unparser = Unparser.find(language)()
        py_unparser = Unparser.find(Language.find('Python'))()
        writer = CodeWriter()

        dir_name = app_name.lower()
        results_path = pathlib.Path(RESULTS_ROOT, 'transformations', 'inlining', dir_name)
        results_path.mkdir(parents=True, exist_ok=True)

        path_pairs = [
            (pathlib.Path('physics/Hydro/HydroMain/unsplit/hy_upwindTransverseFlux_loop.F90'),
             pathlib.Path('physics/Hydro/HydroMain/unsplit/hy_upwindTransverseFlux.F90'),
             (1, 1)),
            (pathlib.Path('physics/Eos/EosMain/Eos_getData_loop1.F90'),
             pathlib.Path('physics/Eos/EosMain/Eos_getData.F90'),
             (1, 2))]

        for inlined_path, target_path, (index, extra_lines) in path_pairs:
            inlined_path = pathlib.Path(_APPS_ROOT_PATHS[app_name], 'source', inlined_path)
            target_path = pathlib.Path(_APPS_ROOT_PATHS[app_name], 'source', target_path)

            output_inlined_path = results_path.joinpath(inlined_path.name)
            output_target_path = results_path.joinpath(target_path.name)
            output_path = results_path.joinpath(target_path.with_suffix('').name + '_inlined.F90')

            inlined_xml = parser.parse('', inlined_path)
            inlined_xml = inlined_xml.find('.//subroutine')
            writer.write_file(ET.tostring(inlined_xml, 'utf-8').decode(),
                              output_inlined_path.with_suffix('.xml'))

            inlined_syntax = ast_generalizer.generalize(inlined_xml)
            writer.write_file(typed_astunparse.dump(inlined_syntax),
                              output_inlined_path.with_suffix('.ast.py'))
            writer.write_file(py_unparser.unparse(inlined_syntax),
                              output_inlined_path.with_suffix('.py'))
            writer.write_file(f_unparser.unparse(inlined_syntax),
                              output_inlined_path.with_suffix('.f95'))

            target_code = reader.read_file(target_path)
            target_xml = parser.parse(target_code, target_path)
            # import ipdb; ipdb.set_trace()
            target_xml = target_xml.findall('.//call')[index]
            writer.write_file(ET.tostring(target_xml, 'utf-8').decode(),
                              output_target_path.with_suffix('.xml'))

            target_syntax = ast_generalizer.generalize(target_xml)
            writer.write_file(typed_astunparse.dump(target_syntax),
                              output_target_path.with_suffix('.ast.py'))
            writer.write_file(py_unparser.unparse(target_syntax),
                              output_target_path.with_suffix('.py'))
            writer.write_file(f_unparser.unparse(target_syntax),
                              output_target_path.with_suffix('.f95'))

            mock_function = typed_ast3.FunctionDef(
                'f', typed_ast3.arguments([], None, [], None, [], []),
                [typed_ast3.Expr(target_syntax)], [], None, None)
            output_syntax = inline_syntax(mock_function, inlined_syntax, globals_=globals())
            output_syntax = st.augment(typed_ast3.Module(output_syntax.body, []), eval_=False)
            writer.write_file(typed_astunparse.dump(output_syntax),
                              output_path.with_suffix('.ast.py'))
            writer.write_file(py_unparser.unparse(output_syntax),
                              output_path.with_suffix('.py'))
            output_code = f_unparser.unparse(output_syntax)
            writer.write_file(output_code, output_path.with_suffix('.f95'))

            _LOG.warning('[%s %s] <- %i', target_xml.attrib['line_begin'],
                         target_xml.attrib['line_end'], len(output_code))
            total_code = replace_scope(
                target_code, int(target_xml.attrib['line_begin']),
                int(target_xml.attrib['line_end']) + extra_lines, output_code)
            writer.write_file(total_code, output_path)
Exemplo n.º 19
0
def insert_comment_tokens_approx(
        tree: typed_ast.ast3.AST, tokens: t.List[tokenize.TokenInfo]) -> typed_ast.ast3.AST:
    assert isinstance(tree, typed_ast.ast3.AST)
    assert isinstance(tokens, list)
    token_locations = get_token_locations(tokens)
    _LOG.debug('token locations: %s', token_locations)
    nodes = ast_to_list(tree, only_localizable=True)
    if not nodes and tokens:
        _LOG.debug('overwriting empty AST with simplest editable tree')
        tree = typed_ast.ast3.Module(body=[], type_ignores=[], lineno=1, col_offset=0)
        nodes = ast_to_list(tree, only_localizable=True)
    node_locations = get_ast_node_locations(nodes)
    _LOG.debug('node locations: %s', node_locations)
    node_locations_iter = enumerate(node_locations)
    token_insertion_indices = []
    tokens_eol_status = []
    for token_index, token_location in enumerate(token_locations):
        eol_comment_here = False
        try:
            node_index, node_location = next(node_locations_iter)
        except StopIteration:
            node_index = len(node_locations)
            node_location = None
        while node_location is not None:
            token_line, _ = token_location
            node_line, _ = node_location
            if node_line > token_line:
                break
            if node_line == token_line:
                eol_comment_here = True
                if node_index < len(node_locations) - 1:
                    next_node_line, _ = node_locations[node_index + 1]
                    if next_node_line == token_line:
                        eol_comment_here = False
                # if eol_comment_here:
                #    raise NotImplementedError(
                #        'code "{}" and comment "{}" in line {}'
                #        ' -- only whole line comments are currently supported'
                #        .format(typed_astunparse.unparse(nodes[node_index]).strip(),
                #                tokens[token_index].string, node_line))
            try:
                node_index, node_location = next(node_locations_iter)
            except StopIteration:
                node_index = len(node_locations)
                break
        tokens_eol_status.append(eol_comment_here)
        token_insertion_indices.append(node_index)
    _LOG.debug('token insertion indices: %s', token_insertion_indices)
    _LOG.debug('tree before insertion:\n"""\n%s\n"""', typed_astunparse.dump(tree))
    _LOG.debug('code before insertion:\n"""\n%s\n"""', typed_astunparse.unparse(tree).strip())
    for token_index, token_insertion_index in reversed(list(enumerate(token_insertion_indices))):
        token = tokens[token_index]
        eol = tokens_eol_status[token_index]
        comment = Comment.from_token(token, eol)
        if token_insertion_index == 0:
            anchor = nodes[token_insertion_index]
            before_anchor = True
        elif token_insertion_index == len(node_locations):
            anchor = nodes[-1]
            before_anchor = False
        else:
            anchor = nodes[token_insertion_index - 1]
            before_anchor = False
        _LOG.debug('inserting %s %s %s', comment, 'before' if before_anchor else 'after', anchor)
        tree = insert_in_tree(tree, comment, anchor=anchor, before_anchor=before_anchor)
    _LOG.debug('tree after insertion:\n"""\n%s\n"""', typed_astunparse.dump(tree))
    # _LOG.warning('code after insertion:\n"""\n%s\n"""', typed_astunparse.unparse(tree).strip())
    return tree
Exemplo n.º 20
0
 def dump(self, tree) -> str:
     return typed_astunparse.dump(tree)
Exemplo n.º 21
0
tree from source (above) != example tree (below)
"""
{}
"""'''
    for _description, _example in EXAMPLES.items():
        for mode in MODES:
            if _example['trees'][mode] is None:
                try:
                    tree_from_source = typed_ast.ast3.parse(
                        source=_example['code'], filename='<string>', mode=mode)
                except SyntaxError:
                    tree_from_source = None
                example_tree = None
            else:
                tree_from_source = typed_astunparse.dump(
                    typed_ast.ast3.parse(source=_example['code'], filename='<string>', mode=mode)
                    ).replace('\n', '').replace(' ', '')
                example_tree = typed_astunparse.dump(
                    _example['trees'][mode]).replace('\n', '').replace(' ', '')
            assert tree_from_source == example_tree, _MSG.format(
                _description, mode, tree_from_source, example_tree)

_ROOT_DIRECTORY_PARTS = [getattr(sys, 'real_prefix', sys.prefix), 'lib']
if platform.system() != 'Windows':
    _ROOT_DIRECTORY_PARTS.append('python{}.{}'.format(*sys.version_info[:2]))

_ROOT_DIRECTORY = os.path.join(*_ROOT_DIRECTORY_PARTS)

# verify root directory
if __debug__:
    assert isinstance(_ROOT_DIRECTORY, str), _ROOT_DIRECTORY
Exemplo n.º 22
0
def dump(tree: Module) -> str:
    return typed_astunparse.dump(tree)
Exemplo n.º 23
0
 def _IfExp(self, t):
     raise NotImplementedError('not yet implemented: {}'.format(typed_astunparse.dump(t)))
Exemplo n.º 24
0
    def _Call(self, t):
        if getattr(t, 'fortran_metadata', {}).get('is_procedure_call', False):
            self.write('call ')
        func_name = horast.unparse(t.func).strip()
        if has_annotation(t, 'is_mpi_call'):
            self.write('call ')
            # val = last_attribute_value(t.func)
            # fname = t.func.attr
            # assert isinstance(val, typed_ast3.Name), type(val)
            func_name = MPI_PYTHON_TO_FORTRAN[t.func.attr]
            # attribute = t.func
            # while isinstance(attribute.value, typed_ast3.Attribute):
            #     attribute = attribute.value
            components = attribute_chain_components(t.func)[:-1]
            t.func = typed_ast3.Name(func_name, typed_ast3.Load())
            t.args += components
            # print()
            # self.write(func_name)
            # raise
            # raise NotImplementedError(self.f.getvalue())

        elif func_name.startswith('Fortran.file_handles['):
            t = copy.copy(t)
            for suffix in ('read', 'close'):
                if func_name.endswith('].{}'.format(suffix)):
                    t.args.insert(0, t.func.value.slice.value)
                    t.func = typed_ast3.Name(id=suffix, ctx=typed_ast3.Load())
                    break
            # if func_name.endswith('].read'):
            #    t.func = typed_ast3.Name(id='read', ctx=typed_ast3.Load())
            # elif func_name.endswith('].close'):
            #    t.func = typed_ast3.Name(id='close', ctx=typed_ast3.Load())
            else:
                raise NotImplementedError(func_name)
        elif func_name.endswith('.format'):
            t = copy.copy(t)
            prefix, _, label = t.func.value.id.rpartition('_')
            assert prefix == 'format_label', prefix
            self.write(label)
            self.write(' ')
            t.func = typed_ast3.Name(id='format', ctx=typed_ast3.Load())
        elif func_name.endswith('.rstrip'):
            t = copy.copy(t)
            t.args.insert(0, t.func.value)
            t.func = typed_ast3.Name(id='trim', ctx=typed_ast3.Load())
        elif func_name.endswith('.sum'):
            t = copy.copy(t)
            t.args.insert(0, t.func.value)
            t.func = typed_ast3.Name(id='count', ctx=typed_ast3.Load())
        elif func_name.endswith('.size'):
            _LOG.warning('assuming np.size()')
            t = copy.copy(t)
            t.args.insert(0, t.func.value)
            t.func = typed_ast3.Name(id='size', ctx=typed_ast3.Load())
        elif func_name.endswith('.shape'):
            _LOG.warning('assuming np.shape()')
            t = copy.copy(t)
            t.args[0].n += 1
            t.args.insert(0, t.func.value)
            t.func = typed_ast3.Name(id='size', ctx=typed_ast3.Load())
        elif func_name in PYTHON_FORTRAN_INTRINSICS \
                and not getattr(t, 'fortran_metadata', {}).get('is_transformed', False):
            new_func = PYTHON_FORTRAN_INTRINSICS[func_name]
            if isinstance(new_func, collections.abc.Callable):
                self.dispatch(new_func(t))
                return
            t = copy.copy(t)
            t.func = typed_ast3.Name(id=new_func, ctx=typed_ast3.Load())
        elif func_name.startswith('np.'):
            raise NotImplementedError('not yet implemented: {}'.format(typed_astunparse.dump(t)))
        if func_name not in ('print',):
            super()._Call(t)
            return

        self.dispatch(t.func)
        self.write(' ')
        comma = False
        for arg in itertools.chain(t.args, t.keywords):
            if comma:
                self.write(", ")
            else:
                comma = True
            self.dispatch(arg)
Exemplo n.º 25
0
def view(scope):
    """Use this as a decorator for functions with observed values."""

    _LOG.debug("parameters.core.view got a scope to handle")

    # parse the srouruce and register all type-hinted vars

    frame_info = inspect.getouterframes(inspect.currentframe())[1]
    caller_frame = frame_info[0]
    globals_ = caller_frame.f_globals
    locals_ = caller_frame.f_locals

    code = inspect.getsource(scope)
    code = textwrap.dedent(code)
    syntax = typed_ast3.parse(code)
    function = syntax.body[0]
    # decorators = function.decorator_list
    function.decorator_list = []
    function = st.augment(function,
                          locals_=locals_,
                          globals_={
                              **globals_,
                              **globals()
                          })

    # _LOG.warning('%s', function._local_vars)
    for var_name, var_types in function._local_vars.items():
        for var_type in var_types:
            if var_type is Observed or isinstance(var_type, Observed):
                raise NotImplementedError(
                    'local variables currently cannot be observed')

    instrumented_targets = {}

    # _LOG.warning('%s', function._nonlocal_assignments)
    for target, var_types in function._nonlocal_assignments.items():
        for var_type in var_types:
            if var_type is Observed or isinstance(var_type, Observed):
                assert isinstance(target, typed_ast3.Attribute), type(target)
                obj = typed_astunparse.unparse(target.value).strip()
                attr = target.attr
                _LOG.debug(
                    'assignment to %s of %s within %s will be instrumented',
                    attr, obj, function.name)
                obj_attr = typed_astunparse.unparse(target).strip()
                # instrumented_targetstarget)
                instrumented_targets[obj_attr] = (obj, attr)
                protonn.parameters._parameters[obj_attr] = None

    #return scope

    class Instrumenter(st.ast_manipulation.RecursiveAstTransformer[ast]):
        def visit_node(self, node):
            if not isinstance(node, ast.Assign) or len(node.targets) != 1 \
                    or not isinstance(node.targets[0], ast.Attribute):
                return node
            obj_attr = typed_astunparse.unparse(node.targets[0]).strip()
            if obj_attr not in instrumented_targets:
                # _LOG.warning('discarding candidate %s', obj_attr)
                return node
            obj, attr = instrumented_targets[obj_attr]
            instrumentation = ast.parse(
                'protonn.parameters.core._observe({}, {}, {})'.format(
                    repr(obj_attr), obj, repr(attr)),
                mode='eval')
            return [node, ast.Expr(instrumentation.body)]

    syntax = ast.parse(code)
    function = syntax.body[0]
    function.decorator_list = []
    function = Instrumenter(fields_first=True).visit(function)
    # transcriber = st.ast_manipulation.AstTranscriber[typed_ast3, ast]()
    # syntax = transcriber.visit(syntax)
    flatten_syntax(syntax)
    _LOG.debug('%s', typed_astunparse.dump(function))
    syntax = ast.fix_missing_locations(syntax)
    expression = compile(syntax, '<instrumented-function>', 'exec')
    empty_locals_ = {}
    eval(expression, globals_, empty_locals_)
    assert len(empty_locals_) == 1
    return next(iter(empty_locals_.values()))
Exemplo n.º 26
0
tree from source (above) != example tree (below)
"""
{}
"""'''
    for _description, _example in EXAMPLES.items():
        for mode in MODES:
            if _example['trees'][mode] is None:
                try:
                    tree_from_source = typed_ast.ast3.parse(
                        source=_example['code'], filename='<string>', mode=mode)
                except SyntaxError:
                    tree_from_source = None
                example_tree = None
            else:
                tree_from_source = typed_astunparse.dump(
                    typed_ast.ast3.parse(source=_example['code'], filename='<string>', mode=mode)
                    ).replace('\n', '').replace(' ', '')
                example_tree = typed_astunparse.dump(
                    _example['trees'][mode]).replace('\n', '').replace(' ', '')
            assert tree_from_source == example_tree, _MSG.format(
                _description, mode, tree_from_source, example_tree)

_ROOT_DIRECTORY_PARTS = [getattr(sys, 'real_prefix', sys.prefix), 'lib']
if platform.system() != 'Windows':
    _ROOT_DIRECTORY_PARTS.append('python{}.{}'.format(*sys.version_info[:2]))

_ROOT_DIRECTORY = os.path.join(*_ROOT_DIRECTORY_PARTS)

# verify root directory
if __debug__:
    assert isinstance(_ROOT_DIRECTORY, str), _ROOT_DIRECTORY
Exemplo n.º 27
0
 def _Compare(self, t):
     if len(t.ops) > 1 or len(t.comparators) > 1 \
             or any([o.__class__.__name__ not in self.cmpops for o in t.ops]):
         raise NotImplementedError('not yet implemented: {}'.format(
             typed_astunparse.dump(t)))
     super()._Compare(t)
Exemplo n.º 28
0
 def _arguments(self, t):
     if t.vararg or t.kwonlyargs or t.kw_defaults or t.kwarg or t.defaults:
         raise NotImplementedError('not yet implemented: {}'.format(typed_astunparse.dump(t)))
     super()._arguments(t)