diff --git a/setuptools/_imp.py b/setuptools/_imp.py index 9d4ead0eb03..d7092df67ce 100644 --- a/setuptools/_imp.py +++ b/setuptools/_imp.py @@ -8,6 +8,7 @@ import importlib.machinery from importlib.util import module_from_spec +from .compat.encoding import encoding_for_open PY_SOURCE = 1 @@ -66,7 +67,7 @@ def find_module(module, paths=None): kind = C_EXTENSION if kind in {PY_SOURCE, PY_COMPILED}: - file = open(path, mode) + file = open(path, mode, encoding=encoding_for_open) else: path = None suffix = mode = '' diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index f14c58d7dad..c9714b1e4f2 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -872,7 +872,7 @@ def write_script(self, script_name, contents, mode="t", blockers=()): ensure_directory(target) if os.path.exists(target): os.unlink(target) - with open(target, "w" + mode) as f: + with open(target, "w" + mode, encoding=encoding_for_open) as f: f.write(contents) chmod(target, 0o777 - mask) diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index 8a4ae7928f2..7ac52b4c2a5 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -30,7 +30,6 @@ List, Mapping, Optional, - Protocol, Tuple, TypeVar, Union, @@ -43,6 +42,7 @@ errors, namespaces, ) +from ..compat.encoding import encoding_for_pth from ..discovery import find_package_path from ..dist import Distribution from ..warnings import ( @@ -55,6 +55,13 @@ if TYPE_CHECKING: from wheel.wheelfile import WheelFile # noqa +if sys.version_info >= (3, 8): + from typing import Protocol +elif TYPE_CHECKING: + from typing_extensions import Protocol +else: + from abc import ABC as Protocol + _Path = Union[str, Path] _P = TypeVar("_P", bound=_Path) _logger = logging.getLogger(__name__) diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index 72b2e45cbcf..653cbbb338e 100644 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -4,6 +4,7 @@ import sys from .._path import ensure_directory +from ..compat.encoding import encoding_for_open class install_scripts(orig.install_scripts): @@ -60,7 +61,7 @@ def write_script(self, script_name, contents, mode="t", *ignored): mask = current_umask() if not self.dry_run: ensure_directory(target) - f = open(target, "w" + mode) + f = open(target, "w" + mode, encoding=encoding_for_open) f.write(contents) f.close() chmod(target, 0o777 - mask) diff --git a/setuptools/command/setopt.py b/setuptools/command/setopt.py index 107c2821b11..8086e0a4d07 100644 --- a/setuptools/command/setopt.py +++ b/setuptools/command/setopt.py @@ -38,7 +38,7 @@ def edit_config(filename, settings, dry_run=False): log.debug("Reading configuration from %s", filename) opts = configparser.RawConfigParser() opts.optionxform = lambda x: x - opts.read([filename]) + opts.read([filename], encoding=encoding_for_open) for section, options in settings.items(): if options is None: log.info("Deleting section [%s] from %s", section, filename) diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 12c5e49625d..f015c15c212 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -1016,7 +1016,7 @@ def __init__(self): rc = os.path.join(os.path.expanduser('~'), '.pypirc') if os.path.exists(rc): - self.read(rc) + self.read(rc, encoding=encoding_for_open) @property def creds_by_repository(self): diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 7634b1320b1..311e14ec569 100644 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -13,6 +13,7 @@ import pkg_resources from distutils.errors import DistutilsError from pkg_resources import working_set +from .compat.encoding import encoding_for_open if sys.platform.startswith('java'): import org.python.modules.posix.PosixModule as _os @@ -450,7 +451,7 @@ def _file(self, path, mode='r', *args, **kw): def _open(self, path, mode='r', *args, **kw): if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path): self._violation("open", path, mode, *args, **kw) - return _open(path, mode, *args, **kw) + return _open(path, mode, *args, **kw, encoding=encoding_for_open) def tmpnam(self): self._violation("tmpnam") diff --git a/setuptools/tests/config/test_apply_pyprojecttoml.py b/setuptools/tests/config/test_apply_pyprojecttoml.py index e63a89b0b4e..c87590c573e 100644 --- a/setuptools/tests/config/test_apply_pyprojecttoml.py +++ b/setuptools/tests/config/test_apply_pyprojecttoml.py @@ -19,6 +19,7 @@ import setuptools # noqa ensure monkey patch to metadata from setuptools.dist import Distribution +from setuptools.compat.encoding import encoding_for_open from setuptools.config import setupcfg, pyprojecttoml from setuptools.config import expand from setuptools.config._apply_pyprojecttoml import _MissingDynamic, _some_attrgetter @@ -174,11 +175,11 @@ def _pep621_example_project( replacements = {'readme = "README.rst"': f'readme = "{readme}"'} for orig, subst in replacements.items(): text = text.replace(orig, subst) - pyproject.write_text(text, encoding="utf-8") + pyproject.write_text(text, encoding="utf-8", encoding=encoding_for_open) - (tmp_path / readme).write_text("hello world") - (tmp_path / "LICENSE.txt").write_text("--- LICENSE stub ---") - (tmp_path / "spam.py").write_text(PEP621_EXAMPLE_SCRIPT) + (tmp_path / readme).write_text("hello world", encoding=encoding_for_open) + (tmp_path / "LICENSE.txt").write_text("--- LICENSE stub ---", encoding=encoding_for_open) + (tmp_path / "spam.py").write_text(PEP621_EXAMPLE_SCRIPT, encoding=encoding_for_open) return pyproject diff --git a/setuptools/tests/config/test_expand.py b/setuptools/tests/config/test_expand.py index cdcbffc14c5..5c852f80baf 100644 --- a/setuptools/tests/config/test_expand.py +++ b/setuptools/tests/config/test_expand.py @@ -4,6 +4,7 @@ import pytest from distutils.errors import DistutilsOptionError +from setuptools.compat.encoding import encoding_for_open from setuptools.config import expand from setuptools.discovery import find_package_path @@ -12,7 +13,7 @@ def write_files(files, root_dir): for file, content in files.items(): path = root_dir / file path.parent.mkdir(exist_ok=True, parents=True) - path.write_text(content) + path.write_text(content, encoding=encoding_for_open) def test_glob_relative(tmp_path, monkeypatch): diff --git a/setuptools/tests/config/test_pyprojecttoml.py b/setuptools/tests/config/test_pyprojecttoml.py index 3477232d921..8f57032faf2 100644 --- a/setuptools/tests/config/test_pyprojecttoml.py +++ b/setuptools/tests/config/test_pyprojecttoml.py @@ -98,11 +98,17 @@ def create_example(path, pkg_root): (path / file).parent.mkdir(exist_ok=True, parents=True) (path / file).touch() - pyproject.write_text(EXAMPLE) - (path / "README.md").write_text("hello world") - (path / f"{pkg_root}/pkg/mod.py").write_text("class CustomSdist: pass") - (path / f"{pkg_root}/pkg/__version__.py").write_text("VERSION = (3, 10)") - (path / f"{pkg_root}/pkg/__main__.py").write_text("def exec(): print('hello')") + pyproject.write_text(EXAMPLE, encoding=encoding_for_open) + (path / "README.md").write_text("hello world", encoding=encoding_for_open) + (path / f"{pkg_root}/pkg/mod.py").write_text( + "class CustomSdist: pass", encoding=encoding_for_open + ) + (path / f"{pkg_root}/pkg/__version__.py").write_text( + "VERSION = (3, 10)", encoding=encoding_for_open + ) + (path / f"{pkg_root}/pkg/__main__.py").write_text( + "def exec(): print('hello')", encoding=encoding_for_open + ) def verify_example(config, path, pkg_root): @@ -218,7 +224,9 @@ def test_dynamic(self, tmp_path): Framework :: Flask Programming Language :: Haskell """ - (tmp_path / "classifiers.txt").write_text(cleandoc(classifiers)) + (tmp_path / "classifiers.txt").write_text( + cleandoc(classifiers), encoding=encoding_for_open + ) pyproject = tmp_path / "pyproject.toml" config = read_configuration(pyproject, expand=False) @@ -246,7 +254,7 @@ def test_dynamic_without_config(self, tmp_path): """ pyproject = tmp_path / "pyproject.toml" - pyproject.write_text(cleandoc(config)) + pyproject.write_text(cleandoc(config), encoding=encoding_for_open) with pytest.raises(OptionError, match="No configuration .* .classifiers."): read_configuration(pyproject) @@ -258,7 +266,7 @@ def test_dynamic_readme_from_setup_script_args(self, tmp_path): dynamic = ["readme"] """ pyproject = tmp_path / "pyproject.toml" - pyproject.write_text(cleandoc(config)) + pyproject.write_text(cleandoc(config), encoding=encoding_for_open) dist = Distribution(attrs={"long_description": "42"}) # No error should occur because of missing `readme` dist = apply_configuration(dist, pyproject) @@ -276,7 +284,7 @@ def test_dynamic_without_file(self, tmp_path): """ pyproject = tmp_path / "pyproject.toml" - pyproject.write_text(cleandoc(config)) + pyproject.write_text(cleandoc(config), encoding=encoding_for_open) with pytest.warns(UserWarning, match="File .*classifiers.txt. cannot be found"): expanded = read_configuration(pyproject) assert "classifiers" not in expanded["project"] @@ -297,7 +305,7 @@ def test_dynamic_without_file(self, tmp_path): ) def test_ignore_unrelated_config(tmp_path, example): pyproject = tmp_path / "pyproject.toml" - pyproject.write_text(cleandoc(example)) + pyproject.write_text(cleandoc(example), encoding=encoding_for_open) # Make sure no error is raised due to 3rd party configs in pyproject.toml assert read_configuration(pyproject) is not None @@ -319,7 +327,7 @@ def test_ignore_unrelated_config(tmp_path, example): ) def test_invalid_example(tmp_path, example, error_msg): pyproject = tmp_path / "pyproject.toml" - pyproject.write_text(cleandoc(example)) + pyproject.write_text(cleandoc(example), encoding=encoding_for_open) pattern = re.compile(f"invalid pyproject.toml.*{error_msg}.*", re.M | re.S) with pytest.raises(ValueError, match=pattern): @@ -329,7 +337,7 @@ def test_invalid_example(tmp_path, example, error_msg): @pytest.mark.parametrize("config", ("", "[tool.something]\nvalue = 42")) def test_empty(tmp_path, config): pyproject = tmp_path / "pyproject.toml" - pyproject.write_text(config) + pyproject.write_text(config, encoding=encoding_for_open) # Make sure no error is raised assert read_configuration(pyproject) == {} @@ -341,7 +349,7 @@ def test_include_package_data_by_default(tmp_path, config): default. """ pyproject = tmp_path / "pyproject.toml" - pyproject.write_text(config) + pyproject.write_text(config, encoding=encoding_for_open) config = read_configuration(pyproject) assert config["tool"]["setuptools"]["include-package-data"] is True @@ -354,9 +362,14 @@ def test_include_package_data_in_setuppy(tmp_path): See https://github.com/pypa/setuptools/issues/3197#issuecomment-1079023889 """ pyproject = tmp_path / "pyproject.toml" - pyproject.write_text("[project]\nname = 'myproj'\nversion='42'\n") + pyproject.write_text( + "[project]\nname = 'myproj'\nversion='42'\n", encoding=encoding_for_open + ) setuppy = tmp_path / "setup.py" - setuppy.write_text("__import__('setuptools').setup(include_package_data=False)") + setuppy.write_text( + "__import__('setuptools').setup(include_package_data=False)", + encoding=encoding_for_open, + ) with _Path(tmp_path): dist = distutils.core.run_setup("setup.py", {}, stop_after="config") diff --git a/setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py b/setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py index b6516227c09..e4a6bb1da20 100644 --- a/setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py +++ b/setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py @@ -1,5 +1,6 @@ import pytest +from setuptools.compat.encoding import encoding_for_open from setuptools.config.pyprojecttoml import apply_configuration from setuptools.dist import Distribution from setuptools.tests.textwrap import DALS @@ -23,7 +24,8 @@ def test_dynamic_dependencies(tmp_path): [tool.setuptools.dynamic.dependencies] file = ["requirements.txt"] """ - ) + ), + encoding=encoding_for_open, ) dist = Distribution() dist = apply_configuration(dist, pyproject) @@ -31,11 +33,12 @@ def test_dynamic_dependencies(tmp_path): def test_dynamic_optional_dependencies(tmp_path): - (tmp_path / "requirements-docs.txt").write_text("sphinx\n # comment\n") + (tmp_path / "requirements-docs.txt").write_text( + "sphinx\n # comment\n", encoding=encoding_for_open + ) pyproject = tmp_path / "pyproject.toml" pyproject.write_text( - DALS( - """ + DALS(""" [project] name = "myproj" version = "1.0" @@ -47,8 +50,8 @@ def test_dynamic_optional_dependencies(tmp_path): [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" - """ - ) + """), + encoding=encoding_for_open, ) dist = Distribution() dist = apply_configuration(dist, pyproject) @@ -61,11 +64,12 @@ def test_mixed_dynamic_optional_dependencies(tmp_path): configurations in the case of fields containing sub-fields (groups), things would work out. """ - (tmp_path / "requirements-images.txt").write_text("pillow~=42.0\n # comment\n") + (tmp_path / "requirements-images.txt").write_text( + "pillow~=42.0\n # comment\n", encoding=encoding_for_open + ) pyproject = tmp_path / "pyproject.toml" pyproject.write_text( - DALS( - """ + DALS(""" [project] name = "myproj" version = "1.0" @@ -80,8 +84,8 @@ def test_mixed_dynamic_optional_dependencies(tmp_path): [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" - """ - ) + """), + encoding=encoding_for_open, ) # Test that the mix-and-match doesn't currently validate. with pytest.raises(ValueError, match="project.optional-dependencies"): diff --git a/setuptools/tests/config/test_setupcfg.py b/setuptools/tests/config/test_setupcfg.py index 7f93858bd4d..f6175d12219 100644 --- a/setuptools/tests/config/test_setupcfg.py +++ b/setuptools/tests/config/test_setupcfg.py @@ -7,8 +7,9 @@ import pytest from distutils.errors import DistutilsOptionError, DistutilsFileError -from setuptools.dist import Distribution, _Distribution +from setuptools.compat.encoding import encoding_for_open from setuptools.config.setupcfg import ConfigHandler, read_configuration +from setuptools.dist import Distribution, _Distribution from setuptools.extern.packaging.requirements import InvalidRequirement from setuptools.warnings import SetuptoolsDeprecationWarning from ..textwrap import DALS @@ -904,7 +905,8 @@ def test_cmdclass(self, tmpdir): module_path = Path(tmpdir, "src/custom_build.py") # auto discovery for src module_path.parent.mkdir(parents=True, exist_ok=True) module_path.write_text( - "from distutils.core import Command\n" "class CustomCmd(Command): pass\n" + "from distutils.core import Command\n" "class CustomCmd(Command): pass\n", + encoding=encoding_for_open, ) setup_cfg = """ diff --git a/setuptools/tests/environment.py b/setuptools/tests/environment.py index df2bd37ff65..20e4d6a8f46 100644 --- a/setuptools/tests/environment.py +++ b/setuptools/tests/environment.py @@ -3,6 +3,7 @@ import subprocess import unicodedata from subprocess import Popen as _Popen, PIPE as _PIPE +from ..compat.encoding import encoding_for_open import jaraco.envs @@ -31,6 +32,8 @@ def run(self, cmd, *args, **kwargs): if "PYTHONPATH" in env: del env["PYTHONPATH"] kwargs["env"] = env + if "encoding" not in kwargs: + kwargs["encoding"] = encoding_for_open return subprocess.check_output(cmd, *args, **kwargs) diff --git a/setuptools/tests/integration/helpers.py b/setuptools/tests/integration/helpers.py index 82cb36a2e46..33c0434180c 100644 --- a/setuptools/tests/integration/helpers.py +++ b/setuptools/tests/integration/helpers.py @@ -10,6 +10,7 @@ import tarfile from zipfile import ZipFile from pathlib import Path +from setuptools.compat.encoding import encoding_for_open def run(cmd, env=None): @@ -19,6 +20,7 @@ def run(cmd, env=None): text=True, env={**os.environ, **(env or {})}, # ^-- allow overwriting instead of discarding the current env + encoding=encoding_for_open, ) out = r.stdout + "\n" + r.stderr diff --git a/setuptools/tests/test_config_discovery.py b/setuptools/tests/test_config_discovery.py index 2fe1cc8b5f8..8a95b0adcc9 100644 --- a/setuptools/tests/test_config_discovery.py +++ b/setuptools/tests/test_config_discovery.py @@ -177,11 +177,13 @@ def test_purposefully_empty(self, tmp_path, config_file, param, circumstance): else: # Make sure build works with or without setup.cfg pyproject = self.PURPOSEFULLY_EMPY["template-pyproject.toml"] - (tmp_path / "pyproject.toml").write_text(pyproject) + (tmp_path / "pyproject.toml").write_text( + pyproject, encoding=encoding_for_open + ) template_param = param config = self.PURPOSEFULLY_EMPY[config_file].format(param=template_param) - (tmp_path / config_file).write_text(config) + (tmp_path / config_file).write_text(config, encoding=encoding_for_open) dist = _get_dist(tmp_path, {}) # When either parameter package or py_modules is an empty list, @@ -293,10 +295,13 @@ class TestWithAttrDirective: def test_setupcfg_metadata(self, tmp_path, folder, opts): files = [f"{folder}/pkg/__init__.py", "setup.cfg"] _populate_project_dir(tmp_path, files, opts) - (tmp_path / folder / "pkg/__init__.py").write_text("version = 42") + (tmp_path / folder / "pkg/__init__.py").write_text( + "version = 42", encoding=encoding_for_open + ) (tmp_path / "setup.cfg").write_text( "[metadata]\nversion = attr: pkg.version\n" - + (tmp_path / "setup.cfg").read_text() + + (tmp_path / "setup.cfg").read_text(encoding=encoding_for_open), + encoding=encoding_for_open, ) dist = _get_dist(tmp_path, {}) @@ -313,10 +318,13 @@ def test_setupcfg_metadata(self, tmp_path, folder, opts): def test_pyproject_metadata(self, tmp_path): _populate_project_dir(tmp_path, ["src/pkg/__init__.py"], {}) - (tmp_path / "src/pkg/__init__.py").write_text("version = 42") + (tmp_path / "src/pkg/__init__.py").write_text( + "version = 42", encoding=encoding_for_open + ) (tmp_path / "pyproject.toml").write_text( "[project]\nname = 'pkg'\ndynamic = ['version']\n" - "[tool.setuptools.dynamic]\nversion = {attr = 'pkg.version'}\n" + "[tool.setuptools.dynamic]\nversion = {attr = 'pkg.version'}\n", + encoding=encoding_for_open, ) dist = _get_dist(tmp_path, {}) assert dist.get_version() == "42" @@ -355,7 +363,9 @@ def _simulate_package_with_extension(self, tmp_path): ] setup(ext_modules=ext_modules) """ - (tmp_path / "setup.py").write_text(DALS(setup_script)) + (tmp_path / "setup.py").write_text( + DALS(setup_script), encoding=encoding_for_open + ) def test_skip_discovery_with_setupcfg_metadata(self, tmp_path): """Ensure that auto-discovery is not triggered when the project is based on @@ -368,14 +378,16 @@ def test_skip_discovery_with_setupcfg_metadata(self, tmp_path): requires = [] build-backend = 'setuptools.build_meta' """ - (tmp_path / "pyproject.toml").write_text(DALS(pyproject)) + (tmp_path / "pyproject.toml").write_text( + DALS(pyproject), encoding=encoding_for_open + ) setupcfg = """ [metadata] name = proj version = 42 """ - (tmp_path / "setup.cfg").write_text(DALS(setupcfg)) + (tmp_path / "setup.cfg").write_text(DALS(setupcfg), encoding=encoding_for_open) dist = _get_dist(tmp_path, {}) assert dist.get_name() == "proj" @@ -400,7 +412,9 @@ def test_dont_skip_discovery_with_pyproject_metadata(self, tmp_path): name = 'proj' version = '42' """ - (tmp_path / "pyproject.toml").write_text(DALS(pyproject)) + (tmp_path / "pyproject.toml").write_text( + DALS(pyproject), encoding=encoding_for_open + ) with pytest.raises(PackageDiscoveryError, match="multiple (packages|modules)"): _get_dist(tmp_path, {}) @@ -417,7 +431,9 @@ def _simulate_package_with_data_files(self, tmp_path, src_root): manifest = """ global-include *.py *.txt """ - (tmp_path / "MANIFEST.in").write_text(DALS(manifest)) + (tmp_path / "MANIFEST.in").write_text( + DALS(manifest), encoding=encoding_for_open + ) EXAMPLE_SETUPCFG = """ [metadata] @@ -565,9 +581,11 @@ def _populate_project_dir(root, files, options): # NOTE: Currently pypa/build will refuse to build the project if no # `pyproject.toml` or `setup.py` is found. So it is impossible to do # completely "config-less" projects. - (root / "setup.py").write_text("import setuptools\nsetuptools.setup()") - (root / "README.md").write_text("# Example Package") - (root / "LICENSE").write_text("Copyright (c) 2018") + (root / "setup.py").write_text( + "import setuptools\nsetuptools.setup()", encoding=encoding_for_open + ) + (root / "README.md").write_text("# Example Package", encoding=encoding_for_open) + (root / "LICENSE").write_text("Copyright (c) 2018", encoding=encoding_for_open) _write_setupcfg(root, options) paths = (root / f for f in files) for path in paths: @@ -595,7 +613,7 @@ def _write_setupcfg(root, options): with open(root / "setup.cfg", "w", encoding=encoding_for_open) as f: setupcfg.write(f) print("~~~~~ setup.cfg ~~~~~") - print((root / "setup.cfg").read_text()) + print((root / "setup.cfg").read_text(encoding=encoding_for_open)) def _run_build(path, *flags): diff --git a/setuptools/tests/test_dist_info.py b/setuptools/tests/test_dist_info.py index ad6cebad0b6..5a9d60de71e 100644 --- a/setuptools/tests/test_dist_info.py +++ b/setuptools/tests/test_dist_info.py @@ -12,6 +12,7 @@ import pkg_resources from setuptools.archive_util import unpack_archive from .textwrap import DALS +from ..compat.encoding import encoding_for_open read = partial(pathlib.Path.read_text, encoding="utf-8") @@ -199,6 +200,7 @@ def run_command_inner(*cmd, **kwargs): "stdout": subprocess.PIPE, "text": True, 'check': True, + "encoding": encoding_for_open, **kwargs, } cmd = [sys.executable, "-c", "__import__('setuptools').setup()", *map(str, cmd)] diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 1f3813eebe2..e025c046b6e 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -531,6 +531,7 @@ def test_setup_install_includes_dependencies(self, tmp_path, mock_index): stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, + encoding=encoding_for_open, ) assert cp.returncode != 0 try: diff --git a/setuptools/tests/test_editable_install.py b/setuptools/tests/test_editable_install.py index 862f8172cde..7a42a51acfb 100644 --- a/setuptools/tests/test_editable_install.py +++ b/setuptools/tests/test_editable_install.py @@ -19,6 +19,7 @@ from path import Path as _Path from . import contexts, namespaces +from ..compat.encoding import encoding_for_open from setuptools._importlib import resources as importlib_resources from setuptools.command.editable_wheel import ( @@ -144,8 +145,8 @@ def test_editable_with_pyproject(tmp_path, venv, files, editable_opts): cmd = [venv.exe(), "-m", "mypkg"] assert subprocess.check_output(cmd).strip() == b"3.14159.post0 Hello World" - (project / "src/mypkg/data.txt").write_text("foobar") - (project / "src/mypkg/mod.py").write_text("x = 42") + (project / "src/mypkg/data.txt").write_text("foobar", encoding=encoding_for_open) + (project / "src/mypkg/mod.py").write_text("x = 42", encoding=encoding_for_open) assert subprocess.check_output(cmd).strip() == b"3.14159.post0 foobar 42" diff --git a/setuptools/tests/test_logging.py b/setuptools/tests/test_logging.py index 7a9a33f1ea7..9bef8eb87bb 100644 --- a/setuptools/tests/test_logging.py +++ b/setuptools/tests/test_logging.py @@ -4,6 +4,7 @@ import sys import pytest +from setuptools.compat.encoding import encoding_for_open IS_PYPY = '__pypy__' in sys.builtin_module_names @@ -33,7 +34,7 @@ def test_verbosity_level(tmp_path, monkeypatch, flag, expected_level): assert logging.getLevelName(unset_log_level) == "NOTSET" setup_script = tmp_path / "setup.py" - setup_script.write_text(setup_py) + setup_script.write_text(setup_py, encoding=encoding_for_open) dist = distutils.core.run_setup(setup_script, stop_after="init") dist.script_args = [flag, "sdist"] dist.parse_command_line() # <- where the log level is set diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py index 41b96614f89..62e47242eda 100644 --- a/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py @@ -7,6 +7,7 @@ import pytest import setuptools.package_index +from ..compat.encoding import encoding_for_open from .textwrap import DALS @@ -257,14 +258,13 @@ class TestPyPIConfig: def test_percent_in_password(self, tmp_home_dir): pypirc = tmp_home_dir / '.pypirc' pypirc.write_text( - DALS( - """ + DALS(""" [pypi] repository=https://pypi.org username=jaraco password=pity% - """ - ) + """), + encoding=encoding_for_open, ) cfg = setuptools.package_index.PyPIConfig() cred = cfg.creds_by_repository['https://pypi.org']