magmax/python-inquirer

[Windows] Import error "AttributeError: 'NoneType' object has no attribute 'fileno'"

aphshir opened this issue · 10 comments

When I try to import python-inquirer on python 3.11 I'm getting this error:

Traceback (most recent call last):
  File "C:/Users/me/Desktop/bordel/bordel.py", line 1, in <module>
    import inquirer
  File "C:\Users\me\AppData\Local\Programs\Python\Python311\Lib\site-packages\inquirer\__init__.py", line 1, in <module>
    from inquirer.prompt import prompt
  File "C:\Users\me\AppData\Local\Programs\Python\Python311\Lib\site-packages\inquirer\prompt.py", line 1, in <module>
    import inquirer.themes as themes
  File "C:\Users\me\AppData\Local\Programs\Python\Python311\Lib\site-packages\inquirer\themes.py", line 9, in <module>
    term = Terminal()
  File "C:\Users\me\AppData\Local\Programs\Python\Python311\Lib\site-packages\blessed\terminal.py", line 167, in __init__
    self.__init__streams()
  File "C:\Users\me\AppData\Local\Programs\Python\Python311\Lib\site-packages\blessed\terminal.py", line 256, in __init__streams
    self._init_descriptor = sys.__stdout__.fileno()
AttributeError: 'NoneType' object has no attribute 'fileno'
iva2k commented

I encounter the same problem in a Windows executable generated by pyinstaller.
pyinstaller build.spec, where build.spec has console=False in exe = EXE(pyz,.... If I change to console=True, the problem goes away, however, when built with console=True the executable runs with an annoying second console window, which stays empty.

@aphshir I can not reproduce this. It works fine on my machine using python v3.11.1. Please provide more details, if possible even a completly reproducable example.

Python 3.11.1 (tags/v3.11.1:a7a450f, Dec  6 2022, 19:58:39) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import inquirer
>>>

@iva2k this is most likly not related. Your problem probably comes from pyinstaller not linking all dependencys into the execuable-package, depending on the mode you use. You probably have to provide it which modules are needed / where to find the packages. But here are also more details required.

iva2k commented

@Cube707 - please read the log pasted in OP. I have an identical log. Nowhere there is a missing import. It unwinds the imports tree from the line import inquirer in the source file, all the way to site-packages\blessed\terminal.py which appears as a dependency of inquirer, and crashes there. I checked - the line is there and it tries to access sys.__stdout__.fileno(), which is present if pyinstaller is built with console=True, and None if console=False. The trick here if I remove inquirer (and the line that uses it eventually), the script works fine without console=True.

I can buy that the issue is not with inquirer package directly, but with blessed package. Specifically, the way it loads and starts messing around right there in the __init__'s trying to open stdout even before anything is invoked is troublesome. At a minimum, blessed should be checking if stdout is present in the things it reaches to mess with when it is imported. It's probably worth bringing it up with blessed package maintainers. On the inquirer package side it is worth noting such undesirable behavior of imported package, and try to deal with it too.

As for a repro - I can't publish a confidential tool it happens in, but can give a stack used:

  • Windows 10
  • pyinstaller build
  • gooey GUI wrapper on top of a
  • regular CLI script
  • which has import inquirer

I'm pretty sure that for this particular case all ingredients are important to trigger this issue.

For this particular case, inquirer is invoked when CLI is run without Gooey, and works fine. It does not fail when I run Gooey wrapper in VSCode Python (import does not fail). But from pyinstaller it does not load with the OP's error when console=False. Luckily, given that I don't really need inquirer in GUI/pyinstaller use, I solved the issue by moving import inquirer into the pure CLI function, so pyinstaller/Gooey is working now.

What I suspect is happening, pyinstaller meddles with stdio/stderr one way, and Gooey meddles with them another way, so the stack still works, and Gooey can intercept the streams. All meddling of Gooey is probably done on sys.stdio, and pyinstaller probably does this on system/process level since it runs python in standalone exacutable, and as net total they don't leave sys.__stdout__ functional, which is probably None due to pyinstaller console=False.

@iva2k ah, now I get whats happening. This is absolutely expected behaviour and (also as expected) is unrelated to OPs problem with the new python version 3.11.

You disable the console and therefor remove stout, but inquire is a tool that heavily works with stdout. This should most defnetly fail, as inquire is unusable without access to stdout.

We could catch the error and provide our own error messages, but as inquire is alwasy described as a tool designed for use inside a console, I don't really see many people having this issue besides you.

The solution for you would be to import depending on your configuration, of you build a GUI version of your app, don't import inquire, it wont be used anyways... if you build the comandline version, than you import.

If you still require more help, please raise a seperate issue for your exact problem

iva2k commented

I chimed in here as exact the same error line points to exactly the same root cause - absence of sys.stdout.

In my case I don't need a solution (I found a sensible workaround).

Still, crashing on import XXX is not a good practice, whatever the reason might be. Moving these things into class init or other similar solution should be used.

For OP's issue, I would debug the sys.stdout and sys.__stdout__ - if they are not set for some reason, there might be something specific to the way the script is invoked, and OP did not provide much info on environment, invoking command, or script itself.

closing due to inactivity and probably no longer relevant

@aphshir feel free to reopen if you still have the issue

HI I want to aplogoize for my inactivity @Cube707 I have a lot of work and totaly forgot to look at my notifications. the probelms ocures when I'm improting the modul. there is no more code or anything. I do it like that on idle :
image

@aphshir please confirm its not a IDLE issue by running from inside a simple CMD window.

python -c "import inquirer"

should throw the same error you got if its not related to IDLE

Also you might consider updating to python v3.11.1, that version worked on my system.

But I will also try running v3.11.0 like you have later.

@aphshir please confirm its not a IDLE issue by running from inside a simple CMD window.

python -c "import inquirer"

should throw the same error you got if its not related to IDLE

I am dumb it is an Idle error thanks for the help I appreciate !