forked from fufvocdi/Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyshell.py
More file actions
152 lines (133 loc) · 4.78 KB
/
Copy pathpyshell.py
File metadata and controls
152 lines (133 loc) · 4.78 KB
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
142
143
144
145
146
147
148
149
150
151
152
# coding:utf-8
import sys,os, traceback,marshal,builtins, warnings, platform
import runpy
try: # 用于打开pyc文件
from importlib._bootstrap_external import MAGIC_NUMBER
except ImportError:
from importlib._bootstrap import MAGIC_NUMBER
# 默认的环境变量
vars_={"__annotations__":{},"__builtins__":__builtins__,"__doc__":None,
"__loader__":__loader__,"__name__":"__main__","__package__":None,
"__spec__":None}
_TITLE="PyShell"
__version__="1.3.3"
def exec_code(code,line=0):
# 执行代码
try:
## result=eval(code,vars_) # 旧版:尝试使用exec或eval, eval优先
## builtins._ = result
## if result is not None:print(repr(result))
## except SyntaxError:
## try:
## exec(code,vars_)
## except BaseException as err:
## try:raise err from None
## except:handle()
if code.strip():
exec(compile(code,'<PyShell #{}>'.format(line),'single'),vars_)
except BaseException:handle()
def run_file(filename):
code=open(filename,'rb').read()
if filename.lower().endswith(".pyc"):
if code[:4] != MAGIC_NUMBER:
warnings.warn("警告: Pyc文件头不匹配。")
code=code[16:] if code[16]==227 else code[12:]
code=marshal.loads(code)
else:
code=code.decode(encoding='utf-8').strip('\ufeff')
backup=sys.argv
sys.argv=sys.argv[1:]
sys.path.append(os.path.split(filename)[0])
vars_["__file__"]=filename
try:exec(code,vars_)
except BaseException:handle()
sys.argv=backup
def in_pythonw(): # 判断是否为pythonw(无控制台窗口)的环境
return "pythonw.exe" in sys.executable or "pyshell_w.exe" in sys.executable
def handle():
traceback.print_exc()
def ask_for_exit(console=None):
msg="\n^C确实要退出吗?(Y/N) "
if console:console.ctext(msg,"green",None,"bold",end='')
else:print(msg,end='')
try:
if input().lower().startswith('y'):return 0
except KeyboardInterrupt:
return ask_for_exit(console)
def help():
print("""用法 Usage:\n
pyshell 某py,pyw或pyc文件: 运行脚本。
pyshell -c <Python代码> : 运行指定的Python指令。
pyshell -m <模块名称> : 运行一个模块。
pyshell -i <其他参数>: 运行脚本或模块后进入交互模式, 建议用于调试python脚本。
pyshell <其他参数> --no-autoexec : 不自动运行autoexec.py。
pyshell -h (或 /?): 显示此帮助信息。
不带参数: 直接进入交互模式。
""")
def main():
# 执行autoexec.py
if '--no-autoexec' not in sys.argv:
try:
autoexecfile=os.path.split(sys.argv[0])[0]+"\\autoexec.py"
run_file(autoexecfile)
except BaseException:handle()
else:sys.argv.remove('--no-autoexec') # 便于处理其他参数
# 处理命令行参数
if len(sys.argv)>1:
if sys.argv[1]=="-i":
interactive=True
del sys.argv[1] # 便于处理其他参数
else:
interactive=False
if sys.argv[1]=="-c":
if len(sys.argv)>=3:# 检查有无提供代码
try:exec_code(sys.argv[2])
except BaseException:handle()
else:help()
elif sys.argv[1]=="-m":
if len(sys.argv)>=3:# 检查有无提供模块名称
global vars_
modname=sys.argv[2]
del sys.argv[1:3]
try:vars_ = runpy.run_module(modname,init_globals=vars_,
run_name='__main__')
except BaseException:handle()
else:help()
elif sys.argv[1] in ('/?','-?','-h','--help'):
help()
else:
filename=os.path.realpath(sys.argv[1])
run_file(filename)
if not interactive:return
print("PyShell v%s (Python %s)"%(__version__, platform.python_version()))
if not in_pythonw():
try:
import console_tool # 初始化console标题, 颜色等
c=console_tool.Console()
c.colorize()
c.title(_TITLE)
input=c.input
except:
c = None
input=builtins.input
os.system("title %s"%_TITLE)
else:
c=None
input=__builtins__.input
lineno=1
while True:
try:
if getattr(sys.stdin,"closed",False): # 其他代码请求了退出Python
return
code=input(">>> ")
if c is not None:
c.title("{} - {}".format(_TITLE,code))
exec_code(code,lineno)
lineno+=1
if c is not None:
c.title(_TITLE)
except KeyboardInterrupt:
if ask_for_exit(c)==0:
return
except EOFError:break
if __name__=="__main__":main()