Tinche / aiofiles

File support for asyncio
Apache License 2.0
2.67k stars 149 forks source link

tell() has to be awaited twice when subclassed. #44

Open Senator3223 opened 6 years ago

Senator3223 commented 6 years ago

I guess the tell() function is bugged for subclassed AsyncBufferedReader objects

the following program returns the this output:

b'ADSEGMENTE' <generator object _make_delegate_method..method at 0x10ac77938>

import aiofiles
import asyncio
#!/usr/bin/env python3.6
# -*- encoding: utf-8 -*-
"""
How do i create attributes in async functions?

Expected result:
    b'THISISTEXT' 10

Actual result:
    b'THISISTEXT' <generator object _make_delegate_method.<locals>.method at 0x10e7cda40>
"""
class Buffer(aiofiles.threadpool.binary.AsyncBufferedReader):

    def __init__(self, stream, block_size):
        super().__init__(stream, loop=stream._loop, executor=stream._executor)
        self.stream = stream
        self.block_size = block_size

    async def __aiter__(self):
        return self

    async def __anext__(self):
        return await self.read(self.block_size)

    async def get_index(self):
        # the following line is a workaround... 
        # return await self.stream.tell()
        return await self.tell()

    @classmethod
    async def new(cls, file_path,  mode='rb', block_size=1024):
        stream = await aiofiles.open(file_path, mode=mode)
        return cls(stream, block_size)

async def run_read():
    bin_buffer = await  Buffer.new('file_name.raw', block_size=10)
    async for chunk_data in bin_buffer:
        # the following line is also a workaround... 
        # print(await chunk_data, await (await bin_buffer.get_index()))
        print(await chunk_data, await bin_buffer.get_index())

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run_read())

When I call stream directly, which is an AsyncBufferedReader, I can access tell() with one await, when I subclass the AsyncBufferedReader I have to await twice to access tell().