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] UnicodeEncodeError on Windows with ruler. #2411

Closed
tobiasraabe opened this issue Jul 20, 2022 · 8 comments
Closed

[BUG] UnicodeEncodeError on Windows with ruler. #2411

tobiasraabe opened this issue Jul 20, 2022 · 8 comments
Labels
bug Something isn't working

Comments

@tobiasraabe
Copy link

tobiasraabe commented Jul 20, 2022

Describe the bug

The issue started appearing in my test suite, and I could boil it down to this reproducible example. I am using rich 12.5.1.

# Content of script.py.

from rich.console import Console


if __name__ == '__main__':
    console = Console()
    console.rule()  # or console.print("─")
# Content of run.py.

import subprocess

result = subprocess.run(("python", "rich_script.py"), check=True)

and then I am executing pytest run.py, which results in

Click to expand
================================================= test session starts =================================================
platform win32 -- Python 3.10.5, pytest-7.1.2, pluggy-1.0.0
rootdir: C:\Users\TobiasR\git\pytask, configfile: tox.ini
plugins: anyio-3.6.1, cov-3.0.0, forked-1.4.0, xdist-2.5.0
collected 0 items / 2 errors

======================================================= ERRORS ========================================================
_______________________________________________ ERROR collecting run.py _______________________________________________
run.py:3: in <module>
    result = subprocess.run(("python", "rich_script.py"), check=True)
C:\tools\miniconda3\envs\pytask\lib\subprocess.py:524: in run
    raise CalledProcessError(retcode, process.args,
E   subprocess.CalledProcessError: Command '('python', 'rich_script.py')' returned non-zero exit status 1.
--------------------------------------------------- Captured stderr ---------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\TobiasR\git\pytask\rich_script.py", line 6, in <module>
    console.rule()
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 1553, in rule
    self.print(rule)
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 1646, in print
    with self:
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 848, in __exit__
    self._exit_buffer()
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 806, in _exit_buffer
    self._check_buffer()
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 1999, in _check_buffer
    legacy_windows_render(
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\_windows_renderer.py", line 17, in legacy_windows_render
    term.write_styled(text, style)
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\_win32_console.py", line 442, in write_styled
    self.write_text(text)
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\_win32_console.py", line 403, in write_text
    self.write(text)
  File "C:\tools\miniconda3\envs\pytask\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-78: character maps to <undefined>
_______________________________________________ ERROR collecting run.py _______________________________________________
run.py:3: in <module>
    result = subprocess.run(("python", "rich_script.py"), check=True)
C:\tools\miniconda3\envs\pytask\lib\subprocess.py:524: in run
    raise CalledProcessError(retcode, process.args,
E   subprocess.CalledProcessError: Command '('python', 'rich_script.py')' returned non-zero exit status 1.
--------------------------------------------------- Captured stderr ---------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\TobiasR\git\pytask\rich_script.py", line 6, in <module>
    console.rule()
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 1553, in rule
    self.print(rule)
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 1646, in print
    with self:
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 848, in __exit__
    self._exit_buffer()
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 806, in _exit_buffer
    self._check_buffer()
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\console.py", line 1999, in _check_buffer
    legacy_windows_render(
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\_windows_renderer.py", line 17, in legacy_windows_render
    term.write_styled(text, style)
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\_win32_console.py", line 442, in write_styled
    self.write_text(text)
  File "C:\tools\miniconda3\envs\pytask\lib\site-packages\rich\_win32_console.py", line 403, in write_text
    self.write(text)
  File "C:\tools\miniconda3\envs\pytask\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-78: character maps to <undefined>
=============================================== short test summary info ===============================================
ERROR run.py - subprocess.CalledProcessError: Command '('python', 'rich_script.py')' returned non-zero exit status 1.
ERROR run.py - subprocess.CalledProcessError: Command '('python', 'rich_script.py')' returned non-zero exit status 1.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 2 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================== 2 errors in 0.72s ==================================================

The error does not occur when I

  • switch to rich 12.4.4 or ...
  • set PYTHONIOENCODING to utf-8 or ...
  • execute python run.py

Platform

Click to expand

The issue occurred only on Windows and I am running Powershell Core embedded in Windows Terminal.

python -m rich.diagnose
pip freeze | grep rich
╭───────────────────────── <class 'rich.console.Console'> ─────────────────────────╮
│ A high level console interface.                                                  │
│                                                                                  │
│ ╭──────────────────────────────────────────────────────────────────────────────╮ │
│ │ <console width=120 ColorSystem.TRUECOLOR>                                    │ │
│ ╰──────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                  │
│     color_system = 'truecolor'                                                   │
│         encoding = 'utf-8'                                                       │
│             file = <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'> │
│           height = 30                                                            │
│    is_alt_screen = False                                                         │
│ is_dumb_terminal = False                                                         │
│   is_interactive = True                                                          │
│       is_jupyter = False                                                         │
│      is_terminal = True                                                          │
│   legacy_windows = False                                                         │
│         no_color = False                                                         │
│          options = ConsoleOptions(                                               │
│                        size=ConsoleDimensions(width=120, height=30),             │
│                        legacy_windows=False,                                     │
│                        min_width=1,                                              │
│                        max_width=120,                                            │
│                        is_terminal=True,                                         │
│                        encoding='utf-8',                                         │
│                        max_height=30,                                            │
│                        justify=None,                                             │
│                        overflow=None,                                            │
│                        no_wrap=False,                                            │
│                        highlight=None,                                           │
│                        markup=None,                                              │
│                        height=None                                               │
│                    )                                                             │
│            quiet = False                                                         │
│           record = False                                                         │
│         safe_box = True                                                          │
│             size = ConsoleDimensions(width=120, height=30)                       │
│        soft_wrap = False                                                         │
│           stderr = False                                                         │
│            style = None                                                          │
│         tab_size = 8                                                             │
│            width = 120                                                           │
╰──────────────────────────────────────────────────────────────────────────────────╯
╭── <class 'rich._windows.WindowsConsoleFeatures'> ───╮
│ Windows features available.                         │
│                                                     │
│ ╭─────────────────────────────────────────────────╮ │
│ │ WindowsConsoleFeatures(vt=True, truecolor=True) │ │
│ ╰─────────────────────────────────────────────────╯ │
│                                                     │
│ truecolor = True                                    │
│        vt = True                                    │
╰─────────────────────────────────────────────────────╯
╭────── Environment Variables ───────╮
│ {                                  │
│     'TERM': None,                  │
│     'COLORTERM': None,             │
│     'CLICOLOR': None,              │
│     'NO_COLOR': None,              │
│     'TERM_PROGRAM': None,          │
│     'COLUMNS': None,               │
│     'LINES': None,                 │
│     'JUPYTER_COLUMNS': None,       │
│     'JUPYTER_LINES': None,         │
│     'JPY_PARENT_PID': None,        │
│     'VSCODE_VERBOSE_LOGGING': None │
│ }                                  │
╰────────────────────────────────────╯
platform="Windows"
@willmcgugan
Copy link
Collaborator

Not the first time we've been bitten by Windows CP-1252 encoding.

The solution may be to force utf8

@willmcgugan willmcgugan reopened this Aug 5, 2022
@Textualize Textualize deleted a comment from github-actions bot Aug 5, 2022
@darrenburns
Copy link
Member

darrenburns commented Aug 5, 2022

I can't reproduce this. Running the same Python version, Rich version, tried legacy/non-legacy terminals, tried forcing the encoding to cp1252 and utf-8, tried with an without running in a subprocess. Every time the rule renders without an error. I'm not sure where else the difference could lie 🤔

It's interesting that you've supplied the example as a subprocess - is that because you can only reproduce the issue when you run it in a subprocess?

I noticed in the "Platform" information you shared, legacy_windows = False, yet the code path which raises the error implies that legacy_windows = True. I wonder if for some reason, the console reports legacy Windows in the subprocess but not in the parent process? Regardless, I can't reproduce even when I force legacy and cp1252 on my end, so I'm stumped at the moment!

Also, comparing the version that works with you with the latest version, I can't see any relevant (encoding-related) changes at all: v12.4.4...v12.5.1

@tobiasraabe
Copy link
Author

Yes, this error only occurs when I am using pytest to execute the subprocess script with pytest run.py. python run.py works. So, for me, it seemed like pytest influences which console settings are detected in the subprocess.

@ubaumann
Copy link
Contributor

ubaumann commented Aug 5, 2022

I also had it after an update in my windows tests in github
https://github.com/InfrastructureAsCode-ch/nornir_rich/runs/7483512482?check_suite_focus=true

I am using PYTHONIOENCODING: utf-8 at the moment and it works fine but for me on windows pytest . worked well. So I have the problam only in the workflow on GitHub

@willmcgugan
Copy link
Collaborator

For tests, you probably want to set legacy_windows to True or False, so you aren't at the mercy of the environment. Ditto with the other parameters that auto-detect.

@github-actions
Copy link

Did I solve your problem?

Why not buy the devs a coffee to say thanks?

@mattip
Copy link

mattip commented Dec 16, 2022

I am seeing this in a azure pipelines run of a conda-forge feedstock. Should I open another issue? Relevant bits:

Python 3.8, rich 12.6.0-pyhd8ed1ab_0 from conda-forge.

ConsoleOptions

From this log

| | render_options = ConsoleOptions(                                        | |
| |                      size=ConsoleDimensions(width=79, height=25),       | |
| |                      legacy_windows=True,                               | |
| |                      min_width=1,                                       | |
| |                      max_width=79,                                      | |
| |                      is_terminal=False,                                 | |
| |                      encoding='cp1252',                                 | |
| |                      max_height=25,                                     | |
| |                      justify=None,                                      | |
| |                      overflow=None,                                     | |
| |                      no_wrap=None,                                      | |
| |                      highlight=None,                                    | |
| |                      markup=None,                                       | |
| |                      height=None                                        | |
| |                  )                                                      | |

when rendering this string

text = '.                                                  \u2554\u2584\u2593\u2593\u2593\u2593\u2584'

@ManchurianMan
Copy link

This is still an issue. In CP1252 encoding (which is what the :! operator in nvim uses) console.print(Rule()) and console.rule() throw an error when no title is provided. They work fine with a title provided.

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

No branches or pull requests

6 participants