Search code examples
pythonpython-idle

How to fix this AttributeError: 'NoneType' object has no attribute 'fileno' in Python3.8


I am using the Pick package to create a curses-based interactive selection list in my IDLE terminal. This is the code I currenty have:

from pick import pick
title = 'Please choose your favorite programming language: '
options = ['Java', 'JavaScript', 'Python', 'PHP', 'C++', 'Erlang', 'Haskell']
option, index = pick(options, title)
print(option)
print(index)

However, I am running into the following error:

Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> 
= RESTART: C:\Users\haneg\OneDrive\Documents\Python-Scripts\Restrictieenzymen.py
---
Traceback (most recent call last):
  File "C:\Users\haneg\OneDrive\Documents\Python-Scripts\Restrictieenzymen.py", line 5, in <module>
    option, index = pick(options, title)
  File "C:\Users\haneg\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pick\__init__.py", line 195, in pick
    return picker.start()
  File "C:\Users\haneg\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\pick\__init__.py", line 181, in start
    return curses.wrapper(self._start)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1520.0_x64__qbz5n2kfra8p0\lib\curses\__init__.py", line 84, in wrapper
    stdscr = initscr()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1520.0_x64__qbz5n2kfra8p0\lib\curses\__init__.py", line 30, in initscr
    fd=_sys.__stdout__.fileno())
AttributeError: 'NoneType' object has no attribute 'fileno'

If I run this code directly in Python, without IDLE, I do not get this error. Does anyone have any suggestions on how to fix this problem? Any help is appreciated!


Solution

  • IDLE is involved but only as a GUI app not normally started from a command line.

    1. The immediate bug is trying to access .fileno without catching the AttributeError and exiting gracefully. You could mention this to pick people. This situation is not unique to IDLE.

    2. The deeper error is trying to run curses in an environment where the error occurs. The circumstance of sys.stdxxx being none in mentioned in the IDLE doc. You can fix this by starting IDLE in a console with > python -m idlelib. (This should be clearer in the doc.) When I do so on Windows, I get the expected fileno.

        >>> import sys;
        >>> sys.__stderr__.fileno()
        2
    
    1. The stdlib curses is documented as Unix-only. If pick runs on Windows, it must include something sufficient for its needs.

    Running from Command Prompt or PowerShell should suffice for you, but I have two additional ideas to help others in the future. I am noting this here to not forget.

    1. Add a new mechanism to check error class and message. For this case, ff AttributeError and template matches and object is Nonetype and attribute is std stream attribute, add an IDLE-specific addendum suggesting fixes.

    2. Add an option to the newish Run => Run ... customized menu dialog to run in a system terminal (for those who did not start IDLE in a terminal). My first attempt at this failed, but this question add another use case. So I should try again.