Skip to content

gh-119670: Add 'always' keyword argument to shlex.quote #119674

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

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

jb2170
Copy link
Contributor

@jb2170 jb2170 commented May 28, 2024

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

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

Thanks for your interesting change.

Please add tests to Lib/test/test_shlex.py. Also, you can copy the NEWS entry in Doc/whatsnew/3.14.rst, in a new "shlex" sub-section of Improved Modules.

jb2170 added 5 commits June 3, 2024 23:15
The first assertTrue test checks all strings now start with a single quote, ie they have actually been escaped

The second test of assertFalse checks that not all the strings have been escaped when always=False (the default value), since the first, third, and fifth string do not need escaping unless requested.
@jb2170
Copy link
Contributor Author

jb2170 commented Jun 3, 2024

Tests added in b8ef5ce, and whatsnew entry added in bf7dce0 😄

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

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

Personally, I'd prefer "force" rather than "always" but that's bike-shedding (using "force" is more common when you want to force a behaviour I think).

Comment on lines 1 to 2
:func:`shlex.quote` now has an *always* keyword argument for forcing
the escaping of the string passed to it
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
:func:`shlex.quote` now has an *always* keyword argument for forcing
the escaping of the string passed to it
Allow :func:`shlex.quote` to unconditionally escape its input
via the keyword-only argument *always*.

Comment on lines 189 to 190
* Add keyword-only argument of *always* to :func:`shlex.quote` for forcing
the escaping of the string passed to it.
Copy link
Member

Choose a reason for hiding this comment

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

* Allow :func:`shlex.quote` to unconditionally escape its input
  via ``shlex.quote(string, always=True)``.

  (Contributed by YOUR_NAME_OR_GITHUB_NICKNAME in :gh:`119670`.)

Comment on lines 58 to 60
If the *always* keyword argument is set to ``True`` then the string *s*
will always be escaped, even in the absence of special characters. This is
nice for uniformity, for example when escaping a list of strings.
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
If the *always* keyword argument is set to ``True`` then the string *s*
will always be escaped, even in the absence of special characters. This is
nice for uniformity, for example when escaping a list of strings.
If *always* is ``True``, then the string *s* is
unconditionally escaped, even in the absence of
special characters. This is typically useful for
uniformly escaping a list of strings:

@vstinner
Copy link
Member

vstinner commented Sep 9, 2024

Personally, I'd prefer "force" rather than "always"

Oh, I also like force=True. What do you think @jb2170?

@jb2170
Copy link
Contributor Author

jb2170 commented Sep 10, 2024

@picnixz

Personally, I'd prefer "force" rather than "always" but that's bike-shedding (using "force" is more common when you want to force a behaviour I think).

I could be swayed; force seems like a conventional word within the programming world, eg 'rm -rf'. But that is then superseded by the following:

@vstinner

Oh, I also like force=True. What do you think @jb2170?

Changing the behaviour to always quote its input would be ideal in my eyes! It requires tweaking a couple of the tests in Lib/test/test_shlex.py but I will commit those.

At this point however I question "who would ever want quote(s, force=False)?". We could get rid of the force kwarg, returning to the function's existing mono-parameter signature, and reduce the function body down to just

def quote(s):
    return "'" + s.replace("'", "'\"'\"'") + "'"

This simplifies quote to the one-liner that it should be, and it does-what-it-says-on-the-tin. Oh and the re import can be removed, since that's the only place it's used! 😄

Perhaps my main issue is that quote doesn't always quote, its behaviour quite unpredictable from the function name alone, relying on a footgun regex.

If we were to go ahead with this simplification the only question is "is there anyone out there relying on basic strings not being quoted by quote?". I would guess no-one would care, paraphrasing the discussion on PEP 475's backwards compatibility "The authors of this (PEP) don’t think that such applications exist"

I'll push a commit, see what you think... 👀 😃

@jb2170
Copy link
Contributor Author

jb2170 commented Sep 10, 2024

(docs test failed but no new documentation needed)

@vstinner
Copy link
Member

I only asked about the parameter name force instead of always, not to enable it by default, sorry.

@picnixz
Copy link
Member

picnixz commented Aug 22, 2025

Could you:

  • resolve the conflicts?
  • revert the unconditional quoting but use force instead of always?

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

Successfully merging this pull request may close these issues.

3 participants