From d784a14eebda3a3342d36348bfb7264cd26bedc9 Mon Sep 17 00:00:00 2001 From: Dan LaManna Date: Mon, 1 Jul 2024 10:00:54 -0400 Subject: [PATCH] Encode metadata to stdout as utf8 This fixes a regression from #79. --- isic_cli/cli/metadata.py | 10 +++++----- tests/conftest.py | 10 ++++++++++ tests/test_cli_metadata.py | 25 +++++++++++++++++++------ tox.ini | 1 + 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/isic_cli/cli/metadata.py b/isic_cli/cli/metadata.py index 709e567..983b809 100644 --- a/isic_cli/cli/metadata.py +++ b/isic_cli/cli/metadata.py @@ -201,11 +201,11 @@ def download( headers, records = _extract_metadata(images, progress, task) if records: - stream = ( - sys.stdout - if outfile is None or os.fsdecode(outfile) == "-" - else Path(outfile).open("w", newline="", encoding="utf8") # noqa: SIM115 - ) + if outfile is None or os.fsdecode(outfile) == "-": + sys.stdout.reconfigure(encoding="utf8") + stream = sys.stdout + else: + stream = Path(outfile).open("w", newline="", encoding="utf8") # noqa: SIM115 writer = csv.DictWriter(stream, headers) writer.writeheader() diff --git a/tests/conftest.py b/tests/conftest.py index de6c593..1ec0c87 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,11 +18,21 @@ def runner(): return CliRunner() +@pytest.fixture() +def runner_non_utf8(): + return CliRunner(charset="cp1251") + + @pytest.fixture() def cli_run(runner): return functools.partial(runner.invoke, cli) +@pytest.fixture() +def cli_run_non_utf8(runner_non_utf8): + return functools.partial(runner_non_utf8.invoke, cli) + + @pytest.fixture() def _isolated_filesystem(runner): with runner.isolated_filesystem(): diff --git a/tests/test_cli_metadata.py b/tests/test_cli_metadata.py index 66cd723..a932293 100644 --- a/tests/test_cli_metadata.py +++ b/tests/test_cli_metadata.py @@ -4,6 +4,7 @@ import re import pytest +from pytest_lazy_fixtures import lf @pytest.fixture() @@ -60,15 +61,23 @@ def test_metadata_validate_lesions_patients(runner, cli_run): @pytest.mark.usefixtures("_mock_image_metadata") -def test_metadata_download_stdout(cli_run): - result = cli_run(["metadata", "download"]) +@pytest.mark.parametrize( + "cli_runner", + [lf("cli_run"), lf("cli_run_non_utf8")], +) +def test_metadata_download_stdout(cli_runner): + result = cli_runner(["metadata", "download"]) assert result.exit_code == 0, result.exception assert re.search(r"ISIC_0000000.*Foo.*CC-0.*melanoma.*male", result.output), result.output @pytest.mark.usefixtures("_mock_image_metadata", "_isolated_filesystem") -def test_metadata_download_file(cli_run): - result = cli_run(["metadata", "download", "-o", "foo.csv"]) +@pytest.mark.parametrize( + "cli_runner", + [lf("cli_run"), lf("cli_run_non_utf8")], +) +def test_metadata_download_file(cli_runner): + result = cli_runner(["metadata", "download", "-o", "foo.csv"]) assert result.exit_code == 0, result.exception @@ -79,8 +88,12 @@ def test_metadata_download_file(cli_run): @pytest.mark.usefixtures("_mock_image_metadata") -def test_metadata_download_newlines(cli_run, mocker): - result = cli_run(["metadata", "download", "-o", "foo.csv"]) +@pytest.mark.parametrize( + "cli_runner", + [lf("cli_run"), lf("cli_run_non_utf8")], +) +def test_metadata_download_newlines(cli_runner, mocker): + result = cli_runner(["metadata", "download", "-o", "foo.csv"]) assert result.exit_code == 0, result.exception diff --git a/tox.ini b/tox.ini index ba6dc9e..d3a3183 100644 --- a/tox.ini +++ b/tox.ini @@ -16,6 +16,7 @@ commands = [testenv:test] deps = pytest + pytest-lazy-fixtures pytest-mock commands = pytest {posargs}