1 # Everything is done inside the loader function so that no other names
2 # are placed in the global namespace. Before user code is executed,
3 # even this name is unbound.
5 import sys
, os
, protocol
, threading
, time
8 ## Use to debug the loading process itself:
9 ## sys.stdout = open('c:\\windows\\desktop\\stdout.txt','a')
10 ## sys.stderr = open('c:\\windows\\desktop\\stderr.txt','a')
12 # Ensure that there is absolutely no pollution of the global
13 # namespace by deleting the global name of this function.
19 client
= protocol
.Client()
20 except protocol
.connectionLost
, cL
:
21 print 'loader: Unable to connect to IDLE', cL
24 # Connect to an ExecBinding object that needs our help. If
25 # the user is starting multiple programs right now, we might get a
26 # different one than the one that started us. Proving that's okay is
27 # left as an exercise to the reader. (HINT: Twelve, by the pigeonhole
29 ExecBinding
= client
.getobject('ExecBinding')
31 print "loader: IDLE does not need me."
34 # All of our input and output goes through ExecBinding.
35 sys
.stdin
= Remote
.pseudoIn( ExecBinding
.readline
)
36 sys
.stdout
= Remote
.pseudoOut( ExecBinding
.write
.void
, tag
="stdout" )
37 sys
.stderr
= Remote
.pseudoOut( ExecBinding
.write
.void
, tag
="stderr" )
39 # Create a Remote object and start it running.
40 remote
= Remote
.Remote(globals(), ExecBinding
)
41 rthread
= threading
.Thread(target
=remote
.mainloop
)
45 # Block until either the client or the user program stops
46 user
= rthread
.isAlive
47 while user
and client
.isAlive():
51 user
= hasattr(sys
, "ready_to_exit") and sys
.ready_to_exit
52 for t
in threading
.enumerate():
53 if not t
.isDaemon() and t
.isAlive() and t
!=threading
.currentThread():
57 # We need to make sure we actually exit, so that the user doesn't get
58 # stuck with an invisible process. We want to finalize C modules, so
59 # we don't use os._exit(), but we don't call sys.exitfunc, which might