Split a command line and report which tokens were originally quoted. Returns a list of ``(token, was_quoted)`` pairs. ``token`` is the unquoted form, as ``shlex.split(posix=True)`` returns, and ``was_quoted`` is True if that token had any single- or double-quote characters in ``commandl
(
commandline: str, strict: bool = True
)
| 224 | |
| 225 | |
| 226 | def arg_split_with_quotes( |
| 227 | commandline: str, strict: bool = True |
| 228 | ) -> list[tuple[str, bool]]: |
| 229 | """Split a command line and report which tokens were originally quoted. |
| 230 | |
| 231 | Returns a list of ``(token, was_quoted)`` pairs. ``token`` is the unquoted |
| 232 | form, as ``shlex.split(posix=True)`` returns, and ``was_quoted`` is True |
| 233 | if that token had any single- or double-quote characters in ``commandline``. |
| 234 | |
| 235 | Useful for callers like ``%run`` that want to honor shell quoting when |
| 236 | deciding wether to apply further expansion (glob, tilde) to a token. |
| 237 | |
| 238 | Detection is shlex-based on both passes so the quote semantics are the |
| 239 | same on Posix and Windows. If ``strict`` is False, malformed input (e.g. |
| 240 | an unbalanced quote) returns whatever was parsed so far instead of raising. |
| 241 | """ |
| 242 | def _tokenize(s: str, posix: bool) -> list[str]: |
| 243 | lex = shlex.shlex(s, posix=posix) |
| 244 | lex.whitespace_split = True |
| 245 | lex.commenters = '' |
| 246 | out = [] |
| 247 | while True: |
| 248 | try: |
| 249 | out.append(next(lex)) |
| 250 | except StopIteration: |
| 251 | break |
| 252 | except ValueError: |
| 253 | if strict: |
| 254 | raise |
| 255 | out.append(lex.token) |
| 256 | break |
| 257 | return out |
| 258 | |
| 259 | raw_tokens = _tokenize(commandline, posix=False) |
| 260 | clean_tokens = _tokenize(commandline, posix=True) |
| 261 | |
| 262 | if len(raw_tokens) != len(clean_tokens): |
| 263 | # If the two passes disagree (exotic input) report nothing as quoted |
| 264 | # so callers get the legacy, non-quote-aware behavior. |
| 265 | return [(t, False) for t in clean_tokens] |
| 266 | |
| 267 | return [ |
| 268 | (clean, ("'" in raw) or ('"' in raw)) |
| 269 | for clean, raw in zip(clean_tokens, raw_tokens) |
| 270 | ] |
searching dependent graphs…