Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
5d2af63c
Commit
5d2af63c
authored
May 26, 2002
by
Chui Tey
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
GvR's rpc patch
parent
38d53451
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1208 additions
and
94 deletions
+1208
-94
Lib/idlelib/Debugger.py
Lib/idlelib/Debugger.py
+82
-58
Lib/idlelib/PyShell.py
Lib/idlelib/PyShell.py
+188
-17
Lib/idlelib/RemoteDebugger.py
Lib/idlelib/RemoteDebugger.py
+287
-0
Lib/idlelib/RemoteObjectBrowser.py
Lib/idlelib/RemoteObjectBrowser.py
+36
-0
Lib/idlelib/ScriptBinding.py
Lib/idlelib/ScriptBinding.py
+36
-19
Lib/idlelib/rpc.py
Lib/idlelib/rpc.py
+530
-0
Lib/idlelib/run.py
Lib/idlelib/run.py
+49
-0
No files found.
Lib/idlelib/Debugger.py
View file @
5d2af63c
import
os
import
bdb
import
types
import
traceback
from
Tkinter
import
*
from
WindowList
import
ListedToplevel
...
...
@@ -7,20 +8,66 @@ from WindowList import ListedToplevel
import
StackViewer
class
Debugger
(
bdb
.
Bdb
):
class
Idb
(
bdb
.
Bdb
):
def
__init__
(
self
,
gui
):
self
.
gui
=
gui
bdb
.
Bdb
.
__init__
(
self
)
def
user_line
(
self
,
frame
):
# get the currently executing function
co_filename
=
frame
.
f_code
.
co_filename
co_name
=
frame
.
f_code
.
co_name
try
:
func
=
frame
.
f_locals
[
co_name
]
if
getattr
(
func
,
"DebuggerStepThrough"
,
0
):
print
"XXXX DEBUGGER STEPPING THROUGH"
self
.
set_step
()
return
except
:
pass
if
co_filename
in
(
'rpc.py'
,
'<string>'
):
self
.
set_step
()
return
if
co_filename
.
endswith
(
'threading.py'
):
self
.
set_step
()
return
message
=
self
.
__frame2message
(
frame
)
self
.
gui
.
interaction
(
message
,
frame
)
def
user_exception
(
self
,
frame
,
info
):
message
=
self
.
__frame2message
(
frame
)
self
.
gui
.
interaction
(
message
,
frame
,
info
)
def
__frame2message
(
self
,
frame
):
code
=
frame
.
f_code
filename
=
code
.
co_filename
lineno
=
frame
.
f_lineno
basename
=
os
.
path
.
basename
(
filename
)
message
=
"%s:%s"
%
(
basename
,
lineno
)
if
code
.
co_name
!=
"?"
:
message
=
"%s: %s()"
%
(
message
,
code
.
co_name
)
return
message
interacting
=
0
class
Debugger
:
interacting
=
0
vstack
=
vsource
=
vlocals
=
vglobals
=
None
def
__init__
(
self
,
pyshell
):
bdb
.
Bdb
.
__init__
(
self
)
def
__init__
(
self
,
pyshell
,
idb
=
None
):
if
idb
is
None
:
idb
=
Idb
(
self
)
self
.
pyshell
=
pyshell
self
.
idb
=
idb
self
.
make_gui
()
def
canonic
(
self
,
filename
):
# Canonicalize filename -- called by Bdb
return
os
.
path
.
normcase
(
os
.
path
.
abspath
(
filename
))
def
run
(
self
,
*
args
):
try
:
self
.
interacting
=
1
return
self
.
idb
.
run
(
*
args
)
finally
:
self
.
interacting
=
0
def
close
(
self
,
event
=
None
):
if
self
.
interacting
:
...
...
@@ -31,24 +78,6 @@ class Debugger(bdb.Bdb):
self
.
pyshell
.
close_debugger
()
self
.
top
.
destroy
()
def
run
(
self
,
*
args
):
try
:
self
.
interacting
=
1
return
apply
(
bdb
.
Bdb
.
run
,
(
self
,)
+
args
)
finally
:
self
.
interacting
=
0
def
user_line
(
self
,
frame
):
self
.
interaction
(
frame
)
def
user_return
(
self
,
frame
,
rv
):
# XXX show rv?
##self.interaction(frame)
pass
def
user_exception
(
self
,
frame
,
info
):
self
.
interaction
(
frame
,
info
)
def
make_gui
(
self
):
pyshell
=
self
.
pyshell
self
.
flist
=
pyshell
.
flist
...
...
@@ -128,16 +157,8 @@ class Debugger(bdb.Bdb):
frame
=
None
def
interaction
(
self
,
frame
,
info
=
None
):
def
interaction
(
self
,
message
,
frame
,
info
=
None
):
self
.
frame
=
frame
code
=
frame
.
f_code
file
=
code
.
co_filename
base
=
os
.
path
.
basename
(
file
)
lineno
=
frame
.
f_lineno
#
message
=
"%s:%s"
%
(
base
,
lineno
)
if
code
.
co_name
!=
"?"
:
message
=
"%s: %s()"
%
(
message
,
code
.
co_name
)
self
.
status
.
configure
(
text
=
message
)
#
if
info
:
...
...
@@ -160,7 +181,7 @@ class Debugger(bdb.Bdb):
#
sv
=
self
.
stackviewer
if
sv
:
stack
,
i
=
self
.
get_stack
(
self
.
frame
,
tb
)
stack
,
i
=
self
.
idb
.
get_stack
(
self
.
frame
,
tb
)
sv
.
load_stack
(
stack
,
i
)
#
self
.
show_variables
(
1
)
...
...
@@ -184,32 +205,34 @@ class Debugger(bdb.Bdb):
frame
=
self
.
frame
if
not
frame
:
return
filename
,
lineno
=
self
.
__frame2fileline
(
frame
)
if
filename
[:
1
]
+
filename
[
-
1
:]
!=
"<>"
and
os
.
path
.
exists
(
filename
):
self
.
flist
.
gotofileline
(
filename
,
lineno
)
def
__frame2fileline
(
self
,
frame
):
code
=
frame
.
f_code
file
=
code
.
co_filename
file
name
=
code
.
co_filename
lineno
=
frame
.
f_lineno
if
file
[:
1
]
+
file
[
-
1
:]
!=
"<>"
and
os
.
path
.
exists
(
file
):
edit
=
self
.
flist
.
open
(
file
)
if
edit
:
edit
.
gotoline
(
lineno
)
return
filename
,
lineno
def
cont
(
self
):
self
.
set_continue
()
self
.
idb
.
set_continue
()
self
.
root
.
quit
()
def
step
(
self
):
self
.
set_step
()
self
.
idb
.
set_step
()
self
.
root
.
quit
()
def
next
(
self
):
self
.
set_next
(
self
.
frame
)
self
.
idb
.
set_next
(
self
.
frame
)
self
.
root
.
quit
()
def
ret
(
self
):
self
.
set_return
(
self
.
frame
)
self
.
idb
.
set_return
(
self
.
frame
)
self
.
root
.
quit
()
def
quit
(
self
):
self
.
set_quit
()
self
.
idb
.
set_quit
()
self
.
root
.
quit
()
stackviewer
=
None
...
...
@@ -219,7 +242,7 @@ class Debugger(bdb.Bdb):
self
.
stackviewer
=
sv
=
StackViewer
.
StackViewer
(
self
.
fstack
,
self
.
flist
,
self
)
if
self
.
frame
:
stack
,
i
=
self
.
get_stack
(
self
.
frame
,
None
)
stack
,
i
=
self
.
idb
.
get_stack
(
self
.
frame
,
None
)
sv
.
load_stack
(
stack
,
i
)
else
:
sv
=
self
.
stackviewer
...
...
@@ -233,6 +256,7 @@ class Debugger(bdb.Bdb):
self
.
sync_source_line
()
def
show_frame
(
self
,
(
frame
,
lineno
)):
# Called from OldStackViewer
self
.
frame
=
frame
self
.
show_variables
()
...
...
@@ -295,15 +319,15 @@ class Debugger(bdb.Bdb):
text
.
tag_add
(
"BREAK"
,
"insert linestart"
,
"insert lineend +1char"
)
# A literal copy of Bdb.set_break() without the print statement at the end
def
set_break
(
self
,
filename
,
lineno
,
temporary
=
0
,
cond
=
None
):
import
linecache
# Import as late as possible
filename
=
self
.
canonic
(
filename
)
line
=
linecache
.
getline
(
filename
,
lineno
)
if
not
line
:
return
'That line does not exist!'
if
not
self
.
breaks
.
has_key
(
filename
):
self
.
breaks
[
filename
]
=
[]
list
=
self
.
breaks
[
filename
]
if
not
lineno
in
list
:
list
.
append
(
lineno
)
bp
=
bdb
.
Breakpoint
(
filename
,
lineno
,
temporary
,
cond
)
#
def set_break(self, filename, lineno, temporary=0, cond = None):
#
import linecache # Import as late as possible
#
filename = self.canonic(filename)
#
line = linecache.getline(filename, lineno)
#
if not line:
#
return 'That line does not exist!'
#
if not self.breaks.has_key(filename):
#
self.breaks[filename] = []
#
list = self.breaks[filename]
#
if not lineno in list:
#
list.append(lineno)
#
bp = bdb.Breakpoint(filename, lineno, temporary, cond)
Lib/idlelib/PyShell.py
View file @
5d2af63c
...
...
@@ -29,7 +29,10 @@ import string
import
getopt
import
re
import
protocol
import
socket
import
time
import
warnings
import
traceback
import
linecache
from
code
import
InteractiveInterpreter
...
...
@@ -45,6 +48,21 @@ from OutputWindow import OutputWindow, OnDemandOutputWindow
from
configHandler
import
idleConf
import
idlever
import
rpc
use_subprocess
=
0
# Set to 1 to spawn subprocess for command execution
# Change warnings module to write to sys.__stderr__
try
:
import
warnings
except
ImportError
:
pass
else
:
def
idle_showwarning
(
message
,
category
,
filename
,
lineno
):
file
=
sys
.
__stderr__
file
.
write
(
warnings
.
formatwarning
(
message
,
category
,
filename
,
lineno
))
warnings
.
showwarning
=
idle_showwarning
# We need to patch linecache.checkcache, because we don't want it
# to throw away our <pyshell#...> entries.
# Rather than repeating its code here, we save those entries,
...
...
@@ -186,6 +204,99 @@ class ModifiedInterpreter(InteractiveInterpreter):
InteractiveInterpreter
.
__init__
(
self
,
locals
=
locals
)
self
.
save_warnings_filters
=
None
global
flist
self
.
output
=
OnDemandOutputWindow
(
flist
)
rpcclt
=
None
rpcpid
=
None
def
spawn_subprocess
(
self
):
port
=
8833
addr
=
(
"localhost"
,
port
)
w
=
[
'-W'
+
s
for
s
in
sys
.
warnoptions
]
args
=
[
sys
.
executable
]
+
w
+
[
"-c"
,
"__import__('run').main()"
,
str
(
port
)]
self
.
rpcpid
=
os
.
spawnv
(
os
.
P_NOWAIT
,
args
[
0
],
args
)
for
i
in
range
(
5
):
time
.
sleep
(
i
)
try
:
self
.
rpcclt
=
rpc
.
RPCClient
(
addr
)
break
except
socket
.
error
,
err
:
if
i
>
3
:
print
>>
sys
.
__stderr__
,
"Socket error:"
,
err
,
"; retry..."
else
:
# XXX Make this a dialog?
print
>>
sys
.
__stderr__
,
"Can't spawn subprocess!"
return
self
.
output
.
stdout
=
PseudoFile
(
self
.
output
,
"stdout"
)
self
.
output
.
stderr
=
PseudoFile
(
self
.
output
,
"stderr"
)
self
.
rpcclt
.
register
(
"stdin"
,
self
.
output
)
self
.
rpcclt
.
register
(
"stdout"
,
self
.
output
.
stdout
)
self
.
rpcclt
.
register
(
"stderr"
,
self
.
output
.
stderr
)
self
.
rpcclt
.
register
(
"flist"
,
self
.
tkconsole
.
flist
)
self
.
poll_subprocess
()
active_seq
=
None
def
poll_subprocess
(
self
):
clt
=
self
.
rpcclt
if
clt
is
None
:
return
response
=
clt
.
pollresponse
(
self
.
active_seq
)
self
.
tkconsole
.
text
.
after
(
50
,
self
.
poll_subprocess
)
if
response
:
self
.
tkconsole
.
resetoutput
()
self
.
active_seq
=
None
how
,
what
=
response
file
=
self
.
tkconsole
.
console
if
how
==
"OK"
:
if
what
is
not
None
:
print
>>
file
,
`what`
elif
how
==
"EXCEPTION"
:
mod
,
name
,
args
,
tb
=
what
print
>>
file
,
'Traceback (most recent call last):'
while
tb
and
tb
[
0
][
0
]
in
(
"run.py"
,
"rpc.py"
):
del
tb
[
0
]
while
tb
and
tb
[
-
1
][
0
]
in
(
"run.py"
,
"rpc.py"
):
del
tb
[
-
1
]
for
i
in
range
(
len
(
tb
)):
fn
,
ln
,
nm
,
line
=
tb
[
i
]
if
not
line
and
fn
.
startswith
(
"<pyshell#"
):
line
=
linecache
.
getline
(
fn
,
ln
)
tb
[
i
]
=
fn
,
ln
,
nm
,
line
traceback
.
print_list
(
tb
,
file
=
file
)
if
mod
and
mod
!=
"exceptions"
:
name
=
mod
+
"."
+
name
print
>>
file
,
name
+
":"
,
" "
.
join
(
map
(
str
,
args
))
if
self
.
tkconsole
.
getvar
(
"<<toggle-jit-stack-viewer>>"
):
self
.
remote_stack_viewer
()
elif
how
==
"ERROR"
:
print
>>
sys
.
__stderr__
,
"Oops:"
,
how
,
what
print
>>
file
,
"Oops:"
,
how
,
what
self
.
tkconsole
.
endexecuting
()
def
kill_subprocess
(
self
):
clt
=
self
.
rpcclt
self
.
rpcclt
=
None
if
clt
is
not
None
:
clt
.
close
()
def
remote_stack_viewer
(
self
):
import
RemoteObjectBrowser
oid
=
self
.
rpcclt
.
remotecall
(
"exec"
,
"stackviewer"
,
(
"flist"
,),
{})
if
oid
is
None
:
self
.
tkconsole
.
root
.
bell
()
return
item
=
RemoteObjectBrowser
.
StubObjectTreeItem
(
self
.
rpcclt
,
oid
)
from
TreeWidget
import
ScrolledCanvas
,
TreeNode
top
=
Toplevel
(
self
.
tkconsole
.
root
)
sc
=
ScrolledCanvas
(
top
,
bg
=
"white"
,
highlightthickness
=
0
)
sc
.
frame
.
pack
(
expand
=
1
,
fill
=
"both"
)
node
=
TreeNode
(
sc
.
canvas
,
None
,
item
)
node
.
expand
()
# XXX Should GC the remote tree when closing the window
gid
=
0
def
execsource
(
self
,
source
):
...
...
@@ -264,10 +375,11 @@ class ModifiedInterpreter(InteractiveInterpreter):
def
showtraceback
(
self
):
# Extend base class method to reset output properly
text
=
self
.
tkconsole
.
text
self
.
tkconsole
.
resetoutput
()
self
.
checklinecache
()
InteractiveInterpreter
.
showtraceback
(
self
)
if
self
.
tkconsole
.
getvar
(
"<<toggle-jit-stack-viewer>>"
):
self
.
tkconsole
.
open_stack_viewer
()
def
checklinecache
(
self
):
c
=
linecache
.
cache
...
...
@@ -283,12 +395,43 @@ class ModifiedInterpreter(InteractiveInterpreter):
def
getdebugger
(
self
):
return
self
.
debugger
def
runcommand
(
self
,
code
):
# This runs the code without invoking the debugger.
# The code better not raise an exception!
if
self
.
tkconsole
.
executing
:
tkMessageBox
.
showerror
(
"Already executing"
,
"The Python Shell window is already executing a command; "
"please wait until it is finished."
,
master
=
self
.
tkconsole
.
text
)
return
0
if
self
.
rpcclt
:
self
.
rpcclt
.
remotecall
(
"exec"
,
"runcode"
,
(
code
,),
{})
else
:
exec
code
in
self
.
locals
return
1
def
runcode
(
self
,
code
):
# Override base class method
if
self
.
tkconsole
.
executing
:
tkMessageBox
.
showerror
(
"Already executing"
,
"The Python Shell window is already executing a command; "
"please wait until it is finished."
,
master
=
self
.
tkconsole
.
text
)
return
self
.
checklinecache
()
if
self
.
save_warnings_filters
is
not
None
:
warnings
.
filters
[:]
=
self
.
save_warnings_filters
self
.
save_warnings_filters
=
None
debugger
=
self
.
debugger
if
not
debugger
and
self
.
rpcclt
is
not
None
:
self
.
tkconsole
.
beginexecuting
()
self
.
active_seq
=
self
.
rpcclt
.
asynccall
(
"exec"
,
"runcode"
,
(
code
,),
{})
return
try
:
self
.
tkconsole
.
beginexecuting
()
try
:
...
...
@@ -305,12 +448,8 @@ class ModifiedInterpreter(InteractiveInterpreter):
raise
else
:
self
.
showtraceback
()
if
self
.
tkconsole
.
getvar
(
"<<toggle-jit-stack-viewer>>"
):
self
.
tkconsole
.
open_stack_viewer
()
except
:
self
.
showtraceback
()
if
self
.
tkconsole
.
getvar
(
"<<toggle-jit-stack-viewer>>"
):
self
.
tkconsole
.
open_stack_viewer
()
finally
:
self
.
tkconsole
.
endexecuting
()
...
...
@@ -319,7 +458,6 @@ class ModifiedInterpreter(InteractiveInterpreter):
# Override base class write
self
.
tkconsole
.
console
.
write
(
s
)
class
PyShell
(
OutputWindow
):
shell_title
=
"Python Shell"
...
...
@@ -366,13 +504,19 @@ class PyShell(OutputWindow):
self
.
save_stdout
=
sys
.
stdout
self
.
save_stderr
=
sys
.
stderr
self
.
save_stdin
=
sys
.
stdin
sys
.
stdout
=
PseudoFile
(
self
,
"stdout"
)
sys
.
stderr
=
PseudoFile
(
self
,
"stderr"
)
sys
.
stdin
=
self
self
.
stdout
=
PseudoFile
(
self
,
"stdout"
)
self
.
stderr
=
PseudoFile
(
self
,
"stderr"
)
self
.
console
=
PseudoFile
(
self
,
"console"
)
if
not
use_subprocess
:
sys
.
stdout
=
self
.
stdout
sys
.
stderr
=
self
.
stderr
sys
.
stdin
=
self
self
.
history
=
self
.
History
(
self
.
text
)
if
use_subprocess
:
self
.
interp
.
spawn_subprocess
()
reading
=
0
executing
=
0
canceled
=
0
...
...
@@ -411,12 +555,22 @@ class PyShell(OutputWindow):
self
.
set_debugger_indicator
()
def
open_debugger
(
self
):
if
self
.
interp
.
rpcclt
:
return
self
.
open_remote_debugger
()
import
Debugger
self
.
interp
.
setdebugger
(
Debugger
.
Debugger
(
self
))
sys
.
ps1
=
"[DEBUG ON]
\
n
>>> "
self
.
showprompt
()
self
.
set_debugger_indicator
()
def
open_remote_debugger
(
self
):
import
RemoteDebugger
gui
=
RemoteDebugger
.
start_remote_debugger
(
self
.
interp
.
rpcclt
,
self
)
self
.
interp
.
setdebugger
(
gui
)
sys
.
ps1
=
"[DEBUG ON]
\
n
>>> "
self
.
showprompt
()
self
.
set_debugger_indicator
()
def
beginexecuting
(
self
):
# Helper for ModifiedInterpreter
self
.
resetoutput
()
...
...
@@ -430,6 +584,7 @@ class PyShell(OutputWindow):
##self._cancel_check = None
self
.
executing
=
0
self
.
canceled
=
0
self
.
showprompt
()
def
close
(
self
):
# Extend base class method
...
...
@@ -449,6 +604,7 @@ class PyShell(OutputWindow):
def
_close
(
self
):
self
.
close_debugger
()
self
.
interp
.
kill_subprocess
()
# Restore std streams
sys
.
stdout
=
self
.
save_stdout
sys
.
stderr
=
self
.
save_stderr
...
...
@@ -520,9 +676,18 @@ class PyShell(OutputWindow):
self
.
showprompt
()
return
"break"
self
.
endoffile
=
0
self
.
canceled
=
1
if
self
.
reading
:
self
.
canceled
=
1
self
.
top
.
quit
()
elif
(
self
.
executing
and
self
.
interp
.
rpcclt
and
self
.
interp
.
rpcpid
and
hasattr
(
os
,
"kill"
)):
try
:
from
signal
import
SIGINT
except
ImportError
:
SIGINT
=
2
os
.
kill
(
self
.
interp
.
rpcpid
,
SIGINT
)
else
:
self
.
canceled
=
1
return
"break"
def
eof_callback
(
self
,
event
):
...
...
@@ -532,11 +697,6 @@ class PyShell(OutputWindow):
self
.
text
.
compare
(
"insert"
,
"=="
,
"end-1c"
)):
return
# Let the default binding (delete next char) take over
if
not
self
.
executing
:
## if not tkMessageBox.askokcancel(
## "Exit?",
## "Are you sure you want to exit?",
## default="ok", master=self.text):
## return "break"
self
.
resetoutput
()
self
.
close
()
else
:
...
...
@@ -656,6 +816,8 @@ class PyShell(OutputWindow):
return
self
.
_cancel_check
def
open_stack_viewer
(
self
,
event
=
None
):
if
self
.
interp
.
rpcclt
:
return
self
.
interp
.
remote_stack_viewer
()
try
:
sys
.
last_traceback
except
:
...
...
@@ -675,6 +837,7 @@ class PyShell(OutputWindow):
s
=
""
self
.
console
.
write
(
s
)
self
.
text
.
mark_set
(
"insert"
,
"end-1c"
)
self
.
set_line_and_column
()
def
resetoutput
(
self
):
source
=
self
.
text
.
get
(
"iomark"
,
"end-1c"
)
...
...
@@ -683,6 +846,7 @@ class PyShell(OutputWindow):
if
self
.
text
.
get
(
"end-2c"
)
!=
"
\
n
"
:
self
.
text
.
insert
(
"end-1c"
,
"
\
n
"
)
self
.
text
.
mark_set
(
"iomark"
,
"end-1c"
)
self
.
set_line_and_column
()
sys
.
stdout
.
softspace
=
0
def
write
(
self
,
s
,
tags
=
()):
...
...
@@ -698,6 +862,7 @@ class PseudoFile:
def
__init__
(
self
,
shell
,
tags
):
self
.
shell
=
shell
self
.
tags
=
tags
self
.
softspace
=
0
def
write
(
self
,
s
):
self
.
shell
.
write
(
s
,
self
.
tags
)
...
...
@@ -718,9 +883,10 @@ idle file(s) (without options) edit the file(s)
-c cmd run the command in a shell
-d enable the debugger
-e edit mode; arguments are files to be edited
-i open an interactive shell
-i file(s) open a shell and also an editor window for each file
-r script
run a file as a script in a shell
-r script
use experimental remote (subprocess) execution feature
-s run $IDLESTARTUP or $PYTHONSTARTUP before anything else
-t title set title of shell window
...
...
@@ -822,9 +988,10 @@ be a security risk on a single-user machine.
interactive
=
0
script
=
None
startup
=
0
global
use_subprocess
try
:
opts
,
args
=
getopt
.
getopt
(
argv
,
"c:d
ir:st:"
)
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
"c:de
ir:st:"
)
except
getopt
.
error
,
msg
:
sys
.
stderr
.
write
(
"Error: %s
\
n
"
%
str
(
msg
))
sys
.
stderr
.
write
(
usage_msg
)
...
...
@@ -836,10 +1003,14 @@ be a security risk on a single-user machine.
cmd
=
a
if
o
==
'-d'
:
debug
=
1
if
o
==
'-e'
:
edit
=
1
if
o
==
'-i'
:
interactive
=
1
if
o
==
'-r'
:
edit
=
1
script
=
a
use_subprocess
=
1
if
o
==
'-s'
:
startup
=
1
if
o
==
'-t'
:
...
...
Lib/idlelib/RemoteDebugger.py
0 → 100644
View file @
5d2af63c
"""Support for remote Python debugging.
Some ASCII art to describe the structure:
IN PYTHON SUBPROCESS # IN IDLE PROCESS
#
# oid='gui_adapter'
+----------+ # +------------+ +-----+
| GUIProxy |--remote#call-->| GUIAdapter |--calls-->| GUI |
+-----+--calls-->+----------+ # +------------+ +-----+
| Idb | # /
+-----+<-calls--+------------+ # +----------+<--calls-/
| IdbAdapter |<--remote#call--| IdbProxy |
+------------+ # +----------+
oid='idb_adapter' #
The purpose of the Proxy and Adapter classes is to translate certain
arguments and return values that cannot be transported through the RPC
barrier, in particular frame and traceback objects.
"""
import
sys
import
rpc
import
Debugger
# In the PYTHON subprocess
frametable
=
{}
dicttable
=
{}
codetable
=
{}
def
wrap_frame
(
frame
):
fid
=
id
(
frame
)
frametable
[
fid
]
=
frame
return
fid
def
wrap_info
(
info
):
if
info
is
None
:
return
None
else
:
return
None
# XXX for now
class
GUIProxy
:
def
__init__
(
self
,
conn
,
oid
):
self
.
conn
=
conn
self
.
oid
=
oid
def
interaction
(
self
,
message
,
frame
,
info
=
None
):
self
.
conn
.
remotecall
(
self
.
oid
,
"interaction"
,
(
message
,
wrap_frame
(
frame
),
wrap_info
(
info
)),
{})
class
IdbAdapter
:
def
__init__
(
self
,
idb
):
self
.
idb
=
idb
def
set_step
(
self
):
self
.
idb
.
set_step
()
def
set_quit
(
self
):
self
.
idb
.
set_quit
()
def
set_continue
(
self
):
self
.
idb
.
set_continue
()
def
set_next
(
self
,
fid
):
frame
=
frametable
[
fid
]
self
.
idb
.
set_next
(
frame
)
def
set_return
(
self
,
fid
):
frame
=
frametable
[
fid
]
self
.
idb
.
set_return
(
frame
)
def
get_stack
(
self
,
fid
,
tbid
):
##print >>sys.__stderr__, "get_stack(%s, %s)" % (`fid`, `tbid`)
frame
=
frametable
[
fid
]
tb
=
None
# XXX for now
stack
,
i
=
self
.
idb
.
get_stack
(
frame
,
tb
)
##print >>sys.__stderr__, "get_stack() ->", stack
stack
=
[(
wrap_frame
(
frame
),
k
)
for
frame
,
k
in
stack
]
##print >>sys.__stderr__, "get_stack() ->", stack
return
stack
,
i
def
run
(
self
,
cmd
):
import
__main__
self
.
idb
.
run
(
cmd
,
__main__
.
__dict__
)
def
frame_attr
(
self
,
fid
,
name
):
frame
=
frametable
[
fid
]
return
getattr
(
frame
,
name
)
def
frame_globals
(
self
,
fid
):
frame
=
frametable
[
fid
]
dict
=
frame
.
f_globals
did
=
id
(
dict
)
dicttable
[
did
]
=
dict
return
did
def
frame_locals
(
self
,
fid
):
frame
=
frametable
[
fid
]
dict
=
frame
.
f_locals
did
=
id
(
dict
)
dicttable
[
did
]
=
dict
return
did
def
frame_code
(
self
,
fid
):
frame
=
frametable
[
fid
]
code
=
frame
.
f_code
cid
=
id
(
code
)
codetable
[
cid
]
=
code
return
cid
def
code_name
(
self
,
cid
):
code
=
codetable
[
cid
]
return
code
.
co_name
def
code_filename
(
self
,
cid
):
code
=
codetable
[
cid
]
return
code
.
co_filename
def
dict_keys
(
self
,
did
):
dict
=
dicttable
[
did
]
return
dict
.
keys
()
def
dict_item
(
self
,
did
,
key
):
dict
=
dicttable
[
did
]
value
=
dict
[
key
]
try
:
# Test for picklability
import
cPickle
cPickle
.
dumps
(
value
)
except
:
value
=
None
return
value
def
start_debugger
(
conn
,
gui_oid
):
#
# launched in the python subprocess
#
gui
=
GUIProxy
(
conn
,
gui_oid
)
idb
=
Debugger
.
Idb
(
gui
)
ada
=
IdbAdapter
(
idb
)
ada_oid
=
"idb_adapter"
conn
.
register
(
ada_oid
,
ada
)
return
ada_oid
# In the IDLE process
class
FrameProxy
:
def
__init__
(
self
,
conn
,
fid
):
self
.
_conn
=
conn
self
.
_fid
=
fid
self
.
_oid
=
"idb_adapter"
self
.
_dictcache
=
{}
def
__getattr__
(
self
,
name
):
if
name
[:
1
]
==
"_"
:
raise
AttributeError
,
name
if
name
==
"f_code"
:
return
self
.
_get_f_code
()
if
name
==
"f_globals"
:
return
self
.
_get_f_globals
()
if
name
==
"f_locals"
:
return
self
.
_get_f_locals
()
return
self
.
_conn
.
remotecall
(
self
.
_oid
,
"frame_attr"
,
(
self
.
_fid
,
name
),
{})
def
_get_f_code
(
self
):
cid
=
self
.
_conn
.
remotecall
(
self
.
_oid
,
"frame_code"
,
(
self
.
_fid
,),
{})
return
CodeProxy
(
self
.
_conn
,
self
.
_oid
,
cid
)
def
_get_f_globals
(
self
):
did
=
self
.
_conn
.
remotecall
(
self
.
_oid
,
"frame_globals"
,
(
self
.
_fid
,),
{})
return
self
.
_get_dict_proxy
(
did
)
def
_get_f_locals
(
self
):
did
=
self
.
_conn
.
remotecall
(
self
.
_oid
,
"frame_locals"
,
(
self
.
_fid
,),
{})
return
self
.
_get_dict_proxy
(
did
)
def
_get_dict_proxy
(
self
,
did
):
if
self
.
_dictcache
.
has_key
(
did
):
return
self
.
_dictcache
[
did
]
dp
=
DictProxy
(
self
.
_conn
,
self
.
_oid
,
did
)
self
.
_dictcache
[
did
]
=
dp
return
dp
class
CodeProxy
:
def
__init__
(
self
,
conn
,
oid
,
cid
):
self
.
_conn
=
conn
self
.
_oid
=
oid
self
.
_cid
=
cid
def
__getattr__
(
self
,
name
):
if
name
==
"co_name"
:
return
self
.
_conn
.
remotecall
(
self
.
_oid
,
"code_name"
,
(
self
.
_cid
,),
{})
if
name
==
"co_filename"
:
return
self
.
_conn
.
remotecall
(
self
.
_oid
,
"code_filename"
,
(
self
.
_cid
,),
{})
class
DictProxy
:
def
__init__
(
self
,
conn
,
oid
,
did
):
self
.
_conn
=
conn
self
.
_oid
=
oid
self
.
_did
=
did
def
keys
(
self
):
return
self
.
_conn
.
remotecall
(
self
.
_oid
,
"dict_keys"
,
(
self
.
_did
,),
{})
def
__getitem__
(
self
,
key
):
return
self
.
_conn
.
remotecall
(
self
.
_oid
,
"dict_item"
,
(
self
.
_did
,
key
),
{})
def
__getattr__
(
self
,
name
):
##print >>sys.__stderr__, "failed DictProxy.__getattr__:", name
raise
AttributeError
,
name
class
GUIAdaper
:
def
__init__
(
self
,
conn
,
gui
):
self
.
conn
=
conn
self
.
gui
=
gui
def
interaction
(
self
,
message
,
fid
,
iid
):
print
"interaction(%s, %s, %s)"
%
(
`message`
,
`fid`
,
`iid`
)
frame
=
FrameProxy
(
self
.
conn
,
fid
)
info
=
None
# XXX for now
self
.
gui
.
interaction
(
message
,
frame
,
info
)
class
IdbProxy
:
def
__init__
(
self
,
conn
,
oid
):
self
.
oid
=
oid
self
.
conn
=
conn
def
call
(
self
,
methodname
,
*
args
,
**
kwargs
):
##print "call %s %s %s" % (methodname, args, kwargs)
value
=
self
.
conn
.
remotecall
(
self
.
oid
,
methodname
,
args
,
kwargs
)
##print "return %s" % `value`
return
value
def
run
(
self
,
cmd
,
locals
):
# Ignores locals on purpose!
self
.
call
(
"run"
,
cmd
)
def
get_stack
(
self
,
frame
,
tb
):
stack
,
i
=
self
.
call
(
"get_stack"
,
frame
.
_fid
,
None
)
stack
=
[(
FrameProxy
(
self
.
conn
,
fid
),
k
)
for
fid
,
k
in
stack
]
return
stack
,
i
def
set_continue
(
self
):
self
.
call
(
"set_continue"
)
def
set_step
(
self
):
self
.
call
(
"set_step"
)
def
set_next
(
self
,
frame
):
self
.
call
(
"set_next"
,
frame
.
_fid
)
def
set_return
(
self
,
frame
):
self
.
call
(
"set_return"
,
frame
.
_fid
)
def
set_quit
(
self
):
self
.
call
(
"set_quit"
)
def
start_remote_debugger
(
conn
,
pyshell
):
#
# instruct the (remote) subprocess to create
# a debugger instance, and lets it know that
# the local GUIAdapter called "gui_adapter"
# is waiting notification of debugging events
#
ada_oid
=
"gui_adapter"
idb_oid
=
conn
.
remotecall
(
"exec"
,
"start_debugger"
,
(
ada_oid
,),
{})
idb
=
IdbProxy
(
conn
,
idb_oid
)
gui
=
Debugger
.
Debugger
(
pyshell
,
idb
)
ada
=
GUIAdaper
(
conn
,
gui
)
conn
.
register
(
ada_oid
,
ada
)
return
gui
Lib/idlelib/RemoteObjectBrowser.py
0 → 100644
View file @
5d2af63c
import
rpc
def
remote_object_tree_item
(
item
):
wrapper
=
WrappedObjectTreeItem
(
item
)
oid
=
id
(
wrapper
)
rpc
.
objecttable
[
oid
]
=
wrapper
return
oid
class
WrappedObjectTreeItem
:
# Lives in PYTHON subprocess
def
__init__
(
self
,
item
):
self
.
__item
=
item
def
__getattr__
(
self
,
name
):
value
=
getattr
(
self
.
__item
,
name
)
return
value
def
_GetSubList
(
self
):
list
=
self
.
__item
.
_GetSubList
()
return
map
(
remote_object_tree_item
,
list
)
class
StubObjectTreeItem
:
# Lives in IDLE process
def
__init__
(
self
,
sockio
,
oid
):
self
.
sockio
=
sockio
self
.
oid
=
oid
def
__getattr__
(
self
,
name
):
value
=
rpc
.
MethodProxy
(
self
.
sockio
,
self
.
oid
,
name
)
return
value
def
_GetSubList
(
self
):
list
=
self
.
sockio
.
remotecall
(
self
.
oid
,
"_GetSubList"
,
(),
{})
return
[
StubObjectTreeItem
(
self
.
sockio
,
oid
)
for
oid
in
list
]
Lib/idlelib/ScriptBinding.py
View file @
5d2af63c
...
...
@@ -14,6 +14,14 @@ namespace. Output goes to the shell window.
- Run module (Control-F5) does the same but executes the module's
code in the __main__ namespace.
XXX Redesign this interface (yet again) as follows:
- Present a dialog box for ``Run script''
- Allow specify command line arguments in the dialog box
- Restart the interpreter when running a script
"""
import
sys
...
...
@@ -25,9 +33,9 @@ indent_message = """Error: Inconsistent indentation detected!
This means that either:
(
1) your indentation is outright incorrect (easy to fix), or
1) your indentation is outright incorrect (easy to fix), or
(
2) your indentation mixes tabs and spaces in a way that depends on
\
2) your indentation mixes tabs and spaces in a way that depends on
\
how many spaces a tab is worth.
To fix case 2, change all tabs to spaces by using Select All followed
\
...
...
@@ -105,28 +113,31 @@ class ScriptBinding:
return
1
def
import_module_event
(
self
,
event
):
flist
=
self
.
editwin
.
flist
shell
=
flist
.
open_shell
()
interp
=
shell
.
interp
filename
=
self
.
getfilename
()
if
not
filename
:
return
modname
,
ext
=
os
.
path
.
splitext
(
os
.
path
.
basename
(
filename
))
if
sys
.
modules
.
has_key
(
modname
):
mod
=
sys
.
modules
[
modname
]
else
:
mod
=
imp
.
new_module
(
modname
)
sys
.
modules
[
modname
]
=
mod
mod
.
__file__
=
filename
setattr
(
sys
.
modules
[
'__main__'
],
modname
,
mod
)
dir
=
os
.
path
.
dirname
(
filename
)
dir
=
os
.
path
.
normpath
(
os
.
path
.
abspath
(
dir
))
if
dir
not
in
sys
.
path
:
sys
.
path
.
insert
(
0
,
dir
)
flist
=
self
.
editwin
.
flist
shell
=
flist
.
open_shell
()
interp
=
shell
.
interp
interp
.
runcode
(
"reload(%s)"
%
modname
)
interp
.
runcode
(
"""if 1:
import sys as _sys
if %s not in _sys.path:
_sys.path.insert(0, %s)
if _sys.modules.get(%s):
del _sys
import %s
reload(%s)
else:
del _sys
import %s
\
n
"""
%
(
`dir`
,
`dir`
,
`modname`
,
modname
,
modname
,
modname
))
def
run_script_event
(
self
,
event
):
filename
=
self
.
getfilename
()
...
...
@@ -136,10 +147,16 @@ class ScriptBinding:
flist
=
self
.
editwin
.
flist
shell
=
flist
.
open_shell
()
interp
=
shell
.
interp
if
(
not
sys
.
argv
or
os
.
path
.
basename
(
sys
.
argv
[
0
])
!=
os
.
path
.
basename
(
filename
)):
# XXX Too often this discards arguments the user just set...
sys
.
argv
=
[
filename
]
interp
.
runcommand
(
"""if 1:
_filename = %s
import sys as _sys
from os.path import basename as _basename
if (not _sys.argv or
_basename(_sys.argv[0]) != _basename(_filename)):
_sys.argv = [_filename]
del _filename, _sys, _basename
\
n
"""
%
`filename`
)
interp
.
execfile
(
filename
)
def
getfilename
(
self
):
...
...
Lib/idlelib/rpc.py
0 → 100644
View file @
5d2af63c
# ASCII-art documentation
#
# +---------------------------------+ +----------+
# | SocketServer.BaseRequestHandler | | SocketIO |
# +---------------------------------+ +----------+
# ^ ^ ^
# | | |
# | + -------------------+ |
# | | |
# +-------------------------+ +-----------------+
# | RPCHandler | | RPCClient |
# |-------------------------| |-----------------|
# | register() | | remotecall() |
# | unregister() | | register() |
# | | | unregister() |
# | | | get_remote_proxy|
# +-------------------------+ +-----------------+
#
import
sys
import
socket
import
select
import
SocketServer
import
struct
import
cPickle
as
pickle
import
threading
import
traceback
import
copy_reg
import
types
import
marshal
def
unpickle_code
(
ms
):
co
=
marshal
.
loads
(
ms
)
assert
isinstance
(
co
,
types
.
CodeType
)
return
co
def
pickle_code
(
co
):
assert
isinstance
(
co
,
types
.
CodeType
)
ms
=
marshal
.
dumps
(
co
)
return
unpickle_code
,
(
ms
,)
def
unpickle_function
(
ms
):
return
ms
def
pickle_function
(
fn
):
assert
isinstance
(
fn
,
type
.
FunctionType
)
return
`fn`
copy_reg
.
pickle
(
types
.
CodeType
,
pickle_code
,
unpickle_code
)
copy_reg
.
pickle
(
types
.
FunctionType
,
pickle_function
,
unpickle_function
)
BUFSIZE
=
8
*
1024
class
RPCServer
(
SocketServer
.
TCPServer
):
def
__init__
(
self
,
addr
,
handlerclass
=
None
):
if
handlerclass
is
None
:
handlerclass
=
RPCHandler
self
.
objtable
=
objecttable
SocketServer
.
TCPServer
.
__init__
(
self
,
addr
,
handlerclass
)
def
verify_request
(
self
,
request
,
client_address
):
host
,
port
=
client_address
if
host
!=
"127.0.0.1"
:
print
"Disallowed host:"
,
host
return
0
else
:
return
1
def
register
(
self
,
oid
,
object
):
self
.
objtable
[
oid
]
=
object
def
unregister
(
self
,
oid
):
try
:
del
self
.
objtable
[
oid
]
except
KeyError
:
pass
objecttable
=
{}
class
SocketIO
:
debugging
=
0
def
__init__
(
self
,
sock
,
objtable
=
None
,
debugging
=
None
):
self
.
mainthread
=
threading
.
currentThread
()
if
debugging
is
not
None
:
self
.
debugging
=
debugging
self
.
sock
=
sock
if
objtable
is
None
:
objtable
=
objecttable
self
.
objtable
=
objtable
self
.
statelock
=
threading
.
Lock
()
self
.
responses
=
{}
self
.
cvars
=
{}
def
close
(
self
):
sock
=
self
.
sock
self
.
sock
=
None
if
sock
is
not
None
:
sock
.
close
()
def
debug
(
self
,
*
args
):
if
not
self
.
debugging
:
return
s
=
str
(
threading
.
currentThread
().
getName
())
for
a
in
args
:
s
=
s
+
" "
+
str
(
a
)
s
=
s
+
"
\
n
"
sys
.
__stderr__
.
write
(
s
)
def
register
(
self
,
oid
,
object
):
self
.
objtable
[
oid
]
=
object
def
unregister
(
self
,
oid
):
try
:
del
self
.
objtable
[
oid
]
except
KeyError
:
pass
def
localcall
(
self
,
request
):
##self.debug("localcall:", request)
try
:
how
,
(
oid
,
methodname
,
args
,
kwargs
)
=
request
except
TypeError
:
return
(
"ERROR"
,
"Bad request format"
)
assert
how
==
"call"
if
not
self
.
objtable
.
has_key
(
oid
):
return
(
"ERROR"
,
"Unknown object id: %s"
%
`oid`
)
obj
=
self
.
objtable
[
oid
]
if
methodname
==
"__methods__"
:
methods
=
{}
_getmethods
(
obj
,
methods
)
return
(
"OK"
,
methods
)
if
methodname
==
"__attributes__"
:
attributes
=
{}
_getattributes
(
obj
,
attributes
)
return
(
"OK"
,
attributes
)
if
not
hasattr
(
obj
,
methodname
):
return
(
"ERROR"
,
"Unsupported method name: %s"
%
`methodname`
)
method
=
getattr
(
obj
,
methodname
)
try
:
ret
=
method
(
*
args
,
**
kwargs
)
if
isinstance
(
ret
,
RemoteObject
):
ret
=
remoteref
(
ret
)
return
(
"OK"
,
ret
)
except
:
##traceback.print_exc(file=sys.__stderr__)
typ
,
val
,
tb
=
info
=
sys
.
exc_info
()
sys
.
last_type
,
sys
.
last_value
,
sys
.
last_traceback
=
info
if
isinstance
(
typ
,
type
(
Exception
)):
# Class exceptions
mod
=
typ
.
__module__
name
=
typ
.
__name__
if
issubclass
(
typ
,
Exception
):
args
=
val
.
args
else
:
args
=
(
str
(
val
),)
else
:
# String exceptions
mod
=
None
name
=
typ
args
=
(
str
(
val
),)
tb
=
traceback
.
extract_tb
(
tb
)
return
(
"EXCEPTION"
,
(
mod
,
name
,
args
,
tb
))
def
remotecall
(
self
,
oid
,
methodname
,
args
,
kwargs
):
seq
=
self
.
asynccall
(
oid
,
methodname
,
args
,
kwargs
)
return
self
.
asyncreturn
(
seq
)
def
asynccall
(
self
,
oid
,
methodname
,
args
,
kwargs
):
request
=
(
"call"
,
(
oid
,
methodname
,
args
,
kwargs
))
seq
=
self
.
putrequest
(
request
)
return
seq
def
asyncreturn
(
self
,
seq
):
response
=
self
.
getresponse
(
seq
)
return
self
.
decoderesponse
(
response
)
def
decoderesponse
(
self
,
response
):
how
,
what
=
response
if
how
==
"OK"
:
return
what
if
how
==
"EXCEPTION"
:
mod
,
name
,
args
,
tb
=
what
self
.
traceback
=
tb
if
mod
:
try
:
__import__
(
mod
)
module
=
sys
.
modules
[
mod
]
except
ImportError
:
pass
else
:
try
:
cls
=
getattr
(
module
,
name
)
except
AttributeError
:
pass
else
:
raise
getattr
(
__import__
(
mod
),
name
)(
*
args
)
else
:
if
mod
:
name
=
mod
+
"."
+
name
raise
name
,
args
if
how
==
"ERROR"
:
raise
RuntimeError
,
what
raise
SystemError
,
(
how
,
what
)
def
mainloop
(
self
):
try
:
self
.
getresponse
(
None
)
except
EOFError
:
pass
def
getresponse
(
self
,
myseq
):
response
=
self
.
_getresponse
(
myseq
)
if
response
is
not
None
:
how
,
what
=
response
if
how
==
"OK"
:
response
=
how
,
self
.
_proxify
(
what
)
return
response
def
_proxify
(
self
,
obj
):
if
isinstance
(
obj
,
RemoteProxy
):
return
RPCProxy
(
self
,
obj
.
oid
)
if
isinstance
(
obj
,
types
.
ListType
):
return
map
(
self
.
_proxify
,
obj
)
# XXX Check for other types -- not currently needed
return
obj
def
_getresponse
(
self
,
myseq
):
if
threading
.
currentThread
()
is
self
.
mainthread
:
# Main thread: does all reading of requests and responses
while
1
:
response
=
self
.
pollresponse
(
myseq
,
None
)
if
response
is
not
None
:
return
response
else
:
# Auxiliary thread: wait for notification from main thread
cvar
=
threading
.
Condition
(
self
.
statelock
)
self
.
statelock
.
acquire
()
self
.
cvars
[
myseq
]
=
cvar
while
not
self
.
responses
.
has_key
(
myseq
):
cvar
.
wait
()
response
=
self
.
responses
[
myseq
]
del
self
.
responses
[
myseq
]
del
self
.
cvars
[
myseq
]
self
.
statelock
.
release
()
return
response
def
putrequest
(
self
,
request
):
seq
=
self
.
newseq
()
self
.
putmessage
((
seq
,
request
))
return
seq
nextseq
=
0
def
newseq
(
self
):
self
.
nextseq
=
seq
=
self
.
nextseq
+
2
return
seq
def
putmessage
(
self
,
message
):
try
:
s
=
pickle
.
dumps
(
message
)
except
:
print
>>
sys
.
__stderr__
,
"Cannot pickle:"
,
`message`
raise
s
=
struct
.
pack
(
"<i"
,
len
(
s
))
+
s
while
len
(
s
)
>
0
:
n
=
self
.
sock
.
send
(
s
)
s
=
s
[
n
:]
def
ioready
(
self
,
wait
=
0.0
):
r
,
w
,
x
=
select
.
select
([
self
.
sock
.
fileno
()],
[],
[],
wait
)
return
len
(
r
)
buffer
=
""
bufneed
=
4
bufstate
=
0
# meaning: 0 => reading count; 1 => reading data
def
pollpacket
(
self
,
wait
=
0.0
):
self
.
_stage0
()
if
len
(
self
.
buffer
)
<
self
.
bufneed
:
if
not
self
.
ioready
(
wait
):
return
None
try
:
s
=
self
.
sock
.
recv
(
BUFSIZE
)
except
socket
.
error
:
raise
EOFError
if
len
(
s
)
==
0
:
raise
EOFError
self
.
buffer
+=
s
self
.
_stage0
()
return
self
.
_stage1
()
def
_stage0
(
self
):
if
self
.
bufstate
==
0
and
len
(
self
.
buffer
)
>=
4
:
s
=
self
.
buffer
[:
4
]
self
.
buffer
=
self
.
buffer
[
4
:]
self
.
bufneed
=
struct
.
unpack
(
"<i"
,
s
)[
0
]
self
.
bufstate
=
1
def
_stage1
(
self
):
if
self
.
bufstate
==
1
and
len
(
self
.
buffer
)
>=
self
.
bufneed
:
packet
=
self
.
buffer
[:
self
.
bufneed
]
self
.
buffer
=
self
.
buffer
[
self
.
bufneed
:]
self
.
bufneed
=
4
self
.
bufstate
=
0
return
packet
def
pollmessage
(
self
,
wait
=
0.0
):
packet
=
self
.
pollpacket
(
wait
)
if
packet
is
None
:
return
None
try
:
message
=
pickle
.
loads
(
packet
)
except
:
print
>>
sys
.
__stderr__
,
"-----------------------"
print
>>
sys
.
__stderr__
,
"cannot unpickle packet:"
,
`packet`
traceback
.
print_stack
(
file
=
sys
.
__stderr__
)
print
>>
sys
.
__stderr__
,
"-----------------------"
raise
return
message
def
pollresponse
(
self
,
myseq
,
wait
=
0.0
):
# Loop while there's no more buffered input or until specific response
while
1
:
message
=
self
.
pollmessage
(
wait
)
if
message
is
None
:
return
None
wait
=
0.0
seq
,
resq
=
message
if
resq
[
0
]
==
"call"
:
response
=
self
.
localcall
(
resq
)
self
.
putmessage
((
seq
,
response
))
continue
elif
seq
==
myseq
:
return
resq
else
:
self
.
statelock
.
acquire
()
self
.
responses
[
seq
]
=
resq
cv
=
self
.
cvars
.
get
(
seq
)
if
cv
is
not
None
:
cv
.
notify
()
self
.
statelock
.
release
()
continue
class
RemoteObject
:
# Token mix-in class
pass
def
remoteref
(
obj
):
oid
=
id
(
obj
)
objecttable
[
oid
]
=
obj
return
RemoteProxy
(
oid
)
class
RemoteProxy
:
def
__init__
(
self
,
oid
):
self
.
oid
=
oid
class
RPCHandler
(
SocketServer
.
BaseRequestHandler
,
SocketIO
):
debugging
=
0
def
__init__
(
self
,
sock
,
addr
,
svr
):
svr
.
current_handler
=
self
## cgt xxx
SocketIO
.
__init__
(
self
,
sock
)
SocketServer
.
BaseRequestHandler
.
__init__
(
self
,
sock
,
addr
,
svr
)
def
setup
(
self
):
SocketServer
.
BaseRequestHandler
.
setup
(
self
)
print
>>
sys
.
__stderr__
,
"Connection from"
,
self
.
client_address
def
finish
(
self
):
print
>>
sys
.
__stderr__
,
"End connection from"
,
self
.
client_address
SocketServer
.
BaseRequestHandler
.
finish
(
self
)
def
handle
(
self
):
self
.
mainloop
()
def
get_remote_proxy
(
self
,
oid
):
return
RPCProxy
(
self
,
oid
)
class
RPCClient
(
SocketIO
):
nextseq
=
1
# Requests coming from the client are odd
def
__init__
(
self
,
address
,
family
=
socket
.
AF_INET
,
type
=
socket
.
SOCK_STREAM
):
sock
=
socket
.
socket
(
family
,
type
)
sock
.
connect
(
address
)
SocketIO
.
__init__
(
self
,
sock
)
def
get_remote_proxy
(
self
,
oid
):
return
RPCProxy
(
self
,
oid
)
class
RPCProxy
:
__methods
=
None
__attributes
=
None
def
__init__
(
self
,
sockio
,
oid
):
self
.
sockio
=
sockio
self
.
oid
=
oid
def
__getattr__
(
self
,
name
):
if
self
.
__methods
is
None
:
self
.
__getmethods
()
if
self
.
__methods
.
get
(
name
):
return
MethodProxy
(
self
.
sockio
,
self
.
oid
,
name
)
if
self
.
__attributes
is
None
:
self
.
__getattributes
()
if
not
self
.
__attributes
.
has_key
(
name
):
raise
AttributeError
,
name
__getattr__
.
DebuggerStepThrough
=
1
def
__getattributes
(
self
):
self
.
__attributes
=
self
.
sockio
.
remotecall
(
self
.
oid
,
"__attributes__"
,
(),
{})
def
__getmethods
(
self
):
self
.
__methods
=
self
.
sockio
.
remotecall
(
self
.
oid
,
"__methods__"
,
(),
{})
def
_getmethods
(
obj
,
methods
):
# Helper to get a list of methods from an object
# Adds names to dictionary argument 'methods'
for
name
in
dir
(
obj
):
attr
=
getattr
(
obj
,
name
)
if
callable
(
attr
):
methods
[
name
]
=
1
if
type
(
obj
)
==
types
.
InstanceType
:
_getmethods
(
obj
.
__class__
,
methods
)
if
type
(
obj
)
==
types
.
ClassType
:
for
super
in
obj
.
__bases__
:
_getmethods
(
super
,
methods
)
def
_getattributes
(
obj
,
attributes
):
for
name
in
dir
(
obj
):
attr
=
getattr
(
obj
,
name
)
if
not
callable
(
attr
):
attributes
[
name
]
=
1
class
MethodProxy
:
def
__init__
(
self
,
sockio
,
oid
,
name
):
self
.
sockio
=
sockio
self
.
oid
=
oid
self
.
name
=
name
def
__call__
(
self
,
*
args
,
**
kwargs
):
value
=
self
.
sockio
.
remotecall
(
self
.
oid
,
self
.
name
,
args
,
kwargs
)
return
value
#
# Self Test
#
def
testServer
(
addr
):
class
RemotePerson
:
def
__init__
(
self
,
name
):
self
.
name
=
name
def
greet
(
self
,
name
):
print
"(someone called greet)"
print
"Hello %s, I am %s."
%
(
name
,
self
.
name
)
print
def
getName
(
self
):
print
"(someone called getName)"
print
return
self
.
name
def
greet_this_guy
(
self
,
name
):
print
"(someone called greet_this_guy)"
print
"About to greet %s ..."
%
name
remote_guy
=
self
.
server
.
current_handler
.
get_remote_proxy
(
name
)
remote_guy
.
greet
(
"Thomas Edison"
)
print
"Done."
print
person
=
RemotePerson
(
"Thomas Edison"
)
svr
=
RPCServer
(
addr
)
svr
.
register
(
'thomas'
,
person
)
person
.
server
=
svr
# only required if callbacks are used
# svr.serve_forever()
svr
.
handle_request
()
# process once only
def
testClient
(
addr
):
#
# demonstrates RPC Client
#
import
time
clt
=
RPCClient
(
addr
)
thomas
=
clt
.
get_remote_proxy
(
"thomas"
)
print
"The remote person's name is ..."
print
thomas
.
getName
()
# print clt.remotecall("thomas", "getName", (), {})
print
time
.
sleep
(
1
)
print
"Getting remote thomas to say hi..."
thomas
.
greet
(
"Alexander Bell"
)
#clt.remotecall("thomas","greet",("Alexander Bell",), {})
print
"Done."
print
time
.
sleep
(
2
)
# demonstrates remote server calling local instance
class
LocalPerson
:
def
__init__
(
self
,
name
):
self
.
name
=
name
def
greet
(
self
,
name
):
print
"You've greeted me!"
def
getName
(
self
):
return
self
.
name
person
=
LocalPerson
(
"Alexander Bell"
)
clt
.
register
(
"alexander"
,
person
)
thomas
.
greet_this_guy
(
"alexander"
)
# clt.remotecall("thomas","greet_this_guy",("alexander",), {})
def
test
():
addr
=
(
"localhost"
,
8833
)
if
len
(
sys
.
argv
)
==
2
:
if
sys
.
argv
[
1
]
==
'-server'
:
testServer
(
addr
)
return
testClient
(
addr
)
if
__name__
==
'__main__'
:
test
()
Lib/idlelib/run.py
0 → 100644
View file @
5d2af63c
import
sys
import
rpc
def
main
():
port
=
8833
if
sys
.
argv
[
1
:]:
port
=
int
(
sys
.
argv
[
1
])
sys
.
argv
[:]
=
[
""
]
addr
=
(
"localhost"
,
port
)
svr
=
rpc
.
RPCServer
(
addr
,
MyHandler
)
svr
.
handle_request
()
# A single request only
class
MyHandler
(
rpc
.
RPCHandler
):
def
handle
(
self
):
executive
=
Executive
(
self
)
self
.
register
(
"exec"
,
executive
)
sys
.
stdin
=
self
.
get_remote_proxy
(
"stdin"
)
sys
.
stdout
=
self
.
get_remote_proxy
(
"stdout"
)
sys
.
stderr
=
self
.
get_remote_proxy
(
"stderr"
)
rpc
.
RPCHandler
.
handle
(
self
)
class
Executive
:
def
__init__
(
self
,
rpchandler
):
self
.
conn
=
rpchandler
import
__main__
self
.
locals
=
__main__
.
__dict__
def
runcode
(
self
,
code
):
exec
code
in
self
.
locals
def
start_debugger
(
self
,
gui_oid
):
import
RemoteDebugger
return
RemoteDebugger
.
start_debugger
(
self
.
conn
,
gui_oid
)
def
stackviewer
(
self
,
flist_oid
=
None
):
if
not
hasattr
(
sys
,
"last_traceback"
):
return
None
flist
=
None
if
flist_oid
is
not
None
:
flist
=
self
.
conn
.
get_remote_proxy
(
flist_oid
)
import
RemoteObjectBrowser
import
StackViewer
tb
=
sys
.
last_traceback
while
tb
and
tb
.
tb_frame
.
f_globals
[
"__name__"
]
in
[
"rpc"
,
"run"
]:
tb
=
tb
.
tb_next
item
=
StackViewer
.
StackTreeItem
(
flist
,
tb
)
return
RemoteObjectBrowser
.
remote_object_tree_item
(
item
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment