77# iterator interface by Gustavo Niemeyer, April 2003.
88# changes to tokenize more like Posix shells by Vinay Sajip, July 2016.
99
10- import os
11- import re
1210import sys
13- from collections import deque
14-
1511from io import StringIO
1612
1713__all__ = ["shlex" , "split" , "quote" , "join" ]
@@ -20,6 +16,8 @@ class shlex:
2016 "A lexical analyzer class for simple shell-like syntaxes."
2117 def __init__ (self , instream = None , infile = None , posix = False ,
2218 punctuation_chars = False ):
19+ from collections import deque # deferred import for performance
20+
2321 if isinstance (instream , str ):
2422 instream = StringIO (instream )
2523 if instream is not None :
@@ -278,6 +276,7 @@ def read_token(self):
278276
279277 def sourcehook (self , newfile ):
280278 "Hook called on a filename to be sourced."
279+ import os .path
281280 if newfile [0 ] == '"' :
282281 newfile = newfile [1 :- 1 ]
283282 # This implements cpp-like semantics for relative-path inclusion.
@@ -318,13 +317,17 @@ def join(split_command):
318317 return ' ' .join (quote (arg ) for arg in split_command )
319318
320319
321- _find_unsafe = re .compile (r'[^\w@%+=:,./-]' , re .ASCII ).search
322-
323320def quote (s ):
324321 """Return a shell-escaped version of the string *s*."""
325322 if not s :
326323 return "''"
327- if _find_unsafe (s ) is None :
324+
325+ # Use bytes.translate() for performance
326+ safe_chars = (b'%+,-./0123456789:=@'
327+ b'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'
328+ b'abcdefghijklmnopqrstuvwxyz' )
329+ # No quoting is needed if `s` is an ASCII string consisting only of `safe_chars`
330+ if s .isascii () and not s .encode ().translate (None , delete = safe_chars ):
328331 return s
329332
330333 # use single quotes, and put single quotes into double quotes
0 commit comments