Skip to content

Implement async def, async for, and await syntax for method extraction#389

Merged
lieryan merged 12 commits into
masterfrom
fix-375-async-def-extract
Sep 17, 2021
Merged

Implement async def, async for, and await syntax for method extraction#389
lieryan merged 12 commits into
masterfrom
fix-375-async-def-extract

Conversation

@lieryan

@lieryan lieryan commented Sep 13, 2021

Copy link
Copy Markdown
Member

@lieryan

lieryan commented Sep 13, 2021

Copy link
Copy Markdown
Member Author

Currently still failing cases:

    @testutils.only_for_versions_higher('3.5')
    def test_extract_async_for_loop_2(self):
        code = dedent('''\
            async def my_func(my_list):
                async for x in my_list:
                    var = x + 1
                return var
        ''')
        start, end = self._convert_line_range_to_offset(code, 2, 3)
        refactored = self.do_extract_method(code, start, end, 'new_func')
        expected = dedent('''\
            async def my_func(my_list):
                var = new_func()
                return var

            def new_func():
                async for x in my_list:
                    var = x + 1
                return var
        ''')
        self.assertEqual(expected, refactored)

@lieryan

lieryan commented Sep 13, 2021

Copy link
Copy Markdown
Member Author

Currently still failing cases:

    @testutils.only_for_versions_higher('3.5')
    def test_extract_inner_async_function(self):
        code = dedent('''\
            def my_func(my_list):
                async def inner_func(my_list):
                    for x in my_list:
                        var = x + 1
                return inner_func
        ''')
        start, end = self._convert_line_range_to_offset(code, 2, 4)
        refactored = self.do_extract_method(code, start, end, 'new_func')
        expected = dedent('''\
            def my_func(my_list):
                inner_func = new_func(my_list)
                return new_func

            def new_func(my_list):
                async def inner_func(my_list):
                    for x in my_list:
                        var = x + 1
                return inner_func
        ''')
        self.assertEqual(expected, refactored)



@lieryan lieryan marked this pull request as draft September 13, 2021 18:03
In Python 3.6 and earlier, `async for` and `await` are only valid within
an `async def`. This is a restriction that is later removed, but are
causing tests to fail unnecessarily.
@lieryan lieryan force-pushed the fix-375-async-def-extract branch from d7832bc to bb858a6 Compare September 14, 2021 21:50
Named expression is not a statement.
We need to be able to parse top-level `async`/`await` statements to
parse the extracted snippet. Python supports `async`/`await` syntax
since 3.5 but only in Python 3.8, that the `ast` supports
PyCF_ALLOW_TOP_LEVEL_AWAIT which allows us to parse `async`/`await`
outside of an `async def` block.
@lieryan lieryan force-pushed the fix-375-async-def-extract branch from 1a2128c to 5aaaea5 Compare September 17, 2021 23:10
@lieryan lieryan changed the title Implement async def, async for, and await syntax on patchedast Implement async def, async for, and await syntax for method extraction Sep 17, 2021
@lieryan lieryan marked this pull request as ready for review September 17, 2021 23:20
@lieryan lieryan merged commit f3f87e6 into master Sep 17, 2021
@lieryan lieryan deleted the fix-375-async-def-extract branch September 17, 2021 23:26
@lieryan lieryan added this to the 0.20.x milestone Sep 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement extract refactoring inside async def

1 participant