File size: 3,462 Bytes
4c5305b
ae0dabc
4c5305b
eb73a33
 
 
ae0dabc
 
eb73a33
 
4c5305b
eb73a33
 
 
 
 
 
 
 
 
ae0dabc
 
 
 
 
eb73a33
 
 
 
 
c21268c
 
 
 
 
 
eb73a33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c21268c
ae0dabc
eb73a33
 
 
 
 
 
 
 
 
ae0dabc
 
eb73a33
ae0dabc
 
 
4c5305b
 
 
eb73a33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c5305b
 
 
 
ae0dabc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import gradio as gr
import flake8.main.application
import autopep8
import pylint.lint
import isort
import black
import tempfile
import os
import difflib
import io

def lint_and_format(code, enable_flake8, enable_pylint, enable_isort, enable_black):
    flake8_output = ""
    pylint_output = ""
    isort_output = ""
    formatted_code = code
    diff_output = ""
    black_output = ""

    # Temporary file for linters
    with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.py') as temp_file:
        temp_file.write(code)
        temp_file_path = temp_file.name

    try:
        # Flake8
        if enable_flake8:
            app = flake8.main.application.Application()
            app.initialize(['--format=default', temp_file_path])
            app.run_checks()
            # Corrected Flake8 output retrieval
            flake8_output_stream = io.StringIO()
            app.report_formatter.output_file = flake8_output_stream
            app.report_formatter.start()
            app.report_formatter.stop()
            flake8_output = flake8_output_stream.getvalue().strip()

        # Pylint
        if enable_pylint:
            pylint_output_stream = io.StringIO()
            pylint_runner = pylint.lint.Run([temp_file_path], do_exit=False, output_stream=pylint_output_stream)
            pylint_output = pylint_output_stream.getvalue().strip()

        # isort
        if enable_isort:
            isort_output = isort.file(temp_file_path, show_diff=True).strip()

        # Black
        if enable_black:
            try:
                formatted_code = black.format_file_in_place(
                    src=temp_file_path,
                    fast=False,
                    mode=black.FileMode(),
                    write_back=black.WriteBack.YES,
                )
                with open(temp_file_path, "r") as f:
                    formatted_code = f.read()
            except black.NothingChanged:
                pass

        # AutoPEP8 (if Black is not enabled)
        if not enable_black:
            formatted_code = autopep8.fix_code(formatted_code)

        # Diff
        diff = difflib.unified_diff(code.splitlines(keepends=True), formatted_code.splitlines(keepends=True), fromfile="original.py", tofile="formatted.py")
        diff_output = "".join(diff)

        return flake8_output, pylint_output, isort_output, formatted_code, diff_output

    except Exception as e:
        return f"An error occurred: {str(e)}", "", "", code, ""

    finally:
        os.remove(temp_file_path)

def main():
    with gr.Interface(
        fn=lint_and_format,
        inputs=[
            gr.Code(label="Python Code", language="python", lines=10),
            gr.Checkbox(label="Enable Flake8", value=True),
            gr.Checkbox(label="Enable Pylint", value=False),
            gr.Checkbox(label="Enable isort", value=True),
            gr.Checkbox(label="Enable Black", value=True),
        ],
        outputs=[
            gr.Textbox(label="Flake8 Output"),
            gr.Textbox(label="Pylint Output"),
            gr.Textbox(label="isort Output"),
            gr.Code(label="Formatted Code", language="python"),
            gr.Textbox(label="Diff"),
        ],
        title="Python Code Linter and Formatter",
        description="Paste your Python code, and this tool will lint and format it using Flake8, Pylint, isort and Black/AutoPEP8.",
    ) as demo:
        demo.launch()

if __name__ == "__main__":
    main()