Commit graph

2416 commits

Author SHA1 Message Date
Paul Gauthier
9c0ae45317 change faq links to aider.chat 2023-07-07 09:48:41 -07:00
Paul Gauthier
0716684b34 copy 2023-07-07 09:45:12 -07:00
Paul Gauthier
57d93f8f99 link to ctags faq 2023-07-07 09:41:03 -07:00
Paul Gauthier
f3434418c9 Merge remote-tracking branch 'origin/main' 2023-07-07 09:39:21 -07:00
Paul Gauthier
9e92eaef59 Added FAQ link 2023-07-07 09:39:01 -07:00
Paul Gauthier
07560483cf added faq 2023-07-07 09:36:27 -07:00
paul-gauthier
6e8695999d
Merge pull request #59 from paul-gauthier/glob-add
Updated the /add and /drop commands to glob files
2023-07-07 09:19:27 -07:00
Paul Gauthier
033541d01f Merge branch 'main' into glob-add 2023-07-07 09:10:56 -07:00
Paul Gauthier
681ef38463 Corrected .aider.config.yml -> .aider.conf.yml 2023-07-07 09:07:34 -07:00
Paul Gauthier
1654ee422f add test for conf yml 2023-07-07 09:07:02 -07:00
Paul Gauthier
d8e125f552 added test_no_files_new_file_should_ask 2023-07-07 08:35:22 -07:00
Paul Gauthier
61e9003ce0 handle valerr in render_incremental_response 2023-07-07 08:29:53 -07:00
Paul Gauthier
40787b3637 test case to tickle bug in wholefiles 2023-07-07 08:25:19 -07:00
Paul Gauthier
75b533b4c3 commit new files to git 2023-07-07 08:24:44 -07:00
Paul Gauthier
6a0cff50f8 filter against git 2023-07-06 18:09:26 -07:00
Paul Gauthier
cb2b2c5ce3 Merge branch 'main' into glob-add 2023-07-06 17:53:46 -07:00
Paul Gauthier
d0b7753091 Merge remote-tracking branch 'origin/main' 2023-07-06 17:44:45 -07:00
Paul Gauthier
42977230b1 Mark gpt-4 as always_available to skip the availability check on startup 2023-07-06 17:44:12 -07:00
paul-gauthier
e3497a3fcb
Update README.md 2023-07-06 16:09:39 -07:00
Paul Gauthier
c45074b937 version bump to 0.8.0 2023-07-06 14:08:47 -07:00
Paul Gauthier
25f3db6a72 preparing for v0.8.0 2023-07-06 14:04:20 -07:00
Paul Gauthier
44311f4737 preparing for v0.8.0 2023-07-06 14:03:06 -07:00
paul-gauthier
c5f8f564a4
Merge pull request #58 from paul-gauthier/encodings
Use an explicit encoding to read/write text files, utf-8 by default
2023-07-06 13:40:02 -07:00
Paul Gauthier
95a777a48c More accurate /tokens 2023-07-06 13:35:17 -07:00
Paul Gauthier
6cb4428cb7 Merge branch 'main' into encodings 2023-07-06 13:33:53 -07:00
Paul Gauthier
1291c2424a better message for no /ls output 2023-07-06 12:52:33 -07:00
Paul Gauthier
274caab6b1 Merge branch 'main' into glob-add 2023-07-06 12:43:53 -07:00
Paul Gauthier
09f79e5a42 fix PermErr in test on windows 2023-07-06 12:37:32 -07:00
Paul Gauthier
0f1af1d991 improve filehandle hygene 2023-07-06 12:29:49 -07:00
Paul Gauthier
656af5cd83 rename did not help 2023-07-06 12:26:29 -07:00
Paul Gauthier
2b69c11672 Try renaming to avoid windows PermErr 2023-07-06 12:08:07 -07:00
Paul Gauthier
4a15b6c010 test_run_with_file_utf_unicode_error 2023-07-06 11:57:44 -07:00
Paul Gauthier
7cadfd9b4c aider: Changed encoding to 'latin-1' and provided content that will cause an error when read with 'utf-8' encoding in the test_run_with_file_utf_unicode_error method.
# Context:
USER: do the TODOs
ASSISTANT: I see two TODOs in the provided code.

1. In the `test_run_with_file_utf_unicode_error` method, you need to specify an encoding other than 'utf-8'.
2. In the same method, you need to provide content that will cause an error when read with 'utf-8' encoding.

Here are the proposed changes:

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        encoding = 'pick something other than utf-8' # TODO
=======
        encoding = 'latin-1'
>>>>>>> UPDATED
```

```python
tests/test_coder.py
<<<<<<< ORIGINAL
        some_content_which_will_error_if_read_with_encoding_utf8 = '' # TODO
=======
        some_content_which_will_error_if_read_with_encoding_utf8 = 'ÅÍÎÏ'.encode('utf-16')
>>>>>>> UPDATED
```

In the first change, I've chosen 'latin-1' as the encoding. It's a common encoding that's different from 'utf-8'.

In the second change, I've provided a string of characters that are not valid 'utf-8' when encoded with 'utf-16'. This will cause an error when trying to read the file with 'utf-8' encoding.
2023-07-06 11:56:15 -07:00
Paul Gauthier
5ec5b60660 better /tokens test 2023-07-06 11:50:13 -07:00
Paul Gauthier
eb6ac6841f aider: Redirected the standard output to an instance of io.StringIO and captured the console output of cmd_tokens.
# Context:
USER: how can i capture the console output of `cmd_tokens`?
ASSISTANT: To capture the console output of `cmd_tokens`, you can modify the `test_cmd_tokens` method in the `tests/test_commands.py` file. You can use the `io.StringIO` class to capture the standard output.

Here's how you can do it:

1. Import the `io` module at the top of the file.
2. In the `test_cmd_tokens` method, redirect the standard output to an instance of `io.StringIO` before calling `commands.cmd_tokens("")`.
3. After calling `commands.cmd_tokens("")`, you can get the console output from the `io.StringIO` instance.

Here is the *edit block* for the changes:

```python
tests/test_commands.py
<<<<<<< ORIGINAL
import codecs
import os
import shutil
import tempfile
from unittest import TestCase

from aider import models
from aider.commands import Commands
from aider.io import InputOutput
=======
import codecs
import os
import shutil
import tempfile
from unittest import TestCase
import io

from aider import models
from aider.commands import Commands
from aider.io import InputOutput
>>>>>>> UPDATED

tests/test_commands.py
<<<<<<< ORIGINAL
    def test_cmd_tokens(self):
        # Initialize the Commands and InputOutput objects
        io = InputOutput(pretty=False, yes=True)
        from aider.coders import Coder

        coder = Coder.create(models.GPT35, None, io, openai_api_key="deadbeef")
        commands = Commands(io, coder)

        commands.cmd_add("foo.txt bar.txt")
        commands.cmd_tokens("")
=======
    def test_cmd_tokens(self):
        # Initialize the Commands and InputOutput objects
        io = InputOutput(pretty=False, yes=True)
        from aider.coders import Coder

        coder = Coder.create(models.GPT35, None, io, openai_api_key="deadbeef")
        commands = Commands(io, coder)

        commands.cmd_add("foo.txt bar.txt")

        # Redirect the standard output to an instance of io.StringIO
        stdout = io.StringIO()
        sys.stdout = stdout

        commands.cmd_tokens("")

        # Reset the standard output
        sys.stdout = sys.__stdout__

        # Get the console output
        console_output = stdout.getvalue()
        print(console_output)
>>>>>>> UPDATED
```

Please note that this will only capture the output of `print` statements. If the `cmd_tokens` method writes to the console in a different way (for example, by writing directly to `sys.stdout`), this might not capture that output.
2023-07-06 11:46:20 -07:00
Paul Gauthier
089fa57ede full edit for wholefile 2023-07-06 11:43:20 -07:00
Paul Gauthier
7d3c40ea21 test dry run 2023-07-06 11:34:19 -07:00
Paul Gauthier
7bbf0c0870 test full editblock edit 2023-07-06 11:32:31 -07:00
Paul Gauthier
610dd223b5 added test for choose_fence 2023-07-06 11:08:13 -07:00
Paul Gauthier
b03f2e54cc Merge branch 'main' into encodings 2023-07-06 10:59:45 -07:00
Paul Gauthier
ffee2c9511 test for unicode errors 2023-07-06 10:59:25 -07:00
Paul Gauthier
5647240207 aider: Added a new test test_run_with_file_unicode_error that expects a UnicodeDecodeError to be raised when the run method of the Coder object is called with a file containing non-UTF8 text.
# Context:
USER: I did `git reset --hard HEAD~1` to discard the last edits.
ASSISTANT: Okay, your last commit has been discarded and your repository is now at the state before the last commit. If you need to make any further changes or need assistance with anything else, feel free to ask.
USER: try again, but don't elide code with ...
ASSISTANT: Understood. Here's the updated *edit block* without eliding any code:

```python
tests/test_coder.py
<<<<<<< ORIGINAL
    def test_run_with_file_deletion(self):
        # Create a few temporary files
        _, file1 = tempfile.mkstemp()
        _, file2 = tempfile.mkstemp()

        files = [file1, file2]

        # Initialize the Coder object with the mocked IO and mocked repo
        coder = Coder.create(
            models.GPT4, None, io=InputOutput(), openai_api_key="fake_key", fnames=files
        )

        def mock_send(*args, **kwargs):
            coder.partial_response_content = "ok"
            coder.partial_response_function_call = dict()

        coder.send = MagicMock(side_effect=mock_send)

        # Call the run method with a message
        coder.run(with_message="hi")
        self.assertEqual(len(coder.abs_fnames), 2)

        # Delete one of the files
        os.remove(file1)

        # Call the run method again with a message
        coder.run(with_message="hi")
        self.assertEqual(len(coder.abs_fnames), 1)

if __name__ == "__main__":
    unittest.main()
=======
    def test_run_with_file_deletion(self):
        # Create a few temporary files
        _, file1 = tempfile.mkstemp()
        _, file2 = tempfile.mkstemp()

        files = [file1, file2]

        # Initialize the Coder object with the mocked IO and mocked repo
        coder = Coder.create(
            models.GPT4, None, io=InputOutput(), openai_api_key="fake_key", fnames=files
        )

        def mock_send(*args, **kwargs):
            coder.partial_response_content = "ok"
            coder.partial_response_function_call = dict()

        coder.send = MagicMock(side_effect=mock_send)

        # Call the run method with a message
        coder.run(with_message="hi")
        self.assertEqual(len(coder.abs_fnames), 2)

        # Delete one of the files
        os.remove(file1)

        # Call the run method again with a message
        coder.run(with_message="hi")
        self.assertEqual(len(coder.abs_fnames), 1)

    def test_run_with_file_unicode_error(self):
        # Create a temporary file
        _, file = tempfile.mkstemp()

        # Write some non-UTF8 text into the file
        with open(file, "wb") as f:
            f.write(b"\x80abc")

        # Initialize the Coder object with the temporary file
        coder = Coder.create(
            models.GPT4, None, io=InputOutput(), openai_api_key="fake_key", fnames=[file]
        )

        # Expect a UnicodeDecodeError to be raised when the run method is called
        with self.assertRaises(UnicodeDecodeError):
            coder.run(with_message="hi")

    if __name__ == "__main__":
        unittest.main()
>>>>>>> UPDATED
```

This new test `test_run_with_file_unicode_error` will write non-UTF8 text into a temporary file and expect a `UnicodeDecodeError` to be raised when the `run` method of the `Coder` object is called.
2023-07-06 10:58:36 -07:00
Paul Gauthier
3c443d68d0 working test 2023-07-06 10:55:38 -07:00
Paul Gauthier
79828096d1 copy 2023-07-06 06:55:49 -07:00
Paul Gauthier
c2abffe003 copy 2023-07-05 22:04:35 -07:00
Paul Gauthier
0590846b29 copy 2023-07-05 21:59:05 -07:00
Paul Gauthier
4e84ca97ea copy 2023-07-05 21:58:53 -07:00
Paul Gauthier
ca7d43ac4d Updated HISTORY 2023-07-05 21:56:38 -07:00
Paul Gauthier
d2c13b2976 aider: Refactored cmd_drop method to match glob pattern against the filename only, not the full file path.
# Context:
USER: I ran this command:

 pytest tests/test_commands.py

And got this output:

============================= test session starts ==============================
platform darwin -- Python 3.11.3, pytest-7.3.1, pluggy-1.2.0
rootdir: /Users/gauthier/Projects/aider
configfile: pytest.ini
collected 3 items

tests/test_commands.py ..F                                               [100%]

=================================== FAILURES ===================================
________________ TestCommands.test_cmd_drop_with_glob_patterns _________________

self = <tests.test_commands.TestCommands testMethod=test_cmd_drop_with_glob_patterns>

    def test_cmd_drop_with_glob_patterns(self):
        # Initialize the Commands and InputOutput objects
        io = InputOutput(pretty=False, yes=True)
        from aider.coders import Coder

        coder = Coder.create(models.GPT35, None, io, openai_api_key="deadbeef")
        commands = Commands(io, coder)

        with open("test1.py", "w") as f:
            f.write("print('test1')")
        with open("test2.py", "w") as f:
            f.write("print('test2')")

        # Add some files to the chat session
        commands.cmd_add("*.py")

        # Call the cmd_drop method with a glob pattern
        commands.cmd_drop("*2.py")

        # Check if the Python files have been removed from the chat session
>       self.assertIn(os.path.abspath("test1.py"), coder.abs_fnames)
E       AssertionError: '/private/var/folders/49/kxrdwwbx0h9bchx99397477c0000gn/T/tmpijmz7big/test1.py' not found in set()

tests/test_commands.py:81: AssertionError
----------------------------- Captured stdout call -----------------------------
Model: gpt-3.5-turbo
Git repo: none
Repo-map: disabled
Added test1.py to the chat
Added test2.py to the chat
Removed test2.py from the chat
Removed test1.py from the chat
=========================== short test summary info ============================
FAILED tests/test_commands.py::TestCommands::test_cmd_drop_with_glob_patterns
========================= 1 failed, 2 passed in 0.98s ==========================

ASSISTANT: It seems like the test `test_cmd_drop_with_glob_patterns` is failing because the `cmd_drop` method is removing all files that match the glob pattern "*2.py", which includes "test1.py" and "test2.py". This is because the glob pattern is being matched against the full file path, not just the filename.

To fix this, we need to modify the `cmd_drop` method in the `Commands` class in the `aider/commands.py` file. Specifically, we need to change the way we match the glob pattern against the file paths.

Here are the changes:

```python
aider/commands.py
<<<<<<< ORIGINAL
    def cmd_drop(self, args):
        "Remove matching files from the chat session"

        if not args.strip():
            self.io.tool_output("Dropping all files from the chat session.")
            self.coder.abs_fnames = set()

        for word in args.split():
            matched_files = [
                file
                for file in self.coder.abs_fnames
                if any(glob.fnmatch.fnmatch(os.path.relpath(file, self.coder.root), word) for file in self.coder.abs_fnames)
            ]
            if not matched_files:
                self.io.tool_error(f"No files matched '{word}'")

            for matched_file in matched_files:
                relative_fname = os.path.relpath(matched_file, self.coder.root)
                self.coder.abs_fnames.remove(matched_file)
                self.io.tool_output(f"Removed {relative_fname} from the chat")
=======
    def cmd_drop(self, args):
        "Remove matching files from the chat session"

        if not args.strip():
            self.io.tool_output("Dropping all files from the chat session.")
            self.coder.abs_fnames = set()

        for word in args.split():
            matched_files = [
                file
                for file in self.coder.abs_fnames
                if glob.fnmatch.fnmatch(os.path.basename(file), word)
            ]
            if not matched_files:
                self.io.tool_error(f"No files matched '{word}'")

            for matched_file in matched_files:
                relative_fname = os.path.relpath(matched_file, self.coder.root)
                self.coder.abs_fnames.remove(matched_file)
                self.io.tool_output(f"Removed {relative_fname} from the chat")
>>>>>>> UPDATED
```

This change will ensure that the glob pattern is matched against the filename only, not the full file path. This should fix the failing test.
2023-07-05 21:42:36 -07:00
Paul Gauthier
927b97bea1 Added test1.py and test2.py files, dropped *2.py files, and checked if test1.py file is in the abs_fnames list. 2023-07-05 21:41:31 -07:00