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