1 import errno 2 import os 3 import shutil 4 import tempfile 5 import warnings 6 from unittest.mock import patch 7 8 from tempfile import TemporaryDirectory 9 from testpath import assert_isdir, assert_isfile, modified_env 10 11 from IPython import paths 12 from IPython.testing.decorators import skip_win32 13 14 TMP_TEST_DIR = os.path.realpath(tempfile.mkdtemp()) 15 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir") 16 XDG_TEST_DIR = os.path.join(HOME_TEST_DIR, "xdg_test_dir") 17 XDG_CACHE_DIR = os.path.join(HOME_TEST_DIR, "xdg_cache_dir") 18 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython') 19 20 def setup_module(): 21 """Setup testenvironment for the module: 22 23 - Adds dummy home dir tree 24 """ 25 # Do not mask exceptions here. In particular, catching WindowsError is a 26 # problem because that exception is only defined on Windows... 27 os.makedirs(IP_TEST_DIR) 28 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython')) 29 os.makedirs(os.path.join(XDG_CACHE_DIR, 'ipython')) 30 31 32 def teardown_module(): 33 """Teardown testenvironment for the module: 34 35 - Remove dummy home dir tree 36 """ 37 # Note: we remove the parent test dir, which is the root of all test 38 # subdirs we may have created. Use shutil instead of os.removedirs, so 39 # that non-empty directories are all recursively removed. 40 shutil.rmtree(TMP_TEST_DIR) 41 42 def patch_get_home_dir(dirpath): 43 return patch.object(paths, 'get_home_dir', return_value=dirpath) 44 45 46 def test_get_ipython_dir_1(): 47 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions.""" 48 env_ipdir = os.path.join("someplace", ".ipython") 49 with patch.object(paths, '_writable_dir', return_value=True), \ 50 modified_env({'IPYTHONDIR': env_ipdir}): 51 ipdir = paths.get_ipython_dir() 52 53 assert ipdir == env_ipdir 54 55 def test_get_ipython_dir_2(): 56 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions.""" 57 with patch_get_home_dir('someplace'), \ 58 patch.object(paths, 'get_xdg_dir', return_value=None), \ 59 patch.object(paths, '_writable_dir', return_value=True), \ 60 patch('os.name', "posix"), \ 61 modified_env({'IPYTHON_DIR': None, 62 'IPYTHONDIR': None, 63 'XDG_CONFIG_HOME': None 64 }): 65 ipdir = paths.get_ipython_dir() 66 67 assert ipdir == os.path.join("someplace", ".ipython") 68 69 def test_get_ipython_dir_3(): 70 """test_get_ipython_dir_3, use XDG if defined and exists, and .ipython doesn't exist.""" 71 tmphome = TemporaryDirectory() 72 try: 73 with patch_get_home_dir(tmphome.name), \ 74 patch('os.name', 'posix'), \ 75 modified_env({ 76 'IPYTHON_DIR': None, 77 'IPYTHONDIR': None, 78 'XDG_CONFIG_HOME': XDG_TEST_DIR, 79 }), warnings.catch_warnings(record=True) as w: 80 ipdir = paths.get_ipython_dir() 81 82 assert ipdir == os.path.join(tmphome.name, XDG_TEST_DIR, "ipython") 83 assert len(w) == 0 84 finally: 85 tmphome.cleanup() 86 87 def test_get_ipython_dir_4(): 88 """test_get_ipython_dir_4, warn if XDG and home both exist.""" 89 with patch_get_home_dir(HOME_TEST_DIR), \ 90 patch('os.name', 'posix'): 91 try: 92 os.mkdir(os.path.join(XDG_TEST_DIR, 'ipython')) 93 except OSError as e: 94 if e.errno != errno.EEXIST: 95 raise 96 97 98 with modified_env({ 99 'IPYTHON_DIR': None, 100 'IPYTHONDIR': None, 101 'XDG_CONFIG_HOME': XDG_TEST_DIR, 102 }), warnings.catch_warnings(record=True) as w: 103 ipdir = paths.get_ipython_dir() 104 105 assert len(w) == 1 106 assert "Ignoring" in str(w[0]) 107 108 109 def test_get_ipython_dir_5(): 110 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist.""" 111 with patch_get_home_dir(HOME_TEST_DIR), \ 112 patch('os.name', 'posix'): 113 try: 114 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython')) 115 except OSError as e: 116 if e.errno != errno.ENOENT: 117 raise 118 119 with modified_env({ 120 'IPYTHON_DIR': None, 121 'IPYTHONDIR': None, 122 'XDG_CONFIG_HOME': XDG_TEST_DIR, 123 }): 124 ipdir = paths.get_ipython_dir() 125 126 assert ipdir == IP_TEST_DIR 127 128 def test_get_ipython_dir_6(): 129 """test_get_ipython_dir_6, use home over XDG if defined and neither exist.""" 130 xdg = os.path.join(HOME_TEST_DIR, 'somexdg') 131 os.mkdir(xdg) 132 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython')) 133 print(paths._writable_dir) 134 with patch_get_home_dir(HOME_TEST_DIR), \ 135 patch.object(paths, 'get_xdg_dir', return_value=xdg), \ 136 patch('os.name', 'posix'), \ 137 modified_env({ 138 'IPYTHON_DIR': None, 139 'IPYTHONDIR': None, 140 'XDG_CONFIG_HOME': None, 141 }), warnings.catch_warnings(record=True) as w: 142 ipdir = paths.get_ipython_dir() 143 144 assert ipdir == os.path.join(HOME_TEST_DIR, ".ipython") 145 assert len(w) == 0 146 147 def test_get_ipython_dir_7(): 148 """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR""" 149 home_dir = os.path.normpath(os.path.expanduser('~')) 150 with modified_env({'IPYTHONDIR': os.path.join('~', 'somewhere')}), \ 151 patch.object(paths, '_writable_dir', return_value=True): 152 ipdir = paths.get_ipython_dir() 153 assert ipdir == os.path.join(home_dir, "somewhere") 154 155 156 @skip_win32 157 def test_get_ipython_dir_8(): 158 """test_get_ipython_dir_8, test / home directory""" 159 if not os.access("/", os.W_OK): 160 # test only when HOME directory actually writable 161 return 162 163 with ( 164 patch.object(paths, "_writable_dir", lambda path: bool(path)), 165 patch.object(paths, "get_xdg_dir", return_value=None), 166 modified_env( 167 { 168 "IPYTHON_DIR": None, 169 "IPYTHONDIR": None, 170 "HOME": "/", 171 } 172 ), 173 ): 174 assert paths.get_ipython_dir() == "/.ipython" 175 176 177 def test_get_ipython_cache_dir(): 178 with modified_env({'HOME': HOME_TEST_DIR}): 179 if os.name == "posix": 180 # test default 181 os.makedirs(os.path.join(HOME_TEST_DIR, ".cache")) 182 with modified_env({'XDG_CACHE_HOME': None}): 183 ipdir = paths.get_ipython_cache_dir() 184 assert os.path.join(HOME_TEST_DIR, ".cache", "ipython") == ipdir 185 assert_isdir(ipdir) 186 187 # test env override 188 with modified_env({"XDG_CACHE_HOME": XDG_CACHE_DIR}): 189 ipdir = paths.get_ipython_cache_dir() 190 assert_isdir(ipdir) 191 assert ipdir == os.path.join(XDG_CACHE_DIR, "ipython") 192 else: 193 assert paths.get_ipython_cache_dir() == paths.get_ipython_dir() 194 195 def test_get_ipython_package_dir(): 196 ipdir = paths.get_ipython_package_dir() 197 assert_isdir(ipdir) 198 199 200 def test_get_ipython_module_path(): 201 ipapp_path = paths.get_ipython_module_path('IPython.terminal.ipapp') 202 assert_isfile(ipapp_path) 203