Skip to content
This repository
Browse code

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
Min RK minrk authored

Showing 2 changed files with 129 additions and 5 deletions. Show diff stats Hide diff stats

  1. +43 5 IPython/utils/path.py
  2. +86 0 IPython/utils/tests/test_path.py
48 IPython/utils/path.py
@@ -246,6 +246,24 @@ def get_home_dir():
246 246 else:
247 247 raise HomeDirError('No valid home directory could be found for your OS')
248 248
  249 +def get_xdg_dir():
  250 + """Return the XDG_CONFIG_HOME, if it is defined and exists, else None.
  251 +
  252 + This is only for posix (Linux,Unix,OS X, etc) systems.
  253 + """
  254 +
  255 + isdir = os.path.isdir
  256 + env = os.environ
  257 +
  258 + if os.name == 'posix':
  259 + # Linux, Unix, AIX, OS X
  260 + # use ~/.config if not set OR empty
  261 + xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config')
  262 + if xdg and isdir(xdg):
  263 + return xdg.decode(sys.getfilesystemencoding())
  264 +
  265 + return None
  266 +
249 267
250 268 def get_ipython_dir():
251 269 """Get the IPython directory for this platform and user.
@@ -253,14 +271,34 @@ def get_ipython_dir():
253 271 This uses the logic in `get_home_dir` to find the home directory
254 272 and the adds .ipython to the end of the path.
255 273 """
  274 +
  275 + env = os.environ
  276 + pjoin = os.path.join
  277 + exists = os.path.exists
  278 +
256 279 ipdir_def = '.ipython'
  280 + xdg_def = 'ipython'
  281 +
257 282 home_dir = get_home_dir()
  283 + xdg_dir = get_xdg_dir()
258 284 # import pdb; pdb.set_trace() # dbg
259   - ipdir = os.environ.get(
260   - 'IPYTHON_DIR', os.environ.get(
261   - 'IPYTHONDIR', os.path.join(home_dir, ipdir_def)
262   - )
263   - )
  285 + ipdir = env.get('IPYTHON_DIR', env.get('IPYTHONDIR', None))
  286 + if ipdir is None:
  287 + # not set explicitly, use XDG_CONFIG_HOME or HOME
  288 + home_ipdir = pjoin(home_dir, ipdir_def)
  289 + if xdg_dir:
  290 + # use XDG, as long as the user isn't already
  291 + # using $HOME/.ipython and *not* XDG/ipython
  292 +
  293 + xdg_ipdir = pjoin(xdg_dir, xdg_def)
  294 +
  295 + if exists(xdg_ipdir) or not exists(home_ipdir):
  296 + ipdir = xdg_ipdir
  297 +
  298 + if ipdir is None:
  299 + # not using XDG
  300 + ipdir = home_ipdir
  301 +
264 302 return ipdir.decode(sys.getfilesystemencoding())
265 303
266 304
86 IPython/utils/tests/test_path.py
@@ -46,6 +46,7 @@
46 46 TEST_FILE_PATH = split(abspath(__file__))[0]
47 47 TMP_TEST_DIR = tempfile.mkdtemp()
48 48 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
  49 +XDG_TEST_DIR = join(HOME_TEST_DIR, "xdg_test_dir")
49 50 IP_TEST_DIR = join(HOME_TEST_DIR,'.ipython')
50 51 #
51 52 # Setup/teardown functions/decorators
@@ -59,6 +60,7 @@ def setup():
59 60 # Do not mask exceptions here. In particular, catching WindowsError is a
60 61 # problem because that exception is only defined on Windows...
61 62 os.makedirs(IP_TEST_DIR)
  63 + os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
62 64
63 65
64 66 def teardown():
@@ -236,9 +238,93 @@ def test_get_ipython_dir_2():
236 238 os.name = "posix"
237 239 env.pop('IPYTHON_DIR', None)
238 240 env.pop('IPYTHONDIR', None)
  241 + env.pop('XDG_CONFIG_HOME', None)
239 242 ipdir = path.get_ipython_dir()
240 243 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
241 244
  245 +@with_environment
  246 +def test_get_ipython_dir_3():
  247 + """test_get_ipython_dir_3, use XDG if defined, and .ipython doesn't exist."""
  248 + path.get_home_dir = lambda : "someplace"
  249 + os.name = "posix"
  250 + env.pop('IPYTHON_DIR', None)
  251 + env.pop('IPYTHONDIR', None)
  252 + env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
  253 + ipdir = path.get_ipython_dir()
  254 + nt.assert_equal(ipdir, os.path.join(XDG_TEST_DIR, "ipython"))
  255 +
  256 +@with_environment
  257 +def test_get_ipython_dir_4():
  258 + """test_get_ipython_dir_4, use XDG if both exist."""
  259 + path.get_home_dir = lambda : HOME_TEST_DIR
  260 + os.name = "posix"
  261 + env.pop('IPYTHON_DIR', None)
  262 + env.pop('IPYTHONDIR', None)
  263 + env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
  264 + xdg_ipdir = os.path.join(XDG_TEST_DIR, "ipython")
  265 + ipdir = path.get_ipython_dir()
  266 + nt.assert_equal(ipdir, xdg_ipdir)
  267 +
  268 +@with_environment
  269 +def test_get_ipython_dir_5():
  270 + """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
  271 + os.name = "posix"
  272 + env.pop('IPYTHON_DIR', None)
  273 + env.pop('IPYTHONDIR', None)
  274 + env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
  275 + os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
  276 + ipdir = path.get_ipython_dir()
  277 + nt.assert_equal(ipdir, IP_TEST_DIR)
  278 +
  279 +@with_environment
  280 +def test_get_ipython_dir_6():
  281 + """test_get_ipython_dir_6, use XDG if defined and neither exist."""
  282 + path.get_home_dir = lambda : 'somehome'
  283 + path.get_xdg_dir = lambda : 'somexdg'
  284 + os.name = "posix"
  285 + env.pop('IPYTHON_DIR', None)
  286 + env.pop('IPYTHONDIR', None)
  287 + xdg_ipdir = os.path.join("somexdg", "ipython")
  288 + ipdir = path.get_ipython_dir()
  289 + nt.assert_equal(ipdir, xdg_ipdir)
  290 +
  291 +@with_environment
  292 +def test_get_xdg_dir_1():
  293 + """test_get_xdg_dir_1, check xdg_dir"""
  294 + reload(path)
  295 + path.get_home_dir = lambda : 'somewhere'
  296 + os.name = "posix"
  297 + env.pop('IPYTHON_DIR', None)
  298 + env.pop('IPYTHONDIR', None)
  299 + env.pop('XDG_CONFIG_HOME', None)
  300 +
  301 + nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
  302 +
  303 +
  304 +@with_environment
  305 +def test_get_xdg_dir_1():
  306 + """test_get_xdg_dir_1, check nonexistant xdg_dir"""
  307 + reload(path)
  308 + path.get_home_dir = lambda : HOME_TEST_DIR
  309 + os.name = "posix"
  310 + env.pop('IPYTHON_DIR', None)
  311 + env.pop('IPYTHONDIR', None)
  312 + env.pop('XDG_CONFIG_HOME', None)
  313 + nt.assert_equal(path.get_xdg_dir(), None)
  314 +
  315 +@with_environment
  316 +def test_get_xdg_dir_2():
  317 + """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
  318 + reload(path)
  319 + path.get_home_dir = lambda : HOME_TEST_DIR
  320 + os.name = "posix"
  321 + env.pop('IPYTHON_DIR', None)
  322 + env.pop('IPYTHONDIR', None)
  323 + env.pop('XDG_CONFIG_HOME', None)
  324 + cfgdir=os.path.join(path.get_home_dir(), '.config')
  325 + os.makedirs(cfgdir)
  326 +
  327 + nt.assert_equal(path.get_xdg_dir(), cfgdir)
242 328
243 329 def test_filefind():
244 330 """Various tests for filefind"""

0 comments on commit c1c2a71

Please sign in to comment.
Something went wrong with that request. Please try again.