diff --git a/newsfragments/4261.misc.rst b/newsfragments/4261.misc.rst new file mode 100644 index 0000000000..83c10f0f66 --- /dev/null +++ b/newsfragments/4261.misc.rst @@ -0,0 +1 @@ +Avoid implicit ``encoding`` parameter in ``setuptools/tests``. diff --git a/setuptools/tests/config/test_apply_pyprojecttoml.py b/setuptools/tests/config/test_apply_pyprojecttoml.py index 555489b140..2ca35759bc 100644 --- a/setuptools/tests/config/test_apply_pyprojecttoml.py +++ b/setuptools/tests/config/test_apply_pyprojecttoml.py @@ -44,8 +44,9 @@ def test_apply_pyproject_equivalent_to_setupcfg(url, monkeypatch, tmp_path): monkeypatch.setattr(expand, "read_attr", Mock(return_value="0.0.1")) setupcfg_example = retrieve_file(url) pyproject_example = Path(tmp_path, "pyproject.toml") - toml_config = Translator().translate(setupcfg_example.read_text(), "setup.cfg") - pyproject_example.write_text(toml_config) + setupcfg_text = setupcfg_example.read_text(encoding="utf-8") + toml_config = Translator().translate(setupcfg_text, "setup.cfg") + pyproject_example.write_text(toml_config, encoding="utf-8") dist_toml = pyprojecttoml.apply_configuration(makedist(tmp_path), pyproject_example) dist_cfg = setupcfg.apply_configuration(makedist(tmp_path), setupcfg_example) @@ -177,9 +178,9 @@ def _pep621_example_project( text = text.replace(orig, subst) pyproject.write_text(text, encoding="utf-8") - (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="utf-8") + (tmp_path / "LICENSE.txt").write_text("--- LICENSE stub ---", encoding="utf-8") + (tmp_path / "spam.py").write_text(PEP621_EXAMPLE_SCRIPT, encoding="utf-8") return pyproject diff --git a/setuptools/tests/config/test_expand.py b/setuptools/tests/config/test_expand.py index cdcbffc14c..fe80890678 100644 --- a/setuptools/tests/config/test_expand.py +++ b/setuptools/tests/config/test_expand.py @@ -12,7 +12,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="utf-8") def test_glob_relative(tmp_path, monkeypatch): diff --git a/setuptools/tests/config/test_pyprojecttoml.py b/setuptools/tests/config/test_pyprojecttoml.py index 6a40f3bfd7..abec68ab30 100644 --- a/setuptools/tests/config/test_pyprojecttoml.py +++ b/setuptools/tests/config/test_pyprojecttoml.py @@ -2,6 +2,7 @@ from configparser import ConfigParser from inspect import cleandoc +import jaraco.path import pytest import tomli_w from path import Path @@ -82,25 +83,32 @@ def create_example(path, pkg_root): - pyproject = path / "pyproject.toml" - - files = [ - f"{pkg_root}/pkg/__init__.py", - "_files/file.txt", - ] - if pkg_root != ".": # flat-layout will raise error for multi-package dist - # Ensure namespaces are discovered - files.append(f"{pkg_root}/other/nested/__init__.py") + files = { + "pyproject.toml": EXAMPLE, + "README.md": "hello world", + "_files": { + "file.txt": "", + }, + } + packages = { + "pkg": { + "__init__.py": "", + "mod.py": "class CustomSdist: pass", + "__version__.py": "VERSION = (3, 10)", + "__main__.py": "def exec(): print('hello')", + }, + } + + assert pkg_root # Meta-test: cannot be empty string. - for file in files: - (path / file).parent.mkdir(exist_ok=True, parents=True) - (path / file).touch() + if pkg_root == ".": + files = {**files, **packages} + # skip other files: flat-layout will raise error for multi-package dist + else: + # Use this opportunity to ensure namespaces are discovered + files[pkg_root] = {**packages, "other": {"nested": {"__init__.py": ""}}} - 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')") + jaraco.path.build(files, prefix=path) def verify_example(config, path, pkg_root): @@ -174,7 +182,7 @@ class TestEntryPoints: def write_entry_points(self, tmp_path): entry_points = ConfigParser() entry_points.read_dict(ENTRY_POINTS) - with open(tmp_path / "entry-points.txt", "w") as f: + with open(tmp_path / "entry-points.txt", "w", encoding="utf-8") as f: entry_points.write(f) def pyproject(self, dynamic=None): @@ -208,11 +216,13 @@ def test_dynamic(self, tmp_path): # Let's create a project example that has dynamic classifiers # coming from a txt file. create_example(tmp_path, "src") - classifiers = """\ - Framework :: Flask - Programming Language :: Haskell - """ - (tmp_path / "classifiers.txt").write_text(cleandoc(classifiers)) + classifiers = cleandoc( + """ + Framework :: Flask + Programming Language :: Haskell + """ + ) + (tmp_path / "classifiers.txt").write_text(classifiers, encoding="utf-8") pyproject = tmp_path / "pyproject.toml" config = read_configuration(pyproject, expand=False) @@ -240,7 +250,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="utf-8") with pytest.raises(OptionError, match="No configuration .* .classifiers."): read_configuration(pyproject) @@ -252,7 +262,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="utf-8") dist = Distribution(attrs={"long_description": "42"}) # No error should occur because of missing `readme` dist = apply_configuration(dist, pyproject) @@ -270,7 +280,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="utf-8") with pytest.warns(UserWarning, match="File .*classifiers.txt. cannot be found"): expanded = read_configuration(pyproject) assert "classifiers" not in expanded["project"] @@ -291,7 +301,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="utf-8") # Make sure no error is raised due to 3rd party configs in pyproject.toml assert read_configuration(pyproject) is not None @@ -313,7 +323,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="utf-8") pattern = re.compile(f"invalid pyproject.toml.*{error_msg}.*", re.M | re.S) with pytest.raises(ValueError, match=pattern): @@ -323,7 +333,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="utf-8") # Make sure no error is raised assert read_configuration(pyproject) == {} @@ -335,7 +345,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="utf-8") config = read_configuration(pyproject) assert config["tool"]["setuptools"]["include-package-data"] is True @@ -347,10 +357,11 @@ 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") - setuppy = tmp_path / "setup.py" - setuppy.write_text("__import__('setuptools').setup(include_package_data=False)") + files = { + "pyproject.toml": "[project]\nname = 'myproj'\nversion='42'\n", + "setup.py": "__import__('setuptools').setup(include_package_data=False)", + } + jaraco.path.build(files, prefix=tmp_path) 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 b6516227c0..37e5234a45 100644 --- a/setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py +++ b/setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py @@ -1,57 +1,59 @@ +from inspect import cleandoc + import pytest +from jaraco import path from setuptools.config.pyprojecttoml import apply_configuration from setuptools.dist import Distribution -from setuptools.tests.textwrap import DALS def test_dynamic_dependencies(tmp_path): - (tmp_path / "requirements.txt").write_text("six\n # comment\n") - pyproject = tmp_path / "pyproject.toml" - pyproject.write_text( - DALS( + files = { + "requirements.txt": "six\n # comment\n", + "pyproject.toml": cleandoc( """ - [project] - name = "myproj" - version = "1.0" - dynamic = ["dependencies"] + [project] + name = "myproj" + version = "1.0" + dynamic = ["dependencies"] - [build-system] - requires = ["setuptools", "wheel"] - build-backend = "setuptools.build_meta" + [build-system] + requires = ["setuptools", "wheel"] + build-backend = "setuptools.build_meta" - [tool.setuptools.dynamic.dependencies] - file = ["requirements.txt"] - """ - ) - ) + [tool.setuptools.dynamic.dependencies] + file = ["requirements.txt"] + """ + ), + } + path.build(files, prefix=tmp_path) dist = Distribution() - dist = apply_configuration(dist, pyproject) + dist = apply_configuration(dist, tmp_path / "pyproject.toml") assert dist.install_requires == ["six"] def test_dynamic_optional_dependencies(tmp_path): - (tmp_path / "requirements-docs.txt").write_text("sphinx\n # comment\n") - pyproject = tmp_path / "pyproject.toml" - pyproject.write_text( - DALS( + files = { + "requirements-docs.txt": "sphinx\n # comment\n", + "pyproject.toml": cleandoc( """ - [project] - name = "myproj" - version = "1.0" - dynamic = ["optional-dependencies"] + [project] + name = "myproj" + version = "1.0" + dynamic = ["optional-dependencies"] - [tool.setuptools.dynamic.optional-dependencies.docs] - file = ["requirements-docs.txt"] + [tool.setuptools.dynamic.optional-dependencies.docs] + file = ["requirements-docs.txt"] - [build-system] - requires = ["setuptools", "wheel"] - build-backend = "setuptools.build_meta" - """ - ) - ) + [build-system] + requires = ["setuptools", "wheel"] + build-backend = "setuptools.build_meta" + """ + ), + } + path.build(files, prefix=tmp_path) dist = Distribution() - dist = apply_configuration(dist, pyproject) + dist = apply_configuration(dist, tmp_path / "pyproject.toml") assert dist.extras_require == {"docs": ["sphinx"]} @@ -61,29 +63,32 @@ 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") - pyproject = tmp_path / "pyproject.toml" - pyproject.write_text( - DALS( + files = { + "requirements-images.txt": "pillow~=42.0\n # comment\n", + "pyproject.toml": cleandoc( """ - [project] - name = "myproj" - version = "1.0" - dynamic = ["optional-dependencies"] + [project] + name = "myproj" + version = "1.0" + dynamic = ["optional-dependencies"] - [project.optional-dependencies] - docs = ["sphinx"] + [project.optional-dependencies] + docs = ["sphinx"] - [tool.setuptools.dynamic.optional-dependencies.images] - file = ["requirements-images.txt"] + [tool.setuptools.dynamic.optional-dependencies.images] + file = ["requirements-images.txt"] + + [build-system] + requires = ["setuptools", "wheel"] + build-backend = "setuptools.build_meta" + """ + ), + } + + path.build(files, prefix=tmp_path) - [build-system] - requires = ["setuptools", "wheel"] - build-backend = "setuptools.build_meta" - """ - ) - ) # Test that the mix-and-match doesn't currently validate. + pyproject = tmp_path / "pyproject.toml" with pytest.raises(ValueError, match="project.optional-dependencies"): apply_configuration(Distribution(), pyproject) diff --git a/setuptools/tests/config/test_setupcfg.py b/setuptools/tests/config/test_setupcfg.py index 7f93858bd4..706e2d0ebe 100644 --- a/setuptools/tests/config/test_setupcfg.py +++ b/setuptools/tests/config/test_setupcfg.py @@ -904,7 +904,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="utf-8", ) setup_cfg = """ diff --git a/setuptools/tests/integration/helpers.py b/setuptools/tests/integration/helpers.py index 82cb36a2e4..615c43b2e0 100644 --- a/setuptools/tests/integration/helpers.py +++ b/setuptools/tests/integration/helpers.py @@ -17,6 +17,7 @@ def run(cmd, env=None): cmd, capture_output=True, text=True, + encoding="utf-8", env={**os.environ, **(env or {})}, # ^-- allow overwriting instead of discarding the current env ) diff --git a/setuptools/tests/test_build_meta.py b/setuptools/tests/test_build_meta.py index 9332781764..c2a1e6dc75 100644 --- a/setuptools/tests/test_build_meta.py +++ b/setuptools/tests/test_build_meta.py @@ -272,14 +272,14 @@ def test_build_with_existing_file_present(self, build_type, tmpdir_cwd): [metadata] name = foo version = file: VERSION - """ + """ ), 'pyproject.toml': DALS( """ [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" - """ + """ ), } @@ -296,7 +296,7 @@ def test_build_with_existing_file_present(self, build_type, tmpdir_cwd): first_result = build_method(dist_dir) # Change version. - with open("VERSION", "wt") as version_file: + with open("VERSION", "wt", encoding="utf-8") as version_file: version_file.write("0.0.2") # Build a *second* sdist/wheel. @@ -306,7 +306,7 @@ def test_build_with_existing_file_present(self, build_type, tmpdir_cwd): assert first_result != second_result # And if rebuilding the exact same sdist/wheel? - open(os.path.join(dist_dir, second_result), 'w').close() + open(os.path.join(dist_dir, second_result), 'wb').close() third_result = build_method(dist_dir) assert third_result == second_result assert os.path.getsize(os.path.join(dist_dir, third_result)) > 0 @@ -568,9 +568,9 @@ def test_build_sdist_version_change(self, build_backend): if not os.path.exists(setup_loc): setup_loc = os.path.abspath("setup.cfg") - with open(setup_loc, 'rt') as file_handler: + with open(setup_loc, 'rt', encoding="utf-8") as file_handler: content = file_handler.read() - with open(setup_loc, 'wt') as file_handler: + with open(setup_loc, 'wt', encoding="utf-8") as file_handler: file_handler.write(content.replace("version='0.0.0'", "version='0.0.1'")) shutil.rmtree(sdist_into_directory) diff --git a/setuptools/tests/test_build_py.py b/setuptools/tests/test_build_py.py index 500a9ab6f3..4aa1fe68fa 100644 --- a/setuptools/tests/test_build_py.py +++ b/setuptools/tests/test_build_py.py @@ -49,7 +49,7 @@ def test_recursive_in_package_data_glob(tmpdir_cwd): ) ) os.makedirs('path/subpath/subsubpath') - open('path/subpath/subsubpath/data', 'w').close() + open('path/subpath/subsubpath/data', 'wb').close() dist.parse_command_line() dist.run_commands() @@ -77,8 +77,8 @@ def test_read_only(tmpdir_cwd): ) ) os.makedirs('pkg') - open('pkg/__init__.py', 'w').close() - open('pkg/data.dat', 'w').close() + open('pkg/__init__.py', 'wb').close() + open('pkg/data.dat', 'wb').close() os.chmod('pkg/__init__.py', stat.S_IREAD) os.chmod('pkg/data.dat', stat.S_IREAD) dist.parse_command_line() @@ -108,8 +108,8 @@ def test_executable_data(tmpdir_cwd): ) ) os.makedirs('pkg') - open('pkg/__init__.py', 'w').close() - open('pkg/run-me', 'w').close() + open('pkg/__init__.py', 'wb').close() + open('pkg/run-me', 'wb').close() os.chmod('pkg/run-me', 0o700) dist.parse_command_line() diff --git a/setuptools/tests/test_config_discovery.py b/setuptools/tests/test_config_discovery.py index ef2979d4f5..72772caebf 100644 --- a/setuptools/tests/test_config_discovery.py +++ b/setuptools/tests/test_config_discovery.py @@ -176,11 +176,11 @@ 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="utf-8") 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="utf-8") dist = _get_dist(tmp_path, {}) # When either parameter package or py_modules is an empty list, @@ -292,11 +292,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 / "setup.cfg").write_text( - "[metadata]\nversion = attr: pkg.version\n" - + (tmp_path / "setup.cfg").read_text() - ) + + config = (tmp_path / "setup.cfg").read_text(encoding="utf-8") + overwrite = { + folder: {"pkg": {"__init__.py": "version = 42"}}, + "setup.cfg": "[metadata]\nversion = attr: pkg.version\n" + config, + } + jaraco.path.build(overwrite, prefix=tmp_path) dist = _get_dist(tmp_path, {}) assert dist.get_name() == "pkg" @@ -312,11 +314,16 @@ 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 / "pyproject.toml").write_text( - "[project]\nname = 'pkg'\ndynamic = ['version']\n" - "[tool.setuptools.dynamic]\nversion = {attr = 'pkg.version'}\n" - ) + + overwrite = { + "src": {"pkg": {"__init__.py": "version = 42"}}, + "pyproject.toml": ( + "[project]\nname = 'pkg'\ndynamic = ['version']\n" + "[tool.setuptools.dynamic]\nversion = {attr = 'pkg.version'}\n" + ), + } + jaraco.path.build(overwrite, prefix=tmp_path) + dist = _get_dist(tmp_path, {}) assert dist.get_version() == "42" assert dist.package_dir == {"": "src"} @@ -354,7 +361,7 @@ 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="utf-8") def test_skip_discovery_with_setupcfg_metadata(self, tmp_path): """Ensure that auto-discovery is not triggered when the project is based on @@ -367,14 +374,14 @@ 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="utf-8") setupcfg = """ [metadata] name = proj version = 42 """ - (tmp_path / "setup.cfg").write_text(DALS(setupcfg)) + (tmp_path / "setup.cfg").write_text(DALS(setupcfg), encoding="utf-8") dist = _get_dist(tmp_path, {}) assert dist.get_name() == "proj" @@ -399,7 +406,7 @@ 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="utf-8") with pytest.raises(PackageDiscoveryError, match="multiple (packages|modules)"): _get_dist(tmp_path, {}) @@ -416,7 +423,7 @@ 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="utf-8") EXAMPLE_SETUPCFG = """ [metadata] @@ -564,9 +571,12 @@ 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") + basic = { + "setup.py": "import setuptools\nsetuptools.setup()", + "README.md": "# Example Package", + "LICENSE": "Copyright (c) 2018", + } + jaraco.path.build(basic, prefix=root) _write_setupcfg(root, options) paths = (root / f for f in files) for path in paths: @@ -591,10 +601,10 @@ def _write_setupcfg(root, options): setupcfg["options"][key] = "\n" + str_value else: setupcfg["options"][key] = str(value) - with open(root / "setup.cfg", "w") as f: + with open(root / "setup.cfg", "w", encoding="utf-8") as f: setupcfg.write(f) print("~~~~~ setup.cfg ~~~~~") - print((root / "setup.cfg").read_text()) + print((root / "setup.cfg").read_text(encoding="utf-8")) def _run_build(path, *flags): diff --git a/setuptools/tests/test_dist_info.py b/setuptools/tests/test_dist_info.py index ad6cebad0b..c6fe97e2ba 100644 --- a/setuptools/tests/test_dist_info.py +++ b/setuptools/tests/test_dist_info.py @@ -198,7 +198,8 @@ def run_command_inner(*cmd, **kwargs): "stderr": subprocess.STDOUT, "stdout": subprocess.PIPE, "text": True, - 'check': True, + "encoding": "utf-8", + "check": True, **kwargs, } cmd = [sys.executable, "-c", "__import__('setuptools').setup()", *map(str, cmd)] diff --git a/setuptools/tests/test_distutils_adoption.py b/setuptools/tests/test_distutils_adoption.py index eb7feba637..74883d2199 100644 --- a/setuptools/tests/test_distutils_adoption.py +++ b/setuptools/tests/test_distutils_adoption.py @@ -8,6 +8,8 @@ IS_PYPY = '__pypy__' in sys.builtin_module_names +_TEXT_KWARGS = {"text": True, "encoding": "utf-8"} # For subprocess.run + def win_sr(env): """ @@ -24,7 +26,7 @@ def win_sr(env): def find_distutils(venv, imports='distutils', env=None, **kwargs): py_cmd = 'import {imports}; print(distutils.__file__)'.format(**locals()) cmd = ['python', '-c', py_cmd] - return venv.run(cmd, env=win_sr(env), text=True, **kwargs) + return venv.run(cmd, env=win_sr(env), **_TEXT_KWARGS, **kwargs) def count_meta_path(venv, env=None): @@ -36,7 +38,7 @@ def count_meta_path(venv, env=None): """ ) cmd = ['python', '-c', py_cmd] - return int(venv.run(cmd, env=win_sr(env), text=True)) + return int(venv.run(cmd, env=win_sr(env), **_TEXT_KWARGS)) skip_without_stdlib_distutils = pytest.mark.skipif( @@ -82,7 +84,7 @@ def test_pip_import(venv): Regression test for #3002. """ cmd = ['python', '-c', 'import pip'] - venv.run(cmd, text=True) + venv.run(cmd, **_TEXT_KWARGS) def test_distutils_has_origin(): @@ -130,7 +132,7 @@ def test_modules_are_not_duplicated_on_import( env = dict(SETUPTOOLS_USE_DISTUTILS=distutils_version) script = ENSURE_IMPORTS_ARE_NOT_DUPLICATED.format(imported_module=imported_module) cmd = ['python', '-c', script] - output = venv.run(cmd, env=win_sr(env), text=True).strip() + output = venv.run(cmd, env=win_sr(env), **_TEXT_KWARGS).strip() assert output == "success" @@ -154,5 +156,5 @@ def test_modules_are_not_duplicated_on_import( def test_log_module_is_not_duplicated_on_import(distutils_version, tmpdir_cwd, venv): env = dict(SETUPTOOLS_USE_DISTUTILS=distutils_version) cmd = ['python', '-c', ENSURE_LOG_IMPORT_IS_NOT_DUPLICATED] - output = venv.run(cmd, env=win_sr(env), text=True).strip() + output = venv.run(cmd, env=win_sr(env), **_TEXT_KWARGS).strip() assert output == "success" diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index a001ae27c5..950cb23d21 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -467,7 +467,7 @@ def distutils_package(): 'from distutils.core import setup', ) with contexts.tempdir(cd=os.chdir): - with open('setup.py', 'w') as f: + with open('setup.py', 'w', encoding="utf-8") as f: f.write(distutils_setup_py) yield @@ -530,6 +530,7 @@ def test_setup_install_includes_dependencies(self, tmp_path, mock_index): stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, + encoding="utf-8", ) assert cp.returncode != 0 try: @@ -784,7 +785,7 @@ def test_setup_requires_honors_pip_env(self, mock_index, monkeypatch): setup_attrs=dict(dependency_links=[]), ) test_setup_cfg = os.path.join(test_pkg, 'setup.cfg') - with open(test_setup_cfg, 'w') as fp: + with open(test_setup_cfg, 'w', encoding="utf-8") as fp: fp.write( DALS( """ @@ -918,7 +919,7 @@ def test_setup_requires_with_find_links_in_setup_cfg( test_setup_py = os.path.join(test_pkg, 'setup.py') test_setup_cfg = os.path.join(test_pkg, 'setup.cfg') os.mkdir(test_pkg) - with open(test_setup_py, 'w') as fp: + with open(test_setup_py, 'w', encoding="utf-8") as fp: if with_dependency_links_in_setup_py: dependency_links = [os.path.join(temp_dir, 'links')] else: @@ -932,7 +933,7 @@ def test_setup_requires_with_find_links_in_setup_cfg( """ ).format(dependency_links=dependency_links) ) - with open(test_setup_cfg, 'w') as fp: + with open(test_setup_cfg, 'w', encoding="utf-8") as fp: fp.write( DALS( """ @@ -984,7 +985,7 @@ def test_setup_requires_with_transitive_extra_dependency(self, monkeypatch): test_pkg = os.path.join(temp_dir, 'test_pkg') test_setup_py = os.path.join(test_pkg, 'setup.py') os.mkdir(test_pkg) - with open(test_setup_py, 'w') as fp: + with open(test_setup_py, 'w', encoding="utf-8") as fp: fp.write( DALS( """ @@ -1068,7 +1069,7 @@ class epcmd(build_py): test_pkg = os.path.join(temp_dir, 'test_pkg') test_setup_py = os.path.join(test_pkg, 'setup.py') os.mkdir(test_pkg) - with open(test_setup_py, 'w') as fp: + with open(test_setup_py, 'w', encoding="utf-8") as fp: fp.write( DALS( """ @@ -1244,7 +1245,7 @@ def create_setup_requires_package( ) else: test_setup_cfg_contents = '' - with open(os.path.join(test_pkg, 'setup.cfg'), 'w') as f: + with open(os.path.join(test_pkg, 'setup.cfg'), 'w', encoding="utf-8") as f: f.write(test_setup_cfg_contents) # setup.py @@ -1255,7 +1256,7 @@ def create_setup_requires_package( setuptools.setup(**%r) """ ) - with open(os.path.join(test_pkg, 'setup.py'), 'w') as f: + with open(os.path.join(test_pkg, 'setup.py'), 'w', encoding="utf-8") as f: f.write(setup_py_template % test_setup_attrs) foobar_path = os.path.join(path, '%s-%s.tar.gz' % (distname, version)) diff --git a/setuptools/tests/test_editable_install.py b/setuptools/tests/test_editable_install.py index df85699586..1df09fd256 100644 --- a/setuptools/tests/test_editable_install.py +++ b/setuptools/tests/test_editable_install.py @@ -144,8 +144,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="utf-8") + (project / "src/mypkg/mod.py").write_text("x = 42", encoding="utf-8") assert subprocess.check_output(cmd).strip() == b"3.14159.post0 foobar 42" diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index ba019dc79d..a4b0ecf398 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -94,7 +94,7 @@ def test_egg_info_save_version_info_setup_empty(self, tmpdir_cwd, env): ei.initialize_options() ei.save_version_info(setup_cfg) - with open(setup_cfg, 'r') as f: + with open(setup_cfg, 'r', encoding="utf-8") as f: content = f.read() assert '[egg_info]' in content @@ -139,7 +139,7 @@ def test_egg_info_save_version_info_setup_defaults(self, tmpdir_cwd, env): ei.initialize_options() ei.save_version_info(setup_cfg) - with open(setup_cfg, 'r') as f: + with open(setup_cfg, 'r', encoding="utf-8") as f: content = f.read() assert '[egg_info]' in content @@ -251,7 +251,7 @@ def test_manifest_template_is_read(self, tmpdir_cwd, env): self._run_egg_info_command(tmpdir_cwd, env) egg_info_dir = os.path.join('.', 'foo.egg-info') sources_txt = os.path.join(egg_info_dir, 'SOURCES.txt') - with open(sources_txt) as f: + with open(sources_txt, encoding="utf-8") as f: assert 'docs/usage.rst' in f.read().split('\n') def _setup_script_with_requires(self, requires, use_setup_cfg=False): @@ -492,7 +492,7 @@ def test_requires( egg_info_dir = os.path.join('.', 'foo.egg-info') requires_txt = os.path.join(egg_info_dir, 'requires.txt') if os.path.exists(requires_txt): - with open(requires_txt) as fp: + with open(requires_txt, encoding="utf-8") as fp: install_requires = fp.read() else: install_requires = '' @@ -538,8 +538,8 @@ def test_provides_extra(self, tmpdir_cwd, env): env=environ, ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') assert 'Provides-Extra: foobar' in pkg_info_lines assert 'Metadata-Version: 2.1' in pkg_info_lines @@ -557,8 +557,8 @@ def test_doesnt_provides_extra(self, tmpdir_cwd, env): env=environ, ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_text = pkginfo_file.read() + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_text = fp.read() assert 'Provides-Extra:' not in pkg_info_text @pytest.mark.parametrize( @@ -636,8 +636,7 @@ def test_setup_cfg_license_file(self, tmpdir_cwd, env, files, license_in_sources ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'SOURCES.txt')) as sources_file: - sources_text = sources_file.read() + sources_text = Path(egg_info_dir, "SOURCES.txt").read_text(encoding="utf-8") if license_in_sources: assert 'LICENSE' in sources_text @@ -849,8 +848,8 @@ def test_setup_cfg_license_files( ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'SOURCES.txt')) as sources_file: - sources_lines = list(line.strip() for line in sources_file) + sources_text = Path(egg_info_dir, "SOURCES.txt").read_text(encoding="utf-8") + sources_lines = [line.strip() for line in sources_text.splitlines()] for lf in incl_licenses: assert sources_lines.count(lf) == 1 @@ -1033,8 +1032,8 @@ def test_setup_cfg_license_file_license_files( ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'SOURCES.txt')) as sources_file: - sources_lines = list(line.strip() for line in sources_file) + sources_text = Path(egg_info_dir, "SOURCES.txt").read_text(encoding="utf-8") + sources_lines = [line.strip() for line in sources_text.splitlines()] for lf in incl_licenses: assert sources_lines.count(lf) == 1 @@ -1065,8 +1064,8 @@ def test_license_file_attr_pkg_info(self, tmpdir_cwd, env): pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]), ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') license_file_lines = [ line for line in pkg_info_lines if line.startswith('License-File:') ] @@ -1086,8 +1085,8 @@ def test_metadata_version(self, tmpdir_cwd, env): data_stream=1, ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') # Update metadata version if changed assert self._extract_mv_version(pkg_info_lines) == (2, 1) @@ -1112,8 +1111,8 @@ def test_long_description_content_type(self, tmpdir_cwd, env): env=environ, ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') expected_line = 'Description-Content-Type: text/markdown' assert expected_line in pkg_info_lines assert 'Metadata-Version: 2.1' in pkg_info_lines @@ -1133,8 +1132,8 @@ def test_long_description(self, tmpdir_cwd, env): data_stream=1, ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') assert 'Metadata-Version: 2.1' in pkg_info_lines assert '' == pkg_info_lines[-1] # last line should be empty long_desc_lines = pkg_info_lines[pkg_info_lines.index('') :] @@ -1165,8 +1164,8 @@ def test_project_urls(self, tmpdir_cwd, env): env=environ, ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') expected_line = 'Project-URL: Link One, https://example.com/one/' assert expected_line in pkg_info_lines expected_line = 'Project-URL: Link Two, https://example.com/two/' @@ -1182,8 +1181,8 @@ def test_license(self, tmpdir_cwd, env): data_stream=1, ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') assert 'License: MIT' in pkg_info_lines def test_license_escape(self, tmpdir_cwd, env): @@ -1197,8 +1196,8 @@ def test_license_escape(self, tmpdir_cwd, env): data_stream=1, ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') assert 'License: This is a long license text ' in pkg_info_lines assert ' over multiple lines' in pkg_info_lines @@ -1216,8 +1215,8 @@ def test_python_requires_egg_info(self, tmpdir_cwd, env): env=environ, ) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') assert 'Requires-Python: >=2.7.12' in pkg_info_lines assert self._extract_mv_version(pkg_info_lines) >= (1, 2) @@ -1240,7 +1239,7 @@ def test_egg_info_includes_setup_py(self, tmpdir_cwd): assert 'setup.py' in egg_info_instance.filelist.files - with open(egg_info_instance.egg_info + "/SOURCES.txt") as f: + with open(egg_info_instance.egg_info + "/SOURCES.txt", encoding="utf-8") as f: sources = f.read().split('\n') assert 'setup.py' in sources @@ -1277,8 +1276,8 @@ def test_egg_info_tag_only_once(self, tmpdir_cwd, env): }) self._run_egg_info_command(tmpdir_cwd, env) egg_info_dir = os.path.join('.', 'foo.egg-info') - with open(os.path.join(egg_info_dir, 'PKG-INFO')) as pkginfo_file: - pkg_info_lines = pkginfo_file.read().split('\n') + with open(os.path.join(egg_info_dir, 'PKG-INFO'), encoding="utf-8") as fp: + pkg_info_lines = fp.read().split('\n') assert 'Version: 0.0.0.dev0' in pkg_info_lines diff --git a/setuptools/tests/test_find_packages.py b/setuptools/tests/test_find_packages.py index cb1900df3d..4fefd3dccf 100644 --- a/setuptools/tests/test_find_packages.py +++ b/setuptools/tests/test_find_packages.py @@ -72,8 +72,7 @@ def _mkdir(self, path, parent_dir=None): def _touch(self, path, dir_=None): if dir_: path = os.path.join(dir_, path) - fp = open(path, 'w') - fp.close() + open(path, 'wb').close() return path def test_regular_package(self): diff --git a/setuptools/tests/test_install_scripts.py b/setuptools/tests/test_install_scripts.py index a783459730..595b7ade67 100644 --- a/setuptools/tests/test_install_scripts.py +++ b/setuptools/tests/test_install_scripts.py @@ -41,7 +41,7 @@ def test_sys_executable_escaping_unix(self, tmpdir, monkeypatch): monkeypatch.setattr('sys.executable', self.unix_exe) with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir)) - with open(str(tmpdir.join('foo')), 'r') as f: + with open(str(tmpdir.join('foo')), 'r', encoding="utf-8") as f: actual = f.readline() assert actual == expected @@ -55,7 +55,7 @@ def test_sys_executable_escaping_win32(self, tmpdir, monkeypatch): monkeypatch.setattr('sys.executable', self.win32_exe) with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir)) - with open(str(tmpdir.join('foo-script.py')), 'r') as f: + with open(str(tmpdir.join('foo-script.py')), 'r', encoding="utf-8") as f: actual = f.readline() assert actual == expected @@ -69,7 +69,7 @@ def test_executable_with_spaces_escaping_unix(self, tmpdir): expected = '#!%s\n' % self.unix_spaces_exe with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir), self.unix_spaces_exe) - with open(str(tmpdir.join('foo')), 'r') as f: + with open(str(tmpdir.join('foo')), 'r', encoding="utf-8") as f: actual = f.readline() assert actual == expected @@ -83,6 +83,6 @@ def test_executable_arg_escaping_win32(self, tmpdir): expected = '#!"%s"\n' % self.win32_exe with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir), '"' + self.win32_exe + '"') - with open(str(tmpdir.join('foo-script.py')), 'r') as f: + with open(str(tmpdir.join('foo-script.py')), 'r', encoding="utf-8") as f: actual = f.readline() assert actual == expected diff --git a/setuptools/tests/test_logging.py b/setuptools/tests/test_logging.py index 7a9a33f1ea..cf89b3bd00 100644 --- a/setuptools/tests/test_logging.py +++ b/setuptools/tests/test_logging.py @@ -33,7 +33,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="utf-8") 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_manifest.py b/setuptools/tests/test_manifest.py index 16fa2c2460..6911b0224c 100644 --- a/setuptools/tests/test_manifest.py +++ b/setuptools/tests/test_manifest.py @@ -54,7 +54,7 @@ def quiet(): def touch(filename): - open(filename, 'w').close() + open(filename, 'wb').close() # The set of files always in the manifest, including all files in the @@ -174,7 +174,7 @@ class TestManifestTest(TempDirTestCase): def setup_method(self, method): super().setup_method(method) - f = open(os.path.join(self.temp_dir, 'setup.py'), 'w') + f = open(os.path.join(self.temp_dir, 'setup.py'), 'w', encoding="utf-8") f.write(SETUP_PY) f.close() """ @@ -212,7 +212,8 @@ def setup_method(self, method): def make_manifest(self, contents): """Write a MANIFEST.in.""" - with open(os.path.join(self.temp_dir, 'MANIFEST.in'), 'w') as f: + manifest = os.path.join(self.temp_dir, 'MANIFEST.in') + with open(manifest, 'w', encoding="utf-8") as f: f.write(DALS(contents)) def get_files(self): @@ -369,7 +370,7 @@ def make_files(self, files): file = os.path.join(self.temp_dir, file) dirname, basename = os.path.split(file) os.makedirs(dirname, exist_ok=True) - open(file, 'w').close() + touch(file) def test_process_template_line(self): # testing all MANIFEST.in template patterns diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py index 41b96614f8..93474ae5af 100644 --- a/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py @@ -2,12 +2,12 @@ import urllib.request import urllib.error import http.client +from inspect import cleandoc from unittest import mock import pytest import setuptools.package_index -from .textwrap import DALS class TestPackageIndex: @@ -257,14 +257,15 @@ class TestPyPIConfig: def test_percent_in_password(self, tmp_home_dir): pypirc = tmp_home_dir / '.pypirc' pypirc.write_text( - DALS( + cleandoc( """ - [pypi] - repository=https://pypi.org - username=jaraco - password=pity% - """ - ) + [pypi] + repository=https://pypi.org + username=jaraco + password=pity% + """ + ), + encoding="utf-8", ) cfg = setuptools.package_index.PyPIConfig() cred = cfg.creds_by_repository['https://pypi.org'] diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 9b4937e213..f666615d99 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -17,7 +17,7 @@ def test_devnull(self, tmpdir): @staticmethod def _file_writer(path): def do_write(): - with open(path, 'w') as f: + with open(path, 'w', encoding="utf-8") as f: f.write('xxx') return do_write @@ -114,7 +114,7 @@ def test_sandbox_violation_raised_hiding_setuptools(self, tmpdir): def write_file(): "Trigger a SandboxViolation by writing outside the sandbox" - with open('/etc/foo', 'w'): + with open('/etc/foo', 'w', encoding="utf-8"): pass with pytest.raises(setuptools.sandbox.SandboxViolation) as caught: @@ -126,8 +126,9 @@ def write_file(): cmd, args, kwargs = caught.value.args assert cmd == 'open' assert args == ('/etc/foo', 'w') - assert kwargs == {} + assert kwargs == {"encoding": "utf-8"} msg = str(caught.value) assert 'open' in msg assert "('/etc/foo', 'w')" in msg + assert "{'encoding': 'utf-8'}" in msg diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 5d597709ed..387ec3bebf 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -10,7 +10,6 @@ import logging import distutils from inspect import cleandoc -from pathlib import Path from unittest import mock import pytest @@ -116,9 +115,7 @@ def latin1_fail(): def touch(path): - if isinstance(path, str): - path = Path(path) - path.write_text('', encoding='utf-8') + open(path, 'wb').close() return path @@ -386,7 +383,7 @@ def test_setup_py_missing(self): assert 'setup.py' not in manifest def test_setup_py_excluded(self): - with open("MANIFEST.in", "w") as manifest_file: + with open("MANIFEST.in", "w", encoding="utf-8") as manifest_file: manifest_file.write("exclude setup.py") dist = Distribution(SETUP_ATTRS) @@ -441,7 +438,7 @@ def test_manifest_is_written_with_utf8_encoding(self): filename = os.path.join('sdist_test', 'smörbröd.py') # Must create the file or it will get stripped. - open(filename, 'w').close() + touch(filename) # Add UTF-8 filename and write manifest with quiet(): @@ -469,7 +466,7 @@ def test_write_manifest_allows_utf8_filenames(self): filename = os.path.join(b'sdist_test', Filenames.utf_8) # Must touch the file or risk removal - open(filename, "w").close() + touch(filename) # Add filename and write manifest with quiet(): @@ -546,7 +543,7 @@ def test_manifest_is_read_with_utf8_encoding(self): manifest.close() # The file must exist to be included in the filelist - open(filename, 'w').close() + touch(filename) # Re-read manifest cmd.filelist.files = [] @@ -577,7 +574,7 @@ def test_read_manifest_skips_non_utf8_filenames(self): manifest.close() # The file must exist to be included in the filelist - open(filename, 'w').close() + touch(filename) # Re-read manifest cmd.filelist.files = [] @@ -598,7 +595,7 @@ def test_sdist_with_utf8_encoded_filename(self): cmd.ensure_finalized() filename = os.path.join(b'sdist_test', Filenames.utf_8) - open(filename, 'w').close() + touch(filename) with quiet(): cmd.run() @@ -639,7 +636,7 @@ def test_sdist_with_latin1_encoded_filename(self): # Latin-1 filename filename = os.path.join(b'sdist_test', Filenames.latin_1) - open(filename, 'w').close() + touch(filename) assert os.path.isfile(filename) with quiet(): @@ -736,7 +733,7 @@ def test_pyproject_toml_excluded(self, source_dir): Check that pyproject.toml can excluded even if present """ touch(source_dir / 'pyproject.toml') - with open('MANIFEST.in', 'w') as mts: + with open('MANIFEST.in', 'w', encoding="utf-8") as mts: print('exclude pyproject.toml', file=mts) dist = Distribution(SETUP_ATTRS) dist.script_name = 'setup.py'