Show More
@@ -552,10 +552,7 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
552 |
|
552 | |||
553 | def init_pushd_popd_magic(self): |
|
553 | def init_pushd_popd_magic(self): | |
554 | # for pushd/popd management |
|
554 | # for pushd/popd management | |
555 | try: |
|
555 | self.home_dir = get_home_dir() | |
556 | self.home_dir = get_home_dir() |
|
|||
557 | except HomeDirError, msg: |
|
|||
558 | fatal(msg) |
|
|||
559 |
|
556 | |||
560 | self.dir_stack = [] |
|
557 | self.dir_stack = [] | |
561 |
|
558 | |||
@@ -1751,12 +1748,10 b' class InteractiveShell(SingletonConfigurable, Magic):' | |||||
1751 | # Or if libedit is used, load editrc. |
|
1748 | # Or if libedit is used, load editrc. | |
1752 | inputrc_name = os.environ.get('INPUTRC') |
|
1749 | inputrc_name = os.environ.get('INPUTRC') | |
1753 | if inputrc_name is None: |
|
1750 | if inputrc_name is None: | |
1754 | home_dir = get_home_dir() |
|
1751 | inputrc_name = '.inputrc' | |
1755 |
if |
|
1752 | if readline.uses_libedit: | |
1756 |
inputrc_name = '.i |
|
1753 | inputrc_name = '.editrc' | |
1757 | if readline.uses_libedit: |
|
1754 | inputrc_name = os.path.join(self.home_dir, inputrc_name) | |
1758 | inputrc_name = '.editrc' |
|
|||
1759 | inputrc_name = os.path.join(home_dir, inputrc_name) |
|
|||
1760 | if os.path.isfile(inputrc_name): |
|
1755 | if os.path.isfile(inputrc_name): | |
1761 | try: |
|
1756 | try: | |
1762 | readline.read_init_file(inputrc_name) |
|
1757 | readline.read_init_file(inputrc_name) |
@@ -167,23 +167,25 b' class HomeDirError(Exception):' | |||||
167 | pass |
|
167 | pass | |
168 |
|
168 | |||
169 |
|
169 | |||
170 | def get_home_dir(): |
|
170 | def get_home_dir(require_writable=False): | |
171 | """Return the closest possible equivalent to a 'home' directory. |
|
171 | """Return the 'home' directory, as a unicode string. | |
172 |
|
||||
173 | * On POSIX, we try $HOME. |
|
|||
174 | * On Windows we try: |
|
|||
175 | - %HOMESHARE% |
|
|||
176 | - %HOMEDRIVE\%HOMEPATH% |
|
|||
177 | - %USERPROFILE% |
|
|||
178 | - Registry hack for My Documents |
|
|||
179 | - %HOME%: rare, but some people with unix-like setups may have defined it |
|
|||
180 | * On Dos C:\ |
|
|||
181 |
|
||||
182 | Currently only Posix and NT are implemented, a HomeDirError exception is |
|
|||
183 | raised for all other OSes. |
|
|||
184 | """ |
|
|||
185 |
|
|
172 | ||
186 | env = os.environ |
|
173 | * First, check for frozen env in case of py2exe | |
|
174 | * Otherwise, defer to os.path.expanduser('~') | |||
|
175 | ||||
|
176 | See stdlib docs for how this is determined. | |||
|
177 | $HOME is first priority on *ALL* platforms. | |||
|
178 | ||||
|
179 | Parameters | |||
|
180 | ---------- | |||
|
181 | ||||
|
182 | require_writable : bool [default: False] | |||
|
183 | if True: | |||
|
184 | guarantees the return value is a writable directory, otherwise | |||
|
185 | raises HomeDirError | |||
|
186 | if False: | |||
|
187 | The path is resolved, but it is not guaranteed to exist or be writable. | |||
|
188 | """ | |||
187 |
|
189 | |||
188 | # first, check py2exe distribution root directory for _ipython. |
|
190 | # first, check py2exe distribution root directory for _ipython. | |
189 | # This overrides all. Normally does not exist. |
|
191 | # This overrides all. Normally does not exist. | |
@@ -197,59 +199,11 b' def get_home_dir():' | |||||
197 | if _writable_dir(os.path.join(root, '_ipython')): |
|
199 | if _writable_dir(os.path.join(root, '_ipython')): | |
198 | os.environ["IPYKITROOT"] = root |
|
200 | os.environ["IPYKITROOT"] = root | |
199 | return py3compat.cast_unicode(root, fs_encoding) |
|
201 | return py3compat.cast_unicode(root, fs_encoding) | |
200 |
|
202 | |||
201 | if os.name == 'posix': |
|
203 | homedir = os.path.expanduser('~') | |
202 | # Linux, Unix, AIX, OS X |
|
204 | ||
203 | try: |
|
205 | if not _writable_dir(homedir) and os.name == 'nt': | |
204 | homedir = env['HOME'] |
|
206 | # expanduser failed, use the registry to get the 'My Documents' folder. | |
205 | except KeyError: |
|
|||
206 | # Last-ditch attempt at finding a suitable $HOME, on systems where |
|
|||
207 | # it may not be defined in the environment but the system shell |
|
|||
208 | # still knows it - reported once as: |
|
|||
209 | # https://github.com/ipython/ipython/issues/154 |
|
|||
210 | from subprocess import Popen, PIPE |
|
|||
211 | homedir = Popen('echo $HOME', shell=True, |
|
|||
212 | stdout=PIPE).communicate()[0].strip() |
|
|||
213 | if homedir: |
|
|||
214 | return py3compat.cast_unicode(homedir, fs_encoding) |
|
|||
215 | else: |
|
|||
216 | raise HomeDirError('Undefined $HOME, IPython cannot proceed.') |
|
|||
217 | else: |
|
|||
218 | return py3compat.cast_unicode(homedir, fs_encoding) |
|
|||
219 | elif os.name == 'nt': |
|
|||
220 | # Now for win9x, XP, Vista, 7? |
|
|||
221 | # For some strange reason all of these return 'nt' for os.name. |
|
|||
222 | # First look for a network home directory. This will return the UNC |
|
|||
223 | # path (\\server\\Users\%username%) not the mapped path (Z:\). This |
|
|||
224 | # is needed when running IPython on cluster where all paths have to |
|
|||
225 | # be UNC. |
|
|||
226 | try: |
|
|||
227 | homedir = env['HOMESHARE'] |
|
|||
228 | except KeyError: |
|
|||
229 | pass |
|
|||
230 | else: |
|
|||
231 | if _writable_dir(homedir): |
|
|||
232 | return py3compat.cast_unicode(homedir, fs_encoding) |
|
|||
233 |
|
||||
234 | # Now look for a local home directory |
|
|||
235 | try: |
|
|||
236 | homedir = os.path.join(env['HOMEDRIVE'],env['HOMEPATH']) |
|
|||
237 | except KeyError: |
|
|||
238 | pass |
|
|||
239 | else: |
|
|||
240 | if _writable_dir(homedir): |
|
|||
241 | return py3compat.cast_unicode(homedir, fs_encoding) |
|
|||
242 |
|
||||
243 | # Now the users profile directory |
|
|||
244 | try: |
|
|||
245 | homedir = os.path.join(env['USERPROFILE']) |
|
|||
246 | except KeyError: |
|
|||
247 | pass |
|
|||
248 | else: |
|
|||
249 | if _writable_dir(homedir): |
|
|||
250 | return py3compat.cast_unicode(homedir, fs_encoding) |
|
|||
251 |
|
||||
252 | # Use the registry to get the 'My Documents' folder. |
|
|||
253 | try: |
|
207 | try: | |
254 | import _winreg as wreg |
|
208 | import _winreg as wreg | |
255 | key = wreg.OpenKey( |
|
209 | key = wreg.OpenKey( | |
@@ -260,27 +214,12 b' def get_home_dir():' | |||||
260 | key.Close() |
|
214 | key.Close() | |
261 | except: |
|
215 | except: | |
262 | pass |
|
216 | pass | |
263 | else: |
|
217 | ||
264 |
|
|
218 | if (not require_writable) or _writable_dir(homedir): | |
265 |
|
|
219 | return py3compat.cast_unicode(homedir, fs_encoding) | |
266 |
|
||||
267 | # A user with a lot of unix tools in win32 may have defined $HOME. |
|
|||
268 | # Try this as a last ditch option. |
|
|||
269 | try: |
|
|||
270 | homedir = env['HOME'] |
|
|||
271 | except KeyError: |
|
|||
272 | pass |
|
|||
273 | else: |
|
|||
274 | if _writable_dir(homedir): |
|
|||
275 | return py3compat.cast_unicode(homedir, fs_encoding) |
|
|||
276 |
|
||||
277 | # If all else fails, raise HomeDirError |
|
|||
278 | raise HomeDirError('No valid home directory could be found') |
|
|||
279 | elif os.name == 'dos': |
|
|||
280 | # Desperate, may do absurd things in classic MacOS. May work under DOS. |
|
|||
281 | return u'C:\\' |
|
|||
282 | else: |
|
220 | else: | |
283 | raise HomeDirError('No valid home directory could be found for your OS') |
|
221 | raise HomeDirError('%s is not a writable dir, ' | |
|
222 | 'set $HOME environment variable to override' % homedir) | |||
284 |
|
223 | |||
285 | def get_xdg_dir(): |
|
224 | def get_xdg_dir(): | |
286 | """Return the XDG_CONFIG_HOME, if it is defined and exists, else None. |
|
225 | """Return the XDG_CONFIG_HOME, if it is defined and exists, else None. | |
@@ -292,7 +231,7 b' def get_xdg_dir():' | |||||
292 |
|
231 | |||
293 | if os.name == 'posix': |
|
232 | if os.name == 'posix': | |
294 | # Linux, Unix, AIX, OS X |
|
233 | # Linux, Unix, AIX, OS X | |
295 |
# use ~/.config if |
|
234 | # use ~/.config if empty OR not set | |
296 | xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config') |
|
235 | xdg = env.get("XDG_CONFIG_HOME", None) or os.path.join(get_home_dir(), '.config') | |
297 | if xdg and _writable_dir(xdg): |
|
236 | if xdg and _writable_dir(xdg): | |
298 | return py3compat.cast_unicode(xdg, fs_encoding) |
|
237 | return py3compat.cast_unicode(xdg, fs_encoding) | |
@@ -316,6 +255,7 b' def get_ipython_dir():' | |||||
316 |
|
255 | |||
317 | home_dir = get_home_dir() |
|
256 | home_dir = get_home_dir() | |
318 | xdg_dir = get_xdg_dir() |
|
257 | xdg_dir = get_xdg_dir() | |
|
258 | ||||
319 | # import pdb; pdb.set_trace() # dbg |
|
259 | # import pdb; pdb.set_trace() # dbg | |
320 | ipdir = env.get('IPYTHON_DIR', env.get('IPYTHONDIR', None)) |
|
260 | ipdir = env.get('IPYTHON_DIR', env.get('IPYTHONDIR', None)) | |
321 | if ipdir is None: |
|
261 | if ipdir is None: |
@@ -118,7 +118,6 b' def teardown_environment():' | |||||
118 | # Build decorator that uses the setup_environment/setup_environment |
|
118 | # Build decorator that uses the setup_environment/setup_environment | |
119 | with_environment = with_setup(setup_environment, teardown_environment) |
|
119 | with_environment = with_setup(setup_environment, teardown_environment) | |
120 |
|
120 | |||
121 |
|
||||
122 | @skip_if_not_win32 |
|
121 | @skip_if_not_win32 | |
123 | @with_environment |
|
122 | @with_environment | |
124 | def test_get_home_dir_1(): |
|
123 | def test_get_home_dir_1(): | |
@@ -142,71 +141,34 b' def test_get_home_dir_2():' | |||||
142 | #fake filename for IPython.__init__ |
|
141 | #fake filename for IPython.__init__ | |
143 | IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower() |
|
142 | IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower() | |
144 |
|
143 | |||
145 | home_dir = path.get_home_dir() |
|
144 | home_dir = path.get_home_dir(True) | |
146 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower()) |
|
145 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR).lower()) | |
147 |
|
146 | |||
148 |
|
147 | |||
149 | @with_environment |
|
148 | @with_environment | |
150 | @skip_win32 |
|
|||
151 | def test_get_home_dir_3(): |
|
149 | def test_get_home_dir_3(): | |
152 | """Testcase $HOME is set, then use its value as home directory.""" |
|
150 | """get_home_dir() uses $HOME if set""" | |
153 | env["HOME"] = HOME_TEST_DIR |
|
151 | env["HOME"] = HOME_TEST_DIR | |
154 | home_dir = path.get_home_dir() |
|
152 | home_dir = path.get_home_dir(True) | |
155 | nt.assert_equal(home_dir, env["HOME"]) |
|
153 | nt.assert_equal(home_dir, env["HOME"]) | |
156 |
|
154 | |||
157 |
|
155 | |||
158 | @with_environment |
|
156 | @with_environment | |
159 | @skip_win32 |
|
|||
160 | def test_get_home_dir_4(): |
|
157 | def test_get_home_dir_4(): | |
161 | """Testcase $HOME is not set, os=='posix'. |
|
158 | """get_home_dir() still works if $HOME is not set""" | |
162 | This should fail with HomeDirError""" |
|
|||
163 |
|
159 | |||
164 | os.name = 'posix' |
|
|||
165 | if 'HOME' in env: del env['HOME'] |
|
160 | if 'HOME' in env: del env['HOME'] | |
166 | nt.assert_raises(path.HomeDirError, path.get_home_dir) |
|
161 | # this should still succeed, but we don't know what the answer should be | |
|
162 | home = path.get_home_dir(True) | |||
|
163 | nt.assert_true(path._writable_dir(home)) | |||
167 |
|
164 | |||
168 |
|
||||
169 | @skip_if_not_win32 |
|
|||
170 | @with_environment |
|
165 | @with_environment | |
171 | def test_get_home_dir_5(): |
|
166 | def test_get_home_dir_5(): | |
172 | """Using HOMEDRIVE + HOMEPATH, os=='nt'. |
|
167 | """raise HomeDirError if $HOME is specified, but not a writable dir""" | |
173 |
|
168 | env['HOME'] = abspath(HOME_TEST_DIR+'garbage') | ||
174 | HOMESHARE is missing. |
|
169 | # set os.name = posix, to prevent My Documents fallback on Windows | |
175 | """ |
|
170 | os.name = 'posix' | |
176 |
|
171 | nt.assert_raises(path.HomeDirError, path.get_home_dir, True) | ||
177 | os.name = 'nt' |
|
|||
178 | env.pop('HOMESHARE', None) |
|
|||
179 | env['HOMEDRIVE'], env['HOMEPATH'] = os.path.splitdrive(HOME_TEST_DIR) |
|
|||
180 | home_dir = path.get_home_dir() |
|
|||
181 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) |
|
|||
182 |
|
||||
183 |
|
||||
184 | @skip_if_not_win32 |
|
|||
185 | @with_environment |
|
|||
186 | def test_get_home_dir_6(): |
|
|||
187 | """Using USERPROFILE, os=='nt'. |
|
|||
188 |
|
||||
189 | HOMESHARE, HOMEDRIVE, HOMEPATH are missing. |
|
|||
190 | """ |
|
|||
191 |
|
||||
192 | os.name = 'nt' |
|
|||
193 | env.pop('HOMESHARE', None) |
|
|||
194 | env.pop('HOMEDRIVE', None) |
|
|||
195 | env.pop('HOMEPATH', None) |
|
|||
196 | env["USERPROFILE"] = abspath(HOME_TEST_DIR) |
|
|||
197 | home_dir = path.get_home_dir() |
|
|||
198 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) |
|
|||
199 |
|
||||
200 |
|
||||
201 | @skip_if_not_win32 |
|
|||
202 | @with_environment |
|
|||
203 | def test_get_home_dir_7(): |
|
|||
204 | """Using HOMESHARE, os=='nt'.""" |
|
|||
205 |
|
||||
206 | os.name = 'nt' |
|
|||
207 | env["HOMESHARE"] = abspath(HOME_TEST_DIR) |
|
|||
208 | home_dir = path.get_home_dir() |
|
|||
209 | nt.assert_equal(home_dir, abspath(HOME_TEST_DIR)) |
|
|||
210 |
|
172 | |||
211 |
|
173 | |||
212 | # Should we stub wreg fully so we can run the test on all platforms? |
|
174 | # Should we stub wreg fully so we can run the test on all platforms? |
General Comments 0
You need to be logged in to leave comments.
Login now