test_path.py
506 lines
| 15.6 KiB
| text/x-python
|
PythonLexer
Brian Granger
|
r1617 | # encoding: utf-8 | ||
Brian Granger
|
r2498 | """Tests for IPython.utils.path.py""" | ||
Brian Granger
|
r1617 | |||
MinRK
|
r16489 | # Copyright (c) IPython Development Team. | ||
# Distributed under the terms of the Modified BSD License. | ||||
Robert Kern
|
r4688 | |||
Fernando Perez
|
r1843 | import os | ||
import shutil | ||||
import sys | ||||
import tempfile | ||||
Matthias Bussonnier
|
r23706 | import unittest | ||
David Wolever
|
r11653 | from contextlib import contextmanager | ||
Nikita Kniazev
|
r27076 | from importlib import reload | ||
Matthias Bussonnier
|
r27509 | from os.path import abspath, join | ||
from unittest.mock import patch | ||||
Fernando Perez
|
r1843 | |||
Samuel Gaist
|
r26923 | import pytest | ||
Matthias Bussonnier
|
r27509 | from tempfile import TemporaryDirectory | ||
Brian Granger
|
r1617 | |||
Fernando Perez
|
r1843 | import IPython | ||
Min RK
|
r21253 | from IPython import paths | ||
Fernando Perez
|
r2436 | from IPython.testing import decorators as dec | ||
Matthias Bussonnier
|
r27154 | from IPython.testing.decorators import ( | ||
Matthias Bussonnier
|
r27509 | onlyif_unicode_paths, | ||
Matthias Bussonnier
|
r27154 | skip_if_not_win32, | ||
skip_win32, | ||||
) | ||||
Matthias Bussonnier
|
r25335 | from IPython.testing.tools import make_tempfile | ||
Thomas Kluyver
|
r11127 | from IPython.utils import path | ||
Nicholas Bollweg
|
r25224 | |||
Fernando Perez
|
r1843 | # Platform-dependent imports | ||
Jorgen Stenarson
|
r1750 | try: | ||
Nicholas Bollweg
|
r25223 | import winreg as wreg | ||
Jorgen Stenarson
|
r1750 | except ImportError: | ||
Srinivas Reddy Thatiparthy
|
r23092 | #Fake _winreg module on non-windows platforms | ||
import types | ||||
wr_name = "winreg" | ||||
sys.modules[wr_name] = types.ModuleType(wr_name) | ||||
Thomas Kluyver
|
r13354 | try: | ||
Srinivas Reddy Thatiparthy
|
r23092 | import winreg as wreg | ||
Thomas Kluyver
|
r13354 | except ImportError: | ||
Srinivas Reddy Thatiparthy
|
r23092 | import _winreg as wreg | ||
Matthias Bussonnier
|
r27509 | |||
Thomas Kluyver
|
r13354 | #Add entries that needs to be stubbed by the testing code | ||
(wreg.OpenKey, wreg.QueryValueEx,) = (None, None) | ||||
Bernardo B. Marques
|
r4872 | |||
Fernando Perez
|
r1843 | #----------------------------------------------------------------------------- | ||
# Globals | ||||
#----------------------------------------------------------------------------- | ||||
env = os.environ | ||||
TMP_TEST_DIR = tempfile.mkdtemp() | ||||
HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir") | ||||
Jorgen Stenarson
|
r1804 | # | ||
# Setup/teardown functions/decorators | ||||
Jorgen Stenarson
|
r1803 | # | ||
Matthias Bussonnier
|
r25082 | def setup_module(): | ||
Jorgen Stenarson
|
r1805 | """Setup testenvironment for the module: | ||
Bernardo B. Marques
|
r4872 | |||
Matthias Bussonnier
|
r26419 | - Adds dummy home dir tree | ||
Jorgen Stenarson
|
r1805 | """ | ||
Fernando Perez
|
r1843 | # Do not mask exceptions here. In particular, catching WindowsError is a | ||
# problem because that exception is only defined on Windows... | ||||
Thomas Kluyver
|
r21041 | os.makedirs(os.path.join(HOME_TEST_DIR, 'ipython')) | ||
Jorgen Stenarson
|
r1803 | |||
Brian Granger
|
r2505 | |||
Matthias Bussonnier
|
r25082 | def teardown_module(): | ||
Jorgen Stenarson
|
r1805 | """Teardown testenvironment for the module: | ||
Bernardo B. Marques
|
r4872 | |||
Matthias Bussonnier
|
r26419 | - Remove dummy home dir tree | ||
Jorgen Stenarson
|
r1805 | """ | ||
Fernando Perez
|
r1843 | # Note: we remove the parent test dir, which is the root of all test | ||
# subdirs we may have created. Use shutil instead of os.removedirs, so | ||||
# that non-empty directories are all recursively removed. | ||||
shutil.rmtree(TMP_TEST_DIR) | ||||
Jorgen Stenarson
|
r1803 | |||
Brian Granger
|
r2505 | |||
M Bussonnier
|
r28850 | # Build decorator that uses the setup_environment/setup_environment | ||
@pytest.fixture | ||||
def environment(): | ||||
Jorgen Stenarson
|
r1750 | global oldstuff, platformstuff | ||
M Bussonnier
|
r28850 | oldstuff = ( | ||
env.copy(), | ||||
os.name, | ||||
sys.platform, | ||||
path.get_home_dir, | ||||
IPython.__file__, | ||||
os.getcwd(), | ||||
) | ||||
Jorgen Stenarson
|
r1750 | |||
M Bussonnier
|
r28850 | yield | ||
( | ||||
oldenv, | ||||
os.name, | ||||
sys.platform, | ||||
path.get_home_dir, | ||||
IPython.__file__, | ||||
old_wd, | ||||
) = oldstuff | ||||
Robert Kern
|
r4688 | os.chdir(old_wd) | ||
MinRK
|
r4475 | reload(path) | ||
Bernardo B. Marques
|
r4872 | |||
Thomas Kluyver
|
r13373 | for key in list(env): | ||
Jorgen Stenarson
|
r1750 | if key not in oldenv: | ||
del env[key] | ||||
env.update(oldenv) | ||||
M Bussonnier
|
r28850 | assert not hasattr(sys, "frozen") | ||
Nikita Kniazev
|
r27042 | |||
with_environment = pytest.mark.usefixtures("environment") | ||||
Jorgen Stenarson
|
r1750 | |||
Jorgen Stenarson
|
r1820 | @skip_if_not_win32 | ||
Fernando Perez
|
r2436 | @with_environment | ||
Matthias Bussonnier
|
r28849 | def test_get_home_dir_1(monkeypatch): | ||
Jorgen Stenarson
|
r1746 | """Testcase for py2exe logic, un-compressed lib | ||
""" | ||||
MinRK
|
r11502 | unfrozen = path.get_home_dir() | ||
M Bussonnier
|
r28850 | monkeypatch.setattr(sys, "frozen", True, raising=False) | ||
Bernardo B. Marques
|
r4872 | |||
Jorgen Stenarson
|
r1746 | #fake filename for IPython.__init__ | ||
Jorgen Stenarson
|
r1855 | IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py")) | ||
Bernardo B. Marques
|
r4872 | |||
bgranger
|
r2513 | home_dir = path.get_home_dir() | ||
Matthias Bussonnier
|
r26719 | assert home_dir == unfrozen | ||
Brian Granger
|
r2505 | |||
Jorgen Stenarson
|
r1812 | @skip_if_not_win32 | ||
Fernando Perez
|
r2436 | @with_environment | ||
Matthias Bussonnier
|
r28849 | def test_get_home_dir_2(monkeypatch): | ||
Jorgen Stenarson
|
r1746 | """Testcase for py2exe logic, compressed lib | ||
""" | ||||
MinRK
|
r11502 | unfrozen = path.get_home_dir() | ||
M Bussonnier
|
r28850 | monkeypatch.setattr(sys, "frozen", True, raising=False) | ||
Matthias Bussonnier
|
r28849 | # fake filename for IPython.__init__ | ||
IPython.__file__ = abspath( | ||||
join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py") | ||||
).lower() | ||||
Bernardo B. Marques
|
r4872 | |||
MinRK
|
r5384 | home_dir = path.get_home_dir(True) | ||
Matthias Bussonnier
|
r26719 | assert home_dir == unfrozen | ||
Jorgen Stenarson
|
r1746 | |||
Brian Granger
|
r2505 | |||
Matthias Bussonnier
|
r27154 | @skip_win32 | ||
Fernando Perez
|
r2436 | @with_environment | ||
Jorgen Stenarson
|
r1800 | def test_get_home_dir_3(): | ||
MinRK
|
r5383 | """get_home_dir() uses $HOME if set""" | ||
Fernando Perez
|
r1843 | env["HOME"] = HOME_TEST_DIR | ||
MinRK
|
r5384 | home_dir = path.get_home_dir(True) | ||
MinRK
|
r6123 | # get_home_dir expands symlinks | ||
Matthias Bussonnier
|
r26719 | assert home_dir == os.path.realpath(env["HOME"]) | ||
Jorgen Stenarson
|
r1745 | |||
Brian Granger
|
r2505 | |||
Fernando Perez
|
r2436 | @with_environment | ||
Jorgen Stenarson
|
r1800 | def test_get_home_dir_4(): | ||
MinRK
|
r5383 | """get_home_dir() still works if $HOME is not set""" | ||
Bernardo B. Marques
|
r4872 | |||
Jorgen Stenarson
|
r1812 | if 'HOME' in env: del env['HOME'] | ||
MinRK
|
r7669 | # this should still succeed, but we don't care what the answer is | ||
home = path.get_home_dir(False) | ||||
Brian Granger
|
r2505 | |||
Matthias Bussonnier
|
r27154 | @skip_win32 | ||
Fernando Perez
|
r2436 | @with_environment | ||
Matthias Bussonnier
|
r28849 | def test_get_home_dir_5(monkeypatch): | ||
MinRK
|
r5383 | """raise HomeDirError if $HOME is specified, but not a writable dir""" | ||
env['HOME'] = abspath(HOME_TEST_DIR+'garbage') | ||||
MinRK
|
r5385 | # set os.name = posix, to prevent My Documents fallback on Windows | ||
Matthias Bussonnier
|
r28849 | monkeypatch.setattr(os, "name", "posix") | ||
Samuel Gaist
|
r26923 | pytest.raises(path.HomeDirError, path.get_home_dir, True) | ||
Fernando Perez
|
r3373 | |||
bgranger
|
r2513 | # Should we stub wreg fully so we can run the test on all platforms? | ||
@skip_if_not_win32 | ||||
@with_environment | ||||
Matthias Bussonnier
|
r28849 | def test_get_home_dir_8(monkeypatch): | ||
bgranger
|
r2513 | """Using registry hack for 'My Documents', os=='nt' | ||
Bernardo B. Marques
|
r4872 | |||
bgranger
|
r2513 | HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing. | ||
Jorgen Stenarson
|
r1746 | """ | ||
Matthias Bussonnier
|
r28849 | monkeypatch.setattr(os, "name", "nt") | ||
Fernando Perez
|
r2447 | # Remove from stub environment all keys that may be set | ||
for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']: | ||||
env.pop(key, None) | ||||
Jorgen Stenarson
|
r1746 | |||
Thomas Kluyver
|
r18050 | class key: | ||
Matthias Bussonnier
|
r25293 | def __enter__(self): | ||
pass | ||||
Thomas Kluyver
|
r18050 | def Close(self): | ||
pass | ||||
Matthias Bussonnier
|
r25293 | def __exit__(*args, **kwargs): | ||
pass | ||||
Jorgen Stenarson
|
r1746 | |||
Thomas Kluyver
|
r18050 | with patch.object(wreg, 'OpenKey', return_value=key()), \ | ||
patch.object(wreg, 'QueryValueEx', return_value=[abspath(HOME_TEST_DIR)]): | ||||
home_dir = path.get_home_dir() | ||||
Matthias Bussonnier
|
r26719 | assert home_dir == abspath(HOME_TEST_DIR) | ||
Jorgen Stenarson
|
r1745 | |||
MinRK
|
r3896 | @with_environment | ||
Matthias Bussonnier
|
r28849 | def test_get_xdg_dir_0(monkeypatch): | ||
MinRK
|
r7086 | """test_get_xdg_dir_0, check xdg_dir""" | ||
Matthias Bussonnier
|
r28849 | monkeypatch.setattr(path, "_writable_dir", lambda path: True) | ||
monkeypatch.setattr(path, "get_home_dir", lambda: "somewhere") | ||||
monkeypatch.setattr(os, "name", "posix") | ||||
monkeypatch.setattr(sys, "platform", "linux2") | ||||
MinRK
|
r3347 | env.pop('IPYTHON_DIR', None) | ||
env.pop('IPYTHONDIR', None) | ||||
env.pop('XDG_CONFIG_HOME', None) | ||||
Bernardo B. Marques
|
r4872 | |||
Matthias Bussonnier
|
r26719 | assert path.get_xdg_dir() == os.path.join("somewhere", ".config") | ||
MinRK
|
r3347 | |||
@with_environment | ||||
Matthias Bussonnier
|
r28849 | def test_get_xdg_dir_1(monkeypatch): | ||
luzpaz
|
r24084 | """test_get_xdg_dir_1, check nonexistent xdg_dir""" | ||
Matthias Bussonnier
|
r28849 | monkeypatch.setattr(path, "get_home_dir", lambda: HOME_TEST_DIR) | ||
monkeypatch.setattr(os, "name", "posix") | ||||
monkeypatch.setattr(sys, "platform", "linux2") | ||||
env.pop("IPYTHON_DIR", None) | ||||
env.pop("IPYTHONDIR", None) | ||||
env.pop("XDG_CONFIG_HOME", None) | ||||
Matthias Bussonnier
|
r26719 | assert path.get_xdg_dir() is None | ||
MinRK
|
r3347 | |||
@with_environment | ||||
Matthias Bussonnier
|
r28849 | def test_get_xdg_dir_2(monkeypatch): | ||
MinRK
|
r3347 | """test_get_xdg_dir_2, check xdg_dir default to ~/.config""" | ||
Matthias Bussonnier
|
r28849 | monkeypatch.setattr(path, "get_home_dir", lambda: HOME_TEST_DIR) | ||
monkeypatch.setattr(os, "name", "posix") | ||||
monkeypatch.setattr(sys, "platform", "linux2") | ||||
env.pop("IPYTHON_DIR", None) | ||||
env.pop("IPYTHONDIR", None) | ||||
env.pop("XDG_CONFIG_HOME", None) | ||||
cfgdir = os.path.join(path.get_home_dir(), ".config") | ||||
MinRK
|
r7086 | if not os.path.exists(cfgdir): | ||
os.makedirs(cfgdir) | ||||
Bernardo B. Marques
|
r4872 | |||
Matthias Bussonnier
|
r26719 | assert path.get_xdg_dir() == cfgdir | ||
Fernando Perez
|
r1969 | |||
MinRK
|
r7086 | @with_environment | ||
Matthias Bussonnier
|
r28849 | def test_get_xdg_dir_3(monkeypatch): | ||
Julien Rabinow
|
r26956 | """test_get_xdg_dir_3, check xdg_dir not used on non-posix systems""" | ||
Matthias Bussonnier
|
r28849 | monkeypatch.setattr(path, "get_home_dir", lambda: HOME_TEST_DIR) | ||
monkeypatch.setattr(os, "name", "nt") | ||||
monkeypatch.setattr(sys, "platform", "win32") | ||||
env.pop("IPYTHON_DIR", None) | ||||
env.pop("IPYTHONDIR", None) | ||||
env.pop("XDG_CONFIG_HOME", None) | ||||
cfgdir = os.path.join(path.get_home_dir(), ".config") | ||||
Samuel Gaist
|
r26923 | os.makedirs(cfgdir, exist_ok=True) | ||
MinRK
|
r7086 | |||
Matthias Bussonnier
|
r26719 | assert path.get_xdg_dir() is None | ||
MinRK
|
r7086 | |||
Fernando Perez
|
r1969 | def test_filefind(): | ||
"""Various tests for filefind""" | ||||
f = tempfile.NamedTemporaryFile() | ||||
Antony Lee
|
r28756 | # print('fname:',f.name) | ||
Min RK
|
r21253 | alt_dirs = paths.get_ipython_dir() | ||
Brian Granger
|
r2505 | t = path.filefind(f.name, alt_dirs) | ||
Antony Lee
|
r28756 | # print('found:',t) | ||
Fernando Perez
|
r2357 | |||
Brian Granger
|
r2505 | |||
Brian Granger
|
r2498 | @dec.skip_if_not_win32 | ||
def test_get_long_path_name_win32(): | ||||
Jonathan Frederic
|
r12083 | with TemporaryDirectory() as tmpdir: | ||
Jonathan Frederic
|
r12085 | |||
Nicholas Bollweg
|
r25223 | # Make a long path. Expands the path of tmpdir prematurely as it may already have a long | ||
watercrossing
|
r13753 | # path component, so ensure we include the long form of it | ||
Srinivas Reddy Thatiparthy
|
r23213 | long_path = os.path.join(path.get_long_path_name(tmpdir), 'this is my long path name') | ||
Jonathan Frederic
|
r12085 | os.makedirs(long_path) | ||
Jonathan Frederic
|
r12083 | |||
Jonathan Frederic
|
r12085 | # Test to see if the short path evaluates correctly. | ||
Srinivas Reddy Thatiparthy
|
r23213 | short_path = os.path.join(tmpdir, 'THISIS~1') | ||
Jonathan Frederic
|
r12085 | evaluated_path = path.get_long_path_name(short_path) | ||
Matthias Bussonnier
|
r26719 | assert evaluated_path.lower() == long_path.lower() | ||
Fernando Perez
|
r2436 | |||
Brian Granger
|
r2505 | |||
Brian Granger
|
r2498 | @dec.skip_win32 | ||
def test_get_long_path_name(): | ||||
Matthias Bussonnier
|
r26719 | p = path.get_long_path_name("/usr/local") | ||
assert p == "/usr/local" | ||||
Fernando Perez
|
r2436 | |||
Matthias Bussonnier
|
r25109 | |||
M Bussonnier
|
r28850 | @dec.skip_win32 # can't create not-user-writable dir on win | ||
@with_environment | ||||
def test_not_writable_ipdir(): | ||||
tmpdir = tempfile.mkdtemp() | ||||
os.name = "posix" | ||||
env.pop("IPYTHON_DIR", None) | ||||
env.pop("IPYTHONDIR", None) | ||||
env.pop("XDG_CONFIG_HOME", None) | ||||
env["HOME"] = tmpdir | ||||
ipdir = os.path.join(tmpdir, ".ipython") | ||||
os.mkdir(ipdir, 0o555) | ||||
try: | ||||
open(os.path.join(ipdir, "_foo_"), "w", encoding="utf-8").close() | ||||
except IOError: | ||||
pass | ||||
else: | ||||
# I can still write to an unwritable dir, | ||||
# assume I'm root and skip the test | ||||
pytest.skip("I can't create directories that I can't write to") | ||||
with pytest.warns(UserWarning, match="is not a writable location"): | ||||
ipdir = paths.get_ipython_dir() | ||||
env.pop("IPYTHON_DIR", None) | ||||
Robert Kern
|
r4688 | |||
@with_environment | ||||
def test_get_py_filename(): | ||||
os.chdir(TMP_TEST_DIR) | ||||
Matthias Bussonnier
|
r26719 | with make_tempfile("foo.py"): | ||
assert path.get_py_filename("foo.py") == "foo.py" | ||||
assert path.get_py_filename("foo") == "foo.py" | ||||
with make_tempfile("foo"): | ||||
assert path.get_py_filename("foo") == "foo" | ||||
Samuel Gaist
|
r26923 | pytest.raises(IOError, path.get_py_filename, "foo.py") | ||
pytest.raises(IOError, path.get_py_filename, "foo") | ||||
pytest.raises(IOError, path.get_py_filename, "foo.py") | ||||
Matthias Bussonnier
|
r26719 | true_fn = "foo with spaces.py" | ||
Antony Lee
|
r22457 | with make_tempfile(true_fn): | ||
Matthias Bussonnier
|
r26719 | assert path.get_py_filename("foo with spaces") == true_fn | ||
assert path.get_py_filename("foo with spaces.py") == true_fn | ||||
Samuel Gaist
|
r26923 | pytest.raises(IOError, path.get_py_filename, '"foo with spaces.py"') | ||
pytest.raises(IOError, path.get_py_filename, "'foo with spaces.py'") | ||||
Thomas Kluyver
|
r12166 | |||
@onlyif_unicode_paths | ||||
r6152 | def test_unicode_in_filename(): | |||
Thomas Kluyver
|
r6164 | """When a file doesn't exist, the exception raised should be safe to call | ||
str() on - i.e. in Python 2 it must only have ASCII characters. | ||||
Nicholas Bollweg
|
r25223 | |||
Thomas Kluyver
|
r6164 | https://github.com/ipython/ipython/issues/875 | ||
""" | ||||
r6152 | try: | |||
# these calls should not throw unicode encode exceptions | ||||
Matthias Bussonnier
|
r25109 | path.get_py_filename('fooéè.py') | ||
r6152 | except IOError as ex: | |||
str(ex) | ||||
Takafumi Arakaki
|
r8014 | |||
Matthias Bussonnier
|
r23706 | class TestShellGlob(unittest.TestCase): | ||
Takafumi Arakaki
|
r8014 | |||
Takafumi Arakaki
|
r8638 | @classmethod | ||
def setUpClass(cls): | ||||
Thomas Kluyver
|
r13373 | cls.filenames_start_with_a = ['a0', 'a1', 'a2'] | ||
cls.filenames_end_with_b = ['0b', '1b', '2b'] | ||||
Takafumi Arakaki
|
r8638 | cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b | ||
cls.tempdir = TemporaryDirectory() | ||||
td = cls.tempdir.name | ||||
Takafumi Arakaki
|
r8014 | |||
Takafumi Arakaki
|
r8638 | with cls.in_tempdir(): | ||
Takafumi Arakaki
|
r8014 | # Create empty files | ||
Takafumi Arakaki
|
r8638 | for fname in cls.filenames: | ||
gousaiyang
|
r27495 | open(os.path.join(td, fname), "w", encoding="utf-8").close() | ||
Takafumi Arakaki
|
r8014 | |||
Takafumi Arakaki
|
r8638 | @classmethod | ||
def tearDownClass(cls): | ||||
cls.tempdir.cleanup() | ||||
@classmethod | ||||
@contextmanager | ||||
def in_tempdir(cls): | ||||
Srinivas Reddy Thatiparthy
|
r23045 | save = os.getcwd() | ||
Takafumi Arakaki
|
r8640 | try: | ||
os.chdir(cls.tempdir.name) | ||||
yield | ||||
finally: | ||||
os.chdir(save) | ||||
Takafumi Arakaki
|
r8638 | |||
def check_match(self, patterns, matches): | ||||
with self.in_tempdir(): | ||||
# glob returns unordered list. that's why sorted is required. | ||||
Matthias Bussonnier
|
r26719 | assert sorted(path.shellglob(patterns)) == sorted(matches) | ||
Takafumi Arakaki
|
r8638 | |||
def common_cases(self): | ||||
return [ | ||||
(['*'], self.filenames), | ||||
(['a*'], self.filenames_start_with_a), | ||||
(['*c'], ['*c']), | ||||
(['*', 'a*', '*b', '*c'], self.filenames | ||||
+ self.filenames_start_with_a | ||||
+ self.filenames_end_with_b | ||||
+ ['*c']), | ||||
(['a[012]'], self.filenames_start_with_a), | ||||
] | ||||
@skip_win32 | ||||
def test_match_posix(self): | ||||
for (patterns, matches) in self.common_cases() + [ | ||||
([r'\*'], ['*']), | ||||
([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a), | ||||
([r'a\[012]'], ['a[012]']), | ||||
]: | ||||
Nikita Kniazev
|
r27084 | self.check_match(patterns, matches) | ||
Takafumi Arakaki
|
r8638 | |||
@skip_if_not_win32 | ||||
def test_match_windows(self): | ||||
for (patterns, matches) in self.common_cases() + [ | ||||
# In windows, backslash is interpreted as path | ||||
# separator. Therefore, you can't escape glob | ||||
# using it. | ||||
([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a), | ||||
([r'a\[012]'], [r'a\[012]']), | ||||
]: | ||||
Nikita Kniazev
|
r27084 | self.check_match(patterns, matches) | ||
Takafumi Arakaki
|
r8119 | |||
Nate Rush
|
r27423 | @pytest.mark.parametrize( | ||
Matthias Bussonnier
|
r27444 | "globstr, unescaped_globstr", | ||
Nate Rush
|
r27423 | [ | ||
(r"\*\[\!\]\?", "*[!]?"), | ||||
(r"\\*", r"\*"), | ||||
(r"\\\*", r"\*"), | ||||
(r"\\a", r"\a"), | ||||
Matthias Bussonnier
|
r27444 | (r"\a", r"\a"), | ||
], | ||||
Nate Rush
|
r27423 | ) | ||
Nate Rush
|
r27422 | def test_unescape_glob(globstr, unescaped_globstr): | ||
assert path.unescape_glob(globstr) == unescaped_globstr | ||||
David Wolever
|
r11647 | |||
Thomas Kluyver
|
r23892 | @onlyif_unicode_paths | ||
MinRK
|
r16489 | def test_ensure_dir_exists(): | ||
with TemporaryDirectory() as td: | ||||
Srinivas Reddy Thatiparthy
|
r23213 | d = os.path.join(td, '∂ir') | ||
MinRK
|
r16489 | path.ensure_dir_exists(d) # create it | ||
John Kirkham
|
r21733 | assert os.path.isdir(d) | ||
gousaiyang
|
r27495 | path.ensure_dir_exists(d) # no-op | ||
f = os.path.join(td, "Æ’ile") | ||||
open(f, "w", encoding="utf-8").close() # touch | ||||
Samuel Gaist
|
r26923 | with pytest.raises(IOError): | ||
MinRK
|
r16489 | path.ensure_dir_exists(f) | ||
Matthias Bussonnier
|
r25109 | class TestLinkOrCopy(unittest.TestCase): | ||
David Wolever
|
r11647 | def setUp(self): | ||
self.tempdir = TemporaryDirectory() | ||||
self.src = self.dst("src") | ||||
gousaiyang
|
r27495 | with open(self.src, "w", encoding="utf-8") as f: | ||
David Wolever
|
r11647 | f.write("Hello, world!") | ||
def tearDown(self): | ||||
self.tempdir.cleanup() | ||||
def dst(self, *args): | ||||
return os.path.join(self.tempdir.name, *args) | ||||
def assert_inode_not_equal(self, a, b): | ||||
Matthias Bussonnier
|
r26719 | assert ( | ||
os.stat(a).st_ino != os.stat(b).st_ino | ||||
), "%r and %r do reference the same indoes" % (a, b) | ||||
David Wolever
|
r11647 | |||
def assert_inode_equal(self, a, b): | ||||
Matthias Bussonnier
|
r26719 | assert ( | ||
os.stat(a).st_ino == os.stat(b).st_ino | ||||
), "%r and %r do not reference the same indoes" % (a, b) | ||||
David Wolever
|
r11647 | |||
David Wolever
|
r11650 | def assert_content_equal(self, a, b): | ||
gousaiyang
|
r27495 | with open(a, "rb") as a_f: | ||
with open(b, "rb") as b_f: | ||||
Matthias Bussonnier
|
r26719 | assert a_f.read() == b_f.read() | ||
David Wolever
|
r11647 | |||
@skip_win32 | ||||
def test_link_successful(self): | ||||
dst = self.dst("target") | ||||
path.link_or_copy(self.src, dst) | ||||
self.assert_inode_equal(self.src, dst) | ||||
@skip_win32 | ||||
def test_link_into_dir(self): | ||||
dst = self.dst("some_dir") | ||||
os.mkdir(dst) | ||||
path.link_or_copy(self.src, dst) | ||||
expected_dst = self.dst("some_dir", os.path.basename(self.src)) | ||||
self.assert_inode_equal(self.src, expected_dst) | ||||
@skip_win32 | ||||
def test_target_exists(self): | ||||
dst = self.dst("target") | ||||
gousaiyang
|
r27495 | open(dst, "w", encoding="utf-8").close() | ||
David Wolever
|
r11647 | path.link_or_copy(self.src, dst) | ||
self.assert_inode_equal(self.src, dst) | ||||
@skip_win32 | ||||
def test_no_link(self): | ||||
real_link = os.link | ||||
try: | ||||
del os.link | ||||
dst = self.dst("target") | ||||
path.link_or_copy(self.src, dst) | ||||
David Wolever
|
r11650 | self.assert_content_equal(self.src, dst) | ||
David Wolever
|
r11647 | self.assert_inode_not_equal(self.src, dst) | ||
finally: | ||||
os.link = real_link | ||||
@skip_if_not_win32 | ||||
def test_windows(self): | ||||
dst = self.dst("target") | ||||
path.link_or_copy(self.src, dst) | ||||
David Wolever
|
r11650 | self.assert_content_equal(self.src, dst) | ||
Thomas Kluyver
|
r20038 | |||
def test_link_twice(self): | ||||
# Linking the same file twice shouldn't leave duplicates around. | ||||
# See https://github.com/ipython/ipython/issues/6450 | ||||
dst = self.dst('target') | ||||
path.link_or_copy(self.src, dst) | ||||
path.link_or_copy(self.src, dst) | ||||
self.assert_inode_equal(self.src, dst) | ||||
Matthias Bussonnier
|
r26719 | assert sorted(os.listdir(self.tempdir.name)) == ["src", "target"] | ||