generated from python-discord/code-jam-template
/
__main__.py
141 lines (114 loc) · 3.44 KB
/
__main__.py
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""Main WTPython file.
This file parses the command line arguments, runs your program,
and then displays solutions for errors if they occur.
"""
from __future__ import annotations
import argparse
import os.path
import runpy
import sys
import textwrap
from typing import Optional
import pyperclip
from rich import print
from wtpython.backends import SearchEngine, StackOverflow, Trace
from wtpython.displays import TextualDisplay, dump_info
from wtpython.displays.textual_display import store_results_in_module
def run(args: list[str]) -> Optional[Trace]:
"""Execute desired program.
This will set sys.argv as the desired program would receive them and execute the script.
If there are no errors, the program will function just like using python, but formatted with Rich.
If there are errors, this will return the exception object.
Args:
args: The arguments to pass to python. args[0] should be the script to run.
Returns:
The exception object if there are errors, otherwise None.
"""
stashed, sys.argv = sys.argv, args
exc = None
try:
runpy.run_path(args[0], run_name="__main__")
except Exception as e:
exc = Trace(e)
finally:
sys.argv = stashed
return exc
def parse_arguments() -> dict:
"""Parse sys.argv arguments.
Args:
None
Returns:
A dictionary of arguments.
"""
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent("""
additional information:
wtpython acts as a substitute for python. Simply add `wt` to the beginning
of the line and call your program with all the appropriate arguments:
$ wtpython [OPTIONS] <script.py> <arguments>"""),
)
parser.add_argument(
"-n",
"--no-display",
action="store_true",
default=False,
help="Run without display",
)
parser.add_argument(
"-c",
"--copy-error",
action="store_true",
default=False,
help="Copy error to clipboard",
)
parser.add_argument(
"--clear-cache",
action="store_true",
default=False,
help="Clear StackOverflow cache",
)
parser.add_argument(
"args",
nargs="*",
help="Arguments normally passed to wtpython",
)
opts = vars(parser.parse_args())
if not opts['args']:
parser.error("Please specify a script to run")
sys.exit(1)
if not os.path.isfile(opts['args'][0]):
parser.error(f"{opts['args'][0]} is not a file")
sys.exit(1)
return opts
def main() -> None:
"""Run the application.
Args:
None
Returns:
None
"""
opts: dict = parse_arguments()
trace: Optional[Trace] = run(opts['args'])
if trace is None: # No exceptions were raised by user's program
return
engine = SearchEngine(trace)
so = StackOverflow.from_trace(trace=trace, clear_cache=opts["clear_cache"])
print(trace.rich_traceback)
if opts["copy_error"]:
pyperclip.copy(trace.error)
if opts["no_display"]:
dump_info(
so_results=so,
search_engine=engine,
)
else:
store_results_in_module(
trace=trace,
so_results=so,
search_engine=engine,
)
try:
TextualDisplay().run()
except Exception as e:
print(e)