vxgmichel/aioconsole

aioconsole.aprint raises `AttributeError: 'NoneType' object has no attribute 'fileno'`

JoakimJoensuu opened this issue · 5 comments

I have following code using aiohttp and aioconsole.

booking-server/booking_server/__main__.py

import asyncio

from aiohttp import web
from booking_server.api import routes

async def periodic_cleanup(server_data: ServerData):
    while True:
        await aprint(
            "========================================================"
        )
        await aprint(
            "I could clean something"
        )

if __name__ == "__main__":
    initial_server_data: ServerData = {
        "booking_id_counter": 0,
        "bookings": [],
        "resources": [],
        "id_to_booking": {},
    }

    app = web.Application()
    app.add_routes(routes)
    app["server_data"] = initial_server_data

    loop = asyncio.get_event_loop()
    loop.create_task(periodic_cleanup(initial_server_data))

    web.run_app(app, loop=loop)

Running this with python booking-server/booking_server command works, but when I use my script that reloads the application on file changes
server_reload.sh

#!/bin/sh

find booking-server booking-common | entr -r python booking-server/booking_server

it gives an followin error:

Task exception was never retrieved
future: <Task finished name='Task-1' coro=<periodic_cleanup() done, defined at /home/user/repo/booking-server/booking_server/server.py:58> exception=AttributeError("'NoneType' object has no attribute 'fileno'")>
Traceback (most recent call last):
  File "/home/user/repo/booking-server/booking_server/server.py", line 62, in periodic_cleanup
    await aprint(
  File "/home/user/repo/.venv/lib/python3.11/site-packages/aioconsole/stream.py", line 291, in aprint
    streams = await get_standard_streams(use_stderr=use_stderr, loop=loop)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/repo/.venv/lib/python3.11/site-packages/aioconsole/stream.py", line 261, in get_standard_streams
    cache[key] = await connection
                 ^^^^^^^^^^^^^^^^
  File "/home/user/repo/.venv/lib/python3.11/site-packages/aioconsole/stream.py", line 245, in create_standard_streams
    if all(map(is_pipe_transport_compatible, (stdin, stdout, stderr))):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/repo/.venv/lib/python3.11/site-packages/aioconsole/stream.py", line 20, in is_pipe_transport_compatible
    fileno = pipe.fileno()
             ^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'fileno'

If I replace aprint with synchronous print it works with the script.

Using Python 3.11.4 and aioconsole==0.6.1

Hi @JoakimJoensuu and thanks for the report :)

I could not reproduce your issue, could you provide more information? Specifically:

  • does this issue occur if you add await asyncio.sleep(1) in the while loop?
  • could you print sys.stdin, sys.stdout and sys.stderr somewhere in your program and see if one of them is None?
  • does this issue occur if you add await asyncio.sleep(1) in the while loop?

Yes, it still occurs.

  • could you print sys.stdin, sys.stdout and sys.stderr somewhere in your program and see if one of them is None?

Looks like sys.stdin is None when I run my application with find booking-server booking-common | entr -r python booking-server/booking_server.

sys.stderr=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>
sys.stdin=None
sys.stdout=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>

With python booking-server/booking_server it is not None:

sys.stderr=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>
sys.stdin=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>
sys.stdout=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>

So looks like the entr tooling I am using doesn't use stdin and aioconsole tries to create NonFileStreamReader for it even though I'm not using ainput at all, right?

So looks like the entr tooling I am using doesn't use stdin and aioconsole tries to create NonFileStreamReader for it even though I'm not using ainput at all, right?

Yes! Thanks for the valuable information, I'll work on a fix tomorrow.

Funnily enough I could not replicate this behavior on my machine with entr 5.1 and python 3.11.4.

But it's not big deal, I can still test it manually.

So looks like the entr tooling I am using doesn't use stdin and aioconsole tries to create NonFileStreamReader for it even though I'm not using ainput at all, right?

Yes! Thanks for the valuable information, I'll work on a fix tomorrow.

Funnily enough I could not replicate this behavior on my machine with entr 5.1 and python 3.11.4.

But it's not big deal, I can still test it manually.

Looks like I have version 4.4 of entr, that might make a difference.

Huge thanks to you!

Fixed in #110, released v0.6.2 🎉