diff --git a/IPython/core/magic.py b/IPython/core/magic.py index 7540e76..c797cad 100644 --- a/IPython/core/magic.py +++ b/IPython/core/magic.py @@ -593,7 +593,7 @@ Currently the magic system has the following functions:\n""" # if not, try the input as a filename if out == 'not found': try: - filename = get_py_filename(parameter_s) + filename = get_py_filename(parameter_s, sys.platform == 'win32') except IOError,msg: print msg return @@ -1369,7 +1369,7 @@ Currently the magic system has the following functions:\n""" namespace = self.shell.user_ns else: # called to run a program by %run -p try: - filename = get_py_filename(arg_lst[0]) + filename = get_py_filename(arg_lst[0], sys.platform == 'win32') except IOError,msg: error(msg) return @@ -1558,7 +1558,7 @@ Currently the magic system has the following functions:\n""" mode='list',list_all=1) try: - filename = file_finder(arg_lst[0]) + filename = file_finder(arg_lst[0], sys.platform == 'win32') except IndexError: warn('you must provide at least a filename.') print '\n%run:\n',oinspect.getdoc(self.magic_run) @@ -2128,7 +2128,7 @@ Currently the magic system has the following functions:\n""" def make_filename(arg): "Make a filename from the given args" try: - filename = get_py_filename(arg) + filename = get_py_filename(arg, win32=sys.platform == 'win32') except IOError: # If it ends with .py but doesn't already exist, assume we want # a new file. @@ -3148,7 +3148,7 @@ Defaulting color scheme to 'NoColor'""" to be Python source and will show it with syntax highlighting. """ try: - filename = get_py_filename(parameter_s) + filename = get_py_filename(parameter_s, sys.platform == 'win32') cont = file_read(filename) except IOError: try: diff --git a/IPython/testing/globalipapp.py b/IPython/testing/globalipapp.py index 4315da3..89b5f27 100644 --- a/IPython/testing/globalipapp.py +++ b/IPython/testing/globalipapp.py @@ -63,14 +63,14 @@ class py_file_finder(object): def __init__(self,test_filename): self.test_filename = test_filename - def __call__(self,name): + def __call__(self,name,win32=False): from IPython.utils.path import get_py_filename try: - return get_py_filename(name) + return get_py_filename(name,win32=win32) except IOError: test_dir = os.path.dirname(self.test_filename) new_path = os.path.join(test_dir,name) - return get_py_filename(new_path) + return get_py_filename(new_path,win32=win32) def _run_ns_sync(self,arg_s,runner=None): diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py index 3835d58..a611814 100644 --- a/IPython/testing/tools.py +++ b/IPython/testing/tools.py @@ -330,4 +330,16 @@ def mute_warn(): try: yield finally: - warn.warn = save_warn \ No newline at end of file + warn.warn = save_warn + +@contextmanager +def make_tempfile(name): + """ Create an empty, named, temporary file for the duration of the context. + """ + f = open(name, 'w') + f.close() + try: + yield + finally: + os.unlink(name) + diff --git a/IPython/utils/path.py b/IPython/utils/path.py index b1ee7ae..f91b12c 100644 --- a/IPython/utils/path.py +++ b/IPython/utils/path.py @@ -82,13 +82,20 @@ def get_long_path_name(path): return _get_long_path_name(path) -def get_py_filename(name): +def get_py_filename(name, win32=False): """Return a valid python filename in the current directory. If the given name is not a file, it adds '.py' and searches again. - Raises IOError with an informative message if the file isn't found.""" + Raises IOError with an informative message if the file isn't found. + + If the win32 argument is True, then apply Windows semantics to the filename. + In particular, remove any quoting that has been applied to it. + """ name = os.path.expanduser(name) + if win32: + if name.startswith(("'", '"')) and name.endswith(("'", '"')): + name = name[1:-1] if not os.path.isfile(name) and not name.endswith('.py'): name += '.py' if os.path.isfile(name): diff --git a/IPython/utils/tests/test_path.py b/IPython/utils/tests/test_path.py index b92c0a0..2e2a8e4 100644 --- a/IPython/utils/tests/test_path.py +++ b/IPython/utils/tests/test_path.py @@ -12,6 +12,8 @@ # Imports #----------------------------------------------------------------------------- +from __future__ import with_statement + import os import shutil import sys @@ -27,6 +29,7 @@ from nose import with_setup import IPython from IPython.testing import decorators as dec from IPython.testing.decorators import skip_if_not_win32, skip_win32 +from IPython.testing.tools import make_tempfile from IPython.utils import path, io # Platform-dependent imports @@ -83,7 +86,7 @@ def setup_environment(): each testfunction needs a pristine environment. """ global oldstuff, platformstuff - oldstuff = (env.copy(), os.name, path.get_home_dir, IPython.__file__) + oldstuff = (env.copy(), os.name, path.get_home_dir, IPython.__file__, os.getcwd()) if os.name == 'nt': platformstuff = (wreg.OpenKey, wreg.QueryValueEx,) @@ -92,7 +95,8 @@ def setup_environment(): def teardown_environment(): """Restore things that were remebered by the setup_environment function """ - (oldenv, os.name, path.get_home_dir, IPython.__file__,) = oldstuff + (oldenv, os.name, path.get_home_dir, IPython.__file__, old_wd) = oldstuff + os.chdir(old_wd) reload(path) for key in env.keys(): @@ -401,4 +405,26 @@ def test_not_writable_ipdir(): io.stderr = stderr nt.assert_true('WARNING' in pipe.getvalue()) env.pop('IPYTHON_DIR', None) - \ No newline at end of file + +@with_environment +def test_get_py_filename(): + os.chdir(TMP_TEST_DIR) + for win32 in (True, False): + with make_tempfile('foo.py'): + nt.assert_equals(path.get_py_filename('foo.py', win32=win32), 'foo.py') + nt.assert_equals(path.get_py_filename('foo', win32=win32), 'foo.py') + with make_tempfile('foo'): + nt.assert_equals(path.get_py_filename('foo', win32=win32), 'foo') + nt.assert_raises(IOError, path.get_py_filename, 'foo.py', win32=win32) + nt.assert_raises(IOError, path.get_py_filename, 'foo', win32=win32) + nt.assert_raises(IOError, path.get_py_filename, 'foo.py', win32=win32) + true_fn = 'foo with spaces.py' + with make_tempfile(true_fn): + nt.assert_equals(path.get_py_filename('foo with spaces', win32=win32), true_fn) + nt.assert_equals(path.get_py_filename('foo with spaces.py', win32=win32), true_fn) + if win32: + nt.assert_equals(path.get_py_filename('"foo with spaces.py"', win32=True), true_fn) + nt.assert_equals(path.get_py_filename("'foo with spaces.py'", win32=True), true_fn) + else: + nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"', win32=False) + nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'", win32=False)