##// END OF EJS Templates
Commented out a usage of the with statement in a test that was...
Brian E Granger -
Show More
@@ -1,178 +1,180 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 # -*- test-case-name: IPython.kernel.test.test_contexts -*-
2 # -*- test-case-name: IPython.kernel.test.test_contexts -*-
3 """Context managers for IPython.
3 """Context managers for IPython.
4
4
5 Python 2.5 introduced the `with` statement, which is based on the context
5 Python 2.5 introduced the `with` statement, which is based on the context
6 manager protocol. This module offers a few context managers for common cases,
6 manager protocol. This module offers a few context managers for common cases,
7 which can also be useful as templates for writing new, application-specific
7 which can also be useful as templates for writing new, application-specific
8 managers.
8 managers.
9 """
9 """
10
10
11 from __future__ import with_statement
11 from __future__ import with_statement
12
12
13 __docformat__ = "restructuredtext en"
13 __docformat__ = "restructuredtext en"
14
14
15 #-------------------------------------------------------------------------------
15 #-------------------------------------------------------------------------------
16 # Copyright (C) 2008 The IPython Development Team
16 # Copyright (C) 2008 The IPython Development Team
17 #
17 #
18 # Distributed under the terms of the BSD License. The full license is in
18 # Distributed under the terms of the BSD License. The full license is in
19 # the file COPYING, distributed as part of this software.
19 # the file COPYING, distributed as part of this software.
20 #-------------------------------------------------------------------------------
20 #-------------------------------------------------------------------------------
21
21
22 #-------------------------------------------------------------------------------
22 #-------------------------------------------------------------------------------
23 # Imports
23 # Imports
24 #-------------------------------------------------------------------------------
24 #-------------------------------------------------------------------------------
25
25
26 import linecache
26 import linecache
27 import sys
27 import sys
28
28
29 from twisted.internet.error import ConnectionRefusedError
29 from twisted.internet.error import ConnectionRefusedError
30
30
31 from IPython.ultraTB import _fixed_getinnerframes, findsource
31 from IPython.ultraTB import _fixed_getinnerframes, findsource
32 from IPython import ipapi
32 from IPython import ipapi
33
33
34 from IPython.kernel import error
34 from IPython.kernel import error
35
35
36 #---------------------------------------------------------------------------
36 #---------------------------------------------------------------------------
37 # Utility functions needed by all context managers.
37 # Utility functions needed by all context managers.
38 #---------------------------------------------------------------------------
38 #---------------------------------------------------------------------------
39
39
40 def remote():
40 def remote():
41 """Raises a special exception meant to be caught by context managers.
41 """Raises a special exception meant to be caught by context managers.
42 """
42 """
43 m = 'Special exception to stop local execution of parallel code.'
43 m = 'Special exception to stop local execution of parallel code.'
44 raise error.StopLocalExecution(m)
44 raise error.StopLocalExecution(m)
45
45
46
46
47 def strip_whitespace(source,require_remote=True):
47 def strip_whitespace(source,require_remote=True):
48 """strip leading whitespace from input source.
48 """strip leading whitespace from input source.
49
49
50 :Parameters:
50 :Parameters:
51
51
52 """
52 """
53 remote_mark = 'remote()'
53 remote_mark = 'remote()'
54 # Expand tabs to avoid any confusion.
54 # Expand tabs to avoid any confusion.
55 wsource = [l.expandtabs(4) for l in source]
55 wsource = [l.expandtabs(4) for l in source]
56 # Detect the indentation level
56 # Detect the indentation level
57 done = False
57 done = False
58 for line in wsource:
58 for line in wsource:
59 if line.isspace():
59 if line.isspace():
60 continue
60 continue
61 for col,char in enumerate(line):
61 for col,char in enumerate(line):
62 if char != ' ':
62 if char != ' ':
63 done = True
63 done = True
64 break
64 break
65 if done:
65 if done:
66 break
66 break
67 # Now we know how much leading space there is in the code. Next, we
67 # Now we know how much leading space there is in the code. Next, we
68 # extract up to the first line that has less indentation.
68 # extract up to the first line that has less indentation.
69 # WARNINGS: we skip comments that may be misindented, but we do NOT yet
69 # WARNINGS: we skip comments that may be misindented, but we do NOT yet
70 # detect triple quoted strings that may have flush left text.
70 # detect triple quoted strings that may have flush left text.
71 for lno,line in enumerate(wsource):
71 for lno,line in enumerate(wsource):
72 lead = line[:col]
72 lead = line[:col]
73 if lead.isspace():
73 if lead.isspace():
74 continue
74 continue
75 else:
75 else:
76 if not lead.lstrip().startswith('#'):
76 if not lead.lstrip().startswith('#'):
77 break
77 break
78 # The real 'with' source is up to lno
78 # The real 'with' source is up to lno
79 src_lines = [l[col:] for l in wsource[:lno+1]]
79 src_lines = [l[col:] for l in wsource[:lno+1]]
80
80
81 # Finally, check that the source's first non-comment line begins with the
81 # Finally, check that the source's first non-comment line begins with the
82 # special call 'remote()'
82 # special call 'remote()'
83 if require_remote:
83 if require_remote:
84 for nline,line in enumerate(src_lines):
84 for nline,line in enumerate(src_lines):
85 if line.isspace() or line.startswith('#'):
85 if line.isspace() or line.startswith('#'):
86 continue
86 continue
87 if line.startswith(remote_mark):
87 if line.startswith(remote_mark):
88 break
88 break
89 else:
89 else:
90 raise ValueError('%s call missing at the start of code' %
90 raise ValueError('%s call missing at the start of code' %
91 remote_mark)
91 remote_mark)
92 out_lines = src_lines[nline+1:]
92 out_lines = src_lines[nline+1:]
93 else:
93 else:
94 # If the user specified that the remote() call wasn't mandatory
94 # If the user specified that the remote() call wasn't mandatory
95 out_lines = src_lines
95 out_lines = src_lines
96
96
97 # src = ''.join(out_lines) # dbg
97 # src = ''.join(out_lines) # dbg
98 #print 'SRC:\n<<<<<<<>>>>>>>\n%s<<<<<>>>>>>' % src # dbg
98 #print 'SRC:\n<<<<<<<>>>>>>>\n%s<<<<<>>>>>>' % src # dbg
99 return ''.join(out_lines)
99 return ''.join(out_lines)
100
100
101 class RemoteContextBase(object):
101 class RemoteContextBase(object):
102 def __init__(self):
102 def __init__(self):
103 self.ip = ipapi.get()
103 self.ip = ipapi.get()
104
104
105 def _findsource_file(self,f):
105 def _findsource_file(self,f):
106 linecache.checkcache()
106 linecache.checkcache()
107 s = findsource(f.f_code)
107 s = findsource(f.f_code)
108 lnum = f.f_lineno
108 lnum = f.f_lineno
109 wsource = s[0][f.f_lineno:]
109 wsource = s[0][f.f_lineno:]
110 return strip_whitespace(wsource)
110 return strip_whitespace(wsource)
111
111
112 def _findsource_ipython(self,f):
112 def _findsource_ipython(self,f):
113 from IPython import ipapi
113 from IPython import ipapi
114 self.ip = ipapi.get()
114 self.ip = ipapi.get()
115 buf = self.ip.IP.input_hist_raw[-1].splitlines()[1:]
115 buf = self.ip.IP.input_hist_raw[-1].splitlines()[1:]
116 wsource = [l+'\n' for l in buf ]
116 wsource = [l+'\n' for l in buf ]
117
117
118 return strip_whitespace(wsource)
118 return strip_whitespace(wsource)
119
119
120 def findsource(self,frame):
120 def findsource(self,frame):
121 local_ns = frame.f_locals
121 local_ns = frame.f_locals
122 global_ns = frame.f_globals
122 global_ns = frame.f_globals
123 if frame.f_code.co_filename == '<ipython console>':
123 if frame.f_code.co_filename == '<ipython console>':
124 src = self._findsource_ipython(frame)
124 src = self._findsource_ipython(frame)
125 else:
125 else:
126 src = self._findsource_file(frame)
126 src = self._findsource_file(frame)
127 return src
127 return src
128
128
129 def __enter__(self):
129 def __enter__(self):
130 raise NotImplementedError
130 raise NotImplementedError
131
131
132 def __exit__ (self, etype, value, tb):
132 def __exit__ (self, etype, value, tb):
133 if issubclass(etype,error.StopLocalExecution):
133 if issubclass(etype,error.StopLocalExecution):
134 return True
134 return True
135
135
136 class RemoteMultiEngine(RemoteContextBase):
136 class RemoteMultiEngine(RemoteContextBase):
137 def __init__(self,mec):
137 def __init__(self,mec):
138 self.mec = mec
138 self.mec = mec
139 RemoteContextBase.__init__(self)
139 RemoteContextBase.__init__(self)
140
140
141 def __enter__(self):
141 def __enter__(self):
142 src = self.findsource(sys._getframe(1))
142 src = self.findsource(sys._getframe(1))
143 return self.mec.execute(src)
143 return self.mec.execute(src)
144
144
145
145
146 # XXX - Temporary hackish testing, we'll move this into proper tests right
146 # XXX - Temporary hackish testing, we'll move this into proper tests right
147 # away
147 # away. This has been commented out as it doesn't run under Python 2.4
148
148 # because of the usage of the with statement below. We need to protect
149 if __name__ == '__main__':
149 # such things with a try:except.
150
150
151 # XXX - for now, we need a running cluster to be started separately. The
151 # if __name__ == '__main__':
152 # daemon work is almost finished, and will make much of this unnecessary.
152 #
153 from IPython.kernel import client
153 # # XXX - for now, we need a running cluster to be started separately. The
154 mec = client.MultiEngineClient(('127.0.0.1',10105))
154 # # daemon work is almost finished, and will make much of this unnecessary.
155
155 # from IPython.kernel import client
156 try:
156 # mec = client.MultiEngineClient(('127.0.0.1',10105))
157 mec.get_ids()
157 #
158 except ConnectionRefusedError:
158 # try:
159 import os, time
159 # mec.get_ids()
160 os.system('ipcluster -n 2 &')
160 # except ConnectionRefusedError:
161 time.sleep(2)
161 # import os, time
162 mec = client.MultiEngineClient(('127.0.0.1',10105))
162 # os.system('ipcluster -n 2 &')
163
163 # time.sleep(2)
164 mec.block = False
164 # mec = client.MultiEngineClient(('127.0.0.1',10105))
165
165 #
166 import itertools
166 # mec.block = False
167 c = itertools.count()
167 #
168
168 # import itertools
169 parallel = RemoteMultiEngine(mec)
169 # c = itertools.count()
170
170 #
171 with parallel as pr:
171 # parallel = RemoteMultiEngine(mec)
172 # A comment
172 #
173 remote() # this means the code below only runs remotely
173 # with parallel as pr:
174 print 'Hello remote world'
174 # # A comment
175 x = 3.14
175 # remote() # this means the code below only runs remotely
176 # Comments are OK
176 # print 'Hello remote world'
177 # Even misindented.
177 # x = 3.14
178 y = x+1
178 # # Comments are OK
179 # # Even misindented.
180 # y = x+1
General Comments 0
You need to be logged in to leave comments. Login now