##// END OF EJS Templates
Update IPython.utils.path to use stdlib warnings module.
Thomas Kluyver -
Show More
@@ -1,478 +1,478 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Utilities for path handling.
3 Utilities for path handling.
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
7 # Copyright (C) 2008-2009 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import os
17 import os
18 import sys
18 import sys
19 import tempfile
19 import tempfile
20 import warnings
20 from hashlib import md5
21 from hashlib import md5
21
22
22 import IPython
23 import IPython
23 from IPython.utils import warn
24 from IPython.utils.process import system
24 from IPython.utils.process import system
25 from IPython.utils.importstring import import_item
25 from IPython.utils.importstring import import_item
26 from IPython.utils import py3compat
26 from IPython.utils import py3compat
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Code
29 # Code
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 fs_encoding = sys.getfilesystemencoding()
32 fs_encoding = sys.getfilesystemencoding()
33
33
34 def _get_long_path_name(path):
34 def _get_long_path_name(path):
35 """Dummy no-op."""
35 """Dummy no-op."""
36 return path
36 return path
37
37
38 def _writable_dir(path):
38 def _writable_dir(path):
39 """Whether `path` is a directory, to which the user has write access."""
39 """Whether `path` is a directory, to which the user has write access."""
40 return os.path.isdir(path) and os.access(path, os.W_OK)
40 return os.path.isdir(path) and os.access(path, os.W_OK)
41
41
42 if sys.platform == 'win32':
42 if sys.platform == 'win32':
43 def _get_long_path_name(path):
43 def _get_long_path_name(path):
44 """Get a long path name (expand ~) on Windows using ctypes.
44 """Get a long path name (expand ~) on Windows using ctypes.
45
45
46 Examples
46 Examples
47 --------
47 --------
48
48
49 >>> get_long_path_name('c:\\docume~1')
49 >>> get_long_path_name('c:\\docume~1')
50 u'c:\\\\Documents and Settings'
50 u'c:\\\\Documents and Settings'
51
51
52 """
52 """
53 try:
53 try:
54 import ctypes
54 import ctypes
55 except ImportError:
55 except ImportError:
56 raise ImportError('you need to have ctypes installed for this to work')
56 raise ImportError('you need to have ctypes installed for this to work')
57 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
57 _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW
58 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
58 _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p,
59 ctypes.c_uint ]
59 ctypes.c_uint ]
60
60
61 buf = ctypes.create_unicode_buffer(260)
61 buf = ctypes.create_unicode_buffer(260)
62 rv = _GetLongPathName(path, buf, 260)
62 rv = _GetLongPathName(path, buf, 260)
63 if rv == 0 or rv > 260:
63 if rv == 0 or rv > 260:
64 return path
64 return path
65 else:
65 else:
66 return buf.value
66 return buf.value
67
67
68
68
69 def get_long_path_name(path):
69 def get_long_path_name(path):
70 """Expand a path into its long form.
70 """Expand a path into its long form.
71
71
72 On Windows this expands any ~ in the paths. On other platforms, it is
72 On Windows this expands any ~ in the paths. On other platforms, it is
73 a null operation.
73 a null operation.
74 """
74 """
75 return _get_long_path_name(path)
75 return _get_long_path_name(path)
76
76
77
77
78 def unquote_filename(name, win32=(sys.platform=='win32')):
78 def unquote_filename(name, win32=(sys.platform=='win32')):
79 """ On Windows, remove leading and trailing quotes from filenames.
79 """ On Windows, remove leading and trailing quotes from filenames.
80 """
80 """
81 if win32:
81 if win32:
82 if name.startswith(("'", '"')) and name.endswith(("'", '"')):
82 if name.startswith(("'", '"')) and name.endswith(("'", '"')):
83 name = name[1:-1]
83 name = name[1:-1]
84 return name
84 return name
85
85
86
86
87 def get_py_filename(name, force_win32=None):
87 def get_py_filename(name, force_win32=None):
88 """Return a valid python filename in the current directory.
88 """Return a valid python filename in the current directory.
89
89
90 If the given name is not a file, it adds '.py' and searches again.
90 If the given name is not a file, it adds '.py' and searches again.
91 Raises IOError with an informative message if the file isn't found.
91 Raises IOError with an informative message if the file isn't found.
92
92
93 On Windows, apply Windows semantics to the filename. In particular, remove
93 On Windows, apply Windows semantics to the filename. In particular, remove
94 any quoting that has been applied to it. This option can be forced for
94 any quoting that has been applied to it. This option can be forced for
95 testing purposes.
95 testing purposes.
96 """
96 """
97
97
98 name = os.path.expanduser(name)
98 name = os.path.expanduser(name)
99 if force_win32 is None:
99 if force_win32 is None:
100 win32 = (sys.platform == 'win32')
100 win32 = (sys.platform == 'win32')
101 else:
101 else:
102 win32 = force_win32
102 win32 = force_win32
103 name = unquote_filename(name, win32=win32)
103 name = unquote_filename(name, win32=win32)
104 if not os.path.isfile(name) and not name.endswith('.py'):
104 if not os.path.isfile(name) and not name.endswith('.py'):
105 name += '.py'
105 name += '.py'
106 if os.path.isfile(name):
106 if os.path.isfile(name):
107 return name
107 return name
108 else:
108 else:
109 raise IOError,'File `%s` not found.' % name
109 raise IOError,'File `%s` not found.' % name
110
110
111
111
112 def filefind(filename, path_dirs=None):
112 def filefind(filename, path_dirs=None):
113 """Find a file by looking through a sequence of paths.
113 """Find a file by looking through a sequence of paths.
114
114
115 This iterates through a sequence of paths looking for a file and returns
115 This iterates through a sequence of paths looking for a file and returns
116 the full, absolute path of the first occurence of the file. If no set of
116 the full, absolute path of the first occurence of the file. If no set of
117 path dirs is given, the filename is tested as is, after running through
117 path dirs is given, the filename is tested as is, after running through
118 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
118 :func:`expandvars` and :func:`expanduser`. Thus a simple call::
119
119
120 filefind('myfile.txt')
120 filefind('myfile.txt')
121
121
122 will find the file in the current working dir, but::
122 will find the file in the current working dir, but::
123
123
124 filefind('~/myfile.txt')
124 filefind('~/myfile.txt')
125
125
126 Will find the file in the users home directory. This function does not
126 Will find the file in the users home directory. This function does not
127 automatically try any paths, such as the cwd or the user's home directory.
127 automatically try any paths, such as the cwd or the user's home directory.
128
128
129 Parameters
129 Parameters
130 ----------
130 ----------
131 filename : str
131 filename : str
132 The filename to look for.
132 The filename to look for.
133 path_dirs : str, None or sequence of str
133 path_dirs : str, None or sequence of str
134 The sequence of paths to look for the file in. If None, the filename
134 The sequence of paths to look for the file in. If None, the filename
135 need to be absolute or be in the cwd. If a string, the string is
135 need to be absolute or be in the cwd. If a string, the string is
136 put into a sequence and the searched. If a sequence, walk through
136 put into a sequence and the searched. If a sequence, walk through
137 each element and join with ``filename``, calling :func:`expandvars`
137 each element and join with ``filename``, calling :func:`expandvars`
138 and :func:`expanduser` before testing for existence.
138 and :func:`expanduser` before testing for existence.
139
139
140 Returns
140 Returns
141 -------
141 -------
142 Raises :exc:`IOError` or returns absolute path to file.
142 Raises :exc:`IOError` or returns absolute path to file.
143 """
143 """
144
144
145 # If paths are quoted, abspath gets confused, strip them...
145 # If paths are quoted, abspath gets confused, strip them...
146 filename = filename.strip('"').strip("'")
146 filename = filename.strip('"').strip("'")
147 # If the input is an absolute path, just check it exists
147 # If the input is an absolute path, just check it exists
148 if os.path.isabs(filename) and os.path.isfile(filename):
148 if os.path.isabs(filename) and os.path.isfile(filename):
149 return filename
149 return filename
150
150
151 if path_dirs is None:
151 if path_dirs is None:
152 path_dirs = ("",)
152 path_dirs = ("",)
153 elif isinstance(path_dirs, basestring):
153 elif isinstance(path_dirs, basestring):
154 path_dirs = (path_dirs,)
154 path_dirs = (path_dirs,)
155
155
156 for path in path_dirs:
156 for path in path_dirs:
157 if path == '.': path = os.getcwdu()
157 if path == '.': path = os.getcwdu()
158 testname = expand_path(os.path.join(path, filename))
158 testname = expand_path(os.path.join(path, filename))
159 if os.path.isfile(testname):
159 if os.path.isfile(testname):
160 return os.path.abspath(testname)
160 return os.path.abspath(testname)
161
161
162 raise IOError("File %r does not exist in any of the search paths: %r" %
162 raise IOError("File %r does not exist in any of the search paths: %r" %
163 (filename, path_dirs) )
163 (filename, path_dirs) )
164
164
165
165
166 class HomeDirError(Exception):
166 class HomeDirError(Exception):
167 pass
167 pass
168
168
169
169
170 def get_home_dir():
170 def get_home_dir():
171 """Return the closest possible equivalent to a 'home' directory.
171 """Return the closest possible equivalent to a 'home' directory.
172
172
173 * On POSIX, we try $HOME.
173 * On POSIX, we try $HOME.
174 * On Windows we try:
174 * On Windows we try:
175 - %HOMESHARE%
175 - %HOMESHARE%
176 - %HOMEDRIVE\%HOMEPATH%
176 - %HOMEDRIVE\%HOMEPATH%
177 - %USERPROFILE%
177 - %USERPROFILE%
178 - Registry hack for My Documents
178 - Registry hack for My Documents
179 - %HOME%: rare, but some people with unix-like setups may have defined it
179 - %HOME%: rare, but some people with unix-like setups may have defined it
180 * On Dos C:\
180 * On Dos C:\
181
181
182 Currently only Posix and NT are implemented, a HomeDirError exception is
182 Currently only Posix and NT are implemented, a HomeDirError exception is
183 raised for all other OSes.
183 raised for all other OSes.
184 """
184 """
185
185
186 env = os.environ
186 env = os.environ
187
187
188 # first, check py2exe distribution root directory for _ipython.
188 # first, check py2exe distribution root directory for _ipython.
189 # This overrides all. Normally does not exist.
189 # This overrides all. Normally does not exist.
190
190
191 if hasattr(sys, "frozen"): #Is frozen by py2exe
191 if hasattr(sys, "frozen"): #Is frozen by py2exe
192 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
192 if '\\library.zip\\' in IPython.__file__.lower():#libraries compressed to zip-file
193 root, rest = IPython.__file__.lower().split('library.zip')
193 root, rest = IPython.__file__.lower().split('library.zip')
194 else:
194 else:
195 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
195 root=os.path.join(os.path.split(IPython.__file__)[0],"../../")
196 root=os.path.abspath(root).rstrip('\\')
196 root=os.path.abspath(root).rstrip('\\')
197 if _writable_dir(os.path.join(root, '_ipython')):
197 if _writable_dir(os.path.join(root, '_ipython')):
198 os.environ["IPYKITROOT"] = root
198 os.environ["IPYKITROOT"] = root
199 return py3compat.cast_unicode(root, fs_encoding)
199 return py3compat.cast_unicode(root, fs_encoding)
200
200
201 if os.name == 'posix':
201 if os.name == 'posix':
202 # Linux, Unix, AIX, OS X
202 # Linux, Unix, AIX, OS X
203 try:
203 try:
204 homedir = env['HOME']
204 homedir = env['HOME']
205 except KeyError:
205 except KeyError:
206 # Last-ditch attempt at finding a suitable $HOME, on systems where
206 # Last-ditch attempt at finding a suitable $HOME, on systems where
207 # it may not be defined in the environment but the system shell
207 # it may not be defined in the environment but the system shell
208 # still knows it - reported once as:
208 # still knows it - reported once as:
209 # https://github.com/ipython/ipython/issues/154
209 # https://github.com/ipython/ipython/issues/154
210 from subprocess import Popen, PIPE
210 from subprocess import Popen, PIPE
211 homedir = Popen('echo $HOME', shell=True,
211 homedir = Popen('echo $HOME', shell=True,
212 stdout=PIPE).communicate()[0].strip()
212 stdout=PIPE).communicate()[0].strip()
213 if homedir:
213 if homedir:
214 return py3compat.cast_unicode(homedir, fs_encoding)
214 return py3compat.cast_unicode(homedir, fs_encoding)
215 else:
215 else:
216 raise HomeDirError('Undefined $HOME, IPython cannot proceed.')
216 raise HomeDirError('Undefined $HOME, IPython cannot proceed.')
217 else:
217 else:
218 return py3compat.cast_unicode(homedir, fs_encoding)
218 return py3compat.cast_unicode(homedir, fs_encoding)
219 elif os.name == 'nt':
219 elif os.name == 'nt':
220 # Now for win9x, XP, Vista, 7?
220 # Now for win9x, XP, Vista, 7?
221 # For some strange reason all of these return 'nt' for os.name.
221 # For some strange reason all of these return 'nt' for os.name.
222 # First look for a network home directory. This will return the UNC
222 # First look for a network home directory. This will return the UNC
223 # path (\\server\\Users\%username%) not the mapped path (Z:\). This
223 # path (\\server\\Users\%username%) not the mapped path (Z:\). This
224 # is needed when running IPython on cluster where all paths have to
224 # is needed when running IPython on cluster where all paths have to
225 # be UNC.
225 # be UNC.
226 try:
226 try:
227 homedir = env['HOMESHARE']
227 homedir = env['HOMESHARE']
228 except KeyError:
228 except KeyError:
229 pass
229 pass
230 else:
230 else:
231 if _writable_dir(homedir):
231 if _writable_dir(homedir):
232 return py3compat.cast_unicode(homedir, fs_encoding)
232 return py3compat.cast_unicode(homedir, fs_encoding)
233
233
234 # Now look for a local home directory
234 # Now look for a local home directory
235 try:
235 try:
236 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
236 homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH'])
237 except KeyError:
237 except KeyError:
238 pass
238 pass
239 else:
239 else:
240 if _writable_dir(homedir):
240 if _writable_dir(homedir):
241 return py3compat.cast_unicode(homedir, fs_encoding)
241 return py3compat.cast_unicode(homedir, fs_encoding)
242
242
243 # Now the users profile directory
243 # Now the users profile directory
244 try:
244 try:
245 homedir = os.path.join(env['USERPROFILE'])
245 homedir = os.path.join(env['USERPROFILE'])
246 except KeyError:
246 except KeyError:
247 pass
247 pass
248 else:
248 else:
249 if _writable_dir(homedir):
249 if _writable_dir(homedir):
250 return py3compat.cast_unicode(homedir, fs_encoding)
250 return py3compat.cast_unicode(homedir, fs_encoding)
251
251
252 # Use the registry to get the 'My Documents' folder.
252 # Use the registry to get the 'My Documents' folder.
253 try:
253 try:
254 import _winreg as wreg
254 import _winreg as wreg
255 key = wreg.OpenKey(
255 key = wreg.OpenKey(
256 wreg.HKEY_CURRENT_USER,
256 wreg.HKEY_CURRENT_USER,
257 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
257 "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
258 )
258 )
259 homedir = wreg.QueryValueEx(key,'Personal')[0]
259 homedir = wreg.QueryValueEx(key,'Personal')[0]
260 key.Close()
260 key.Close()
261 except:
261 except:
262 pass
262 pass
263 else:
263 else:
264 if _writable_dir(homedir):
264 if _writable_dir(homedir):
265 return py3compat.cast_unicode(homedir, fs_encoding)
265 return py3compat.cast_unicode(homedir, fs_encoding)
266
266
267 # A user with a lot of unix tools in win32 may have defined $HOME.
267 # A user with a lot of unix tools in win32 may have defined $HOME.
268 # Try this as a last ditch option.
268 # Try this as a last ditch option.
269 try:
269 try:
270 homedir = env['HOME']
270 homedir = env['HOME']
271 except KeyError:
271 except KeyError:
272 pass
272 pass
273 else:
273 else:
274 if _writable_dir(homedir):
274 if _writable_dir(homedir):
275 return py3compat.cast_unicode(homedir, fs_encoding)
275 return py3compat.cast_unicode(homedir, fs_encoding)
276
276
277 # If all else fails, raise HomeDirError
277 # If all else fails, raise HomeDirError
278 raise HomeDirError('No valid home directory could be found')
278 raise HomeDirError('No valid home directory could be found')
279 elif os.name == 'dos':
279 elif os.name == 'dos':
280 # Desperate, may do absurd things in classic MacOS. May work under DOS.
280 # Desperate, may do absurd things in classic MacOS. May work under DOS.
281 return u'C:\\'
281 return u'C:\\'
282 else:
282 else:
283 raise HomeDirError('No valid home directory could be found for your OS')
283 raise HomeDirError('No valid home directory could be found for your OS')
284
284
285 def get_xdg_dir():
285 def get_xdg_dir():
286 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
286 """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
287
287
288 This is only for posix (Linux,Unix,OS X, etc) systems.
288 This is only for posix (Linux,Unix,OS X, etc) systems.
289 """
289 """
290
290
291 env = os.environ
291 env = os.environ
292
292
293 if os.name == 'posix':
293 if os.name == 'posix':
294 # Linux, Unix, AIX, OS X
294 # Linux, Unix, AIX, OS X
295 # use ~/.config if not set OR empty
295 # use ~/.config if not set OR empty
296 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
296 xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
297 if xdg and _writable_dir(xdg):
297 if xdg and _writable_dir(xdg):
298 return py3compat.cast_unicode(xdg, fs_encoding)
298 return py3compat.cast_unicode(xdg, fs_encoding)
299
299
300 return None
300 return None
301
301
302
302
303 def get_ipython_dir():
303 def get_ipython_dir():
304 """Get the IPython directory for this platform and user.
304 """Get the IPython directory for this platform and user.
305
305
306 This uses the logic in `get_home_dir` to find the home directory
306 This uses the logic in `get_home_dir` to find the home directory
307 and then adds .ipython to the end of the path.
307 and then adds .ipython to the end of the path.
308 """
308 """
309
309
310 env = os.environ
310 env = os.environ
311 pjoin = os.path.join
311 pjoin = os.path.join
312
312
313
313
314 ipdir_def = '.ipython'
314 ipdir_def = '.ipython'
315 xdg_def = 'ipython'
315 xdg_def = 'ipython'
316
316
317 home_dir = get_home_dir()
317 home_dir = get_home_dir()
318 xdg_dir = get_xdg_dir()
318 xdg_dir = get_xdg_dir()
319 # import pdb; pdb.set_trace() # dbg
319 # import pdb; pdb.set_trace() # dbg
320 ipdir = env.get('IPYTHON_DIR', env.get('IPYTHONDIR', None))
320 ipdir = env.get('IPYTHON_DIR', env.get('IPYTHONDIR', None))
321 if ipdir is None:
321 if ipdir is None:
322 # not set explicitly, use XDG_CONFIG_HOME or HOME
322 # not set explicitly, use XDG_CONFIG_HOME or HOME
323 home_ipdir = pjoin(home_dir, ipdir_def)
323 home_ipdir = pjoin(home_dir, ipdir_def)
324 if xdg_dir:
324 if xdg_dir:
325 # use XDG, as long as the user isn't already
325 # use XDG, as long as the user isn't already
326 # using $HOME/.ipython and *not* XDG/ipython
326 # using $HOME/.ipython and *not* XDG/ipython
327
327
328 xdg_ipdir = pjoin(xdg_dir, xdg_def)
328 xdg_ipdir = pjoin(xdg_dir, xdg_def)
329
329
330 if _writable_dir(xdg_ipdir) or not _writable_dir(home_ipdir):
330 if _writable_dir(xdg_ipdir) or not _writable_dir(home_ipdir):
331 ipdir = xdg_ipdir
331 ipdir = xdg_ipdir
332
332
333 if ipdir is None:
333 if ipdir is None:
334 # not using XDG
334 # not using XDG
335 ipdir = home_ipdir
335 ipdir = home_ipdir
336
336
337 ipdir = os.path.normpath(os.path.expanduser(ipdir))
337 ipdir = os.path.normpath(os.path.expanduser(ipdir))
338
338
339 if os.path.exists(ipdir) and not _writable_dir(ipdir):
339 if os.path.exists(ipdir) and not _writable_dir(ipdir):
340 # ipdir exists, but is not writable
340 # ipdir exists, but is not writable
341 warn.warn("IPython dir '%s' is not a writable location,"
341 warnings.warn("IPython dir '%s' is not a writable location,"
342 " using a temp directory."%ipdir)
342 " using a temp directory."%ipdir)
343 ipdir = tempfile.mkdtemp()
343 ipdir = tempfile.mkdtemp()
344 elif not os.path.exists(ipdir):
344 elif not os.path.exists(ipdir):
345 parent = ipdir.rsplit(os.path.sep, 1)[0]
345 parent = ipdir.rsplit(os.path.sep, 1)[0]
346 if not _writable_dir(parent):
346 if not _writable_dir(parent):
347 # ipdir does not exist and parent isn't writable
347 # ipdir does not exist and parent isn't writable
348 warn.warn("IPython parent '%s' is not a writable location,"
348 warnings.warn("IPython parent '%s' is not a writable location,"
349 " using a temp directory."%parent)
349 " using a temp directory."%parent)
350 ipdir = tempfile.mkdtemp()
350 ipdir = tempfile.mkdtemp()
351
351
352 return py3compat.cast_unicode(ipdir, fs_encoding)
352 return py3compat.cast_unicode(ipdir, fs_encoding)
353
353
354
354
355 def get_ipython_package_dir():
355 def get_ipython_package_dir():
356 """Get the base directory where IPython itself is installed."""
356 """Get the base directory where IPython itself is installed."""
357 ipdir = os.path.dirname(IPython.__file__)
357 ipdir = os.path.dirname(IPython.__file__)
358 return py3compat.cast_unicode(ipdir, fs_encoding)
358 return py3compat.cast_unicode(ipdir, fs_encoding)
359
359
360
360
361 def get_ipython_module_path(module_str):
361 def get_ipython_module_path(module_str):
362 """Find the path to an IPython module in this version of IPython.
362 """Find the path to an IPython module in this version of IPython.
363
363
364 This will always find the version of the module that is in this importable
364 This will always find the version of the module that is in this importable
365 IPython package. This will always return the path to the ``.py``
365 IPython package. This will always return the path to the ``.py``
366 version of the module.
366 version of the module.
367 """
367 """
368 if module_str == 'IPython':
368 if module_str == 'IPython':
369 return os.path.join(get_ipython_package_dir(), '__init__.py')
369 return os.path.join(get_ipython_package_dir(), '__init__.py')
370 mod = import_item(module_str)
370 mod = import_item(module_str)
371 the_path = mod.__file__.replace('.pyc', '.py')
371 the_path = mod.__file__.replace('.pyc', '.py')
372 the_path = the_path.replace('.pyo', '.py')
372 the_path = the_path.replace('.pyo', '.py')
373 return py3compat.cast_unicode(the_path, fs_encoding)
373 return py3compat.cast_unicode(the_path, fs_encoding)
374
374
375
375
376 def expand_path(s):
376 def expand_path(s):
377 """Expand $VARS and ~names in a string, like a shell
377 """Expand $VARS and ~names in a string, like a shell
378
378
379 :Examples:
379 :Examples:
380
380
381 In [2]: os.environ['FOO']='test'
381 In [2]: os.environ['FOO']='test'
382
382
383 In [3]: expand_path('variable FOO is $FOO')
383 In [3]: expand_path('variable FOO is $FOO')
384 Out[3]: 'variable FOO is test'
384 Out[3]: 'variable FOO is test'
385 """
385 """
386 # This is a pretty subtle hack. When expand user is given a UNC path
386 # This is a pretty subtle hack. When expand user is given a UNC path
387 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
387 # on Windows (\\server\share$\%username%), os.path.expandvars, removes
388 # the $ to get (\\server\share\%username%). I think it considered $
388 # the $ to get (\\server\share\%username%). I think it considered $
389 # alone an empty var. But, we need the $ to remains there (it indicates
389 # alone an empty var. But, we need the $ to remains there (it indicates
390 # a hidden share).
390 # a hidden share).
391 if os.name=='nt':
391 if os.name=='nt':
392 s = s.replace('$\\', 'IPYTHON_TEMP')
392 s = s.replace('$\\', 'IPYTHON_TEMP')
393 s = os.path.expandvars(os.path.expanduser(s))
393 s = os.path.expandvars(os.path.expanduser(s))
394 if os.name=='nt':
394 if os.name=='nt':
395 s = s.replace('IPYTHON_TEMP', '$\\')
395 s = s.replace('IPYTHON_TEMP', '$\\')
396 return s
396 return s
397
397
398
398
399 def target_outdated(target,deps):
399 def target_outdated(target,deps):
400 """Determine whether a target is out of date.
400 """Determine whether a target is out of date.
401
401
402 target_outdated(target,deps) -> 1/0
402 target_outdated(target,deps) -> 1/0
403
403
404 deps: list of filenames which MUST exist.
404 deps: list of filenames which MUST exist.
405 target: single filename which may or may not exist.
405 target: single filename which may or may not exist.
406
406
407 If target doesn't exist or is older than any file listed in deps, return
407 If target doesn't exist or is older than any file listed in deps, return
408 true, otherwise return false.
408 true, otherwise return false.
409 """
409 """
410 try:
410 try:
411 target_time = os.path.getmtime(target)
411 target_time = os.path.getmtime(target)
412 except os.error:
412 except os.error:
413 return 1
413 return 1
414 for dep in deps:
414 for dep in deps:
415 dep_time = os.path.getmtime(dep)
415 dep_time = os.path.getmtime(dep)
416 if dep_time > target_time:
416 if dep_time > target_time:
417 #print "For target",target,"Dep failed:",dep # dbg
417 #print "For target",target,"Dep failed:",dep # dbg
418 #print "times (dep,tar):",dep_time,target_time # dbg
418 #print "times (dep,tar):",dep_time,target_time # dbg
419 return 1
419 return 1
420 return 0
420 return 0
421
421
422
422
423 def target_update(target,deps,cmd):
423 def target_update(target,deps,cmd):
424 """Update a target with a given command given a list of dependencies.
424 """Update a target with a given command given a list of dependencies.
425
425
426 target_update(target,deps,cmd) -> runs cmd if target is outdated.
426 target_update(target,deps,cmd) -> runs cmd if target is outdated.
427
427
428 This is just a wrapper around target_outdated() which calls the given
428 This is just a wrapper around target_outdated() which calls the given
429 command if target is outdated."""
429 command if target is outdated."""
430
430
431 if target_outdated(target,deps):
431 if target_outdated(target,deps):
432 system(cmd)
432 system(cmd)
433
433
434 def filehash(path):
434 def filehash(path):
435 """Make an MD5 hash of a file, ignoring any differences in line
435 """Make an MD5 hash of a file, ignoring any differences in line
436 ending characters."""
436 ending characters."""
437 with open(path, "rU") as f:
437 with open(path, "rU") as f:
438 return md5(py3compat.str_to_bytes(f.read())).hexdigest()
438 return md5(py3compat.str_to_bytes(f.read())).hexdigest()
439
439
440 # If the config is unmodified from the default, we'll just delete it.
440 # If the config is unmodified from the default, we'll just delete it.
441 # These are consistent for 0.10.x, thankfully. We're not going to worry about
441 # These are consistent for 0.10.x, thankfully. We're not going to worry about
442 # older versions.
442 # older versions.
443 old_config_md5 = {'ipy_user_conf.py': 'fc108bedff4b9a00f91fa0a5999140d3',
443 old_config_md5 = {'ipy_user_conf.py': 'fc108bedff4b9a00f91fa0a5999140d3',
444 'ipythonrc': '12a68954f3403eea2eec09dc8fe5a9b5'}
444 'ipythonrc': '12a68954f3403eea2eec09dc8fe5a9b5'}
445
445
446 def check_for_old_config(ipython_dir=None):
446 def check_for_old_config(ipython_dir=None):
447 """Check for old config files, and present a warning if they exist.
447 """Check for old config files, and present a warning if they exist.
448
448
449 A link to the docs of the new config is included in the message.
449 A link to the docs of the new config is included in the message.
450
450
451 This should mitigate confusion with the transition to the new
451 This should mitigate confusion with the transition to the new
452 config system in 0.11.
452 config system in 0.11.
453 """
453 """
454 if ipython_dir is None:
454 if ipython_dir is None:
455 ipython_dir = get_ipython_dir()
455 ipython_dir = get_ipython_dir()
456
456
457 old_configs = ['ipy_user_conf.py', 'ipythonrc', 'ipython_config.py']
457 old_configs = ['ipy_user_conf.py', 'ipythonrc', 'ipython_config.py']
458 warned = False
458 warned = False
459 for cfg in old_configs:
459 for cfg in old_configs:
460 f = os.path.join(ipython_dir, cfg)
460 f = os.path.join(ipython_dir, cfg)
461 if os.path.exists(f):
461 if os.path.exists(f):
462 if filehash(f) == old_config_md5.get(cfg, ''):
462 if filehash(f) == old_config_md5.get(cfg, ''):
463 os.unlink(f)
463 os.unlink(f)
464 else:
464 else:
465 warn.warn("Found old IPython config file %r (modified by user)"%f)
465 warnings.warn("Found old IPython config file %r (modified by user)"%f)
466 warned = True
466 warned = True
467
467
468 if warned:
468 if warned:
469 warn.info("""
469 warnings.warn("""
470 The IPython configuration system has changed as of 0.11, and these files will
470 The IPython configuration system has changed as of 0.11, and these files will
471 be ignored. See http://ipython.github.com/ipython-doc/dev/config for details
471 be ignored. See http://ipython.github.com/ipython-doc/dev/config for details
472 of the new config system.
472 of the new config system.
473 To start configuring IPython, do `ipython profile create`, and edit
473 To start configuring IPython, do `ipython profile create`, and edit
474 `ipython_config.py` in <ipython_dir>/profile_default.
474 `ipython_config.py` in <ipython_dir>/profile_default.
475 If you need to leave the old config files in place for an older version of
475 If you need to leave the old config files in place for an older version of
476 IPython and want to suppress this warning message, set
476 IPython and want to suppress this warning message, set
477 `c.InteractiveShellApp.ignore_old_config=True` in the new config.""")
477 `c.InteractiveShellApp.ignore_old_config=True` in the new config.""")
478
478
@@ -1,445 +1,445 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for IPython.utils.path.py"""
2 """Tests for IPython.utils.path.py"""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2008 The IPython Development Team
5 # Copyright (C) 2008 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 from __future__ import with_statement
15 from __future__ import with_statement
16
16
17 import os
17 import os
18 import shutil
18 import shutil
19 import sys
19 import sys
20 import tempfile
20 import tempfile
21 from io import StringIO
21 from io import StringIO
22
22
23 from os.path import join, abspath, split
23 from os.path import join, abspath, split
24
24
25 import nose.tools as nt
25 import nose.tools as nt
26
26
27 from nose import with_setup
27 from nose import with_setup
28
28
29 import IPython
29 import IPython
30 from IPython.testing import decorators as dec
30 from IPython.testing import decorators as dec
31 from IPython.testing.decorators import skip_if_not_win32, skip_win32
31 from IPython.testing.decorators import skip_if_not_win32, skip_win32
32 from IPython.testing.tools import make_tempfile, AssertPrints
32 from IPython.testing.tools import make_tempfile, AssertPrints
33 from IPython.utils import path, io
33 from IPython.utils import path, io
34 from IPython.utils import py3compat
34 from IPython.utils import py3compat
35
35
36 # Platform-dependent imports
36 # Platform-dependent imports
37 try:
37 try:
38 import _winreg as wreg
38 import _winreg as wreg
39 except ImportError:
39 except ImportError:
40 #Fake _winreg module on none windows platforms
40 #Fake _winreg module on none windows platforms
41 import types
41 import types
42 wr_name = "winreg" if py3compat.PY3 else "_winreg"
42 wr_name = "winreg" if py3compat.PY3 else "_winreg"
43 sys.modules[wr_name] = types.ModuleType(wr_name)
43 sys.modules[wr_name] = types.ModuleType(wr_name)
44 import _winreg as wreg
44 import _winreg as wreg
45 #Add entries that needs to be stubbed by the testing code
45 #Add entries that needs to be stubbed by the testing code
46 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
46 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
47
47
48 try:
48 try:
49 reload
49 reload
50 except NameError: # Python 3
50 except NameError: # Python 3
51 from imp import reload
51 from imp import reload
52
52
53 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
54 # Globals
54 # Globals
55 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
56 env = os.environ
56 env = os.environ
57 TEST_FILE_PATH = split(abspath(__file__))[0]
57 TEST_FILE_PATH = split(abspath(__file__))[0]
58 TMP_TEST_DIR = tempfile.mkdtemp()
58 TMP_TEST_DIR = tempfile.mkdtemp()
59 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
59 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
60 XDG_TEST_DIR = join(HOME_TEST_DIR, "xdg_test_dir")
60 XDG_TEST_DIR = join(HOME_TEST_DIR, "xdg_test_dir")
61 IP_TEST_DIR = join(HOME_TEST_DIR,'.ipython')
61 IP_TEST_DIR = join(HOME_TEST_DIR,'.ipython')
62 #
62 #
63 # Setup/teardown functions/decorators
63 # Setup/teardown functions/decorators
64 #
64 #
65
65
66 def setup():
66 def setup():
67 """Setup testenvironment for the module:
67 """Setup testenvironment for the module:
68
68
69 - Adds dummy home dir tree
69 - Adds dummy home dir tree
70 """
70 """
71 # Do not mask exceptions here. In particular, catching WindowsError is a
71 # Do not mask exceptions here. In particular, catching WindowsError is a
72 # problem because that exception is only defined on Windows...
72 # problem because that exception is only defined on Windows...
73 os.makedirs(IP_TEST_DIR)
73 os.makedirs(IP_TEST_DIR)
74 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
74 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
75
75
76
76
77 def teardown():
77 def teardown():
78 """Teardown testenvironment for the module:
78 """Teardown testenvironment for the module:
79
79
80 - Remove dummy home dir tree
80 - Remove dummy home dir tree
81 """
81 """
82 # Note: we remove the parent test dir, which is the root of all test
82 # Note: we remove the parent test dir, which is the root of all test
83 # subdirs we may have created. Use shutil instead of os.removedirs, so
83 # subdirs we may have created. Use shutil instead of os.removedirs, so
84 # that non-empty directories are all recursively removed.
84 # that non-empty directories are all recursively removed.
85 shutil.rmtree(TMP_TEST_DIR)
85 shutil.rmtree(TMP_TEST_DIR)
86
86
87
87
88 def setup_environment():
88 def setup_environment():
89 """Setup testenvironment for some functions that are tested
89 """Setup testenvironment for some functions that are tested
90 in this module. In particular this functions stores attributes
90 in this module. In particular this functions stores attributes
91 and other things that we need to stub in some test functions.
91 and other things that we need to stub in some test functions.
92 This needs to be done on a function level and not module level because
92 This needs to be done on a function level and not module level because
93 each testfunction needs a pristine environment.
93 each testfunction needs a pristine environment.
94 """
94 """
95 global oldstuff, platformstuff
95 global oldstuff, platformstuff
96 oldstuff = (env.copy(), os.name, path.get_home_dir, IPython.__file__, os.getcwd())
96 oldstuff = (env.copy(), os.name, path.get_home_dir, IPython.__file__, os.getcwd())
97
97
98 if os.name == 'nt':
98 if os.name == 'nt':
99 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
99 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
100
100
101
101
102 def teardown_environment():
102 def teardown_environment():
103 """Restore things that were remebered by the setup_environment function
103 """Restore things that were remebered by the setup_environment function
104 """
104 """
105 (oldenv, os.name, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
105 (oldenv, os.name, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
106 os.chdir(old_wd)
106 os.chdir(old_wd)
107 reload(path)
107 reload(path)
108
108
109 for key in env.keys():
109 for key in env.keys():
110 if key not in oldenv:
110 if key not in oldenv:
111 del env[key]
111 del env[key]
112 env.update(oldenv)
112 env.update(oldenv)
113 if hasattr(sys, 'frozen'):
113 if hasattr(sys, 'frozen'):
114 del sys.frozen
114 del sys.frozen
115 if os.name == 'nt':
115 if os.name == 'nt':
116 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
116 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
117
117
118 # Build decorator that uses the setup_environment/setup_environment
118 # Build decorator that uses the setup_environment/setup_environment
119 with_environment = with_setup(setup_environment, teardown_environment)
119 with_environment = with_setup(setup_environment, teardown_environment)
120
120
121
121
122 @skip_if_not_win32
122 @skip_if_not_win32
123 @with_environment
123 @with_environment
124 def test_get_home_dir_1():
124 def test_get_home_dir_1():
125 """Testcase for py2exe logic, un-compressed lib
125 """Testcase for py2exe logic, un-compressed lib
126 """
126 """
127 sys.frozen = True
127 sys.frozen = True
128
128
129 #fake filename for IPython.__init__
129 #fake filename for IPython.__init__
130 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
130 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
131
131
132 home_dir = path.get_home_dir()
132 home_dir = path.get_home_dir()
133 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
133 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
134
134
135
135
136 @skip_if_not_win32
136 @skip_if_not_win32
137 @with_environment
137 @with_environment
138 def test_get_home_dir_2():
138 def test_get_home_dir_2():
139 """Testcase for py2exe logic, compressed lib
139 """Testcase for py2exe logic, compressed lib
140 """
140 """
141 sys.frozen = True
141 sys.frozen = True
142 #fake filename for IPython.__init__
142 #fake filename for IPython.__init__
143 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
143 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
144
144
145 home_dir = path.get_home_dir()
145 home_dir = path.get_home_dir()
146 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
146 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower())
147
147
148
148
149 @with_environment
149 @with_environment
150 @skip_win32
150 @skip_win32
151 def test_get_home_dir_3():
151 def test_get_home_dir_3():
152 """Testcase $HOME is set, then use its value as home directory."""
152 """Testcase $HOME is set, then use its value as home directory."""
153 env["HOME"] = HOME_TEST_DIR
153 env["HOME"] = HOME_TEST_DIR
154 home_dir = path.get_home_dir()
154 home_dir = path.get_home_dir()
155 nt.assert_equal(home_dir, env["HOME"])
155 nt.assert_equal(home_dir, env["HOME"])
156
156
157
157
158 @with_environment
158 @with_environment
159 @skip_win32
159 @skip_win32
160 def test_get_home_dir_4():
160 def test_get_home_dir_4():
161 """Testcase $HOME is not set, os=='posix'.
161 """Testcase $HOME is not set, os=='posix'.
162 This should fail with HomeDirError"""
162 This should fail with HomeDirError"""
163
163
164 os.name = 'posix'
164 os.name = 'posix'
165 if 'HOME' in env: del env['HOME']
165 if 'HOME' in env: del env['HOME']
166 nt.assert_raises(path.HomeDirError, path.get_home_dir)
166 nt.assert_raises(path.HomeDirError, path.get_home_dir)
167
167
168
168
169 @skip_if_not_win32
169 @skip_if_not_win32
170 @with_environment
170 @with_environment
171 def test_get_home_dir_5():
171 def test_get_home_dir_5():
172 """Using HOMEDRIVE + HOMEPATH, os=='nt'.
172 """Using HOMEDRIVE + HOMEPATH, os=='nt'.
173
173
174 HOMESHARE is missing.
174 HOMESHARE is missing.
175 """
175 """
176
176
177 os.name = 'nt'
177 os.name = 'nt'
178 env.pop('HOMESHARE', None)
178 env.pop('HOMESHARE', None)
179 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.splitdrive(HOME_TEST_DIR)
179 env['HOMEDRIVE'], env['HOMEPATH'] = os.path.splitdrive(HOME_TEST_DIR)
180 home_dir = path.get_home_dir()
180 home_dir = path.get_home_dir()
181 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
181 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
182
182
183
183
184 @skip_if_not_win32
184 @skip_if_not_win32
185 @with_environment
185 @with_environment
186 def test_get_home_dir_6():
186 def test_get_home_dir_6():
187 """Using USERPROFILE, os=='nt'.
187 """Using USERPROFILE, os=='nt'.
188
188
189 HOMESHARE, HOMEDRIVE, HOMEPATH are missing.
189 HOMESHARE, HOMEDRIVE, HOMEPATH are missing.
190 """
190 """
191
191
192 os.name = 'nt'
192 os.name = 'nt'
193 env.pop('HOMESHARE', None)
193 env.pop('HOMESHARE', None)
194 env.pop('HOMEDRIVE', None)
194 env.pop('HOMEDRIVE', None)
195 env.pop('HOMEPATH', None)
195 env.pop('HOMEPATH', None)
196 env["USERPROFILE"] = abspath(HOME_TEST_DIR)
196 env["USERPROFILE"] = abspath(HOME_TEST_DIR)
197 home_dir = path.get_home_dir()
197 home_dir = path.get_home_dir()
198 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
198 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
199
199
200
200
201 @skip_if_not_win32
201 @skip_if_not_win32
202 @with_environment
202 @with_environment
203 def test_get_home_dir_7():
203 def test_get_home_dir_7():
204 """Using HOMESHARE, os=='nt'."""
204 """Using HOMESHARE, os=='nt'."""
205
205
206 os.name = 'nt'
206 os.name = 'nt'
207 env["HOMESHARE"] = abspath(HOME_TEST_DIR)
207 env["HOMESHARE"] = abspath(HOME_TEST_DIR)
208 home_dir = path.get_home_dir()
208 home_dir = path.get_home_dir()
209 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
209 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
210
210
211
211
212 # Should we stub wreg fully so we can run the test on all platforms?
212 # Should we stub wreg fully so we can run the test on all platforms?
213 @skip_if_not_win32
213 @skip_if_not_win32
214 @with_environment
214 @with_environment
215 def test_get_home_dir_8():
215 def test_get_home_dir_8():
216 """Using registry hack for 'My Documents', os=='nt'
216 """Using registry hack for 'My Documents', os=='nt'
217
217
218 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
218 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
219 """
219 """
220 os.name = 'nt'
220 os.name = 'nt'
221 # Remove from stub environment all keys that may be set
221 # Remove from stub environment all keys that may be set
222 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
222 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
223 env.pop(key, None)
223 env.pop(key, None)
224
224
225 #Stub windows registry functions
225 #Stub windows registry functions
226 def OpenKey(x, y):
226 def OpenKey(x, y):
227 class key:
227 class key:
228 def Close(self):
228 def Close(self):
229 pass
229 pass
230 return key()
230 return key()
231 def QueryValueEx(x, y):
231 def QueryValueEx(x, y):
232 return [abspath(HOME_TEST_DIR)]
232 return [abspath(HOME_TEST_DIR)]
233
233
234 wreg.OpenKey = OpenKey
234 wreg.OpenKey = OpenKey
235 wreg.QueryValueEx = QueryValueEx
235 wreg.QueryValueEx = QueryValueEx
236
236
237 home_dir = path.get_home_dir()
237 home_dir = path.get_home_dir()
238 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
238 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
239
239
240
240
241 @with_environment
241 @with_environment
242 def test_get_ipython_dir_1():
242 def test_get_ipython_dir_1():
243 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
243 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
244 env_ipdir = os.path.join("someplace", ".ipython")
244 env_ipdir = os.path.join("someplace", ".ipython")
245 path._writable_dir = lambda path: True
245 path._writable_dir = lambda path: True
246 env['IPYTHON_DIR'] = env_ipdir
246 env['IPYTHON_DIR'] = env_ipdir
247 ipdir = path.get_ipython_dir()
247 ipdir = path.get_ipython_dir()
248 nt.assert_equal(ipdir, env_ipdir)
248 nt.assert_equal(ipdir, env_ipdir)
249
249
250
250
251 @with_environment
251 @with_environment
252 def test_get_ipython_dir_2():
252 def test_get_ipython_dir_2():
253 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
253 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
254 path.get_home_dir = lambda : "someplace"
254 path.get_home_dir = lambda : "someplace"
255 path.get_xdg_dir = lambda : None
255 path.get_xdg_dir = lambda : None
256 path._writable_dir = lambda path: True
256 path._writable_dir = lambda path: True
257 os.name = "posix"
257 os.name = "posix"
258 env.pop('IPYTHON_DIR', None)
258 env.pop('IPYTHON_DIR', None)
259 env.pop('IPYTHONDIR', None)
259 env.pop('IPYTHONDIR', None)
260 env.pop('XDG_CONFIG_HOME', None)
260 env.pop('XDG_CONFIG_HOME', None)
261 ipdir = path.get_ipython_dir()
261 ipdir = path.get_ipython_dir()
262 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
262 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
263
263
264 @with_environment
264 @with_environment
265 def test_get_ipython_dir_3():
265 def test_get_ipython_dir_3():
266 """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist."""
266 """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist."""
267 path.get_home_dir = lambda : "someplace"
267 path.get_home_dir = lambda : "someplace"
268 path._writable_dir = lambda path: True
268 path._writable_dir = lambda path: True
269 os.name = "posix"
269 os.name = "posix"
270 env.pop('IPYTHON_DIR', None)
270 env.pop('IPYTHON_DIR', None)
271 env.pop('IPYTHONDIR', None)
271 env.pop('IPYTHONDIR', None)
272 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
272 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
273 ipdir = path.get_ipython_dir()
273 ipdir = path.get_ipython_dir()
274 nt.assert_equal(ipdir, os.path.join(XDG_TEST_DIR, "ipython"))
274 nt.assert_equal(ipdir, os.path.join(XDG_TEST_DIR, "ipython"))
275
275
276 @with_environment
276 @with_environment
277 def test_get_ipython_dir_4():
277 def test_get_ipython_dir_4():
278 """test_get_ipython_dir_4, use XDG if both exist."""
278 """test_get_ipython_dir_4, use XDG if both exist."""
279 path.get_home_dir = lambda : HOME_TEST_DIR
279 path.get_home_dir = lambda : HOME_TEST_DIR
280 os.name = "posix"
280 os.name = "posix"
281 env.pop('IPYTHON_DIR', None)
281 env.pop('IPYTHON_DIR', None)
282 env.pop('IPYTHONDIR', None)
282 env.pop('IPYTHONDIR', None)
283 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
283 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
284 xdg_ipdir = os.path.join(XDG_TEST_DIR, "ipython")
284 xdg_ipdir = os.path.join(XDG_TEST_DIR, "ipython")
285 ipdir = path.get_ipython_dir()
285 ipdir = path.get_ipython_dir()
286 nt.assert_equal(ipdir, xdg_ipdir)
286 nt.assert_equal(ipdir, xdg_ipdir)
287
287
288 @with_environment
288 @with_environment
289 def test_get_ipython_dir_5():
289 def test_get_ipython_dir_5():
290 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
290 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
291 path.get_home_dir = lambda : HOME_TEST_DIR
291 path.get_home_dir = lambda : HOME_TEST_DIR
292 os.name = "posix"
292 os.name = "posix"
293 env.pop('IPYTHON_DIR', None)
293 env.pop('IPYTHON_DIR', None)
294 env.pop('IPYTHONDIR', None)
294 env.pop('IPYTHONDIR', None)
295 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
295 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
296 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
296 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
297 ipdir = path.get_ipython_dir()
297 ipdir = path.get_ipython_dir()
298 nt.assert_equal(ipdir, IP_TEST_DIR)
298 nt.assert_equal(ipdir, IP_TEST_DIR)
299
299
300 @with_environment
300 @with_environment
301 def test_get_ipython_dir_6():
301 def test_get_ipython_dir_6():
302 """test_get_ipython_dir_6, use XDG if defined and neither exist."""
302 """test_get_ipython_dir_6, use XDG if defined and neither exist."""
303 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
303 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
304 os.mkdir(xdg)
304 os.mkdir(xdg)
305 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
305 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
306 path.get_home_dir = lambda : HOME_TEST_DIR
306 path.get_home_dir = lambda : HOME_TEST_DIR
307 path.get_xdg_dir = lambda : xdg
307 path.get_xdg_dir = lambda : xdg
308 os.name = "posix"
308 os.name = "posix"
309 env.pop('IPYTHON_DIR', None)
309 env.pop('IPYTHON_DIR', None)
310 env.pop('IPYTHONDIR', None)
310 env.pop('IPYTHONDIR', None)
311 env.pop('XDG_CONFIG_HOME', None)
311 env.pop('XDG_CONFIG_HOME', None)
312 xdg_ipdir = os.path.join(xdg, "ipython")
312 xdg_ipdir = os.path.join(xdg, "ipython")
313 ipdir = path.get_ipython_dir()
313 ipdir = path.get_ipython_dir()
314 nt.assert_equal(ipdir, xdg_ipdir)
314 nt.assert_equal(ipdir, xdg_ipdir)
315
315
316 @with_environment
316 @with_environment
317 def test_get_ipython_dir_7():
317 def test_get_ipython_dir_7():
318 """test_get_ipython_dir_7, test home directory expansion on IPYTHON_DIR"""
318 """test_get_ipython_dir_7, test home directory expansion on IPYTHON_DIR"""
319 path._writable_dir = lambda path: True
319 path._writable_dir = lambda path: True
320 home_dir = os.path.expanduser('~')
320 home_dir = os.path.expanduser('~')
321 env['IPYTHON_DIR'] = os.path.join('~', 'somewhere')
321 env['IPYTHON_DIR'] = os.path.join('~', 'somewhere')
322 ipdir = path.get_ipython_dir()
322 ipdir = path.get_ipython_dir()
323 nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere'))
323 nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere'))
324
324
325
325
326 @with_environment
326 @with_environment
327 def test_get_xdg_dir_1():
327 def test_get_xdg_dir_1():
328 """test_get_xdg_dir_1, check xdg_dir"""
328 """test_get_xdg_dir_1, check xdg_dir"""
329 reload(path)
329 reload(path)
330 path._writable_dir = lambda path: True
330 path._writable_dir = lambda path: True
331 path.get_home_dir = lambda : 'somewhere'
331 path.get_home_dir = lambda : 'somewhere'
332 os.name = "posix"
332 os.name = "posix"
333 env.pop('IPYTHON_DIR', None)
333 env.pop('IPYTHON_DIR', None)
334 env.pop('IPYTHONDIR', None)
334 env.pop('IPYTHONDIR', None)
335 env.pop('XDG_CONFIG_HOME', None)
335 env.pop('XDG_CONFIG_HOME', None)
336
336
337 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
337 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
338
338
339
339
340 @with_environment
340 @with_environment
341 def test_get_xdg_dir_1():
341 def test_get_xdg_dir_1():
342 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
342 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
343 reload(path)
343 reload(path)
344 path.get_home_dir = lambda : HOME_TEST_DIR
344 path.get_home_dir = lambda : HOME_TEST_DIR
345 os.name = "posix"
345 os.name = "posix"
346 env.pop('IPYTHON_DIR', None)
346 env.pop('IPYTHON_DIR', None)
347 env.pop('IPYTHONDIR', None)
347 env.pop('IPYTHONDIR', None)
348 env.pop('XDG_CONFIG_HOME', None)
348 env.pop('XDG_CONFIG_HOME', None)
349 nt.assert_equal(path.get_xdg_dir(), None)
349 nt.assert_equal(path.get_xdg_dir(), None)
350
350
351 @with_environment
351 @with_environment
352 def test_get_xdg_dir_2():
352 def test_get_xdg_dir_2():
353 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
353 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
354 reload(path)
354 reload(path)
355 path.get_home_dir = lambda : HOME_TEST_DIR
355 path.get_home_dir = lambda : HOME_TEST_DIR
356 os.name = "posix"
356 os.name = "posix"
357 env.pop('IPYTHON_DIR', None)
357 env.pop('IPYTHON_DIR', None)
358 env.pop('IPYTHONDIR', None)
358 env.pop('IPYTHONDIR', None)
359 env.pop('XDG_CONFIG_HOME', None)
359 env.pop('XDG_CONFIG_HOME', None)
360 cfgdir=os.path.join(path.get_home_dir(), '.config')
360 cfgdir=os.path.join(path.get_home_dir(), '.config')
361 os.makedirs(cfgdir)
361 os.makedirs(cfgdir)
362
362
363 nt.assert_equal(path.get_xdg_dir(), cfgdir)
363 nt.assert_equal(path.get_xdg_dir(), cfgdir)
364
364
365 def test_filefind():
365 def test_filefind():
366 """Various tests for filefind"""
366 """Various tests for filefind"""
367 f = tempfile.NamedTemporaryFile()
367 f = tempfile.NamedTemporaryFile()
368 # print 'fname:',f.name
368 # print 'fname:',f.name
369 alt_dirs = path.get_ipython_dir()
369 alt_dirs = path.get_ipython_dir()
370 t = path.filefind(f.name, alt_dirs)
370 t = path.filefind(f.name, alt_dirs)
371 # print 'found:',t
371 # print 'found:',t
372
372
373
373
374 def test_get_ipython_package_dir():
374 def test_get_ipython_package_dir():
375 ipdir = path.get_ipython_package_dir()
375 ipdir = path.get_ipython_package_dir()
376 nt.assert_true(os.path.isdir(ipdir))
376 nt.assert_true(os.path.isdir(ipdir))
377
377
378
378
379 def test_get_ipython_module_path():
379 def test_get_ipython_module_path():
380 ipapp_path = path.get_ipython_module_path('IPython.frontend.terminal.ipapp')
380 ipapp_path = path.get_ipython_module_path('IPython.frontend.terminal.ipapp')
381 nt.assert_true(os.path.isfile(ipapp_path))
381 nt.assert_true(os.path.isfile(ipapp_path))
382
382
383
383
384 @dec.skip_if_not_win32
384 @dec.skip_if_not_win32
385 def test_get_long_path_name_win32():
385 def test_get_long_path_name_win32():
386 p = path.get_long_path_name('c:\\docume~1')
386 p = path.get_long_path_name('c:\\docume~1')
387 nt.assert_equals(p,u'c:\\Documents and Settings')
387 nt.assert_equals(p,u'c:\\Documents and Settings')
388
388
389
389
390 @dec.skip_win32
390 @dec.skip_win32
391 def test_get_long_path_name():
391 def test_get_long_path_name():
392 p = path.get_long_path_name('/usr/local')
392 p = path.get_long_path_name('/usr/local')
393 nt.assert_equals(p,'/usr/local')
393 nt.assert_equals(p,'/usr/local')
394
394
395 @dec.skip_win32 # can't create not-user-writable dir on win
395 @dec.skip_win32 # can't create not-user-writable dir on win
396 @with_environment
396 @with_environment
397 def test_not_writable_ipdir():
397 def test_not_writable_ipdir():
398 tmpdir = tempfile.mkdtemp()
398 tmpdir = tempfile.mkdtemp()
399 os.name = "posix"
399 os.name = "posix"
400 env.pop('IPYTHON_DIR', None)
400 env.pop('IPYTHON_DIR', None)
401 env.pop('IPYTHONDIR', None)
401 env.pop('IPYTHONDIR', None)
402 env.pop('XDG_CONFIG_HOME', None)
402 env.pop('XDG_CONFIG_HOME', None)
403 env['HOME'] = tmpdir
403 env['HOME'] = tmpdir
404 ipdir = os.path.join(tmpdir, '.ipython')
404 ipdir = os.path.join(tmpdir, '.ipython')
405 os.mkdir(ipdir)
405 os.mkdir(ipdir)
406 os.chmod(ipdir, 600)
406 os.chmod(ipdir, 600)
407 with AssertPrints('WARNING', channel='stderr'):
407 with AssertPrints('is not a writable location', channel='stderr'):
408 ipdir = path.get_ipython_dir()
408 ipdir = path.get_ipython_dir()
409 env.pop('IPYTHON_DIR', None)
409 env.pop('IPYTHON_DIR', None)
410
410
411 def test_unquote_filename():
411 def test_unquote_filename():
412 for win32 in (True, False):
412 for win32 in (True, False):
413 nt.assert_equals(path.unquote_filename('foo.py', win32=win32), 'foo.py')
413 nt.assert_equals(path.unquote_filename('foo.py', win32=win32), 'foo.py')
414 nt.assert_equals(path.unquote_filename('foo bar.py', win32=win32), 'foo bar.py')
414 nt.assert_equals(path.unquote_filename('foo bar.py', win32=win32), 'foo bar.py')
415 nt.assert_equals(path.unquote_filename('"foo.py"', win32=True), 'foo.py')
415 nt.assert_equals(path.unquote_filename('"foo.py"', win32=True), 'foo.py')
416 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=True), 'foo bar.py')
416 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=True), 'foo bar.py')
417 nt.assert_equals(path.unquote_filename("'foo.py'", win32=True), 'foo.py')
417 nt.assert_equals(path.unquote_filename("'foo.py'", win32=True), 'foo.py')
418 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=True), 'foo bar.py')
418 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=True), 'foo bar.py')
419 nt.assert_equals(path.unquote_filename('"foo.py"', win32=False), '"foo.py"')
419 nt.assert_equals(path.unquote_filename('"foo.py"', win32=False), '"foo.py"')
420 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=False), '"foo bar.py"')
420 nt.assert_equals(path.unquote_filename('"foo bar.py"', win32=False), '"foo bar.py"')
421 nt.assert_equals(path.unquote_filename("'foo.py'", win32=False), "'foo.py'")
421 nt.assert_equals(path.unquote_filename("'foo.py'", win32=False), "'foo.py'")
422 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=False), "'foo bar.py'")
422 nt.assert_equals(path.unquote_filename("'foo bar.py'", win32=False), "'foo bar.py'")
423
423
424 @with_environment
424 @with_environment
425 def test_get_py_filename():
425 def test_get_py_filename():
426 os.chdir(TMP_TEST_DIR)
426 os.chdir(TMP_TEST_DIR)
427 for win32 in (True, False):
427 for win32 in (True, False):
428 with make_tempfile('foo.py'):
428 with make_tempfile('foo.py'):
429 nt.assert_equals(path.get_py_filename('foo.py', force_win32=win32), 'foo.py')
429 nt.assert_equals(path.get_py_filename('foo.py', force_win32=win32), 'foo.py')
430 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo.py')
430 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo.py')
431 with make_tempfile('foo'):
431 with make_tempfile('foo'):
432 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo')
432 nt.assert_equals(path.get_py_filename('foo', force_win32=win32), 'foo')
433 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
433 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
434 nt.assert_raises(IOError, path.get_py_filename, 'foo', force_win32=win32)
434 nt.assert_raises(IOError, path.get_py_filename, 'foo', force_win32=win32)
435 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
435 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
436 true_fn = 'foo with spaces.py'
436 true_fn = 'foo with spaces.py'
437 with make_tempfile(true_fn):
437 with make_tempfile(true_fn):
438 nt.assert_equals(path.get_py_filename('foo with spaces', force_win32=win32), true_fn)
438 nt.assert_equals(path.get_py_filename('foo with spaces', force_win32=win32), true_fn)
439 nt.assert_equals(path.get_py_filename('foo with spaces.py', force_win32=win32), true_fn)
439 nt.assert_equals(path.get_py_filename('foo with spaces.py', force_win32=win32), true_fn)
440 if win32:
440 if win32:
441 nt.assert_equals(path.get_py_filename('"foo with spaces.py"', force_win32=True), true_fn)
441 nt.assert_equals(path.get_py_filename('"foo with spaces.py"', force_win32=True), true_fn)
442 nt.assert_equals(path.get_py_filename("'foo with spaces.py'", force_win32=True), true_fn)
442 nt.assert_equals(path.get_py_filename("'foo with spaces.py'", force_win32=True), true_fn)
443 else:
443 else:
444 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"', force_win32=False)
444 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"', force_win32=False)
445 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'", force_win32=False)
445 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'", force_win32=False)
General Comments 0
You need to be logged in to leave comments. Login now