summaryrefslogtreecommitdiff
path: root/src/click/parser.py
diff options
context:
space:
mode:
authorSam Schott <ss2151@cam.ac.uk>2020-11-10 09:41:32 +0000
committerDavid Lord <davidism@gmail.com>2020-11-10 13:35:38 -0800
commitf7cd0ff65eaf1c5cf194fe5a8104f61fd69fbc39 (patch)
tree8d7fb176e7aae73196d4db9bd0c7b2967d07aaef /src/click/parser.py
parentf0cc87d491e98b8770af0f3be13fba4b688298b3 (diff)
downloadclick-f7cd0ff65eaf1c5cf194fe5a8104f61fd69fbc39.tar.gz
use shlex to split completion argument string
Co-authored-by: David Lord <davidism@gmail.com>
Diffstat (limited to 'src/click/parser.py')
-rw-r--r--src/click/parser.py48
1 files changed, 31 insertions, 17 deletions
diff --git a/src/click/parser.py b/src/click/parser.py
index 92c9354..d730e01 100644
--- a/src/click/parser.py
+++ b/src/click/parser.py
@@ -21,7 +21,6 @@ Copyright 2002-2006 Python Software Foundation. All rights reserved.
# maintained by the Python Software Foundation.
# Copyright 2001-2006 Gregory P. Ward
# Copyright 2002-2006 Python Software Foundation
-import re
from collections import deque
from .exceptions import BadArgumentUsage
@@ -103,22 +102,37 @@ def normalize_opt(opt, ctx):
def split_arg_string(string):
- """Given an argument string this attempts to split it into small parts."""
- rv = []
- for match in re.finditer(
- r"('([^'\\]*(?:\\.[^'\\]*)*)'|\"([^\"\\]*(?:\\.[^\"\\]*)*)\"|\S+)\s*",
- string,
- re.S,
- ):
- arg = match.group().strip()
- if arg[:1] == arg[-1:] and arg[:1] in "\"'":
- arg = arg[1:-1].encode("ascii", "backslashreplace").decode("unicode-escape")
- try:
- arg = type(string)(arg)
- except UnicodeError:
- pass
- rv.append(arg)
- return rv
+ """Split an argument string as with :func:`shlex.split`, but don't
+ fail if the string is incomplete. Ignores a missing closing quote or
+ incomplete escape sequence and uses the partial token as-is.
+
+ .. code-block:: python
+
+ split_arg_string("example 'my file")
+ ["example", "my file"]
+
+ split_arg_string("example my\\")
+ ["example", "my"]
+
+ :param string: String to split.
+ """
+ import shlex
+
+ lex = shlex.shlex(string, posix=True)
+ lex.whitespace_split = True
+ lex.commenters = ""
+ out = []
+
+ try:
+ for token in lex:
+ out.append(token)
+ except ValueError:
+ # Raised when end-of-string is reached in an invalid state. Use
+ # the partial token as-is. The quote or escape character is in
+ # lex.state, not lex.token.
+ out.append(lex.token)
+
+ return out
class Option: