homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add shlex.quote
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.3
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: eric.araujo Nosy List: anacrolix, brandon-rhodes, eric.araujo, eric.smith, ezio.melotti, georg.brandl, python-dev, r.david.murray, vstinner, xuanji
Priority: normal Keywords: patch

Created on 2010年08月31日 13:40 by brandon-rhodes, last changed 2022年04月11日 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
shlex.quote.diff eric.araujo, 2011年07月18日 16:22 review
Messages (32)
msg115263 - (view) Author: Brandon Rhodes (brandon-rhodes) * Date: 2010年08月31日 13:40
The only way to safely build shell command lines from inside of Python — which is necessary when sending commands across SSH, since that behaves like os.system() rather than like subprocess.call() — is to use the wonderful pipes.call() method to turn possibly-dangerous arguments, like filenames that might have spaces, special characters, and embedded "rm -r" calls, into perfectly quoted strings for an "sh"-like shell (say, bash or zsh).
This call is already recommended on mailing lists, blog posts, and Stack Overflow — and since it doesn't start with a "_", I think its public use is fair game. But the "pipes" documentation itself doesn't officially mention or support it. I think it should be added to the Standard Library documentation for "pipes". So. Yeah.
msg115270 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2010年08月31日 17:38
I think you mean pipe.quote in your message, not pipe.call. The subject looks correct.
I'm not sure pipes is the best place for this, but I agree it should probably be documented in older versions. It seems to me we've had this discussion before about quoting command lines, how it applies differently between Windows and various shells, and which functions to expose. But having said that, I can't find a previous issue that discusses it.
Not the least of my concerns is that pipes says it's available on Unix systems, despite the fact that I have it on a Windows machine. And I might need the functionality of passing a bash command from a Windows machine to a Unix machine, so we definitely need this cross platform.
msg115463 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2010年09月03日 16:33
Eric referred to this thread: http://mail.python.org/pipermail/stdlib-sig/2010-May/thread.html 
msg126674 - (view) Author: Matt Joiner (anacrolix) Date: 2011年01月21日 01:32
I agree, I discovered this function (pipes.quote) only through recommendation here:
http://stackoverflow.com/questions/4748344/whats-the-reverse-of-shlex-split
I suggest that it be added to shlex, perhaps as shlex.quote. While the quoting style it performs, and the module it's found in are specific to Unix tools, the shlex module is available on non-Unix platforms. To this end, adding the function to shlex would make it available elsewhere, as well as be appropriately shell-related.
msg126768 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年01月21日 18:51
Why do you want to move quote from pipes to shlex? The function is available, the issue here is lack of documentation.
msg126830 - (view) Author: Matt Joiner (anacrolix) Date: 2011年01月22日 11:01
Two reasons: The pipes module is Unix only, but pipes.quote is useful on all platforms. Secondly pipes.quote pertains to shell command-lines, this is also the domain of shlex which already cross platform. In pipes, an import shlex.quote would more than sufficient.
If this belongs in another separate bug I shall submit one. Please advise.
msg126850 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年01月22日 18:42
Even if quote does not start with an underscore, its absence from the docs and from the module’s __all__ make it a private function.
I propose to make it public as shlex.quote in 3.3 and deprecate pipes.quote for people that relied on it (i.e. move code from pipes/test_pipes to shlex/test_shlex, add doc, write a pipes.quote function that sends a DeprecationWarning and calls shlex.quote).
msg126863 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011年01月22日 23:03
Rather than doing a code deprecation you can just do 'from shlex import quote' in pipes (with a comment about backward compatibility). I don't think there is any real harm in leaving that kind of backward compatibility in place indefinitely.
msg126936 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年01月24日 17:19
> you can just do 'from shlex import quote' in pipes
We would have had to do that anyway, since pipes needs to use the function. Agreed that a deprecation is not necessary.
msg126939 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011年01月24日 18:03
Yes, I know you have to do it anyway, that's why I used the adverb 'just' (as in 'just that, and nothing more') (I note that 'just' as an adverb tends to get overused by English speakers, and so loses some of its semantic value... :)
msg126950 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2011年01月24日 19:55
Putting quote() into shlex sounds good to me.
msg127957 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年02月05日 00:57
A note from Ian Bicking in http://mail.python.org/pipermail/stdlib-sig/2010-May/000948.html:
> I've had to do this sort of thing for similar reasons, like calling remote
> ssh commands, where a shell command is embedded in a positional argument. I
> implemented my own thing, but the way pipes.quote works would have been
> nicer (the implementation could use a couple regexes instead of iterating
> over strings though).
msg134638 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年04月28日 03:04
Someone on Stack Overflow suggested subprocess.list2cmdline. It’s one of those functions undocumented and absent from __all__ that somehow get found and used by some people. So when we make the patch, let’s include links to the new function doc from subprocess and pipes, and reply to the Stack Overflow thread.
msg134834 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2011年04月30日 02:54
See also #11827 about subprocess.list2cmdline.
msg140601 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年07月18日 16:22
Here’s the patch, please review.
msg141350 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011年07月29日 12:35
New changeset 5966eeb0457d by Éric Araujo in branch 'default':
Add shlex.quote function, to escape filenames and command lines (#9723).
http://hg.python.org/cpython/rev/5966eeb0457d 
msg141368 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011年07月29日 13:10
New changeset 43c41e19527a by Éric Araujo in branch 'default':
Expand shlex.quote example (#9723)
http://hg.python.org/cpython/rev/43c41e19527a 
msg141374 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年07月29日 13:35
I suck at regexes, but the one I came up with lets quote pass the tests that existed for pipes.quote, so I figure it’s good. I did not change the string operations at the end of the function (+ and replace) as it was simple and working.
In the absence of review or opposition here, I have committed my patch. Feedback welcome.
msg141379 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011年07月29日 13:47
Sorry I didn't look at the patch earlier. I thought we were just *moving* pipes.quote. Why is a new regex involved?
msg141380 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年07月29日 13:51
Because I choose to follow Ian’s remark in msg127957:
> the implementation could use a couple regexes instead of iterating
> over strings though
I have not touched the tests, so I felt confident with my regex. FWIW, I’ve also changed the argument name, since the function is not limited to file names (as I hopefully made clear in the doc).
msg141383 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011年07月29日 14:44
Well, it's a micro-optimization (it would be interesting to benchmark, but not worth it). I find the original code much more readable than the regex, but it doesn't matter all that much. (And as far as optimization goes, using translate might be even faster.)
msg141386 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年07月29日 15:11
str.translate is not an option, as the code does not replace but add characters (quotes).
Out of sheer curiosity, I may actually benchmark this.
msg141387 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011年07月29日 15:20
You aren't using a regex to replace the quotes, either.
>>> len('abcd'.translate(str.maketrans('', '', string.ascii_letters ))) > 0
False
I don't know if this is faster than the corresponding search regex, but depending on how much overhead regex has, it might be. Note that the translate table can be pre-built, just like the compiled regex.
msg141430 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2011年07月30日 07:20
+_find_unsafe = re.compile(r'[^\w\d@%_\-\+=:,\./]').search
\w already includes both \d and _, so (unless you really want to be explicit about it) they are redundant. Also keep in mind that they match non-ASCII letters/numbers on Python 3.
'+' and '.' don't need to be escaped in a character class (i.e. [...]), because they lose their meta-characters meaning there.
'-' is correctly escaped there, but it's common practice to place it at the end of the character class, where it doesn't need escaping.
r'[^\w\d@%_\-\+=:,\./]' and r'[^\w@%+=:,./-]' should therefore be equivalent.
msg141439 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年07月30日 13:16
> \w already includes both \d and _, so (unless you really want to be
> explicit about it) they are redundant. [snip]
I just started from the previous list and turned it into a regex. Eliminating redundancy sounds good, I’ll use your version.
> Also keep in mind that they match non-ASCII letters/numbers on
> Python 3.
This was not covered by the previous tests, but I think it’s fine: the shell is concerned about some metacharacters and spaces, not Unicode letters. To be 100% sure, I will add tests with Unicode characters for pipes.quote in 3.2, and when merging with 3.3 I’ll know if the new code still complies.
msg141963 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011年08月12日 16:03
New changeset 8032ea4c3619 by Éric Araujo in branch '3.2':
Test pipes.quote with a few non-ASCII characters (see #9723).
http://hg.python.org/cpython/rev/8032ea4c3619
New changeset 6ae0345a7e29 by Éric Araujo in branch 'default':
Avoid unwanted behavior change in shlex.quote (see #9723).
http://hg.python.org/cpython/rev/6ae0345a7e29 
msg141964 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年08月12日 16:05
I have restored compatibility (see commit messages).
msg141997 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2011年08月12日 23:21
-_find_unsafe = re.compile(r'[^\w\d@%_\-\+=:,\./]').search
+_find_unsafe = re.compile(r'[^\w@%\-\+=:,\./]', re.ASCII).search
FWIW there are still unnecessary escapes before '+' and '.', and possibly '-' ('-' doesn't need escaping only when it's at the end (or beginning) of the regex).
msg142006 - (view) Author: Matt Joiner (anacrolix) Date: 2011年08月13日 03:00
Why can't pipes.quote can't be moved to shlex.quote verbatim as I originally proposed?
Is there justification to also change it as part of the relocation? I think any changes to its behaviour should be a separate issue.
msg142203 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011年08月16日 15:54
> FWIW there are still unnecessary escapes before '+' and '.', and
> possibly '-'
This is IMO cosmetic and not as "important" as the duplicate characters already implied by the character class. Feel free to change it.
> Why can't pipes.quote can't be moved to shlex.quote verbatim as I
> originally proposed?
I took the opportunity of changing some convoluted code.
msg142204 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011年08月16日 16:03
New changeset 5d4438001069 by Ezio Melotti in branch 'default':
#9723: refactor regex.
http://hg.python.org/cpython/rev/5d4438001069 
msg158642 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2012年04月18日 17:13
See #14616 for a doc edition related to this.
History
Date User Action Args
2022年04月11日 14:57:05adminsetgithub: 53932
2012年04月18日 17:13:06eric.araujosetmessages: + msg158642
2011年08月16日 16:03:54python-devsetmessages: + msg142204
2011年08月16日 15:54:15eric.araujosetmessages: + msg142203
2011年08月13日 03:00:36anacrolixsetmessages: + msg142006
2011年08月12日 23:21:01ezio.melottisetmessages: + msg141997
2011年08月12日 16:05:02eric.araujosetstatus: open -> closed

messages: + msg141964
stage: test needed -> resolved
2011年08月12日 16:03:54python-devsetmessages: + msg141963
2011年07月30日 13:16:21eric.araujosetstatus: closed -> open

messages: + msg141439
stage: resolved -> test needed
2011年07月30日 07:20:17ezio.melottisetmessages: + msg141430
2011年07月29日 15:20:13r.david.murraysetmessages: + msg141387
2011年07月29日 15:11:49eric.araujosetmessages: + msg141386
2011年07月29日 14:44:25r.david.murraysetmessages: + msg141383
2011年07月29日 13:51:58eric.araujosetmessages: + msg141380
2011年07月29日 13:47:49r.david.murraysetmessages: + msg141379
2011年07月29日 13:35:57eric.araujosetstatus: open -> closed
resolution: fixed
messages: + msg141374

stage: patch review -> resolved
2011年07月29日 13:10:19python-devsetmessages: + msg141368
2011年07月29日 12:35:19python-devsetnosy: + python-dev
messages: + msg141350
2011年07月18日 16:22:15eric.araujosetfiles: + shlex.quote.diff
messages: + msg140601

assignee: eric.araujo
keywords: + patch
stage: needs patch -> patch review
2011年04月30日 02:54:16ezio.melottisetnosy: + ezio.melotti
messages: + msg134834
2011年04月28日 03:04:02eric.araujosetmessages: + msg134638
2011年04月27日 15:30:17xuanjisetnosy: + xuanji
2011年03月03日 14:36:10vstinnersetnosy: + vstinner
2011年02月05日 00:57:18eric.araujosetnosy: georg.brandl, eric.smith, eric.araujo, r.david.murray, brandon-rhodes, anacrolix
messages: + msg127957
2011年01月24日 19:55:14georg.brandlsetnosy: + georg.brandl
messages: + msg126950
2011年01月24日 18:03:53r.david.murraysetnosy: eric.smith, eric.araujo, r.david.murray, brandon-rhodes, anacrolix
messages: + msg126939
2011年01月24日 17:19:16eric.araujosetnosy: eric.smith, eric.araujo, r.david.murray, brandon-rhodes, anacrolix
messages: + msg126936
2011年01月22日 23:03:20r.david.murraysetnosy: + r.david.murray
messages: + msg126863
2011年01月22日 18:42:03eric.araujosetassignee: docs@python -> (no value)
type: enhancement

components: + Library (Lib), - Documentation
title: pipes.quote() needs to be documented -> Add shlex.quote
nosy: - docs@python
versions: + Python 3.3, - Python 3.1, Python 2.7, Python 3.2
messages: + msg126850
2011年01月22日 11:01:36anacrolixsetnosy: eric.smith, eric.araujo, brandon-rhodes, anacrolix, docs@python
messages: + msg126830
2011年01月21日 18:52:38eric.araujosetnosy: eric.smith, eric.araujo, brandon-rhodes, anacrolix, docs@python
stage: test needed -> needs patch
2011年01月21日 18:51:09eric.araujosetnosy: eric.smith, eric.araujo, brandon-rhodes, anacrolix, docs@python
type: enhancement -> (no value)
messages: + msg126768
stage: test needed
2011年01月21日 01:32:44anacrolixsetnosy: + anacrolix
messages: + msg126674
2010年09月03日 16:33:03eric.araujosetnosy: + eric.araujo

messages: + msg115463
versions: - Python 2.6, Python 2.5, Python 3.3
2010年08月31日 17:38:41eric.smithsetnosy: + eric.smith
messages: + msg115270
2010年08月31日 13:40:13brandon-rhodescreate

AltStyle によって変換されたページ (->オリジナル) /