Skip to content

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

Closed
jb2170 wants to merge 11 commits intopython:mainfrom
jb2170:fix-issue-119670
Closed

gh-119670: Add 'always' keyword argument to shlex.quote#119674
jb2170 wants to merge 11 commits intopython:mainfrom
jb2170:fix-issue-119670

Conversation

@jb2170
Copy link
Copy Markdown
Contributor

@jb2170 jb2170 commented May 28, 2024

Copy link
Copy Markdown
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.

Comment thread Doc/library/shlex.rst Outdated
Comment thread Lib/shlex.py Outdated
Comment thread Doc/library/shlex.rst Outdated
Comment thread Doc/library/shlex.rst Outdated
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
Copy Markdown
Contributor Author

jb2170 commented Jun 3, 2024

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

Comment thread Lib/test/test_shlex.py Outdated
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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 thread Doc/whatsnew/3.14.rst Outdated
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
Copy Markdown
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 thread Doc/library/shlex.rst Outdated
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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... 👀 😃

@vstinner
Copy link
Copy Markdown
Member

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

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Aug 22, 2025

Could you:

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

@vstinner
Copy link
Copy Markdown
Member

vstinner commented Sep 1, 2025

It seems like @jb2170 is inactive for one year. Sadly, I suggest closing the PR and the related issue.

@jb2170
Copy link
Copy Markdown
Contributor Author

jb2170 commented Sep 1, 2025

I'm still here, I'll give it a second look 😅

@vstinner
Copy link
Copy Markdown
Member

vstinner commented Sep 8, 2025

Ping @jb2170.

@github-actions
Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Apr 16, 2026
@jb2170 jb2170 closed this Apr 20, 2026
@jb2170 jb2170 deleted the fix-issue-119670 branch April 20, 2026 22:45
@jb2170 jb2170 restored the fix-issue-119670 branch April 20, 2026 22:45
@jb2170 jb2170 deleted the fix-issue-119670 branch April 20, 2026 22:49
@jb2170
Copy link
Copy Markdown
Contributor Author

jb2170 commented Apr 20, 2026

I'll do a fresh rebase / branch / PR since this PR is very much behind main. Sorry for abandoning it a while!

It's coming along on my branch shlex-quote-force. I suggest force to be an opt-in keyword-only argument for shlex.quote. 🙂

I want to talk about this behavior of shlex.quote too as it caught my attention when I was editing the function. I think the returning of "''" for falsey non-str data isn't right. I've put some commits on another branch shlex-quote-typeerror. I'll have a sleep on it. Discussion thread open here

I'll check my work and open a PR for shlex-quote-force later today.

@jb2170
Copy link
Copy Markdown
Contributor Author

jb2170 commented Apr 21, 2026

Superseded by #148846

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

Labels

awaiting merge stale Stale PR or inactive for long period of time.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants