Find Todos by Line Number (or any other reference) in Python
Comments regarding the structure of the program:


Method names. The name of a method should summarize what it does. However, some of your method names are misleading because they do things they should not do.


When I saw the name get_files(), I thought that this method just returns all the files in path, which is not true;
I would assume show_todos() just prints the todos, however, you also call save_csv() method inside it.

Using classes. I would not create a TodoLocator class. It could be just a method to which path, ext, etc. are passed as parameters. You shouldn't use class fields if you can use local variables and pass them between methods (Similarly to how you should avoid using global variables).


Having said that, I would structure the program as follows:

        def _get_files(path, ext) -&gt; List[str]:
            # return a list of files 

        def _find_todos_in_file(file, todo_token, coment_start) -&gt; List[Tuple[str, str]]:
            # return a list of todos in the file

        def find_todos(path, ext, todo_token = 'TODO', comment_start = '#') -&gt; List[Tuple[str, str]]:
            files = _get_files(path, ext)
            return [todo for file in files for todo in _find_todos_in_file(file, todo_token, coment_start)]

        def show_todos(todos: List[Tuple[str, str]]):
            # show todos

        def save_csv(todos: List[Tuple[str, str], file: str):
            # save todos to a csv file

        if __name__ == "__main__":
            todos = find_todos('.', ext='py')
            show_todos(todos)
            save_csv(todos, file)


Other comments:


use for line_no, line in enumerate(input_): instead of:

line_no = 0
with open(f, "r") as input_:
    for line in input_:
        line_no += 1

Regarding if self.comment in line and self.td in line: line: what if you have a line like this:

TODOs.append(todo) # there are no todos in this line

I am not sure about whether you need a recursive param at all. When would you need to use recursive=False?