From 7db4c0a3f797096fcf335a3a6b66bc9135a1f00b Mon Sep 17 00:00:00 2001 From: Dan Yeaw Date: Sun, 21 Jan 2024 15:19:44 -0500 Subject: [PATCH] Fix encoding warnings with PEP 597 enabled --- .github/workflows/tests.yaml | 3 +++ src/poetry/masonry/builders/editable.py | 7 +++--- .../repositories/installed_repository.py | 3 ++- src/poetry/utils/_compat.py | 9 +++++++ src/poetry/utils/env/base_env.py | 3 ++- src/poetry/utils/env/virtual_env.py | 2 +- src/poetry/utils/setup_reader.py | 0 tests/console/commands/env/test_remove.py | 13 ++++++---- tests/console/commands/self/test_install.py | 2 +- .../commands/self/test_self_command.py | 12 ++++++---- tests/console/commands/test_init.py | 24 +++++++++++-------- tests/console/commands/test_new.py | 2 +- tests/console/commands/test_version.py | 4 ++-- tests/inspection/test_info.py | 21 ++++++++++------ tests/installation/test_wheel_installer.py | 2 +- .../masonry/builders/test_editable_builder.py | 20 +++++++++------- tests/pyproject/conftest.py | 6 ++--- tests/pyproject/test_pyproject_toml_file.py | 2 +- tests/utils/env/test_env.py | 5 ++-- tests/utils/test_cache.py | 11 +++++---- tests/vcs/git/test_system.py | 5 ++-- 21 files changed, 99 insertions(+), 57 deletions(-) create mode 100644 src/poetry/utils/setup_reader.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 24da58132ad..dbf4e046f6c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -13,6 +13,9 @@ defaults: run: shell: bash +env: + PYTHONWARNDEFAULTENCODING: 'true' + jobs: changes: name: Detect changed files diff --git a/src/poetry/masonry/builders/editable.py b/src/poetry/masonry/builders/editable.py index 93c06a7e729..6a077af7d77 100644 --- a/src/poetry/masonry/builders/editable.py +++ b/src/poetry/masonry/builders/editable.py @@ -3,7 +3,6 @@ import csv import hashlib import json -import locale import os from base64 import urlsafe_b64encode @@ -16,6 +15,7 @@ from poetry.utils._compat import WINDOWS from poetry.utils._compat import decode +from poetry.utils._compat import getencoding from poetry.utils.env import build_environment from poetry.utils.helpers import is_dir_writable from poetry.utils.pip import pip_install @@ -125,7 +125,7 @@ def _add_pth(self) -> list[Path]: try: pth_file = self._env.site_packages.write_text( - pth_file, content, encoding=locale.getpreferredencoding() + pth_file, content, encoding=getencoding() ) self._debug( f" - Adding {pth_file.name} to {pth_file.parent} for" @@ -252,7 +252,8 @@ def _add_dist_info(self, added_files: list[Path]) -> None: "dir_info": {"editable": True}, "url": self._poetry.file.path.parent.absolute().as_uri(), } - ) + ), + encoding="utf-8", ) added_files.append(direct_url_json) diff --git a/src/poetry/repositories/installed_repository.py b/src/poetry/repositories/installed_repository.py index 1eb6b1d9742..07a92156a19 100644 --- a/src/poetry/repositories/installed_repository.py +++ b/src/poetry/repositories/installed_repository.py @@ -13,6 +13,7 @@ from poetry.core.utils.helpers import module_name from poetry.repositories.repository import Repository +from poetry.utils._compat import getencoding from poetry.utils._compat import metadata @@ -58,7 +59,7 @@ def get_package_paths(cls, env: Env, name: str) -> set[Path]: if not pth_file.exists(): continue - with pth_file.open() as f: + with pth_file.open(encoding=getencoding()) as f: for line in f: line = line.strip() if line and not line.startswith(("#", "import ", "import\t")): diff --git a/src/poetry/utils/_compat.py b/src/poetry/utils/_compat.py index f2d6157343f..6781096ddaf 100644 --- a/src/poetry/utils/_compat.py +++ b/src/poetry/utils/_compat.py @@ -1,5 +1,6 @@ from __future__ import annotations +import locale import sys from contextlib import suppress @@ -52,6 +53,13 @@ def encode(string: str, encodings: list[str] | None = None) -> bytes: return string.encode(encodings[0], errors="ignore") +def getencoding() -> str: + if sys.version_info < (3, 11): + return locale.getpreferredencoding() + else: + return locale.getencoding() + + def is_relative_to(this: Path, other: Path) -> bool: """ Return whether `this` path is relative to the `other` path. This is compatibility wrapper around @@ -72,6 +80,7 @@ def is_relative_to(this: Path, other: Path) -> bool: "WINDOWS", "decode", "encode", + "getencoding", "is_relative_to", "metadata", "tomllib", diff --git a/src/poetry/utils/env/base_env.py b/src/poetry/utils/env/base_env.py index f4e87d5a5fb..5a8f2fc6146 100644 --- a/src/poetry/utils/env/base_env.py +++ b/src/poetry/utils/env/base_env.py @@ -330,8 +330,9 @@ def _run(self, cmd: list[str], **kwargs: Any) -> str: subprocess.check_call(cmd, stderr=stderr, env=env, **kwargs) output = "" else: + encoding = "locale" if sys.version_info >= (3, 10) else None output = subprocess.check_output( - cmd, stderr=stderr, env=env, text=True, **kwargs + cmd, stderr=stderr, env=env, text=True, encoding=encoding, **kwargs ) except CalledProcessError as e: raise EnvCommandError(e) diff --git a/src/poetry/utils/env/virtual_env.py b/src/poetry/utils/env/virtual_env.py index 9a8680aaefa..22fd0f91415 100644 --- a/src/poetry/utils/env/virtual_env.py +++ b/src/poetry/utils/env/virtual_env.py @@ -136,7 +136,7 @@ def includes_system_site_packages(self) -> bool: return pyvenv_cfg.exists() and ( re.search( r"^\s*include-system-site-packages\s*=\s*true\s*$", - pyvenv_cfg.read_text(), + pyvenv_cfg.read_text(encoding="utf-8"), re.IGNORECASE | re.MULTILINE, ) is not None diff --git a/src/poetry/utils/setup_reader.py b/src/poetry/utils/setup_reader.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/console/commands/env/test_remove.py b/tests/console/commands/env/test_remove.py index 8b2163369f3..04d839f235c 100644 --- a/tests/console/commands/env/test_remove.py +++ b/tests/console/commands/env/test_remove.py @@ -76,13 +76,18 @@ def test_remove_all( if envs_file == "empty": envs_file_path.touch() elif envs_file == "self": - envs_file_path.write_text(f'[{venv_name}]\nminor = "3.9"\npatch = "3.9.1"\n') + envs_file_path.write_text( + f'[{venv_name}]\nminor = "3.9"\npatch = "3.9.1"\n', encoding="utf-8" + ) elif envs_file == "other": - envs_file_path.write_text('[other-abcdefgh]\nminor = "3.9"\npatch = "3.9.1"\n') + envs_file_path.write_text( + '[other-abcdefgh]\nminor = "3.9"\npatch = "3.9.1"\n', encoding="utf-8" + ) elif envs_file == "self_and_other": envs_file_path.write_text( f'[{venv_name}]\nminor = "3.9"\npatch = "3.9.1"\n' - '[other-abcdefgh]\nminor = "3.9"\npatch = "3.9.1"\n' + '[other-abcdefgh]\nminor = "3.9"\npatch = "3.9.1"\n', + encoding="utf-8", ) else: # no envs file -> nothing to prepare @@ -97,7 +102,7 @@ def test_remove_all( if envs_file is not None: assert envs_file_path.exists() - envs_file_content = envs_file_path.read_text() + envs_file_content = envs_file_path.read_text(encoding="utf-8") assert venv_name not in envs_file_content if "other" in envs_file: assert "other-abcdefgh" in envs_file_content diff --git a/tests/console/commands/self/test_install.py b/tests/console/commands/self/test_install.py index 3490a2e7bdd..b9cbbb59dc4 100644 --- a/tests/console/commands/self/test_install.py +++ b/tests/console/commands/self/test_install.py @@ -45,7 +45,7 @@ def test_self_install( assert isinstance(command, SelfInstallCommand) pyproject_path = command.system_pyproject if pyproject_content: - pyproject_path.write_text(pyproject_content) + pyproject_path.write_text(pyproject_content, encoding="utf-8") else: assert not pyproject_path.exists() diff --git a/tests/console/commands/self/test_self_command.py b/tests/console/commands/self/test_self_command.py index 7abf266ed7e..e38cee61873 100644 --- a/tests/console/commands/self/test_self_command.py +++ b/tests/console/commands/self/test_self_command.py @@ -29,9 +29,11 @@ def test_generate_system_pyproject_trailing_newline( example_system_pyproject: str, ) -> None: cmd = SelfCommand() - cmd.system_pyproject.write_text(example_system_pyproject + "\n" * existing_newlines) + cmd.system_pyproject.write_text( + example_system_pyproject + "\n" * existing_newlines, encoding="utf-8" + ) cmd.generate_system_pyproject() - generated = cmd.system_pyproject.read_text() + generated = cmd.system_pyproject.read_text(encoding="utf-8") assert len(generated) - len(generated.rstrip("\n")) == existing_newlines @@ -40,10 +42,12 @@ def test_generate_system_pyproject_carriage_returns( example_system_pyproject: str, ) -> None: cmd = SelfCommand() - cmd.system_pyproject.write_text(example_system_pyproject + "\n") + cmd.system_pyproject.write_text(example_system_pyproject + "\n", encoding="utf-8") cmd.generate_system_pyproject() - with open(cmd.system_pyproject, newline="") as f: # do not translate newlines + with open( + cmd.system_pyproject, newline="", encoding="utf-8" + ) as f: # do not translate newlines generated = f.read() assert "\r\r" not in generated diff --git a/tests/console/commands/test_init.py b/tests/console/commands/test_init.py index 2f8ddbce675..aa1a2fff557 100644 --- a/tests/console/commands/test_init.py +++ b/tests/console/commands/test_init.py @@ -91,7 +91,7 @@ def test_noninteractive( assert tester.io.fetch_output() == expected assert tester.io.fetch_error() == "" - toml_content = (tmp_path / "pyproject.toml").read_text() + toml_content = (tmp_path / "pyproject.toml").read_text(encoding="utf-8") assert 'name = "my-package"' in toml_content assert 'pytest = "^3.6.0"' in toml_content @@ -853,9 +853,11 @@ def test_init_existing_pyproject_simple( [tool.black] line-length = 88 """ - pyproject_file.write_text(existing_section) + pyproject_file.write_text(existing_section, encoding="utf-8") tester.execute(inputs=init_basic_inputs) - assert f"{existing_section}\n{init_basic_toml}" in pyproject_file.read_text() + assert f"{existing_section}\n{init_basic_toml}" in pyproject_file.read_text( + encoding="utf-8" + ) @pytest.mark.parametrize("linesep", ["\n", "\r\n"]) @@ -871,10 +873,10 @@ def test_init_existing_pyproject_consistent_linesep( [tool.black] line-length = 88 """.replace("\n", linesep) - with open(pyproject_file, "w", newline="") as f: + with open(pyproject_file, "w", newline="", encoding="utf-8") as f: f.write(existing_section) tester.execute(inputs=init_basic_inputs) - with open(pyproject_file, newline="") as f: + with open(pyproject_file, newline="", encoding="utf-8") as f: content = f.read() init_basic_toml = init_basic_toml.replace("\n", linesep) assert f"{existing_section}{linesep}{init_basic_toml}" in content @@ -891,7 +893,7 @@ def test_init_non_interactive_existing_pyproject_add_dependency( [tool.black] line-length = 88 """ - pyproject_file.write_text(existing_section) + pyproject_file.write_text(existing_section, encoding="utf-8") repo.add_package(get_package("foo", "1.19.2")) @@ -915,7 +917,9 @@ def test_init_non_interactive_existing_pyproject_add_dependency( python = "^3.6" foo = "^1.19.2" """ - assert f"{existing_section}\n{expected}" in pyproject_file.read_text() + assert f"{existing_section}\n{expected}" in pyproject_file.read_text( + encoding="utf-8" + ) def test_init_existing_pyproject_with_build_system_fails( @@ -927,13 +931,13 @@ def test_init_existing_pyproject_with_build_system_fails( requires = ["setuptools >= 40.6.0", "wheel"] build-backend = "setuptools.build_meta" """ - pyproject_file.write_text(existing_section) + pyproject_file.write_text(existing_section, encoding="utf-8") tester.execute(inputs=init_basic_inputs) assert ( tester.io.fetch_error().strip() == "A pyproject.toml file with a defined build-system already exists." ) - assert existing_section in pyproject_file.read_text() + assert existing_section in pyproject_file.read_text(encoding="utf-8") @pytest.mark.parametrize( @@ -1069,7 +1073,7 @@ def mock_check_output(cmd: str, *_: Any, **__: Any) -> str: python = "^{python}" """ - assert expected in pyproject_file.read_text() + assert expected in pyproject_file.read_text(encoding="utf-8") def test_get_pool(mocker: MockerFixture, source_dir: Path) -> None: diff --git a/tests/console/commands/test_new.py b/tests/console/commands/test_new.py index 3bd1da82fa7..356f1c9f768 100644 --- a/tests/console/commands/test_new.py +++ b/tests/console/commands/test_new.py @@ -228,7 +228,7 @@ def mock_check_output(cmd: str, *_: Any, **__: Any) -> str: python = "^{python}" """ - assert expected in pyproject_file.read_text() + assert expected in pyproject_file.read_text(encoding="utf-8") def test_basic_interactive_new( diff --git a/tests/console/commands/test_version.py b/tests/console/commands/test_version.py index 4772a400be1..5741cf3d9f5 100644 --- a/tests/console/commands/test_version.py +++ b/tests/console/commands/test_version.py @@ -126,9 +126,9 @@ def test_phase_version_update(tester: CommandTester) -> None: def test_dry_run(tester: CommandTester) -> None: assert isinstance(tester.command, VersionCommand) - old_pyproject = tester.command.poetry.file.path.read_text() + old_pyproject = tester.command.poetry.file.path.read_text(encoding="utf-8") tester.execute("--dry-run major") - new_pyproject = tester.command.poetry.file.path.read_text() + new_pyproject = tester.command.poetry.file.path.read_text(encoding="utf-8") assert tester.io.fetch_output() == "Bumping version from 1.2.3 to 2.0.0\n" assert old_pyproject == new_pyproject diff --git a/tests/inspection/test_info.py b/tests/inspection/test_info.py index 704eeba7a21..5f9c75e44b5 100644 --- a/tests/inspection/test_info.py +++ b/tests/inspection/test_info.py @@ -59,7 +59,8 @@ def demo_setup(source_dir: Path) -> Path: "from setuptools import setup; " 'setup(name="demo", ' 'version="0.1.0", ' - 'install_requires=["package"])' + 'install_requires=["package"])', + encoding="utf-8", ) return source_dir @@ -76,7 +77,8 @@ def demo_setup_cfg(source_dir: Path) -> Path: "[options]", "install_requires = package", ] - ) + ), + encoding="utf-8", ) return source_dir @@ -88,7 +90,8 @@ def demo_setup_complex(source_dir: Path) -> Path: "from setuptools import setup; " 'setup(name="demo", ' 'version="0.1.0", ' - 'install_requires=[i for i in ["package"]])' + 'install_requires=[i for i in ["package"]])', + encoding="utf-8", ) return source_dir @@ -96,7 +99,9 @@ def demo_setup_complex(source_dir: Path) -> Path: @pytest.fixture def demo_setup_complex_pep517_legacy(demo_setup_complex: Path) -> Path: pyproject_toml = demo_setup_complex / "pyproject.toml" - pyproject_toml.write_text('[build-system]\nrequires = ["setuptools", "wheel"]') + pyproject_toml.write_text( + '[build-system]\nrequires = ["setuptools", "wheel"]', encoding="utf-8" + ) return demo_setup_complex @@ -114,7 +119,8 @@ def demo_setup_complex_calls_script( [build-system] requires = ["setuptools", "scripts @ {scripts_dir.as_uri()}"] build-backend = "setuptools.build_meta:__legacy__" -""" +""", + encoding="utf-8", ) setup_py = source_dir / "setup.py" @@ -125,7 +131,8 @@ def demo_setup_complex_calls_script( if subprocess.call(["exit-code"]) != 42: raise RuntimeError("Wrong exit code.") setup(name="demo", version="0.1.0", install_requires=[i for i in ["package"]]) -""" +""", + encoding="utf-8", ) return source_dir @@ -358,7 +365,7 @@ def test_info_setup_missing_mandatory_should_trigger_pep517( setup += ")" setup_py = source_dir / "setup.py" - setup_py.write_text(setup) + setup_py.write_text(setup, encoding="utf-8") spy = mocker.spy(ProjectBuilder, "from_isolated_env") _ = PackageInfo.from_directory(source_dir) diff --git a/tests/installation/test_wheel_installer.py b/tests/installation/test_wheel_installer.py index b7b3d7c7c93..f74166fdb8c 100644 --- a/tests/installation/test_wheel_installer.py +++ b/tests/installation/test_wheel_installer.py @@ -54,7 +54,7 @@ def test_default_installation_dist_info_dir_content(default_installation: Path) def test_installer_file_contains_valid_version(default_installation: Path) -> None: installer_file = default_installation / "demo-0.1.0.dist-info" / "INSTALLER" - with open(installer_file) as f: + with open(installer_file, encoding="utf-8") as f: installer_content = f.read() match = re.match(r"Poetry (?P.*)", installer_content) assert match diff --git a/tests/masonry/builders/test_editable_builder.py b/tests/masonry/builders/test_editable_builder.py index 6e297175814..0570099ab40 100644 --- a/tests/masonry/builders/test_editable_builder.py +++ b/tests/masonry/builders/test_editable_builder.py @@ -2,7 +2,6 @@ import csv import json -import locale import os import shutil @@ -21,6 +20,7 @@ from poetry.factory import Factory from poetry.masonry.builders.editable import EditableBuilder from poetry.repositories.installed_repository import InstalledRepository +from poetry.utils._compat import getencoding from poetry.utils.env import EnvCommandError from poetry.utils.env import EnvManager from poetry.utils.env import MockEnv @@ -120,7 +120,9 @@ def test_builder_installs_proper_files_for_standard_packages( assert tmp_venv.site_packages.exists(pth_file) assert ( simple_poetry.file.path.parent.resolve().as_posix() - == tmp_venv.site_packages.find(pth_file)[0].read_text().strip(os.linesep) + == tmp_venv.site_packages.find(pth_file)[0] + .read_text(encoding="utf-8") + .strip(os.linesep) ) dist_info = Path("simple_project-1.2.3.dist-info") @@ -139,12 +141,12 @@ def test_builder_installs_proper_files_for_standard_packages( "dir_info": {"editable": True}, "url": simple_poetry.file.path.parent.as_uri(), }, - json.loads(dist_info.joinpath("direct_url.json").read_text()), + json.loads(dist_info.joinpath("direct_url.json").read_text(encoding="utf-8")), ) - assert dist_info.joinpath("INSTALLER").read_text() == "poetry" + assert dist_info.joinpath("INSTALLER").read_text(encoding="utf-8") == "poetry" assert ( - dist_info.joinpath("entry_points.txt").read_text() + dist_info.joinpath("entry_points.txt").read_text(encoding="utf-8") == "[console_scripts]\nbaz=bar:baz.boom.bim\nfoo=foo:bar\n" "fox=fuz.foo:bar.baz\n\n" ) @@ -207,7 +209,7 @@ def test_builder_installs_proper_files_for_standard_packages( sys.exit(baz.boom.bim()) """ - assert baz_script == tmp_venv._bin_dir.joinpath("baz").read_text() + assert baz_script == tmp_venv._bin_dir.joinpath("baz").read_text(encoding="utf-8") foo_script = f"""\ #!{tmp_venv.python} @@ -218,7 +220,7 @@ def test_builder_installs_proper_files_for_standard_packages( sys.exit(bar()) """ - assert foo_script == tmp_venv._bin_dir.joinpath("foo").read_text() + assert foo_script == tmp_venv._bin_dir.joinpath("foo").read_text(encoding="utf-8") fox_script = f"""\ #!{tmp_venv.python} @@ -229,7 +231,7 @@ def test_builder_installs_proper_files_for_standard_packages( sys.exit(bar.baz()) """ - assert fox_script == tmp_venv._bin_dir.joinpath("fox").read_text() + assert fox_script == tmp_venv._bin_dir.joinpath("fox").read_text(encoding="utf-8") def test_builder_falls_back_on_setup_and_pip_for_packages_with_build_scripts( @@ -297,7 +299,7 @@ def test_builder_installs_proper_files_when_packages_configured( pth_file = tmp_venv.site_packages.find(pth_file)[0] paths = set() - with pth_file.open(encoding=locale.getpreferredencoding()) as f: + with pth_file.open(encoding=getencoding()) as f: for line in f.readlines(): line = line.strip(os.linesep) if line: diff --git a/tests/pyproject/conftest.py b/tests/pyproject/conftest.py index 82ff2198389..8aceff30d8c 100644 --- a/tests/pyproject/conftest.py +++ b/tests/pyproject/conftest.py @@ -12,7 +12,7 @@ @pytest.fixture def pyproject_toml(tmp_path: Path) -> Path: path = tmp_path / "pyproject.toml" - with path.open(mode="w"): + with path.open(mode="w", encoding="utf-8"): pass return path @@ -24,7 +24,7 @@ def build_system_section(pyproject_toml: Path) -> str: requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" """ - with pyproject_toml.open(mode="a") as f: + with pyproject_toml.open(mode="a", encoding="utf-8") as f: f.write(content) return content @@ -38,6 +38,6 @@ def poetry_section(pyproject_toml: Path) -> str: [tool.poetry.dependencies] python = "^3.5" """ - with pyproject_toml.open(mode="a") as f: + with pyproject_toml.open(mode="a", encoding="utf-8") as f: f.write(content) return content diff --git a/tests/pyproject/test_pyproject_toml_file.py b/tests/pyproject/test_pyproject_toml_file.py index 5cb1b8c4327..e8fea9000ec 100644 --- a/tests/pyproject/test_pyproject_toml_file.py +++ b/tests/pyproject/test_pyproject_toml_file.py @@ -14,7 +14,7 @@ def test_pyproject_toml_file_invalid(pyproject_toml: Path) -> None: - with pyproject_toml.open(mode="a") as f: + with pyproject_toml.open(mode="a", encoding="utf-8") as f: f.write("<<<<<<<<<<<") with pytest.raises(PoetryCoreException) as excval: diff --git a/tests/utils/env/test_env.py b/tests/utils/env/test_env.py index e3ee2f2c473..e2b97b1fb13 100644 --- a/tests/utils/env/test_env.py +++ b/tests/utils/env/test_env.py @@ -186,7 +186,8 @@ def test_call_does_not_block_on_full_pipe( import sys for i in range(10000): print('just print a lot of text to fill the buffer', file={out}) -""" +""", + encoding="utf-8", ) def target(result: list[int]) -> None: @@ -276,7 +277,7 @@ def test_env_system_packages( assert ( f"include-system-site-packages = {str(with_system_site_packages).lower()}" - in pyvenv_cfg.read_text() + in pyvenv_cfg.read_text(encoding="utf-8") ) assert env.includes_system_site_packages is with_system_site_packages diff --git a/tests/utils/test_cache.py b/tests/utils/test_cache.py index 05e5e9b636a..09c5c98e75c 100644 --- a/tests/utils/test_cache.py +++ b/tests/utils/test_cache.py @@ -167,9 +167,12 @@ def test_detect_corrupted_cache_key_file( # original content: 9999999999"value" - write_modes = {str: "w", bytes: "wb"} - with open(key1_path, write_modes[type(corrupt_payload)]) as f: - f.write(corrupt_payload) # write corrupt data + if isinstance(corrupt_payload, str): + with open(key1_path, "w", encoding="utf-8") as f: + f.write(corrupt_payload) # write corrupt data + else: + with open(key1_path, "wb") as f: + f.write(corrupt_payload) # write corrupt data assert poetry_file_cache.get("key1") is None @@ -333,7 +336,7 @@ def test_get_cached_archive_for_link_no_race_condition( def replace_file(_: str, dest: Path) -> None: dest.unlink(missing_ok=True) # write some data (so it takes a while) to provoke possible race conditions - dest.write_text("a" * 2**20) + dest.write_text("a" * 2**20, encoding="utf-8") download_mock = mocker.Mock(side_effect=replace_file) diff --git a/tests/vcs/git/test_system.py b/tests/vcs/git/test_system.py index 2491939c64f..5763b3607da 100644 --- a/tests/vcs/git/test_system.py +++ b/tests/vcs/git/test_system.py @@ -23,6 +23,7 @@ def get_head_sha(cwd: Path) -> str: ["git", "rev-parse", "HEAD"], cwd=cwd, text=True, + encoding="utf-8", ).strip() @@ -39,7 +40,7 @@ def temp_repo(tmp_path: Path) -> TempRepoFixture: repo = dulwich.repo.Repo.init(str(tmp_path)) # init commit - (tmp_path / "foo").write_text("foo") + (tmp_path / "foo").write_text("foo", encoding="utf-8") repo.stage(["foo"]) init_commit = repo.do_commit( @@ -50,7 +51,7 @@ def temp_repo(tmp_path: Path) -> TempRepoFixture: ) # extra commit - (tmp_path / "foo").write_text("bar") + (tmp_path / "foo").write_text("bar", encoding="utf-8") repo.stage(["foo"]) head_commit = repo.do_commit(