import errno import os import shutil import tempfile import warnings from unittest.mock import patch from tempfile import TemporaryDirectory from testpath import assert_isdir, assert_isfile, modified_env from IPython import paths from IPython.testing.decorators import skip_win32 TMP_TEST_DIR = os.path.realpath(tempfile.mkdtemp()) HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir") XDG_TEST_DIR = os.path.join(HOME_TEST_DIR, "xdg_test_dir") XDG_CACHE_DIR = os.path.join(HOME_TEST_DIR, "xdg_cache_dir") IP_TEST_DIR = os.path.join(HOME_TEST_DIR, ".ipython") def setup_module(): """Setup testenvironment for the module: - Adds dummy home dir tree """ # Do not mask exceptions here. In particular, catching WindowsError is a # problem because that exception is only defined on Windows... os.makedirs(IP_TEST_DIR) os.makedirs(os.path.join(XDG_TEST_DIR, "ipython")) os.makedirs(os.path.join(XDG_CACHE_DIR, "ipython")) def teardown_module(): """Teardown testenvironment for the module: - Remove dummy home dir tree """ # 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) def patch_get_home_dir(dirpath): return patch.object(paths, "get_home_dir", return_value=dirpath) def test_get_ipython_dir_1(): """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions.""" env_ipdir = os.path.join("someplace", ".ipython") with ( patch.object(paths, "_writable_dir", return_value=True), modified_env({"IPYTHONDIR": env_ipdir}), ): ipdir = paths.get_ipython_dir() assert ipdir == env_ipdir def test_get_ipython_dir_2(): """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions.""" with ( patch_get_home_dir("someplace"), patch.object(paths, "get_xdg_dir", return_value=None), patch.object(paths, "_writable_dir", return_value=True), patch("os.name", "posix"), modified_env( {"IPYTHON_DIR": None, "IPYTHONDIR": None, "XDG_CONFIG_HOME": None} ), ): ipdir = paths.get_ipython_dir() assert ipdir == os.path.join("someplace", ".ipython") def test_get_ipython_dir_3(): """test_get_ipython_dir_3, use XDG if defined and exists, and .ipython doesn't exist.""" tmphome = TemporaryDirectory() try: with ( patch_get_home_dir(tmphome.name), patch("os.name", "posix"), modified_env( { "IPYTHON_DIR": None, "IPYTHONDIR": None, "XDG_CONFIG_HOME": XDG_TEST_DIR, } ), warnings.catch_warnings(record=True) as w, ): ipdir = paths.get_ipython_dir() assert ipdir == os.path.join(tmphome.name, XDG_TEST_DIR, "ipython") assert len(w) == 0 finally: tmphome.cleanup() def test_get_ipython_dir_4(): """test_get_ipython_dir_4, warn if XDG and home both exist.""" with patch_get_home_dir(HOME_TEST_DIR), patch("os.name", "posix"): try: os.mkdir(os.path.join(XDG_TEST_DIR, "ipython")) except OSError as e: if e.errno != errno.EEXIST: raise with ( modified_env( { "IPYTHON_DIR": None, "IPYTHONDIR": None, "XDG_CONFIG_HOME": XDG_TEST_DIR, } ), warnings.catch_warnings(record=True) as w, ): ipdir = paths.get_ipython_dir() assert len(w) == 1 assert "Ignoring" in str(w[0]) def test_get_ipython_dir_5(): """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist.""" with patch_get_home_dir(HOME_TEST_DIR), patch("os.name", "posix"): try: os.rmdir(os.path.join(XDG_TEST_DIR, "ipython")) except OSError as e: if e.errno != errno.ENOENT: raise with modified_env( { "IPYTHON_DIR": None, "IPYTHONDIR": None, "XDG_CONFIG_HOME": XDG_TEST_DIR, } ): ipdir = paths.get_ipython_dir() assert ipdir == IP_TEST_DIR def test_get_ipython_dir_6(): """test_get_ipython_dir_6, use home over XDG if defined and neither exist.""" xdg = os.path.join(HOME_TEST_DIR, "somexdg") os.mkdir(xdg) shutil.rmtree(os.path.join(HOME_TEST_DIR, ".ipython")) print(paths._writable_dir) with ( patch_get_home_dir(HOME_TEST_DIR), patch.object(paths, "get_xdg_dir", return_value=xdg), patch("os.name", "posix"), modified_env( { "IPYTHON_DIR": None, "IPYTHONDIR": None, "XDG_CONFIG_HOME": None, } ), warnings.catch_warnings(record=True) as w, ): ipdir = paths.get_ipython_dir() assert ipdir == os.path.join(HOME_TEST_DIR, ".ipython") assert len(w) == 0 def test_get_ipython_dir_7(): """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR""" home_dir = os.path.normpath(os.path.expanduser("~")) with ( modified_env({"IPYTHONDIR": os.path.join("~", "somewhere")}), patch.object(paths, "_writable_dir", return_value=True), ): ipdir = paths.get_ipython_dir() assert ipdir == os.path.join(home_dir, "somewhere") @skip_win32 def test_get_ipython_dir_8(): """test_get_ipython_dir_8, test / home directory""" if not os.access("/", os.W_OK): # test only when HOME directory actually writable return with ( patch.object(paths, "_writable_dir", lambda path: bool(path)), patch.object(paths, "get_xdg_dir", return_value=None), modified_env( { "IPYTHON_DIR": None, "IPYTHONDIR": None, "HOME": "/", } ), ): assert paths.get_ipython_dir() == "/.ipython" def test_get_ipython_cache_dir(): with modified_env({"HOME": HOME_TEST_DIR}): if os.name == "posix": # test default os.makedirs(os.path.join(HOME_TEST_DIR, ".cache")) with modified_env({"XDG_CACHE_HOME": None}): ipdir = paths.get_ipython_cache_dir() assert os.path.join(HOME_TEST_DIR, ".cache", "ipython") == ipdir assert_isdir(ipdir) # test env override with modified_env({"XDG_CACHE_HOME": XDG_CACHE_DIR}): ipdir = paths.get_ipython_cache_dir() assert_isdir(ipdir) assert ipdir == os.path.join(XDG_CACHE_DIR, "ipython") else: assert paths.get_ipython_cache_dir() == paths.get_ipython_dir() def test_get_ipython_package_dir(): ipdir = paths.get_ipython_package_dir() assert_isdir(ipdir) def test_get_ipython_module_path(): ipapp_path = paths.get_ipython_module_path("IPython.terminal.ipapp") assert_isfile(ipapp_path)