diff --git a/IPython/utils/path.py b/IPython/utils/path.py index 96e96a2..5e224bb 100644 --- a/IPython/utils/path.py +++ b/IPython/utils/path.py @@ -170,21 +170,14 @@ class HomeDirError(Exception): def get_home_dir(): """Return the closest possible equivalent to a 'home' directory. - * On POSIX, we try $HOME. - * On Windows we try: - - %HOMESHARE% - - %HOMEDRIVE\%HOMEPATH% - - %USERPROFILE% - - Registry hack for My Documents - - %HOME%: rare, but some people with unix-like setups may have defined it - * On Dos C:\ - - Currently only Posix and NT are implemented, a HomeDirError exception is - raised for all other OSes. + * First, check for frozen env in case of py2exe + * Otherwise, defer to os.path.expanduser('~'), ensuring unicode + + See stdlib docs for how this is determined. + + $HOME is first priority on *ALL* platforms. """ - env = os.environ - # first, check py2exe distribution root directory for _ipython. # This overrides all. Normally does not exist. @@ -197,90 +190,12 @@ def get_home_dir(): if _writable_dir(os.path.join(root, '_ipython')): os.environ["IPYKITROOT"] = root return py3compat.cast_unicode(root, fs_encoding) - - if os.name == 'posix': - # Linux, Unix, AIX, OS X - try: - homedir = env['HOME'] - except KeyError: - # Last-ditch attempt at finding a suitable $HOME, on systems where - # it may not be defined in the environment but the system shell - # still knows it - reported once as: - # https://github.com/ipython/ipython/issues/154 - from subprocess import Popen, PIPE - homedir = Popen('echo $HOME', shell=True, - stdout=PIPE).communicate()[0].strip() - if homedir: - return py3compat.cast_unicode(homedir, fs_encoding) - else: - raise HomeDirError('Undefined $HOME, IPython cannot proceed.') - else: - return py3compat.cast_unicode(homedir, fs_encoding) - elif os.name == 'nt': - # Now for win9x, XP, Vista, 7? - # For some strange reason all of these return 'nt' for os.name. - # First look for a network home directory. This will return the UNC - # path (\\server\\Users\%username%) not the mapped path (Z:\). This - # is needed when running IPython on cluster where all paths have to - # be UNC. - try: - homedir = env['HOMESHARE'] - except KeyError: - pass - else: - if _writable_dir(homedir): - return py3compat.cast_unicode(homedir, fs_encoding) - - # Now look for a local home directory - try: - homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH']) - except KeyError: - pass - else: - if _writable_dir(homedir): - return py3compat.cast_unicode(homedir, fs_encoding) - - # Now the users profile directory - try: - homedir = os.path.join(env['USERPROFILE']) - except KeyError: - pass - else: - if _writable_dir(homedir): - return py3compat.cast_unicode(homedir, fs_encoding) - - # Use the registry to get the 'My Documents' folder. - try: - import _winreg as wreg - key = wreg.OpenKey( - wreg.HKEY_CURRENT_USER, - "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" - ) - homedir = wreg.QueryValueEx(key,'Personal')[0] - key.Close() - except: - pass - else: - if _writable_dir(homedir): - return py3compat.cast_unicode(homedir, fs_encoding) - - # A user with a lot of unix tools in win32 may have defined $HOME. - # Try this as a last ditch option. - try: - homedir = env['HOME'] - except KeyError: - pass - else: - if _writable_dir(homedir): - return py3compat.cast_unicode(homedir, fs_encoding) - - # If all else fails, raise HomeDirError - raise HomeDirError('No valid home directory could be found') - elif os.name == 'dos': - # Desperate, may do absurd things in classic MacOS. May work under DOS. - return u'C:\\' + + homedir = os.path.expanduser('~') + if _writable_dir(homedir): + return py3compat.cast_unicode(homedir, fs_encoding) else: - raise HomeDirError('No valid home directory could be found for your OS') + raise HomeDirError('%s not a writable dir, set $HOME env to override' % homedir) def get_xdg_dir(): """Return the XDG_CONFIG_HOME, if it is defined and exists, else None. diff --git a/IPython/utils/tests/test_path.py b/IPython/utils/tests/test_path.py index 9881bff..e9429d2 100644 --- a/IPython/utils/tests/test_path.py +++ b/IPython/utils/tests/test_path.py @@ -118,7 +118,6 @@ def teardown_environment(): # Build decorator that uses the setup_environment/setup_environment with_environment = with_setup(setup_environment, teardown_environment) - @skip_if_not_win32 @with_environment def test_get_home_dir_1(): @@ -147,96 +146,27 @@ def test_get_home_dir_2(): @with_environment -@skip_win32 def test_get_home_dir_3(): - """Testcase $HOME is set, then use its value as home directory.""" + """get_home_dir() uses $HOME if set""" env["HOME"] = HOME_TEST_DIR home_dir = path.get_home_dir() nt.assert_equal(home_dir, env["HOME"]) @with_environment -@skip_win32 def test_get_home_dir_4(): - """Testcase $HOME is not set, os=='posix'. - This should fail with HomeDirError""" + """get_home_dir() still works if $HOME is not set""" - os.name = 'posix' if 'HOME' in env: del env['HOME'] - nt.assert_raises(path.HomeDirError, path.get_home_dir) - + # this should still succeed, but we don't know what the answer should be + home = path.get_home_dir() + nt.assert_true(path._writable_dir(home)) -@skip_if_not_win32 @with_environment def test_get_home_dir_5(): - """Using HOMEDRIVE + HOMEPATH, os=='nt'. - - HOMESHARE is missing. - """ - - os.name = 'nt' - env.pop('HOMESHARE', None) - env['HOMEDRIVE'], env['HOMEPATH'] = os.path.splitdrive(HOME_TEST_DIR) - home_dir = path.get_home_dir() - nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) - - -@skip_if_not_win32 -@with_environment -def test_get_home_dir_6(): - """Using USERPROFILE, os=='nt'. - - HOMESHARE, HOMEDRIVE, HOMEPATH are missing. - """ - - os.name = 'nt' - env.pop('HOMESHARE', None) - env.pop('HOMEDRIVE', None) - env.pop('HOMEPATH', None) - env["USERPROFILE"] = abspath(HOME_TEST_DIR) - home_dir = path.get_home_dir() - nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) - - -@skip_if_not_win32 -@with_environment -def test_get_home_dir_7(): - """Using HOMESHARE, os=='nt'.""" - - os.name = 'nt' - env["HOMESHARE"] = abspath(HOME_TEST_DIR) - home_dir = path.get_home_dir() - nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) - - -# Should we stub wreg fully so we can run the test on all platforms? -@skip_if_not_win32 -@with_environment -def test_get_home_dir_8(): - """Using registry hack for 'My Documents', os=='nt' - - HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing. - """ - os.name = 'nt' - # Remove from stub environment all keys that may be set - for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']: - env.pop(key, None) - - #Stub windows registry functions - def OpenKey(x, y): - class key: - def Close(self): - pass - return key() - def QueryValueEx(x, y): - return [abspath(HOME_TEST_DIR)] - - wreg.OpenKey = OpenKey - wreg.QueryValueEx = QueryValueEx - - home_dir = path.get_home_dir() - nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) - + """raise HomeDirError if $HOME is specified, but not a writable dir""" + env['HOME'] = abspath(HOME_TEST_DIR+'garbage') + nt.assert_raises(path.HomeDirError, path.get_home_dir) @with_environment def test_get_ipython_dir_1():