7
7
# iterator interface by Gustavo Niemeyer, April 2003.
8
8
# changes to tokenize more like Posix shells by Vinay Sajip, July 2016.
9
9
10
- import os
11
- import re
12
10
import sys
13
- from collections import deque
14
-
15
11
from io import StringIO
16
12
17
13
__all__ = ["shlex" , "split" , "quote" , "join" ]
@@ -20,6 +16,8 @@ class shlex:
20
16
"A lexical analyzer class for simple shell-like syntaxes."
21
17
def __init__ (self , instream = None , infile = None , posix = False ,
22
18
punctuation_chars = False ):
19
+ from collections import deque # deferred import for performance
20
+
23
21
if isinstance (instream , str ):
24
22
instream = StringIO (instream )
25
23
if instream is not None :
@@ -278,6 +276,7 @@ def read_token(self):
278
276
279
277
def sourcehook (self , newfile ):
280
278
"Hook called on a filename to be sourced."
279
+ import os .path
281
280
if newfile [0 ] == '"' :
282
281
newfile = newfile [1 :- 1 ]
283
282
# This implements cpp-like semantics for relative-path inclusion.
@@ -318,13 +317,17 @@ def join(split_command):
318
317
return ' ' .join (quote (arg ) for arg in split_command )
319
318
320
319
321
- _find_unsafe = re .compile (r'[^\w@%+=:,./-]' , re .ASCII ).search
322
-
323
320
def quote (s ):
324
321
"""Return a shell-escaped version of the string *s*."""
325
322
if not s :
326
323
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 ):
328
331
return s
329
332
330
333
# use single quotes, and put single quotes into double quotes
0 commit comments