diff --git a/src/python/pants/backend/jvm/tasks/jvm_compile/rsc/rsc_compile.py b/src/python/pants/backend/jvm/tasks/jvm_compile/rsc/rsc_compile.py index eec90ae5ecb..441196b86cf 100644 --- a/src/python/pants/backend/jvm/tasks/jvm_compile/rsc/rsc_compile.py +++ b/src/python/pants/backend/jvm/tasks/jvm_compile/rsc/rsc_compile.py @@ -60,9 +60,11 @@ def stdout_contents(wu): return f.read().rstrip() -def dump_digest(output_dir, digest): - safe_file_dump('{}.digest'.format(output_dir), - '{}:{}'.format(digest.fingerprint, digest.serialized_bytes_length), mode='w') +def write_digest(output_dir, digest): + safe_file_dump( + '{}.digest'.format(output_dir), + mode='w', + payload='{}:{}'.format(digest.fingerprint, digest.serialized_bytes_length)) def load_digest(output_dir): @@ -823,7 +825,7 @@ def _runtool_hermetic(self, main, tool_name, args, distribution, tgt=None, input raise TaskError(res.stderr) if output_dir: - dump_digest(output_dir, res.output_directory_digest) + write_digest(output_dir, res.output_directory_digest) self.context._scheduler.materialize_directories(( DirectoryToMaterialize( # NB the first element here is the root to materialize into, not the dir to snapshot diff --git a/src/python/pants/java/nailgun_executor.py b/src/python/pants/java/nailgun_executor.py index d4a16123dd0..5f118496531 100644 --- a/src/python/pants/java/nailgun_executor.py +++ b/src/python/pants/java/nailgun_executor.py @@ -228,8 +228,8 @@ def ensure_connectable(self, nailgun): def _spawn_nailgun_server(self, fingerprint, jvm_options, classpath, stdout, stderr, stdin): """Synchronously spawn a new nailgun server.""" # Truncate the nailguns stdout & stderr. - safe_file_dump(self._ng_stdout, b'') - safe_file_dump(self._ng_stderr, b'') + safe_file_dump(self._ng_stdout, b'', mode='wb') + safe_file_dump(self._ng_stderr, b'', mode='wb') jvm_options = jvm_options + [self._PANTS_NG_BUILDROOT_ARG, self._create_owner_arg(self._workdir), diff --git a/src/python/pants/option/options_bootstrapper.py b/src/python/pants/option/options_bootstrapper.py index 0d727329532..09ff274e610 100644 --- a/src/python/pants/option/options_bootstrapper.py +++ b/src/python/pants/option/options_bootstrapper.py @@ -103,7 +103,7 @@ def create(cls, env=None, args=None): short_flags = set() def filecontent_for(path): - return FileContent(ensure_text(path), read_file(path)) + return FileContent(ensure_text(path), read_file(path, binary_mode=True)) def capture_the_flags(*args, **kwargs): for arg in args: diff --git a/src/python/pants/pantsd/process_manager.py b/src/python/pants/pantsd/process_manager.py index e42cbfa6ecc..4c14f418bae 100644 --- a/src/python/pants/pantsd/process_manager.py +++ b/src/python/pants/pantsd/process_manager.py @@ -191,7 +191,7 @@ def write_metadata_by_name(self, name, metadata_key, metadata_value): """ self._maybe_init_metadata_dir_by_name(name) file_path = self._metadata_file_path(name, metadata_key) - safe_file_dump(file_path, metadata_value, binary_mode=False) + safe_file_dump(file_path, metadata_value, mode='w') def await_metadata_by_name(self, name, metadata_key, timeout, caster=None): """Block up to a timeout for process metadata to arrive on disk. diff --git a/src/python/pants/pantsd/watchman.py b/src/python/pants/pantsd/watchman.py index 09be21e948d..409c7f0f725 100644 --- a/src/python/pants/pantsd/watchman.py +++ b/src/python/pants/pantsd/watchman.py @@ -82,7 +82,7 @@ def _normalize_watchman_path(self, watchman_path): def _maybe_init_metadata(self): safe_mkdir(self._watchman_work_dir) # Initialize watchman with an empty, but valid statefile so it doesn't complain on startup. - safe_file_dump(self._state_file, b'{}') + safe_file_dump(self._state_file, b'{}', mode='wb') def _construct_cmd(self, cmd_parts, state_file, sock_file, pid_file, log_file, log_level): return [part for part in cmd_parts] + ['--no-save-state', diff --git a/src/python/pants/releases/reversion.py b/src/python/pants/releases/reversion.py index 541fcdb6524..8ed8a5638e2 100644 --- a/src/python/pants/releases/reversion.py +++ b/src/python/pants/releases/reversion.py @@ -30,7 +30,7 @@ def replace_in_file(workspace, src_file_path, from_str, to_str): return None dst_file_path = src_file_path.replace(from_str, to_str) - safe_file_dump(os.path.join(workspace, dst_file_path), data.replace(from_bytes, to_bytes)) + safe_file_dump(os.path.join(workspace, dst_file_path), data.replace(from_bytes, to_bytes), mode='wb') if src_file_path != dst_file_path: os.unlink(os.path.join(workspace, src_file_path)) return dst_file_path @@ -88,7 +88,7 @@ def rewrite_record_file(workspace, src_record_file, mutated_file_tuples): output_line = line output_records.append(output_line) - safe_file_dump(file_name, '\r\n'.join(output_records) + '\r\n', binary_mode=False) + safe_file_dump(file_name, '\r\n'.join(output_records) + '\r\n', mode='w') # The wheel METADATA file will contain a line like: `Version: 1.11.0.dev3+7951ec01`. diff --git a/src/python/pants/util/BUILD b/src/python/pants/util/BUILD index bf1b1f55b64..5e2bd8f4a00 100644 --- a/src/python/pants/util/BUILD +++ b/src/python/pants/util/BUILD @@ -56,6 +56,7 @@ python_library( dependencies = [ ':strutil', '3rdparty/python:future', + 'src/python/pants/base:deprecated', ], ) diff --git a/src/python/pants/util/dirutil.py b/src/python/pants/util/dirutil.py index 7dd542b9dcb..7391f072b15 100644 --- a/src/python/pants/util/dirutil.py +++ b/src/python/pants/util/dirutil.py @@ -16,6 +16,7 @@ from collections import defaultdict from contextlib import contextmanager +from pants.base.deprecated import deprecated_conditional from pants.util.strutil import ensure_text @@ -100,15 +101,17 @@ def safe_mkdir_for_all(paths): created_dirs.add(dir_to_make) -def safe_file_dump(filename, payload, binary_mode=None, mode=None): +# TODO(#6742): payload should be Union[str, bytes] in type hint syntax, but from +# https://pythonhosted.org/an_example_pypi_project/sphinx.html#full-code-example it doesn't appear +# that is possible to represent in docstring type syntax. +def safe_file_dump(filename, payload='', binary_mode=None, mode=None): """Write a string to a file. This method is "safe" to the extent that `safe_open` is "safe". See the explanation on the method doc there. - TODO: The `binary_mode` flag should be deprecated and removed from existing callsites. Once - `binary_mode` is removed, mode can directly default to `wb`. - see https://github.com/pantsbuild/pants/issues/6543 + When `payload` is an empty string (the default), this method can be used as a concise way to + create an empty file along with its containing directory (or truncate it if it already exists). :param string filename: The filename of the file to write to. :param string payload: The string to write to the file. @@ -116,9 +119,19 @@ def safe_file_dump(filename, payload, binary_mode=None, mode=None): :param string mode: A mode argument for the python `open` builtin. Mutually exclusive with binary_mode. """ + deprecated_conditional( + lambda: binary_mode is not None, + removal_version='1.16.0.dev2', + entity_description='The binary_mode argument in safe_file_dump()', + hint_message='Use the mode argument instead!') if binary_mode is not None and mode is not None: raise AssertionError('Only one of `binary_mode` and `mode` may be specified.') + deprecated_conditional( + lambda: mode is None, + removal_version='1.16.0.dev2', + entity_description='Not specifying mode explicitly in safe_file_dump()', + hint_message="Function will default to unicode ('w') when pants migrates to python 3!") if mode is None: if binary_mode is False: mode = 'w' @@ -129,7 +142,7 @@ def safe_file_dump(filename, payload, binary_mode=None, mode=None): f.write(payload) -def maybe_read_file(filename, binary_mode=True): +def maybe_read_file(filename, binary_mode=None): """Read and return the contents of a file in a single file.read(). :param string filename: The filename of the file to read. @@ -137,13 +150,22 @@ def maybe_read_file(filename, binary_mode=True): :returns: The contents of the file, or opening the file fails for any reason :rtype: string """ + # TODO(#7121): Default binary_mode=False after the python 3 switchover! + deprecated_conditional( + lambda: binary_mode is None, + removal_version='1.16.0.dev2', + entity_description='Not specifying binary_mode explicitly in maybe_read_file()', + hint_message='Function will default to unicode when pants migrates to python 3!') + if binary_mode is None: + binary_mode = True + try: return read_file(filename, binary_mode=binary_mode) except IOError: return None -def read_file(filename, binary_mode=True): +def read_file(filename, binary_mode=None): """Read and return the contents of a file in a single file.read(). :param string filename: The filename of the file to read. @@ -151,6 +173,15 @@ def read_file(filename, binary_mode=True): :returns: The contents of the file. :rtype: string """ + # TODO(#7121): Default binary_mode=False after the python 3 switchover! + deprecated_conditional( + lambda: binary_mode is None, + removal_version='1.16.0.dev2', + entity_description='Not specifying binary_mode explicitly in read_file()', + hint_message='Function will default to unicode when pants migrates to python 3!') + if binary_mode is None: + binary_mode = True + mode = 'rb' if binary_mode else 'r' with open(filename, mode) as f: return f.read() diff --git a/tests/python/pants_test/backend/jvm/subsystems/test_incomplete_custom_scala.py b/tests/python/pants_test/backend/jvm/subsystems/test_incomplete_custom_scala.py index 5ed3a074b62..6b8243a9d1b 100644 --- a/tests/python/pants_test/backend/jvm/subsystems/test_incomplete_custom_scala.py +++ b/tests/python/pants_test/backend/jvm/subsystems/test_incomplete_custom_scala.py @@ -37,7 +37,7 @@ def tmp_custom_scala(self, path_suffix): def tmp_scalastyle_config(self): with temporary_dir(root_dir=get_buildroot()) as scalastyle_dir: path = os.path.join(scalastyle_dir, 'config.xml') - safe_file_dump(path, '''''', binary_mode=False) + safe_file_dump(path, '''''', mode='w') yield '--lint-scalastyle-config={}'.format(path) def pants_run(self, options=None): diff --git a/tests/python/pants_test/backend/jvm/tasks/test_bundle_create.py b/tests/python/pants_test/backend/jvm/tasks/test_bundle_create.py index 94085f0077e..a235052cd3c 100644 --- a/tests/python/pants_test/backend/jvm/tasks/test_bundle_create.py +++ b/tests/python/pants_test/backend/jvm/tasks/test_bundle_create.py @@ -38,7 +38,7 @@ def add_consolidated_bundle(self, context, tgt, files_dict): entry_path = safe_mkdtemp(dir=target_dir) classpath_dir = safe_mkdtemp(dir=target_dir) for rel_path, content in files_dict.items(): - safe_file_dump(os.path.join(entry_path, rel_path), content, binary_mode=False) + safe_file_dump(os.path.join(entry_path, rel_path), content, mode='w') # Create Jar to mimic consolidate classpath behavior. jarpath = os.path.join(classpath_dir, 'output-0.jar') @@ -71,12 +71,12 @@ def setUp(self): JarDependency(org='org.gnu', name='gary', rev='4.0.0', ext='tar.gz')]) - safe_file_dump(os.path.join(self.build_root, 'resources/foo/file'), '// dummy content', binary_mode=False) + safe_file_dump(os.path.join(self.build_root, 'resources/foo/file'), '// dummy content', mode='w') self.resources_target = self.make_target('//resources:foo-resources', Resources, sources=['foo/file']) # This is so that payload fingerprint can be computed. - safe_file_dump(os.path.join(self.build_root, 'foo/Foo.java'), '// dummy content', binary_mode=False) + safe_file_dump(os.path.join(self.build_root, 'foo/Foo.java'), '// dummy content', mode='w') self.java_lib_target = self.make_target('//foo:foo-library', JavaLibrary, sources=['Foo.java']) self.binary_target = self.make_target(spec='//foo:foo-binary', diff --git a/tests/python/pants_test/backend/jvm/tasks/test_consolidate_classpath.py b/tests/python/pants_test/backend/jvm/tasks/test_consolidate_classpath.py index b30dbf7a17c..79e62c917dd 100644 --- a/tests/python/pants_test/backend/jvm/tasks/test_consolidate_classpath.py +++ b/tests/python/pants_test/backend/jvm/tasks/test_consolidate_classpath.py @@ -48,12 +48,12 @@ def setUp(self): JarDependency(org='org.gnu', name='gary', rev='4.0.0', ext='tar.gz')]) - safe_file_dump(os.path.join(self.build_root, 'resources/foo/file'), '// dummy content', binary_mode=False) + safe_file_dump(os.path.join(self.build_root, 'resources/foo/file'), '// dummy content', mode='w') self.resources_target = self.make_target('//resources:foo-resources', Resources, sources=['foo/file']) # This is so that payload fingerprint can be computed. - safe_file_dump(os.path.join(self.build_root, 'foo/Foo.java'), '// dummy content', binary_mode=False) + safe_file_dump(os.path.join(self.build_root, 'foo/Foo.java'), '// dummy content', mode='w') self.java_lib_target = self.make_target('//foo:foo-library', JavaLibrary, sources=['Foo.java']) self.binary_target = self.make_target(spec='//foo:foo-binary', diff --git a/tests/python/pants_test/backend/jvm/tasks/test_junit_run.py b/tests/python/pants_test/backend/jvm/tasks/test_junit_run.py index c25edde0b26..43e4ff619cc 100644 --- a/tests/python/pants_test/backend/jvm/tasks/test_junit_run.py +++ b/tests/python/pants_test/backend/jvm/tasks/test_junit_run.py @@ -218,7 +218,7 @@ def test_request_classes_by_source(self): # Existing files (with and without the method name) should trigger. srcfile = os.path.join(self.test_workdir, 'this.is.a.source.file.scala') - safe_file_dump(srcfile, 'content!', binary_mode=False) + safe_file_dump(srcfile, 'content!', mode='w') self.assertTrue(JUnitRun.request_classes_by_source([srcfile])) self.assertTrue(JUnitRun.request_classes_by_source(['{}#method'.format(srcfile)])) diff --git a/tests/python/pants_test/base/test_exception_sink_integration.py b/tests/python/pants_test/base/test_exception_sink_integration.py index cffc3b95578..9ea4e38f673 100644 --- a/tests/python/pants_test/base/test_exception_sink_integration.py +++ b/tests/python/pants_test/base/test_exception_sink_integration.py @@ -198,7 +198,7 @@ def test_reset_interactive_output_stream(self): with temporary_dir() as tmpdir: some_file = os.path.join(tmpdir, 'some_file') - safe_file_dump(some_file, b'', binary_mode=True) + safe_file_dump(some_file, b'', mode='wb') redirected_pants_run = self.run_pants([ "--lifecycle-stubs-new-interactive-stream-output-file={}".format(some_file), ] + lifecycle_stub_cmdline) diff --git a/tests/python/pants_test/binaries/test_binary_util.py b/tests/python/pants_test/binaries/test_binary_util.py index 150d09907b5..a81224d27c9 100644 --- a/tests/python/pants_test/binaries/test_binary_util.py +++ b/tests/python/pants_test/binaries/test_binary_util.py @@ -346,11 +346,11 @@ def test_select_argv(self): """Test invoking binary_util.py as a standalone script.""" with temporary_dir() as tmp_dir: config_file_loc = os.path.join(tmp_dir, 'pants.ini') - safe_file_dump(config_file_loc, """\ + safe_file_dump(config_file_loc, mode='w', payload="""\ [GLOBAL] allow_external_binary_tool_downloads: True pants_bootstrapdir: {} -""".format(tmp_dir), binary_mode=False) +""".format(tmp_dir)) expected_output_glob = os.path.join( tmp_dir, 'bin', 'cmake', '*', '*', '3.9.5', 'cmake') with environment_as(PANTS_CONFIG_FILES='[{!r}]'.format(config_file_loc)): diff --git a/tests/python/pants_test/build_graph/test_subproject_integration.py b/tests/python/pants_test/build_graph/test_subproject_integration.py index 208cce39fd5..8861003fce6 100644 --- a/tests/python/pants_test/build_graph/test_subproject_integration.py +++ b/tests/python/pants_test/build_graph/test_subproject_integration.py @@ -76,7 +76,7 @@ def harness(): try: for name, content in BUILD_FILES.items(): - safe_file_dump(name, dedent(content), binary_mode=False) + safe_file_dump(name, dedent(content), mode='w') yield finally: safe_rmtree(SUBPROJ_SPEC) @@ -102,7 +102,7 @@ def test_subproject_with_flag(self): """ with harness(): # Has dependencies below the subproject. - pants_args = ['--subproject-roots={}'.format(SUBPROJ_ROOT), + pants_args = ['--subproject-roots={}'.format(SUBPROJ_ROOT), 'dependencies', SUBPROJ_SPEC] self.assert_success(self.run_pants(pants_args)) diff --git a/tests/python/pants_test/engine/legacy/test_address_mapper.py b/tests/python/pants_test/engine/legacy/test_address_mapper.py index fef53234a73..0c2323d9ca5 100644 --- a/tests/python/pants_test/engine/legacy/test_address_mapper.py +++ b/tests/python/pants_test/engine/legacy/test_address_mapper.py @@ -40,15 +40,15 @@ def create_build_files(self): safe_mkdir(dir_b) safe_mkdir(dir_a_subdir) - safe_file_dump(os.path.join(self.build_root, 'BUILD'), 'target(name="a")\ntarget(name="b")', binary_mode=False) - safe_file_dump(os.path.join(self.build_root, 'BUILD.other'), 'target(name="c")', binary_mode=False) + safe_file_dump(os.path.join(self.build_root, 'BUILD'), 'target(name="a")\ntarget(name="b")', mode='w') + safe_file_dump(os.path.join(self.build_root, 'BUILD.other'), 'target(name="c")', mode='w') - safe_file_dump(os.path.join(dir_a, 'BUILD'), 'target(name="a")\ntarget(name="b")', binary_mode=False) - safe_file_dump(os.path.join(dir_a, 'BUILD.other'), 'target(name="c")', binary_mode=False) + safe_file_dump(os.path.join(dir_a, 'BUILD'), 'target(name="a")\ntarget(name="b")', mode='w') + safe_file_dump(os.path.join(dir_a, 'BUILD.other'), 'target(name="c")', mode='w') - safe_file_dump(os.path.join(dir_b, 'BUILD'), 'target(name="a")', binary_mode=False) + safe_file_dump(os.path.join(dir_b, 'BUILD'), 'target(name="a")', mode='w') - safe_file_dump(os.path.join(dir_a_subdir, 'BUILD'), 'target(name="a")', binary_mode=False) + safe_file_dump(os.path.join(dir_a_subdir, 'BUILD'), 'target(name="a")', mode='w') def test_is_valid_single_address(self): self.create_build_files() diff --git a/tests/python/pants_test/engine/legacy/test_console_rule_integration.py b/tests/python/pants_test/engine/legacy/test_console_rule_integration.py index c0e92db21b9..7c274b5fec8 100644 --- a/tests/python/pants_test/engine/legacy/test_console_rule_integration.py +++ b/tests/python/pants_test/engine/legacy/test_console_rule_integration.py @@ -78,7 +78,7 @@ def test_v2_list_loop(self): rel_tmpdir = fast_relpath(tmpdir, get_buildroot()) def dump(content): - safe_file_dump(os.path.join(tmpdir, 'BUILD'), content, mode="w") + safe_file_dump(os.path.join(tmpdir, 'BUILD'), content, mode='w') # Dump an initial target before starting the loop. dump('target(name="one")') diff --git a/tests/python/pants_test/jvm/jvm_task_test_base.py b/tests/python/pants_test/jvm/jvm_task_test_base.py index 5481ecc31ad..e48a0a2689a 100644 --- a/tests/python/pants_test/jvm/jvm_task_test_base.py +++ b/tests/python/pants_test/jvm/jvm_task_test_base.py @@ -53,7 +53,7 @@ def add_to_runtime_classpath(self, context, tgt, files_dict): safe_mkdir(target_dir) classpath_dir = safe_mkdtemp(dir=target_dir) for rel_path, content in files_dict.items(): - safe_file_dump(os.path.join(classpath_dir, rel_path), content, binary_mode=False) + safe_file_dump(os.path.join(classpath_dir, rel_path), content, mode='w') # Add to the classpath. runtime_classpath.add_for_target(tgt, [('default', classpath_dir)]) diff --git a/tests/python/pants_test/pantsd/test_pantsd_integration.py b/tests/python/pants_test/pantsd/test_pantsd_integration.py index bc1e0480c48..ffa1e3005b5 100644 --- a/tests/python/pants_test/pantsd/test_pantsd_integration.py +++ b/tests/python/pants_test/pantsd/test_pantsd_integration.py @@ -358,17 +358,17 @@ def test_pantsd_invalidation_stale_sources(self): pantsd_run(['help']) checker.assert_started() - safe_file_dump(test_build_file, "python_library(sources=globs('some_non_existent_file.py'))", binary_mode=False) + safe_file_dump(test_build_file, "python_library(sources=globs('some_non_existent_file.py'))", mode='w') result = pantsd_run(export_cmd) checker.assert_running() assertNotRegex(self, result.stdout_data, has_source_root_regex) - safe_file_dump(test_build_file, "python_library(sources=globs('*.py'))", binary_mode=False) + safe_file_dump(test_build_file, "python_library(sources=globs('*.py'))", mode='w') result = pantsd_run(export_cmd) checker.assert_running() assertNotRegex(self, result.stdout_data, has_source_root_regex) - safe_file_dump(test_src_file, 'import this\n', binary_mode=False) + safe_file_dump(test_src_file, 'import this\n', mode='w') result = pantsd_run(export_cmd) checker.assert_running() assertRegex(self, result.stdout_data, has_source_root_regex) @@ -385,7 +385,7 @@ def test_pantsd_parse_exception_success(self): try: safe_mkdir(test_path, clean=True) - safe_file_dump(test_build_file, "{}()".format(invalid_symbol), binary_mode=False) + safe_file_dump(test_build_file, "{}()".format(invalid_symbol), mode='w') for _ in range(3): with self.pantsd_run_context(success=False) as (pantsd_run, checker, _, _): result = pantsd_run(['list', 'testprojects::']) diff --git a/tests/python/pants_test/pantsd/test_process_manager.py b/tests/python/pants_test/pantsd/test_process_manager.py index 4886dc079ab..573546ec926 100644 --- a/tests/python/pants_test/pantsd/test_process_manager.py +++ b/tests/python/pants_test/pantsd/test_process_manager.py @@ -149,7 +149,7 @@ def test_deadline_until(self): def test_wait_for_file(self): with temporary_dir() as td: test_filename = os.path.join(td, 'test.out') - safe_file_dump(test_filename, 'test', binary_mode=False) + safe_file_dump(test_filename, 'test', mode='w') self.pmm._wait_for_file(test_filename, timeout=.1) def test_wait_for_file_timeout(self): diff --git a/tests/python/pants_test/pantsd/test_watchman.py b/tests/python/pants_test/pantsd/test_watchman.py index 0cab6a9653b..2a7a5294f44 100644 --- a/tests/python/pants_test/pantsd/test_watchman.py +++ b/tests/python/pants_test/pantsd/test_watchman.py @@ -57,12 +57,13 @@ def test_resolve_watchman_path_provided_exception(self): metadata_base_dir=self.subprocess_dir) def test_maybe_init_metadata(self): + # TODO(#7106): is this the right path to patch? with mock.patch('pants.pantsd.watchman.safe_mkdir', **self.PATCH_OPTS) as mock_mkdir, \ mock.patch('pants.pantsd.watchman.safe_file_dump', **self.PATCH_OPTS) as mock_file_dump: self.watchman._maybe_init_metadata() mock_mkdir.assert_called_once_with(self._watchman_dir) - mock_file_dump.assert_called_once_with(self._state_file, b'{}') + mock_file_dump.assert_called_once_with(self._state_file, b'{}', mode='wb') def test_construct_cmd(self): output = self.watchman._construct_cmd(['cmd', 'parts', 'etc'], diff --git a/tests/python/pants_test/test_base.py b/tests/python/pants_test/test_base.py index a3b3eb7c01c..38653ea25b5 100644 --- a/tests/python/pants_test/test_base.py +++ b/tests/python/pants_test/test_base.py @@ -632,7 +632,7 @@ def make_snapshot(self, files): """ with temporary_dir() as temp_dir: for file_name, content in files.items(): - safe_file_dump(os.path.join(temp_dir, file_name), content) + safe_file_dump(os.path.join(temp_dir, file_name), content, mode='w') return self.scheduler.capture_snapshots(( PathGlobsAndRoot(PathGlobs(('**',)), text_type(temp_dir)), ))[0] diff --git a/tests/python/pants_test/util/test_dirutil.py b/tests/python/pants_test/util/test_dirutil.py index 1248f8ce985..3481492de73 100644 --- a/tests/python/pants_test/util/test_dirutil.py +++ b/tests/python/pants_test/util/test_dirutil.py @@ -396,6 +396,8 @@ def test_rm_rf_no_such_file_not_an_error(self, file_name='./vanishing_file'): def assert_dump_and_read(self, test_content, dump_kwargs, read_kwargs): with temporary_dir() as td: test_filename = os.path.join(td, 'test.out') + # TODO(#7121): remove all deprecated usages of `binary_mode` and `mode` arguments to + # safe_file_dump() in this file when the deprecation period is over! safe_file_dump(test_filename, test_content, **dump_kwargs) self.assertEqual(read_file(test_filename, **read_kwargs), test_content) @@ -407,7 +409,7 @@ def test_readwrite_file_binary(self): self.assert_dump_and_read(b'333', {'mode': 'w'}, {'binary_mode': True}) with self.assertRaises(AssertionError): # Both `binary_mode` and `mode` specified. - # TODO: Should be removed along with https://github.com/pantsbuild/pants/issues/6543 + # TODO(#6543): Should be removed along with https://github.com/pantsbuild/pants/issues/6543 self.assert_dump_and_read(b'333', {'binary_mode': True, 'mode': 'wb'}, {'binary_mode': True}) def test_readwrite_file_unicode(self):