Skip to content

esp32: asyncio mp_pairheap_pop assertion failure #6758

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
derekenos opened this issue Jan 8, 2021 · 2 comments
Open

esp32: asyncio mp_pairheap_pop assertion failure #6758

derekenos opened this issue Jan 8, 2021 · 2 comments
Labels
py-core Relates to py/ directory in source

Comments

@derekenos
Copy link

derekenos commented Jan 8, 2021

I don't doubt that I'm doing something wrong here, but when I attempt to iterate over an async generator that contains an async for ... loop, it crashes with:

assertion "heap->next == NULL" failed: file "../../py/pairheap.h", line 94, function: mp_pairheap_pop

Script

try:
    import uasyncio as asyncio
except ImportError:
    import asyncio

# Adapted from micropython-async AsyncIterable example:                                                                                                
# https://github.com/peterhinch/micropython-async/blob/master/v3/docs/TUTORIAL.md#42-asynchronous-iterators
class AsyncGenerator:
    def __init__(self, gen):
        self.gen = gen

    def __aiter__(self):
        return self

    async def __anext__(self):
        v = await self.next()
        if v is StopIteration:
            raise StopAsyncIteration
        return v

    async def next(self):
        await asyncio.sleep(0)
        try:
            if hasattr(self.gen, '__anext__'):
                return await self.gen.__anext__()
            return next(self.gen)
        except StopIteration:
            return StopIteration

# AsyncGenerator decorator.                                                                                                                    
def async_generator(func):
    def wrapper(*args, **kwargs):
        return AsyncGenerator(func(*args, **kwargs))
    return wrapper

# A normal Python async generator function with inner SYNC loop,                                                                                      
# wrapped with AsyncGenerator.                                                                                                                         
@async_generator
async def agen1():
    for i in range(10):
        yield i

# A normal Python async generator function with inner ASYNC loop,                                                                                     
# wrapped with AsyncGenerator.                                                                                                                         
@async_generator
async def agen2(agen):
    async for i in agen:
        yield i

# Consume an async generator and print each value.                                                                                                     
async def consume(gen):
    async for i in gen:
        print(i)

def go():
    run = asyncio.get_event_loop().run_until_complete

    print('# Ok')
    run(consume(agen1()))

    print('# Not Ok')
    run(consume(agen2(agen1())))

Micropython v1.13 ESP32 Output:

>>> go()
# Ok
0
1
2
3
4
5
6
7
8
9
# Not Ok
None
assertion "heap->next == NULL" failed: file "../../py/pairheap.h", line 94, function: mp_pairheap_pop
abort() was called at PC 0x4016a1eb on core 1

ELF file SHA256: 0000000000000000000000000000000000000000000000000000000000000000

Backtrace: 0x4008fcb3:0x3ffce300 0x4008ffd1:0x3ffce320 0x4016a1eb:0x3ffce340 0x400edf8b:0x3ffce370 0x400e3781:0x3ffce390 0x400df7a1:0x3ffce3b0 0x400df8c9:0x3ffce3d0 0x400ed011:0x3ffce3f0 0x400e390c:0x3ffce490 0x400df7a1:0x3ffce4c0 0x400ecf89:0x3ffce4e0 0x400e390c:0x3ffce580 0x400df7a1:0x3ffce5f0 0x400ecf89:0x3ffce610 0x400e390c:0x3ffce6b0 0x400df7a1:0x3ffce720 0x400ecf89:0x3ffce740 0x400e390c:0x3ffce7e0 0x400df7a1:0x3ffce840 0x400df7ca:0x3ffce860 0x40104967:0x3ffce880 0x40104b71:0x3ffce910 0x400f5d3c:0x3ffce950 0x400992f6:0x3ffce980

Rebooting...

Python 3.6 Output

>>> go()
# Ok
0
1
2
3
4
5
6
7
8
9
# Not Ok
0
1
2
3
4
5
6
7
8
9
@peterhinch
Copy link
Contributor

Are you using this firmware #6668?

@derekenos
Copy link
Author

Thanks @peterhinch, I didn't know that that PR existed. My code works as expected in #6668, with and without the use of AsyncGenerator.

@dpgeorge dpgeorge added the py-core Relates to py/ directory in source label Apr 13, 2021
tannewt added a commit to tannewt/circuitpython that referenced this issue Aug 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
py-core Relates to py/ directory in source
Projects
None yet
Development

No branches or pull requests

3 participants