diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 116122b6f99..20cf309baac 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,6 +21,9 @@ concurrency: group: tests-${{ github.head_ref || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} +env: + PYTHONWARNDEFAULTENCODING: 'true' + jobs: tests: name: ${{ matrix.os }} / ${{ matrix.python-version }} diff --git a/src/poetry/masonry/builders/editable.py b/src/poetry/masonry/builders/editable.py index 076843ab3db..f54d1e6aa63 100644 --- a/src/poetry/masonry/builders/editable.py +++ b/src/poetry/masonry/builders/editable.py @@ -234,7 +234,8 @@ def _add_dist_info(self, added_files: list[Path]) -> None: json.dumps({ "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..a75c1bb7912 100644 --- a/src/poetry/repositories/installed_repository.py +++ b/src/poetry/repositories/installed_repository.py @@ -58,7 +58,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="utf-8") as f: for line in f: line = line.strip() if line and not line.startswith(("#", "import ", "import\t")): diff --git a/src/poetry/utils/env/base_env.py b/src/poetry/utils/env/base_env.py index 0880502cf41..07583049dc0 100644 --- a/src/poetry/utils/env/base_env.py +++ b/src/poetry/utils/env/base_env.py @@ -348,7 +348,7 @@ def _run(self, cmd: list[str], **kwargs: Any) -> str: output = "" else: output = subprocess.check_output( - cmd, stderr=stderr, env=env, text=True, **kwargs + cmd, stderr=stderr, env=env, text=True, encoding="utf-8", **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 8a573426fec..7d568145fa5 100644 --- a/src/poetry/utils/env/virtual_env.py +++ b/src/poetry/utils/env/virtual_env.py @@ -143,7 +143,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 index ffc10a13a87..4728f676d14 100644 --- a/src/poetry/utils/setup_reader.py +++ b/src/poetry/utils/setup_reader.py @@ -75,7 +75,7 @@ def read_setup_py(self, filepath: Path) -> dict[str, Any]: def read_setup_cfg(self, filepath: Path) -> dict[str, Any]: parser = ConfigParser() - parser.read(str(filepath)) + parser.read(str(filepath), encoding="utf-8") name = None version = None diff --git a/tests/console/commands/env/test_remove.py b/tests/console/commands/env/test_remove.py index 38998f92634..b3f8da37797 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_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 f18570a4eed..4919f94b2fa 100644 --- a/tests/console/commands/test_init.py +++ b/tests/console/commands/test_init.py @@ -122,7 +122,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 @@ -884,9 +884,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"]) @@ -902,10 +904,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 @@ -922,7 +924,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")) @@ -946,7 +948,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( @@ -958,13 +962,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( @@ -1100,7 +1104,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 9bbef7fff17..11654fd535e 100644 --- a/tests/console/commands/test_new.py +++ b/tests/console/commands/test_new.py @@ -228,4 +228,4 @@ 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") 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 933d48a7f0e..4877d1afe56 100644 --- a/tests/inspection/test_info.py +++ b/tests/inspection/test_info.py @@ -61,7 +61,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: "version = 0.1.0", "[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 @@ -109,20 +114,26 @@ def demo_setup_complex_calls_script( shutil.copytree(fixture_dir("scripts"), scripts_dir) pyproject = source_dir / "pyproject.toml" - pyproject.write_text(f"""\ + pyproject.write_text( + f"""\ [build-system] requires = ["setuptools", "scripts @ {scripts_dir.as_uri()}"] build-backend = "setuptools.build_meta:__legacy__" -""") +""", + encoding="utf-8", + ) setup_py = source_dir / "setup.py" - setup_py.write_text("""\ + setup_py.write_text( + """\ import subprocess from setuptools import setup 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 @@ -327,7 +338,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(VirtualEnv, "run") _ = 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 aa7e9e03ef7..bc92569720e 100644 --- a/tests/masonry/builders/test_editable_builder.py +++ b/tests/masonry/builders/test_editable_builder.py @@ -98,7 +98,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") @@ -117,12 +119,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" ) @@ -184,7 +186,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} @@ -195,7 +197,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} @@ -206,7 +208,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( 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 da481455b55..0386f333b67 100644 --- a/tests/utils/env/test_env.py +++ b/tests/utils/env/test_env.py @@ -178,11 +178,14 @@ def test_call_does_not_block_on_full_pipe( ) -> None: """see https://github.com/python-poetry/poetry/issues/7698""" script = tmp_path / "script.py" - script.write_text(f"""\ + script.write_text( + f"""\ 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: tmp_venv.run("python", str(script), call=True) @@ -271,7 +274,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 1f4abfd4974..7c878586780 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(