From 89e19b23708612b0e4e99d0f6d0d0e2df5fe7624 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 10 Jul 2023 16:26:20 -0700 Subject: [PATCH 1/5] Added failing test case --- tests/test_wholefile.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/test_wholefile.py b/tests/test_wholefile.py index bd5a53139..54657f9f7 100644 --- a/tests/test_wholefile.py +++ b/tests/test_wholefile.py @@ -231,6 +231,39 @@ after b self.assertEqual(fname_a.read_text(), "after a\n") self.assertEqual(fname_b.read_text(), "after b\n") + def test_update_named_file_but_extra_unnamed_code_block(self): + sample_file = "hello.py" + new_content = "new\ncontent\ngoes\nhere\n" + + with open(sample_file, "w") as f: + f.write("Original content\n") + + # Initialize WholeFileCoder with the temporary directory + io = InputOutput(yes=True) + coder = WholeFileCoder(main_model=models.GPT35, io=io, fnames=[sample_file]) + + # Set the partial response content with the updated content + coder.partial_response_content = ( + f"Here's the modified `{sample_file}` file that implements the `accumulate`" + f" function as per the given instructions:\n\n```\n{new_content}```\n\nThis" + " implementation uses a list comprehension to apply the `operation` function to" + " each element of the `collection` and returns the resulting list.\n" + "Run it like this:\n\n" + "```\npython hello.py\n```\n\n" + ) + print(coder.partial_response_content) + + # Call update_files method + edited_files = coder.update_files() + + # Check if the sample file was updated + self.assertIn(sample_file, edited_files) + + # Check if the content of the sample file was updated + with open(sample_file, "r") as f: + updated_content = f.read() + self.assertEqual(updated_content, new_content) + def test_full_edit(self): # Create a few temporary files _, file1 = tempfile.mkstemp() From fd8a6c4e2f8714b7b89349d0ded47e32c786d1a2 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 10 Jul 2023 17:03:31 -0700 Subject: [PATCH 2/5] refactor --- aider/coders/wholefile_coder.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/aider/coders/wholefile_coder.py b/aider/coders/wholefile_coder.py index c59e2e4f1..73f81ce75 100644 --- a/aider/coders/wholefile_coder.py +++ b/aider/coders/wholefile_coder.py @@ -38,14 +38,16 @@ class WholeFileCoder(Coder): def update_files(self, mode="update"): content = self.partial_response_content - edited = set() chat_files = self.get_inchat_relative_files() output = [] lines = content.splitlines(keepends=True) + edits = [] + saw_fname = None fname = None + fname_source = None new_lines = [] for i, line in enumerate(lines): if line.startswith(self.fence[0]) or line.startswith(self.fence[1]): @@ -57,10 +59,8 @@ class WholeFileCoder(Coder): if mode == "diff": output += self.do_live_diff(full_path, new_lines) - elif self.allowed_to_edit(fname): - edited.add(fname) - new_lines = "".join(new_lines) - self.io.write_text(full_path, new_lines) + else: + edits.append((fname, fname_source, new_lines)) fname = None new_lines = [] @@ -105,11 +105,13 @@ class WholeFileCoder(Coder): return "\n".join(output) if fname: - full_path = self.allowed_to_edit(fname) - if full_path: + edits.append((fname, fname_source, new_lines)) + + edited = set() + for fname, fname_source, new_lines in edits: + new_lines = "".join(new_lines) + if self.allowed_to_edit(fname, new_lines): edited.add(fname) - new_lines = "".join(new_lines) - self.io.write_text(full_path, new_lines) return edited From 6fc276d3363aee64f0e59bb78a81c968c4803086 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 10 Jul 2023 17:42:23 -0700 Subject: [PATCH 3/5] prioritize how to allocate code blocks to filenames --- aider/coders/wholefile_coder.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/aider/coders/wholefile_coder.py b/aider/coders/wholefile_coder.py index 73f81ce75..5bfb7d3b7 100644 --- a/aider/coders/wholefile_coder.py +++ b/aider/coders/wholefile_coder.py @@ -63,11 +63,13 @@ class WholeFileCoder(Coder): edits.append((fname, fname_source, new_lines)) fname = None + fname_source = None new_lines = [] continue # fname==None ... starting a new block if i > 0: + fname_source = "block" fname = lines[i - 1].strip() # Did gpt prepend a bogus dir? It especially likes to # include the path/to prefix from the one-shot example in @@ -77,8 +79,10 @@ class WholeFileCoder(Coder): if not fname: # blank line? or ``` was on first line i==0 if saw_fname: fname = saw_fname + fname_source = "saw" elif len(chat_files) == 1: fname = chat_files[0] + fname_source = "chat" else: # TODO: sense which file it is by diff size raise ValueError( @@ -108,10 +112,19 @@ class WholeFileCoder(Coder): edits.append((fname, fname_source, new_lines)) edited = set() - for fname, fname_source, new_lines in edits: - new_lines = "".join(new_lines) - if self.allowed_to_edit(fname, new_lines): - edited.add(fname) + # process from most reliable filename, to least reliable + for source in ("block", "saw", "chat"): + for fname, fname_source, new_lines in edits: + if fname_source != source: + continue + # if a higher priority source already edited the file, skip + if fname in edited: + continue + + # we have a winner + new_lines = "".join(new_lines) + if self.allowed_to_edit(fname, new_lines): + edited.add(fname) return edited From 27fbf8699ff4337aa199f7861cffbca9a072b50f Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Mon, 10 Jul 2023 18:21:06 -0700 Subject: [PATCH 4/5] cleanup --- tests/test_wholefile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_wholefile.py b/tests/test_wholefile.py index 54657f9f7..b702c5d87 100644 --- a/tests/test_wholefile.py +++ b/tests/test_wholefile.py @@ -251,7 +251,6 @@ after b "Run it like this:\n\n" "```\npython hello.py\n```\n\n" ) - print(coder.partial_response_content) # Call update_files method edited_files = coder.update_files() From d22b1dfb328e8871cb4973181931b128ee228c54 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Tue, 11 Jul 2023 09:40:54 -0700 Subject: [PATCH 5/5] small improvement to test --- tests/test_wholefile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_wholefile.py b/tests/test_wholefile.py index b944cc4c1..d6ff75b47 100644 --- a/tests/test_wholefile.py +++ b/tests/test_wholefile.py @@ -268,7 +268,7 @@ after b " implementation uses a list comprehension to apply the `operation` function to" " each element of the `collection` and returns the resulting list.\n" "Run it like this:\n\n" - "```\npython hello.py\n```\n\n" + "```\npython {sample_file}\n```\n\n" ) # Call update_files method