Skip to content

%edit editorhook fails if path has spaces #14961

Description

@leewz

Notepad++ editorhook doesn't work for %edit if you try to edit an object from a file whose path has spaces.


Diagnosis

The %edit magic single-quotes the path if it has spaces, before passing to the editor hook:

if " " in quoted:
quoted = "'%s'" % quoted
self.shell.hooks.editor(quoted, lineno)

Then the default editor hook expects a safe filename, and joins it into a string to use in a Popen call:

proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
shell=True)

(Notice that it DOES quote the editor path, conditionally, so that is an inconsistency in how it treats the two paths:
# Enclose in quotes if necessary and legal
if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
editor = '"%s"' % editor
)

However, the editor hooker makes an editor hook which expects the filename to be an unescaped string, and then uses shlex.quote to substitute it into a template and do the call:

cmd = template.format(filename=shlex.quote(filename), line=line)


Solution

In my opinion, the responsibility of escaping should be moved down to the callee, because taking a quoted filepath is weird.

This will break people's custom hooks which correct for this bug.

  • But there is already a test which calls a custom editor hook with unquoted spaces:
    get_ipython().hooks.editor("the file", 64)
  • And _edit_macro also calls the editor hook without quoting:
    filename = self.shell.mktempfile(macro.value)
    self.shell.hooks.editor(filename)

    I suspect that breaks if the temp folder is on a path with spaces.

The escaping is also not the best because it doesn't check for existing special characters. It should just use a safer call, if available.

Also, there should be more consistency between how the default and the custom process calls are done.


Also, %edit takes the absolute path, which might lengthen error messages unnecessarily.

quoted = filename = str(filepath.absolute())

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions