##// END OF EJS Templates
Merge pull request #10485 from Carreau/unused-imports...
Thomas Kluyver -
r23576:fcbde473 merge
parent child Browse files
Show More
@@ -1,482 +1,479
1 1 # encoding: utf-8
2 2 """Tests for IPython.utils.path.py"""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 import errno
8 7 import os
9 8 import shutil
10 9 import sys
11 10 import tempfile
12 import warnings
13 11 from contextlib import contextmanager
14 12 from unittest.mock import patch
15 from os.path import join, abspath, split
13 from os.path import join, abspath
16 14 from imp import reload
17 15
18 16 from nose import SkipTest, with_setup
19 17 import nose.tools as nt
20 18
21 19 import IPython
22 20 from IPython import paths
23 21 from IPython.testing import decorators as dec
24 22 from IPython.testing.decorators import (skip_if_not_win32, skip_win32,
25 23 onlyif_unicode_paths,)
26 24 from IPython.testing.tools import make_tempfile, AssertPrints
27 25 from IPython.utils import path
28 from IPython.utils import py3compat
29 26 from IPython.utils.tempdir import TemporaryDirectory
30 27
31 28 # Platform-dependent imports
32 29 try:
33 30 import winreg as wreg
34 31 except ImportError:
35 32 #Fake _winreg module on non-windows platforms
36 33 import types
37 34 wr_name = "winreg"
38 35 sys.modules[wr_name] = types.ModuleType(wr_name)
39 36 try:
40 37 import winreg as wreg
41 38 except ImportError:
42 39 import _winreg as wreg
43 40 #Add entries that needs to be stubbed by the testing code
44 41 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
45 42
46 43 #-----------------------------------------------------------------------------
47 44 # Globals
48 45 #-----------------------------------------------------------------------------
49 46 env = os.environ
50 47 TMP_TEST_DIR = tempfile.mkdtemp()
51 48 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
52 49 #
53 50 # Setup/teardown functions/decorators
54 51 #
55 52
56 53 def setup():
57 54 """Setup testenvironment for the module:
58 55
59 56 - Adds dummy home dir tree
60 57 """
61 58 # Do not mask exceptions here. In particular, catching WindowsError is a
62 59 # problem because that exception is only defined on Windows...
63 60 os.makedirs(os.path.join(HOME_TEST_DIR, 'ipython'))
64 61
65 62
66 63 def teardown():
67 64 """Teardown testenvironment for the module:
68 65
69 66 - Remove dummy home dir tree
70 67 """
71 68 # Note: we remove the parent test dir, which is the root of all test
72 69 # subdirs we may have created. Use shutil instead of os.removedirs, so
73 70 # that non-empty directories are all recursively removed.
74 71 shutil.rmtree(TMP_TEST_DIR)
75 72
76 73
77 74 def setup_environment():
78 75 """Setup testenvironment for some functions that are tested
79 76 in this module. In particular this functions stores attributes
80 77 and other things that we need to stub in some test functions.
81 78 This needs to be done on a function level and not module level because
82 79 each testfunction needs a pristine environment.
83 80 """
84 81 global oldstuff, platformstuff
85 82 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
86 83
87 84 def teardown_environment():
88 85 """Restore things that were remembered by the setup_environment function
89 86 """
90 87 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
91 88 os.chdir(old_wd)
92 89 reload(path)
93 90
94 91 for key in list(env):
95 92 if key not in oldenv:
96 93 del env[key]
97 94 env.update(oldenv)
98 95 if hasattr(sys, 'frozen'):
99 96 del sys.frozen
100 97
101 98 # Build decorator that uses the setup_environment/setup_environment
102 99 with_environment = with_setup(setup_environment, teardown_environment)
103 100
104 101 @skip_if_not_win32
105 102 @with_environment
106 103 def test_get_home_dir_1():
107 104 """Testcase for py2exe logic, un-compressed lib
108 105 """
109 106 unfrozen = path.get_home_dir()
110 107 sys.frozen = True
111 108
112 109 #fake filename for IPython.__init__
113 110 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
114 111
115 112 home_dir = path.get_home_dir()
116 113 nt.assert_equal(home_dir, unfrozen)
117 114
118 115
119 116 @skip_if_not_win32
120 117 @with_environment
121 118 def test_get_home_dir_2():
122 119 """Testcase for py2exe logic, compressed lib
123 120 """
124 121 unfrozen = path.get_home_dir()
125 122 sys.frozen = True
126 123 #fake filename for IPython.__init__
127 124 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
128 125
129 126 home_dir = path.get_home_dir(True)
130 127 nt.assert_equal(home_dir, unfrozen)
131 128
132 129
133 130 @with_environment
134 131 def test_get_home_dir_3():
135 132 """get_home_dir() uses $HOME if set"""
136 133 env["HOME"] = HOME_TEST_DIR
137 134 home_dir = path.get_home_dir(True)
138 135 # get_home_dir expands symlinks
139 136 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
140 137
141 138
142 139 @with_environment
143 140 def test_get_home_dir_4():
144 141 """get_home_dir() still works if $HOME is not set"""
145 142
146 143 if 'HOME' in env: del env['HOME']
147 144 # this should still succeed, but we don't care what the answer is
148 145 home = path.get_home_dir(False)
149 146
150 147 @with_environment
151 148 def test_get_home_dir_5():
152 149 """raise HomeDirError if $HOME is specified, but not a writable dir"""
153 150 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
154 151 # set os.name = posix, to prevent My Documents fallback on Windows
155 152 os.name = 'posix'
156 153 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
157 154
158 155 # Should we stub wreg fully so we can run the test on all platforms?
159 156 @skip_if_not_win32
160 157 @with_environment
161 158 def test_get_home_dir_8():
162 159 """Using registry hack for 'My Documents', os=='nt'
163 160
164 161 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
165 162 """
166 163 os.name = 'nt'
167 164 # Remove from stub environment all keys that may be set
168 165 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
169 166 env.pop(key, None)
170 167
171 168 class key:
172 169 def Close(self):
173 170 pass
174 171
175 172 with patch.object(wreg, 'OpenKey', return_value=key()), \
176 173 patch.object(wreg, 'QueryValueEx', return_value=[abspath(HOME_TEST_DIR)]):
177 174 home_dir = path.get_home_dir()
178 175 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
179 176
180 177 @with_environment
181 178 def test_get_xdg_dir_0():
182 179 """test_get_xdg_dir_0, check xdg_dir"""
183 180 reload(path)
184 181 path._writable_dir = lambda path: True
185 182 path.get_home_dir = lambda : 'somewhere'
186 183 os.name = "posix"
187 184 sys.platform = "linux2"
188 185 env.pop('IPYTHON_DIR', None)
189 186 env.pop('IPYTHONDIR', None)
190 187 env.pop('XDG_CONFIG_HOME', None)
191 188
192 189 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
193 190
194 191
195 192 @with_environment
196 193 def test_get_xdg_dir_1():
197 194 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
198 195 reload(path)
199 196 path.get_home_dir = lambda : HOME_TEST_DIR
200 197 os.name = "posix"
201 198 sys.platform = "linux2"
202 199 env.pop('IPYTHON_DIR', None)
203 200 env.pop('IPYTHONDIR', None)
204 201 env.pop('XDG_CONFIG_HOME', None)
205 202 nt.assert_equal(path.get_xdg_dir(), None)
206 203
207 204 @with_environment
208 205 def test_get_xdg_dir_2():
209 206 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
210 207 reload(path)
211 208 path.get_home_dir = lambda : HOME_TEST_DIR
212 209 os.name = "posix"
213 210 sys.platform = "linux2"
214 211 env.pop('IPYTHON_DIR', None)
215 212 env.pop('IPYTHONDIR', None)
216 213 env.pop('XDG_CONFIG_HOME', None)
217 214 cfgdir=os.path.join(path.get_home_dir(), '.config')
218 215 if not os.path.exists(cfgdir):
219 216 os.makedirs(cfgdir)
220 217
221 218 nt.assert_equal(path.get_xdg_dir(), cfgdir)
222 219
223 220 @with_environment
224 221 def test_get_xdg_dir_3():
225 222 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
226 223 reload(path)
227 224 path.get_home_dir = lambda : HOME_TEST_DIR
228 225 os.name = "posix"
229 226 sys.platform = "darwin"
230 227 env.pop('IPYTHON_DIR', None)
231 228 env.pop('IPYTHONDIR', None)
232 229 env.pop('XDG_CONFIG_HOME', None)
233 230 cfgdir=os.path.join(path.get_home_dir(), '.config')
234 231 if not os.path.exists(cfgdir):
235 232 os.makedirs(cfgdir)
236 233
237 234 nt.assert_equal(path.get_xdg_dir(), None)
238 235
239 236 def test_filefind():
240 237 """Various tests for filefind"""
241 238 f = tempfile.NamedTemporaryFile()
242 239 # print 'fname:',f.name
243 240 alt_dirs = paths.get_ipython_dir()
244 241 t = path.filefind(f.name, alt_dirs)
245 242 # print 'found:',t
246 243
247 244
248 245 @dec.skip_if_not_win32
249 246 def test_get_long_path_name_win32():
250 247 with TemporaryDirectory() as tmpdir:
251 248
252 249 # Make a long path. Expands the path of tmpdir prematurely as it may already have a long
253 250 # path component, so ensure we include the long form of it
254 251 long_path = os.path.join(path.get_long_path_name(tmpdir), 'this is my long path name')
255 252 os.makedirs(long_path)
256 253
257 254 # Test to see if the short path evaluates correctly.
258 255 short_path = os.path.join(tmpdir, 'THISIS~1')
259 256 evaluated_path = path.get_long_path_name(short_path)
260 257 nt.assert_equal(evaluated_path.lower(), long_path.lower())
261 258
262 259
263 260 @dec.skip_win32
264 261 def test_get_long_path_name():
265 262 p = path.get_long_path_name('/usr/local')
266 263 nt.assert_equal(p,'/usr/local')
267 264
268 265 @dec.skip_win32 # can't create not-user-writable dir on win
269 266 @with_environment
270 267 def test_not_writable_ipdir():
271 268 tmpdir = tempfile.mkdtemp()
272 269 os.name = "posix"
273 270 env.pop('IPYTHON_DIR', None)
274 271 env.pop('IPYTHONDIR', None)
275 272 env.pop('XDG_CONFIG_HOME', None)
276 273 env['HOME'] = tmpdir
277 274 ipdir = os.path.join(tmpdir, '.ipython')
278 275 os.mkdir(ipdir, 0o555)
279 276 try:
280 277 open(os.path.join(ipdir, "_foo_"), 'w').close()
281 278 except IOError:
282 279 pass
283 280 else:
284 281 # I can still write to an unwritable dir,
285 282 # assume I'm root and skip the test
286 283 raise SkipTest("I can't create directories that I can't write to")
287 284 with AssertPrints('is not a writable location', channel='stderr'):
288 285 ipdir = paths.get_ipython_dir()
289 286 env.pop('IPYTHON_DIR', None)
290 287
291 288 @with_environment
292 289 def test_get_py_filename():
293 290 os.chdir(TMP_TEST_DIR)
294 291 with make_tempfile('foo.py'):
295 292 nt.assert_equal(path.get_py_filename('foo.py'), 'foo.py')
296 293 nt.assert_equal(path.get_py_filename('foo'), 'foo.py')
297 294 with make_tempfile('foo'):
298 295 nt.assert_equal(path.get_py_filename('foo'), 'foo')
299 296 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
300 297 nt.assert_raises(IOError, path.get_py_filename, 'foo')
301 298 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
302 299 true_fn = 'foo with spaces.py'
303 300 with make_tempfile(true_fn):
304 301 nt.assert_equal(path.get_py_filename('foo with spaces'), true_fn)
305 302 nt.assert_equal(path.get_py_filename('foo with spaces.py'), true_fn)
306 303 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"')
307 304 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'")
308 305
309 306 @onlyif_unicode_paths
310 307 def test_unicode_in_filename():
311 308 """When a file doesn't exist, the exception raised should be safe to call
312 309 str() on - i.e. in Python 2 it must only have ASCII characters.
313 310
314 311 https://github.com/ipython/ipython/issues/875
315 312 """
316 313 try:
317 314 # these calls should not throw unicode encode exceptions
318 315 path.get_py_filename('fooéè.py', force_win32=False)
319 316 except IOError as ex:
320 317 str(ex)
321 318
322 319
323 320 class TestShellGlob(object):
324 321
325 322 @classmethod
326 323 def setUpClass(cls):
327 324 cls.filenames_start_with_a = ['a0', 'a1', 'a2']
328 325 cls.filenames_end_with_b = ['0b', '1b', '2b']
329 326 cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b
330 327 cls.tempdir = TemporaryDirectory()
331 328 td = cls.tempdir.name
332 329
333 330 with cls.in_tempdir():
334 331 # Create empty files
335 332 for fname in cls.filenames:
336 333 open(os.path.join(td, fname), 'w').close()
337 334
338 335 @classmethod
339 336 def tearDownClass(cls):
340 337 cls.tempdir.cleanup()
341 338
342 339 @classmethod
343 340 @contextmanager
344 341 def in_tempdir(cls):
345 342 save = os.getcwd()
346 343 try:
347 344 os.chdir(cls.tempdir.name)
348 345 yield
349 346 finally:
350 347 os.chdir(save)
351 348
352 349 def check_match(self, patterns, matches):
353 350 with self.in_tempdir():
354 351 # glob returns unordered list. that's why sorted is required.
355 352 nt.assert_equal(sorted(path.shellglob(patterns)),
356 353 sorted(matches))
357 354
358 355 def common_cases(self):
359 356 return [
360 357 (['*'], self.filenames),
361 358 (['a*'], self.filenames_start_with_a),
362 359 (['*c'], ['*c']),
363 360 (['*', 'a*', '*b', '*c'], self.filenames
364 361 + self.filenames_start_with_a
365 362 + self.filenames_end_with_b
366 363 + ['*c']),
367 364 (['a[012]'], self.filenames_start_with_a),
368 365 ]
369 366
370 367 @skip_win32
371 368 def test_match_posix(self):
372 369 for (patterns, matches) in self.common_cases() + [
373 370 ([r'\*'], ['*']),
374 371 ([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a),
375 372 ([r'a\[012]'], ['a[012]']),
376 373 ]:
377 374 yield (self.check_match, patterns, matches)
378 375
379 376 @skip_if_not_win32
380 377 def test_match_windows(self):
381 378 for (patterns, matches) in self.common_cases() + [
382 379 # In windows, backslash is interpreted as path
383 380 # separator. Therefore, you can't escape glob
384 381 # using it.
385 382 ([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a),
386 383 ([r'a\[012]'], [r'a\[012]']),
387 384 ]:
388 385 yield (self.check_match, patterns, matches)
389 386
390 387
391 388 def test_unescape_glob():
392 389 nt.assert_equal(path.unescape_glob(r'\*\[\!\]\?'), '*[!]?')
393 390 nt.assert_equal(path.unescape_glob(r'\\*'), r'\*')
394 391 nt.assert_equal(path.unescape_glob(r'\\\*'), r'\*')
395 392 nt.assert_equal(path.unescape_glob(r'\\a'), r'\a')
396 393 nt.assert_equal(path.unescape_glob(r'\a'), r'\a')
397 394
398 395
399 396 def test_ensure_dir_exists():
400 397 with TemporaryDirectory() as td:
401 398 d = os.path.join(td, 'βˆ‚ir')
402 399 path.ensure_dir_exists(d) # create it
403 400 assert os.path.isdir(d)
404 401 path.ensure_dir_exists(d) # no-op
405 402 f = os.path.join(td, 'Ζ’ile')
406 403 open(f, 'w').close() # touch
407 404 with nt.assert_raises(IOError):
408 405 path.ensure_dir_exists(f)
409 406
410 407 class TestLinkOrCopy(object):
411 408 def setUp(self):
412 409 self.tempdir = TemporaryDirectory()
413 410 self.src = self.dst("src")
414 411 with open(self.src, "w") as f:
415 412 f.write("Hello, world!")
416 413
417 414 def tearDown(self):
418 415 self.tempdir.cleanup()
419 416
420 417 def dst(self, *args):
421 418 return os.path.join(self.tempdir.name, *args)
422 419
423 420 def assert_inode_not_equal(self, a, b):
424 421 nt.assert_not_equal(os.stat(a).st_ino, os.stat(b).st_ino,
425 422 "%r and %r do reference the same indoes" %(a, b))
426 423
427 424 def assert_inode_equal(self, a, b):
428 425 nt.assert_equal(os.stat(a).st_ino, os.stat(b).st_ino,
429 426 "%r and %r do not reference the same indoes" %(a, b))
430 427
431 428 def assert_content_equal(self, a, b):
432 429 with open(a) as a_f:
433 430 with open(b) as b_f:
434 431 nt.assert_equal(a_f.read(), b_f.read())
435 432
436 433 @skip_win32
437 434 def test_link_successful(self):
438 435 dst = self.dst("target")
439 436 path.link_or_copy(self.src, dst)
440 437 self.assert_inode_equal(self.src, dst)
441 438
442 439 @skip_win32
443 440 def test_link_into_dir(self):
444 441 dst = self.dst("some_dir")
445 442 os.mkdir(dst)
446 443 path.link_or_copy(self.src, dst)
447 444 expected_dst = self.dst("some_dir", os.path.basename(self.src))
448 445 self.assert_inode_equal(self.src, expected_dst)
449 446
450 447 @skip_win32
451 448 def test_target_exists(self):
452 449 dst = self.dst("target")
453 450 open(dst, "w").close()
454 451 path.link_or_copy(self.src, dst)
455 452 self.assert_inode_equal(self.src, dst)
456 453
457 454 @skip_win32
458 455 def test_no_link(self):
459 456 real_link = os.link
460 457 try:
461 458 del os.link
462 459 dst = self.dst("target")
463 460 path.link_or_copy(self.src, dst)
464 461 self.assert_content_equal(self.src, dst)
465 462 self.assert_inode_not_equal(self.src, dst)
466 463 finally:
467 464 os.link = real_link
468 465
469 466 @skip_if_not_win32
470 467 def test_windows(self):
471 468 dst = self.dst("target")
472 469 path.link_or_copy(self.src, dst)
473 470 self.assert_content_equal(self.src, dst)
474 471
475 472 def test_link_twice(self):
476 473 # Linking the same file twice shouldn't leave duplicates around.
477 474 # See https://github.com/ipython/ipython/issues/6450
478 475 dst = self.dst('target')
479 476 path.link_or_copy(self.src, dst)
480 477 path.link_or_copy(self.src, dst)
481 478 self.assert_inode_equal(self.src, dst)
482 479 nt.assert_equal(sorted(os.listdir(self.tempdir.name)), ['src', 'target'])
General Comments 0
You need to be logged in to leave comments. Login now