Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libcxx] [test] Quote the python executable in the executor #68208

Merged
merged 3 commits into from
Oct 9, 2023

Conversation

mstorsjo
Copy link
Member

@mstorsjo mstorsjo commented Oct 4, 2023

This reapplies the change from
c218c80, which was lost in the refactoring in 78d649a.

On Windows, the Python interpreter is by default installed in a path like "C:\Program Files\Python38\python.exe", which requires quoting when included in a concatenated command string (as opposed to a command list, where each argument is a separate element).

This doesn't show up in the CI environments as they use Python installed in a different directory, like C:\Python.

@mstorsjo mstorsjo added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Oct 4, 2023
@mstorsjo mstorsjo requested a review from arichardson October 4, 2023 11:31
@mstorsjo mstorsjo requested a review from a team as a code owner October 4, 2023 11:31
@llvmbot
Copy link
Member

llvmbot commented Oct 4, 2023

@llvm/pr-subscribers-libcxx

Changes

This reapplies the change from
c218c80, which was lost in the refactoring in 78d649a.

On Windows, the Python interpreter is by default installed in a path like "C:\Program Files\Python38\python.exe", which requires quoting when included in a concatenated command string (as opposed to a command list, where each argument is a separate element).

This doesn't show up in the CI environments as they use Python installed in a different directory, like C:\Python.


Full diff: https://github.com/llvm/llvm-project/pull/68208.diff

1 Files Affected:

  • (modified) libcxx/utils/libcxx/test/params.py (+1-1)
diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py
index d4e4b722347d623..16dcc837108c550 100644
--- a/libcxx/utils/libcxx/test/params.py
+++ b/libcxx/utils/libcxx/test/params.py
@@ -320,7 +320,7 @@ def getStdFlag(cfg, std):
     Parameter(
         name="executor",
         type=str,
-        default=f"{sys.executable} {Path(__file__).resolve().parent.parent.parent / 'run.py'}",
+        default=f"\"{sys.executable}\" {Path(__file__).resolve().parent.parent.parent / 'run.py'}",
         help="Custom executor to use instead of the configured default.",
         actions=lambda executor: [AddSubstitution("%{executor}", executor)],
     )

Copy link
Member

@arichardson arichardson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the run script path also be quoted?

@@ -320,7 +320,7 @@ def getStdFlag(cfg, std):
Parameter(
name="executor",
type=str,
default=f"{sys.executable} {Path(__file__).resolve().parent.parent.parent / 'run.py'}",
default=f"\"{sys.executable}\" {Path(__file__).resolve().parent.parent.parent / 'run.py'}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also use shutil.quote(sys.executable) to avoid unnecessary quoting?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that’d probably work too - I’ll try that out.

@mstorsjo
Copy link
Member Author

mstorsjo commented Oct 4, 2023

Should the run script path also be quoted?

I guess it could; I guess most people would avoid checking out the source in such a path with spaces, but the default install location of Python usually is in a place with spaces. I’ll try adding that as well.

@mstorsjo
Copy link
Member Author

mstorsjo commented Oct 5, 2023

I updated the branch so that it uses a proper quote function, and quote both the script and the python executable. The proper python cross platform quoting for shell commands is subprocess.list2cmdline, somewhat non-obviously.

@@ -320,7 +325,7 @@ def getStdFlag(cfg, std):
Parameter(
name="executor",
type=str,
default=f"\"{sys.executable}\" {Path(__file__).resolve().parent.parent.parent / 'run.py'}",
default=f"{quote(sys.executable)} {quote(str(Path(__file__).resolve().parent.parent.parent / 'run.py'))}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
default=f"{quote(sys.executable)} {quote(str(Path(__file__).resolve().parent.parent.parent / 'run.py'))}",
default=default=subprocess.list2cmdline(sys.executable,str(Path(file).resolve().parent.parent.parent / 'run.py')),

Wouldn't this be easier?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, indeed it would! (There’s duplicate default= in there though.) I’ll give it a shot later tonight.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm actually it looks like list2cmdline is a private implementation detail: https://github.com/python/cpython/blob/6e97a9647ae028facb392d12fc24973503693bd6/Lib/subprocess.py#L66 so should probably use shlex.quote() instead.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, good catch. I saw some discussions about whether this function should be made public (as they can't practically change it anyway, since lots of people seem to use it) - but for now I guess it'd be best to not use it.

If we're not using that one, I'm on the fence about whether we should go for shlex.quote(), always wrapping double quotes (like we did in cmake before), or maybe a custom function that wraps quotes around it if there are spaces in the string. shlex.quote() isn't generally a great fit, as it is documented to not be cross platform - it specifically does quoting for unix paths/shells. For Windows paths, it always quotes them as they contain backslashes. (Always quoting them isn't an issue in itself per se, though. And the fact that shlex.quote() uses single quotes instead of double quotes, is ok as long as we're using the lit internal shell instead of an actual Windows shell.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to shlex.quote now. Not ideal for Windows paths, but should work as long as we're using the lit internal shell.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. It might be cleaner to use shlex.quote but either way makes sense to me.

This reapplies the change from
c218c80, which was lost in the
refactoring in 78d649a.

On Windows, the Python interpreter is by default installed in
a path like "C:\Program Files\Python38\python.exe", which requires
quoting when included in a concatenated command string (as opposed
to a command list, where each argument is a separate element).

This doesn't show up in the CI environments as they use Python
installed in a different directory, like C:\Python.
Don't use shlex.quote(), that's documented to only be relevant
for Unix (and it uses single quotes which aren't normally
tolerated by windows shells - even if the lit internal shell
does handle them). Additionally, shlex.quote() always quotes
paths that include backslashes, even if those don't need quoting
on Windows.
This isn't ideal on Windows, but subprocess.list2cmdline is
private.

As long as we're using the lit internal shell, the shlex quoting
should work fine.
@mstorsjo mstorsjo force-pushed the libcxx-quote-executor branch from 2c087a9 to 8bae7f4 Compare October 9, 2023 11:26
@mstorsjo mstorsjo merged commit 5e3f43e into llvm:main Oct 9, 2023
@mstorsjo mstorsjo deleted the libcxx-quote-executor branch October 9, 2023 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants