Skip to content
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

[BUG] AttributeError using Console.capture when run with pythonw #2400

Closed
Lx opened this issue Jul 17, 2022 · 7 comments · Fixed by #2513
Closed

[BUG] AttributeError using Console.capture when run with pythonw #2400

Lx opened this issue Jul 17, 2022 · 7 comments · Fixed by #2513
Assignees
Labels
bug Something isn't working

Comments

@Lx
Copy link

Lx commented Jul 17, 2022

Describe the bug

This code, when run using pythonw:

table = Table(box=DOUBLE_EDGE)
printer = Console(force_terminal=False)
with printer.capture() as capture:
    printer.print(table)

fails with this stack trace:

Traceback (most recent call last):
  File "<MY CODE>", line ...
    with printer.capture() as capture:
  File "rich\console.py", line 336, in __exit__
    self._result = self._console.end_capture()
  File "rich\console.py", line 852, in end_capture
    self._exit_buffer()
  File "rich\console.py", line 796, in _exit_buffer
    self._check_buffer()
  File "rich\console.py", line 1979, in _check_buffer
    self.file.fileno() in _STD_STREAMS_OUTPUT
AttributeError: 'NoneType' object has no attribute 'fileno'

My guess is that pythonw causes Console to get some attributes that are usually not null, but in this case, are.

I can probably immediately work around this by instantiating the Console like so:

table = Table(box=DOUBLE_EDGE)
capture = StringIO()
printer = Console(file=capture)
printer.print(table)

but Rich could probably cater for the Console instance having no STDOUT in some cases (such as above).

Platform

  • Windows 10
  • Python v3.10.0

I've avoided including details generated by python -m rich.diagnose because more diagnostic information would be provided using pythonw ...—but of course, since it disables STDOUT, there's no obvious way to grab that info for you. 🤣

@willmcgugan
Copy link
Collaborator

I don't have a Windows box handy. What happens if you run a script with pythonw that does print("hello world") ?

@Lx
Copy link
Author

Lx commented Jul 19, 2022

Hi Will. There is no output. I somewhat expected this as I believe pythonw nullifies its STDOUT handle.

@willmcgugan
Copy link
Collaborator

And is that the behaviour you would expect from Rich? To silently ignore the error?

Could you paste the full traceback?

@Lx
Copy link
Author

Lx commented Jul 22, 2022

To frame my expected behaviour in a slightly alternative manner:

  • When I instantiate a Console purely for the purpose of capture-ing its output to a variable, I would expect Rich not to fail when STDOUT is redirected to null (which is what pythonw appears to do)—particularly since I would expect STDOUT not to be getting used as part of that capturing operation.

Directly answering your question though: yes, I believe there should be no error.

The traceback above is complete except for my calling code, which is no different from the example given.

@willmcgugan
Copy link
Collaborator

I see. So the error occurs regardless of if you are printing to stdout or not.

You didn't include the full traceback btw. The error message would help.

@Lx
Copy link
Author

Lx commented Jul 23, 2022

Yes, the error is occurring despite no intent to print to STDOUT.

Sorry, you're absolutely right: I did fail to paste the actual error message. I've edited that in to the earlier message now, but here's the entire thing from my logging anyway for good measure, in case any of the other bits do actually help:

2022-07-17 15:35:48,860 ERROR    [ClientWorkerThread/ductus.client.gui.eventloopthread.ThreadedEventLoop] exception in asyncio event loop
Traceback (most recent call last):
  File "C:\Users\kate\AppData\Local\Programs\Ductus\ductus\client\gui\eventloopthread.py", line 54, in __thread_main
    asyncio.run(self.__run_coro_cancellable(), debug=True)
  File "C:\Program Files\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
    return future.result()
  File "C:\Users\kate\AppData\Local\Programs\Ductus\ductus\client\gui\eventloopthread.py", line 76, in __run_coro_cancellable
    await await_task
  File "C:\Users\kate\AppData\Local\Programs\Ductus\ductus\client\gui\worker.py", line 85, in __loop_tasks
    await asyncio.gather(
  File "C:\Users\kate\AppData\Local\Programs\Ductus\ductus\client\gui\worker.py", line 128, in __watch_for_auth_requests
    await self.client.google_auth()
  File "C:\Users\kate\AppData\Local\Programs\Ductus\ductus\client\client.py", line 119, in google_auth
    creds = await asyncio.to_thread(google_auth_flow)
  File "C:\Program Files\Python310\lib\asyncio\threads.py", line 25, in to_thread
    return await loop.run_in_executor(None, func_call)
  File "C:\Program Files\Python310\lib\concurrent\futures\thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "C:\Users\kate\AppData\Local\Programs\Ductus\ductus\client\googleauth.py", line 43, in google_auth_flow
    success_message=_browser_finish_message(),
  File "C:\Users\kate\AppData\Local\Programs\Ductus\ductus\client\googleauth.py", line 75, in _browser_finish_message
    with printer.capture() as capture:
  File "...\rich\console.py", line 336, in __exit__
    self._result = self._console.end_capture()
  File "...\rich\console.py", line 852, in end_capture
    self._exit_buffer()
  File "...\rich\console.py", line 796, in _exit_buffer
    self._check_buffer()
  File "...\rich\console.py", line 1979, in _check_buffer
    self.file.fileno() in _STD_STREAMS_OUTPUT
AttributeError: 'NoneType' object has no attribute 'fileno'

In particular, Console is treating its file attribute as if it will never be None. When run under pythonw however, that's exactly what it's defaulting to. Even so though, in my example, there's no obvious reason for self.file to be getting called.

@willmcgugan willmcgugan added bug Something isn't working and removed Needs triage labels Aug 5, 2022
@darrenburns darrenburns self-assigned this Aug 9, 2022
@darrenburns darrenburns linked a pull request Sep 8, 2022 that will close this issue
9 tasks
@github-actions
Copy link

github-actions bot commented Sep 8, 2022

Did I solve your problem?

Why not buy the devs a coffee to say thanks?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants