Show More
@@ -16,6 +16,7 b' Utilities for path handling.' | |||||
16 |
|
16 | |||
17 | import os |
|
17 | import os | |
18 | import sys |
|
18 | import sys | |
|
19 | import tempfile | |||
19 | from hashlib import md5 |
|
20 | from hashlib import md5 | |
20 |
|
21 | |||
21 | import IPython |
|
22 | import IPython | |
@@ -41,6 +42,10 b' def _get_long_path_name(path):' | |||||
41 | """Dummy no-op.""" |
|
42 | """Dummy no-op.""" | |
42 | return path |
|
43 | return path | |
43 |
|
44 | |||
|
45 | def _writable_dir(path): | |||
|
46 | """Whether `path` is a directory, to which the user has write access.""" | |||
|
47 | return os.path.isdir(path) and os.access(path, os.W_OK) | |||
|
48 | ||||
44 | if sys.platform == 'win32': |
|
49 | if sys.platform == 'win32': | |
45 | def _get_long_path_name(path): |
|
50 | def _get_long_path_name(path): | |
46 | """Get a long path name (expand ~) on Windows using ctypes. |
|
51 | """Get a long path name (expand ~) on Windows using ctypes. | |
@@ -166,7 +171,6 b' def get_home_dir():' | |||||
166 | raised for all other OSes. |
|
171 | raised for all other OSes. | |
167 | """ |
|
172 | """ | |
168 |
|
173 | |||
169 | isdir = os.path.isdir |
|
|||
170 | env = os.environ |
|
174 | env = os.environ | |
171 |
|
175 | |||
172 | # first, check py2exe distribution root directory for _ipython. |
|
176 | # first, check py2exe distribution root directory for _ipython. | |
@@ -178,7 +182,7 b' def get_home_dir():' | |||||
178 | else: |
|
182 | else: | |
179 | root=os.path.join(os.path.split(IPython.__file__)[0],"../../") |
|
183 | root=os.path.join(os.path.split(IPython.__file__)[0],"../../") | |
180 | root=os.path.abspath(root).rstrip('\\') |
|
184 | root=os.path.abspath(root).rstrip('\\') | |
181 |
if |
|
185 | if _writable_dir(os.path.join(root, '_ipython')): | |
182 | os.environ["IPYKITROOT"] = root |
|
186 | os.environ["IPYKITROOT"] = root | |
183 | return _cast_unicode(root, fs_encoding) |
|
187 | return _cast_unicode(root, fs_encoding) | |
184 |
|
188 | |||
@@ -212,7 +216,7 b' def get_home_dir():' | |||||
212 | except KeyError: |
|
216 | except KeyError: | |
213 | pass |
|
217 | pass | |
214 | else: |
|
218 | else: | |
215 |
if |
|
219 | if _writable_dir(homedir): | |
216 | return _cast_unicode(homedir, fs_encoding) |
|
220 | return _cast_unicode(homedir, fs_encoding) | |
217 |
|
221 | |||
218 | # Now look for a local home directory |
|
222 | # Now look for a local home directory | |
@@ -221,7 +225,7 b' def get_home_dir():' | |||||
221 | except KeyError: |
|
225 | except KeyError: | |
222 | pass |
|
226 | pass | |
223 | else: |
|
227 | else: | |
224 |
if |
|
228 | if _writable_dir(homedir): | |
225 | return _cast_unicode(homedir, fs_encoding) |
|
229 | return _cast_unicode(homedir, fs_encoding) | |
226 |
|
230 | |||
227 | # Now the users profile directory |
|
231 | # Now the users profile directory | |
@@ -230,7 +234,7 b' def get_home_dir():' | |||||
230 | except KeyError: |
|
234 | except KeyError: | |
231 | pass |
|
235 | pass | |
232 | else: |
|
236 | else: | |
233 |
if |
|
237 | if _writable_dir(homedir): | |
234 | return _cast_unicode(homedir, fs_encoding) |
|
238 | return _cast_unicode(homedir, fs_encoding) | |
235 |
|
239 | |||
236 | # Use the registry to get the 'My Documents' folder. |
|
240 | # Use the registry to get the 'My Documents' folder. | |
@@ -245,7 +249,7 b' def get_home_dir():' | |||||
245 | except: |
|
249 | except: | |
246 | pass |
|
250 | pass | |
247 | else: |
|
251 | else: | |
248 |
if |
|
252 | if _writable_dir(homedir): | |
249 | return _cast_unicode(homedir, fs_encoding) |
|
253 | return _cast_unicode(homedir, fs_encoding) | |
250 |
|
254 | |||
251 | # A user with a lot of unix tools in win32 may have defined $HOME. |
|
255 | # A user with a lot of unix tools in win32 may have defined $HOME. | |
@@ -255,7 +259,7 b' def get_home_dir():' | |||||
255 | except KeyError: |
|
259 | except KeyError: | |
256 | pass |
|
260 | pass | |
257 | else: |
|
261 | else: | |
258 |
if |
|
262 | if _writable_dir(homedir): | |
259 | return _cast_unicode(homedir, fs_encoding) |
|
263 | return _cast_unicode(homedir, fs_encoding) | |
260 |
|
264 | |||
261 | # If all else fails, raise HomeDirError |
|
265 | # If all else fails, raise HomeDirError | |
@@ -272,14 +276,13 b' def get_xdg_dir():' | |||||
272 | This is only for posix (Linux,Unix,OS X, etc) systems. |
|
276 | This is only for posix (Linux,Unix,OS X, etc) systems. | |
273 | """ |
|
277 | """ | |
274 |
|
278 | |||
275 | isdir = os.path.isdir |
|
|||
276 | env = os.environ |
|
279 | env = os.environ | |
277 |
|
280 | |||
278 | if os.name == 'posix': |
|
281 | if os.name == 'posix': | |
279 | # Linux, Unix, AIX, OS X |
|
282 | # Linux, Unix, AIX, OS X | |
280 | # use ~/.config if not set OR empty |
|
283 | # use ~/.config if not set OR empty | |
281 | xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config') |
|
284 | xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config') | |
282 |
if xdg and |
|
285 | if xdg and _writable_dir(xdg): | |
283 | return _cast_unicode(xdg, fs_encoding) |
|
286 | return _cast_unicode(xdg, fs_encoding) | |
284 |
|
287 | |||
285 | return None |
|
288 | return None | |
@@ -294,7 +297,7 b' def get_ipython_dir():' | |||||
294 |
|
297 | |||
295 | env = os.environ |
|
298 | env = os.environ | |
296 | pjoin = os.path.join |
|
299 | pjoin = os.path.join | |
297 | exists = os.path.exists |
|
300 | ||
298 |
|
301 | |||
299 | ipdir_def = '.ipython' |
|
302 | ipdir_def = '.ipython' | |
300 | xdg_def = 'ipython' |
|
303 | xdg_def = 'ipython' | |
@@ -312,7 +315,7 b' def get_ipython_dir():' | |||||
312 |
|
315 | |||
313 | xdg_ipdir = pjoin(xdg_dir, xdg_def) |
|
316 | xdg_ipdir = pjoin(xdg_dir, xdg_def) | |
314 |
|
317 | |||
315 |
if |
|
318 | if _writable_dir(xdg_ipdir) or not _writable_dir(home_ipdir): | |
316 | ipdir = xdg_ipdir |
|
319 | ipdir = xdg_ipdir | |
317 |
|
320 | |||
318 | if ipdir is None: |
|
321 | if ipdir is None: | |
@@ -320,6 +323,19 b' def get_ipython_dir():' | |||||
320 | ipdir = home_ipdir |
|
323 | ipdir = home_ipdir | |
321 |
|
324 | |||
322 | ipdir = os.path.normpath(os.path.expanduser(ipdir)) |
|
325 | ipdir = os.path.normpath(os.path.expanduser(ipdir)) | |
|
326 | ||||
|
327 | if os.path.exists(ipdir) and not _writable_dir(ipdir): | |||
|
328 | # ipdir exists, but is not writable | |||
|
329 | warn.warn("IPython dir '%s' is not a writable location," | |||
|
330 | " using a temp directory."%ipdir) | |||
|
331 | ipdir = tempfile.mkdtemp() | |||
|
332 | elif not os.path.exists(ipdir): | |||
|
333 | parent = ipdir.rsplit(os.path.sep, 1)[0] | |||
|
334 | if not _writable_dir(parent): | |||
|
335 | # ipdir does not exist and parent isn't writable | |||
|
336 | warn.warn("IPython parent '%s' is not a writable location," | |||
|
337 | " using a temp directory."%parent) | |||
|
338 | ipdir = tempfile.mkdtemp() | |||
323 |
|
339 | |||
324 | return _cast_unicode(ipdir, fs_encoding) |
|
340 | return _cast_unicode(ipdir, fs_encoding) | |
325 |
|
341 |
@@ -16,6 +16,7 b' import os' | |||||
16 | import shutil |
|
16 | import shutil | |
17 | import sys |
|
17 | import sys | |
18 | import tempfile |
|
18 | import tempfile | |
|
19 | import StringIO | |||
19 |
|
20 | |||
20 | from os.path import join, abspath, split |
|
21 | from os.path import join, abspath, split | |
21 |
|
22 | |||
@@ -26,7 +27,7 b' from nose import with_setup' | |||||
26 | import IPython |
|
27 | import IPython | |
27 | from IPython.testing import decorators as dec |
|
28 | from IPython.testing import decorators as dec | |
28 | from IPython.testing.decorators import skip_if_not_win32, skip_win32 |
|
29 | from IPython.testing.decorators import skip_if_not_win32, skip_win32 | |
29 | from IPython.utils import path |
|
30 | from IPython.utils import path, io | |
30 |
|
31 | |||
31 | # Platform-dependent imports |
|
32 | # Platform-dependent imports | |
32 | try: |
|
33 | try: | |
@@ -92,7 +93,8 b' def teardown_environment():' | |||||
92 | """Restore things that were remebered by the setup_environment function |
|
93 | """Restore things that were remebered by the setup_environment function | |
93 | """ |
|
94 | """ | |
94 | (oldenv, os.name, path.get_home_dir, IPython.__file__,) = oldstuff |
|
95 | (oldenv, os.name, path.get_home_dir, IPython.__file__,) = oldstuff | |
95 |
|
96 | reload(path) | ||
|
97 | ||||
96 | for key in env.keys(): |
|
98 | for key in env.keys(): | |
97 | if key not in oldenv: |
|
99 | if key not in oldenv: | |
98 | del env[key] |
|
100 | del env[key] | |
@@ -229,6 +231,7 b' def test_get_home_dir_8():' | |||||
229 | def test_get_ipython_dir_1(): |
|
231 | def test_get_ipython_dir_1(): | |
230 | """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions.""" |
|
232 | """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions.""" | |
231 | env_ipdir = os.path.join("someplace", ".ipython") |
|
233 | env_ipdir = os.path.join("someplace", ".ipython") | |
|
234 | path._writable_dir = lambda path: True | |||
232 | env['IPYTHON_DIR'] = env_ipdir |
|
235 | env['IPYTHON_DIR'] = env_ipdir | |
233 | ipdir = path.get_ipython_dir() |
|
236 | ipdir = path.get_ipython_dir() | |
234 | nt.assert_equal(ipdir, env_ipdir) |
|
237 | nt.assert_equal(ipdir, env_ipdir) | |
@@ -238,6 +241,8 b' def test_get_ipython_dir_1():' | |||||
238 | def test_get_ipython_dir_2(): |
|
241 | def test_get_ipython_dir_2(): | |
239 | """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions.""" |
|
242 | """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions.""" | |
240 | path.get_home_dir = lambda : "someplace" |
|
243 | path.get_home_dir = lambda : "someplace" | |
|
244 | path.get_xdg_dir = lambda : None | |||
|
245 | path._writable_dir = lambda path: True | |||
241 | os.name = "posix" |
|
246 | os.name = "posix" | |
242 | env.pop('IPYTHON_DIR', None) |
|
247 | env.pop('IPYTHON_DIR', None) | |
243 | env.pop('IPYTHONDIR', None) |
|
248 | env.pop('IPYTHONDIR', None) | |
@@ -249,6 +254,7 b' def test_get_ipython_dir_2():' | |||||
249 | def test_get_ipython_dir_3(): |
|
254 | def test_get_ipython_dir_3(): | |
250 | """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist.""" |
|
255 | """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist.""" | |
251 | path.get_home_dir = lambda : "someplace" |
|
256 | path.get_home_dir = lambda : "someplace" | |
|
257 | path._writable_dir = lambda path: True | |||
252 | os.name = "posix" |
|
258 | os.name = "posix" | |
253 | env.pop('IPYTHON_DIR', None) |
|
259 | env.pop('IPYTHON_DIR', None) | |
254 | env.pop('IPYTHONDIR', None) |
|
260 | env.pop('IPYTHONDIR', None) | |
@@ -283,18 +289,23 b' def test_get_ipython_dir_5():' | |||||
283 | @with_environment |
|
289 | @with_environment | |
284 | def test_get_ipython_dir_6(): |
|
290 | def test_get_ipython_dir_6(): | |
285 | """test_get_ipython_dir_6, use XDG if defined and neither exist.""" |
|
291 | """test_get_ipython_dir_6, use XDG if defined and neither exist.""" | |
286 | path.get_home_dir = lambda : 'somehome' |
|
292 | xdg = os.path.join(HOME_TEST_DIR, 'somexdg') | |
287 | path.get_xdg_dir = lambda : 'somexdg' |
|
293 | os.mkdir(xdg) | |
|
294 | shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython')) | |||
|
295 | path.get_home_dir = lambda : HOME_TEST_DIR | |||
|
296 | path.get_xdg_dir = lambda : xdg | |||
288 | os.name = "posix" |
|
297 | os.name = "posix" | |
289 | env.pop('IPYTHON_DIR', None) |
|
298 | env.pop('IPYTHON_DIR', None) | |
290 | env.pop('IPYTHONDIR', None) |
|
299 | env.pop('IPYTHONDIR', None) | |
291 | xdg_ipdir = os.path.join("somexdg", "ipython") |
|
300 | env.pop('XDG_CONFIG_HOME', None) | |
|
301 | xdg_ipdir = os.path.join(xdg, "ipython") | |||
292 | ipdir = path.get_ipython_dir() |
|
302 | ipdir = path.get_ipython_dir() | |
293 | nt.assert_equal(ipdir, xdg_ipdir) |
|
303 | nt.assert_equal(ipdir, xdg_ipdir) | |
294 |
|
304 | |||
295 | @with_environment |
|
305 | @with_environment | |
296 | def test_get_ipython_dir_7(): |
|
306 | def test_get_ipython_dir_7(): | |
297 | """test_get_ipython_dir_7, test home directory expansion on IPYTHON_DIR""" |
|
307 | """test_get_ipython_dir_7, test home directory expansion on IPYTHON_DIR""" | |
|
308 | path._writable_dir = lambda path: True | |||
298 | home_dir = os.path.expanduser('~') |
|
309 | home_dir = os.path.expanduser('~') | |
299 | env['IPYTHON_DIR'] = os.path.join('~', 'somewhere') |
|
310 | env['IPYTHON_DIR'] = os.path.join('~', 'somewhere') | |
300 | ipdir = path.get_ipython_dir() |
|
311 | ipdir = path.get_ipython_dir() | |
@@ -305,6 +316,7 b' def test_get_ipython_dir_7():' | |||||
305 | def test_get_xdg_dir_1(): |
|
316 | def test_get_xdg_dir_1(): | |
306 | """test_get_xdg_dir_1, check xdg_dir""" |
|
317 | """test_get_xdg_dir_1, check xdg_dir""" | |
307 | reload(path) |
|
318 | reload(path) | |
|
319 | path._writable_dir = lambda path: True | |||
308 | path.get_home_dir = lambda : 'somewhere' |
|
320 | path.get_home_dir = lambda : 'somewhere' | |
309 | os.name = "posix" |
|
321 | os.name = "posix" | |
310 | env.pop('IPYTHON_DIR', None) |
|
322 | env.pop('IPYTHON_DIR', None) | |
@@ -369,3 +381,24 b' def test_get_long_path_name():' | |||||
369 | p = path.get_long_path_name('/usr/local') |
|
381 | p = path.get_long_path_name('/usr/local') | |
370 | nt.assert_equals(p,'/usr/local') |
|
382 | nt.assert_equals(p,'/usr/local') | |
371 |
|
383 | |||
|
384 | @dec.skip_win32 # can't create not-user-writable dir on win | |||
|
385 | @with_environment | |||
|
386 | def test_not_writable_ipdir(): | |||
|
387 | tmpdir = tempfile.mkdtemp() | |||
|
388 | os.name = "posix" | |||
|
389 | env.pop('IPYTHON_DIR', None) | |||
|
390 | env.pop('IPYTHONDIR', None) | |||
|
391 | env.pop('XDG_CONFIG_HOME', None) | |||
|
392 | env['HOME'] = tmpdir | |||
|
393 | ipdir = os.path.join(tmpdir, '.ipython') | |||
|
394 | os.mkdir(ipdir) | |||
|
395 | os.chmod(ipdir, 600) | |||
|
396 | stderr = io.stderr | |||
|
397 | pipe = StringIO.StringIO() | |||
|
398 | io.stderr = pipe | |||
|
399 | ipdir = path.get_ipython_dir() | |||
|
400 | io.stderr.flush() | |||
|
401 | io.stderr = stderr | |||
|
402 | nt.assert_true('WARNING' in pipe.getvalue()) | |||
|
403 | env.pop('IPYTHON_DIR', None) | |||
|
404 | No newline at end of file |
@@ -164,8 +164,14 b' class Kernel(Configurable):' | |||||
164 | # reason for this to be anything less than ~ 0.1s |
|
164 | # reason for this to be anything less than ~ 0.1s | |
165 | # since it is a real poller and will respond |
|
165 | # since it is a real poller and will respond | |
166 | # to events immediately |
|
166 | # to events immediately | |
167 | poller.poll(10*1000*self._poll_interval) |
|
167 | ||
168 | self.do_one_iteration() |
|
168 | # double nested try/except, to properly catch KeyboardInterrupt | |
|
169 | # due to pyzmq Issue #130 | |||
|
170 | try: | |||
|
171 | poller.poll(10*1000*self._poll_interval) | |||
|
172 | self.do_one_iteration() | |||
|
173 | except: | |||
|
174 | raise | |||
169 | except KeyboardInterrupt: |
|
175 | except KeyboardInterrupt: | |
170 | # Ctrl-C shouldn't crash the kernel |
|
176 | # Ctrl-C shouldn't crash the kernel | |
171 | io.raw_print("KeyboardInterrupt caught in kernel") |
|
177 | io.raw_print("KeyboardInterrupt caught in kernel") |
General Comments 0
You need to be logged in to leave comments.
Login now