##// END OF EJS Templates
Merge branch 'ipython_dir_permissions' of https://github.com/minrk/ipython into minrk-ipython_dir_permissions
Fernando Perez -
r4527:c4196e2e merge
parent child Browse files
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 isdir(os.path.join(root, '_ipython')):
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 isdir(homedir):
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 isdir(homedir):
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 isdir(homedir):
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 isdir(homedir):
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 isdir(homedir):
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 isdir(xdg):
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 exists(xdg_ipdir) or not exists(home_ipdir):
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
General Comments 0
You need to be logged in to leave comments. Login now