Skip to content
Browse files

Merge branch 'master' into htmlnotebook

  • Loading branch information...
2 parents 5bad195 + 32f3d05 commit cc6010e3c2cbebda337430197f99663a9f96795c @ellisonbg ellisonbg committed Aug 14, 2011
Showing with 73 additions and 18 deletions.
  1. +27 −11 IPython/utils/path.py
  2. +38 −5 IPython/utils/tests/test_path.py
  3. +8 −2 IPython/zmq/ipkernel.py
View
38 IPython/utils/path.py
@@ -16,6 +16,7 @@
import os
import sys
+import tempfile
from hashlib import md5
import IPython
@@ -41,6 +42,10 @@ def _get_long_path_name(path):
"""Dummy no-op."""
return path
+def _writable_dir(path):
+ """Whether `path` is a directory, to which the user has write access."""
+ return os.path.isdir(path) and os.access(path, os.W_OK)
+
if sys.platform == 'win32':
def _get_long_path_name(path):
"""Get a long path name (expand ~) on Windows using ctypes.
@@ -166,7 +171,6 @@ def get_home_dir():
raised for all other OSes.
"""
- isdir = os.path.isdir
env = os.environ
# first, check py2exe distribution root directory for _ipython.
@@ -178,7 +182,7 @@ def get_home_dir():
else:
root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
root=os.path.abspath(root).rstrip('\\')
- if isdir(os.path.join(root, '_ipython')):
+ if _writable_dir(os.path.join(root, '_ipython')):
os.environ["IPYKITROOT"] = root
return _cast_unicode(root, fs_encoding)
@@ -212,7 +216,7 @@ def get_home_dir():
except KeyError:
pass
else:
- if isdir(homedir):
+ if _writable_dir(homedir):
return _cast_unicode(homedir, fs_encoding)
# Now look for a local home directory
@@ -221,7 +225,7 @@ def get_home_dir():
except KeyError:
pass
else:
- if isdir(homedir):
+ if _writable_dir(homedir):
return _cast_unicode(homedir, fs_encoding)
# Now the users profile directory
@@ -230,7 +234,7 @@ def get_home_dir():
except KeyError:
pass
else:
- if isdir(homedir):
+ if _writable_dir(homedir):
return _cast_unicode(homedir, fs_encoding)
# Use the registry to get the 'My Documents' folder.
@@ -245,7 +249,7 @@ def get_home_dir():
except:
pass
else:
- if isdir(homedir):
+ if _writable_dir(homedir):
return _cast_unicode(homedir, fs_encoding)
# A user with a lot of unix tools in win32 may have defined $HOME.
@@ -255,7 +259,7 @@ def get_home_dir():
except KeyError:
pass
else:
- if isdir(homedir):
+ if _writable_dir(homedir):
return _cast_unicode(homedir, fs_encoding)
# If all else fails, raise HomeDirError
@@ -272,14 +276,13 @@ def get_xdg_dir():
This is only for posix (Linux,Unix,OS X, etc) systems.
"""
- isdir = os.path.isdir
env = os.environ
if os.name == 'posix':
# Linux, Unix, AIX, OS X
# use ~/.config if not set OR empty
xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
- if xdg and isdir(xdg):
+ if xdg and _writable_dir(xdg):
return _cast_unicode(xdg, fs_encoding)
return None
@@ -294,7 +297,7 @@ def get_ipython_dir():
env = os.environ
pjoin = os.path.join
- exists = os.path.exists
+
ipdir_def = '.ipython'
xdg_def = 'ipython'
@@ -312,14 +315,27 @@ def get_ipython_dir():
xdg_ipdir = pjoin(xdg_dir, xdg_def)
- if exists(xdg_ipdir) or not exists(home_ipdir):
+ if _writable_dir(xdg_ipdir) or not _writable_dir(home_ipdir):
ipdir = xdg_ipdir
if ipdir is None:
# not using XDG
ipdir = home_ipdir
ipdir = os.path.normpath(os.path.expanduser(ipdir))
+
+ if os.path.exists(ipdir) and not _writable_dir(ipdir):
+ # ipdir exists, but is not writable
+ warn.warn("IPython dir '%s' is not a writable location,"
+ " using a temp directory."%ipdir)
+ ipdir = tempfile.mkdtemp()
+ elif not os.path.exists(ipdir):
+ parent = ipdir.rsplit(os.path.sep, 1)[0]
+ if not _writable_dir(parent):
+ # ipdir does not exist and parent isn't writable
+ warn.warn("IPython parent '%s' is not a writable location,"
+ " using a temp directory."%parent)
+ ipdir = tempfile.mkdtemp()
return _cast_unicode(ipdir, fs_encoding)
View
43 IPython/utils/tests/test_path.py
@@ -16,6 +16,7 @@
import shutil
import sys
import tempfile
+import StringIO
from os.path import join, abspath, split
@@ -26,7 +27,7 @@
import IPython
from IPython.testing import decorators as dec
from IPython.testing.decorators import skip_if_not_win32, skip_win32
-from IPython.utils import path
+from IPython.utils import path, io
# Platform-dependent imports
try:
@@ -92,7 +93,8 @@ def teardown_environment():
"""Restore things that were remebered by the setup_environment function
"""
(oldenv, os.name, path.get_home_dir, IPython.__file__,) = oldstuff
-
+ reload(path)
+
for key in env.keys():
if key not in oldenv:
del env[key]
@@ -229,6 +231,7 @@ def QueryValueEx(x, y):
def test_get_ipython_dir_1():
"""test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
env_ipdir = os.path.join("someplace", ".ipython")
+ path._writable_dir = lambda path: True
env['IPYTHON_DIR'] = env_ipdir
ipdir = path.get_ipython_dir()
nt.assert_equal(ipdir, env_ipdir)
@@ -238,6 +241,8 @@ def test_get_ipython_dir_1():
def test_get_ipython_dir_2():
"""test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
path.get_home_dir = lambda : "someplace"
+ path.get_xdg_dir = lambda : None
+ path._writable_dir = lambda path: True
os.name = "posix"
env.pop('IPYTHON_DIR', None)
env.pop('IPYTHONDIR', None)
@@ -249,6 +254,7 @@ def test_get_ipython_dir_2():
def test_get_ipython_dir_3():
"""test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist."""
path.get_home_dir = lambda : "someplace"
+ path._writable_dir = lambda path: True
os.name = "posix"
env.pop('IPYTHON_DIR', None)
env.pop('IPYTHONDIR', None)
@@ -283,18 +289,23 @@ def test_get_ipython_dir_5():
@with_environment
def test_get_ipython_dir_6():
"""test_get_ipython_dir_6, use XDG if defined and neither exist."""
- path.get_home_dir = lambda : 'somehome'
- path.get_xdg_dir = lambda : 'somexdg'
+ xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
+ os.mkdir(xdg)
+ shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
+ path.get_home_dir = lambda : HOME_TEST_DIR
+ path.get_xdg_dir = lambda : xdg
os.name = "posix"
env.pop('IPYTHON_DIR', None)
env.pop('IPYTHONDIR', None)
- xdg_ipdir = os.path.join("somexdg", "ipython")
+ env.pop('XDG_CONFIG_HOME', None)
+ xdg_ipdir = os.path.join(xdg, "ipython")
ipdir = path.get_ipython_dir()
nt.assert_equal(ipdir, xdg_ipdir)
@with_environment
def test_get_ipython_dir_7():
"""test_get_ipython_dir_7, test home directory expansion on IPYTHON_DIR"""
+ path._writable_dir = lambda path: True
home_dir = os.path.expanduser('~')
env['IPYTHON_DIR'] = os.path.join('~', 'somewhere')
ipdir = path.get_ipython_dir()
@@ -305,6 +316,7 @@ def test_get_ipython_dir_7():
def test_get_xdg_dir_1():
"""test_get_xdg_dir_1, check xdg_dir"""
reload(path)
+ path._writable_dir = lambda path: True
path.get_home_dir = lambda : 'somewhere'
os.name = "posix"
env.pop('IPYTHON_DIR', None)
@@ -369,3 +381,24 @@ def test_get_long_path_name():
p = path.get_long_path_name('/usr/local')
nt.assert_equals(p,'/usr/local')
+@dec.skip_win32 # can't create not-user-writable dir on win
+@with_environment
+def test_not_writable_ipdir():
+ tmpdir = tempfile.mkdtemp()
+ os.name = "posix"
+ env.pop('IPYTHON_DIR', None)
+ env.pop('IPYTHONDIR', None)
+ env.pop('XDG_CONFIG_HOME', None)
+ env['HOME'] = tmpdir
+ ipdir = os.path.join(tmpdir, '.ipython')
+ os.mkdir(ipdir)
+ os.chmod(ipdir, 600)
+ stderr = io.stderr
+ pipe = StringIO.StringIO()
+ io.stderr = pipe
+ ipdir = path.get_ipython_dir()
+ io.stderr.flush()
+ io.stderr = stderr
+ nt.assert_true('WARNING' in pipe.getvalue())
+ env.pop('IPYTHON_DIR', None)
+
View
10 IPython/zmq/ipkernel.py
@@ -164,8 +164,14 @@ def start(self):
# reason for this to be anything less than ~ 0.1s
# since it is a real poller and will respond
# to events immediately
- poller.poll(10*1000*self._poll_interval)
- self.do_one_iteration()
+
+ # double nested try/except, to properly catch KeyboardInterrupt
+ # due to pyzmq Issue #130
+ try:
+ poller.poll(10*1000*self._poll_interval)
+ self.do_one_iteration()
+ except:
+ raise
except KeyboardInterrupt:
# Ctrl-C shouldn't crash the kernel
io.raw_print("KeyboardInterrupt caught in kernel")

0 comments on commit cc6010e

Please sign in to comment.
Something went wrong with that request. Please try again.