Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

use XDG_CONFIG_HOME if available

priority is:

$XDG/ipython if both or neither exist
$HOME/.ipython if it exists and $XDG/ipython does not exist

closes gh-48
closes gh-246
  • Loading branch information...
commit c1c2a7104aa859c980e0d0506429c0cfab3766ce 1 parent ebe563d
@minrk minrk authored
Showing with 129 additions and 5 deletions.
  1. +43 −5 IPython/utils/path.py
  2. +86 −0 IPython/utils/tests/test_path.py
View
48 IPython/utils/path.py
@@ -246,6 +246,24 @@ def get_home_dir():
else:
raise HomeDirError('No valid home directory could be found for your OS')
+def get_xdg_dir():
+ """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
+
+ This is only for posix (Linux,Unix,OS X, etc) systems.
+ """
+
+ isdir = os.path.isdir
+ env = os.environ
+
+ if os.name == 'posix':
+ # Linux, Unix, AIX, OS X
+ # use ~/.config if not set OR empty
+ xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
+ if xdg and isdir(xdg):
+ return xdg.decode(sys.getfilesystemencoding())
+
+ return None
+
def get_ipython_dir():
"""Get the IPython directory for this platform and user.
@@ -253,14 +271,34 @@ def get_ipython_dir():
This uses the logic in `get_home_dir` to find the home directory
and the adds .ipython to the end of the path.
"""
+
+ env = os.environ
+ pjoin = os.path.join
+ exists = os.path.exists
+
ipdir_def = '.ipython'
+ xdg_def = 'ipython'
+
home_dir = get_home_dir()
+ xdg_dir = get_xdg_dir()
# import pdb; pdb.set_trace() # dbg
- ipdir = os.environ.get(
- 'IPYTHON_DIR', os.environ.get(
- 'IPYTHONDIR', os.path.join(home_dir, ipdir_def)
- )
- )
+ ipdir = env.get('IPYTHON_DIR', env.get('IPYTHONDIR', None))
+ if ipdir is None:
+ # not set explicitly, use XDG_CONFIG_HOME or HOME
+ home_ipdir = pjoin(home_dir, ipdir_def)
+ if xdg_dir:
+ # use XDG, as long as the user isn't already
+ # using $HOME/.ipython and *not* XDG/ipython
+
+ xdg_ipdir = pjoin(xdg_dir, xdg_def)
+
+ if exists(xdg_ipdir) or not exists(home_ipdir):
+ ipdir = xdg_ipdir
+
+ if ipdir is None:
+ # not using XDG
+ ipdir = home_ipdir
+
return ipdir.decode(sys.getfilesystemencoding())
View
86 IPython/utils/tests/test_path.py
@@ -46,6 +46,7 @@
TEST_FILE_PATH = split(abspath(__file__))[0]
TMP_TEST_DIR = tempfile.mkdtemp()
HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
+XDG_TEST_DIR = join(HOME_TEST_DIR, "xdg_test_dir")
IP_TEST_DIR = join(HOME_TEST_DIR,'.ipython')
#
# Setup/teardown functions/decorators
@@ -59,6 +60,7 @@ def setup():
# 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'))
def teardown():
@@ -236,9 +238,93 @@ def test_get_ipython_dir_2():
os.name = "posix"
env.pop('IPYTHON_DIR', None)
env.pop('IPYTHONDIR', None)
+ env.pop('XDG_CONFIG_HOME', None)
ipdir = path.get_ipython_dir()
nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
+@with_environment
+def test_get_ipython_dir_3():
+ """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist."""
+ path.get_home_dir = lambda : "someplace"
+ os.name = "posix"
+ env.pop('IPYTHON_DIR', None)
+ env.pop('IPYTHONDIR', None)
+ env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
+ ipdir = path.get_ipython_dir()
+ nt.assert_equal(ipdir, os.path.join(XDG_TEST_DIR, "ipython"))
+
+@with_environment
+def test_get_ipython_dir_4():
+ """test_get_ipython_dir_4, use XDG if both exist."""
+ path.get_home_dir = lambda : HOME_TEST_DIR
+ os.name = "posix"
+ env.pop('IPYTHON_DIR', None)
+ env.pop('IPYTHONDIR', None)
+ env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
+ xdg_ipdir = os.path.join(XDG_TEST_DIR, "ipython")
+ ipdir = path.get_ipython_dir()
+ nt.assert_equal(ipdir, xdg_ipdir)
+
+@with_environment
+def test_get_ipython_dir_5():
+ """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
+ os.name = "posix"
+ env.pop('IPYTHON_DIR', None)
+ env.pop('IPYTHONDIR', None)
+ env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
+ os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
+ ipdir = path.get_ipython_dir()
+ nt.assert_equal(ipdir, IP_TEST_DIR)
+
+@with_environment
+def test_get_ipython_dir_6():
+ """test_get_ipython_dir_6, use XDG if defined and neither exist."""
+ path.get_home_dir = lambda : 'somehome'
+ path.get_xdg_dir = lambda : 'somexdg'
+ os.name = "posix"
+ env.pop('IPYTHON_DIR', None)
+ env.pop('IPYTHONDIR', None)
+ xdg_ipdir = os.path.join("somexdg", "ipython")
+ ipdir = path.get_ipython_dir()
+ nt.assert_equal(ipdir, xdg_ipdir)
+
+@with_environment
+def test_get_xdg_dir_1():
+ """test_get_xdg_dir_1, check xdg_dir"""
+ reload(path)
+ path.get_home_dir = lambda : 'somewhere'
+ os.name = "posix"
+ env.pop('IPYTHON_DIR', None)
+ env.pop('IPYTHONDIR', None)
+ env.pop('XDG_CONFIG_HOME', None)
+
+ nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
+
+
+@with_environment
+def test_get_xdg_dir_1():
+ """test_get_xdg_dir_1, check nonexistant xdg_dir"""
+ reload(path)
+ path.get_home_dir = lambda : HOME_TEST_DIR
+ os.name = "posix"
+ env.pop('IPYTHON_DIR', None)
+ env.pop('IPYTHONDIR', None)
+ env.pop('XDG_CONFIG_HOME', None)
+ nt.assert_equal(path.get_xdg_dir(), None)
+
+@with_environment
+def test_get_xdg_dir_2():
+ """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
+ reload(path)
+ path.get_home_dir = lambda : HOME_TEST_DIR
+ os.name = "posix"
+ env.pop('IPYTHON_DIR', None)
+ env.pop('IPYTHONDIR', None)
+ env.pop('XDG_CONFIG_HOME', None)
+ cfgdir=os.path.join(path.get_home_dir(), '.config')
+ os.makedirs(cfgdir)
+
+ nt.assert_equal(path.get_xdg_dir(), cfgdir)
def test_filefind():
"""Various tests for filefind"""
Please sign in to comment.
Something went wrong with that request. Please try again.