Split a shell argument string into args, honoring simple single/double quotes. This is intentionally minimal: it matches how terminals remove surrounding quotes before passing args to the spawned process, which our tests need to emulate.
(cls, s)
| 610 | |
| 611 | @classmethod |
| 612 | def _split_shell_arg_string(cls, s): |
| 613 | """Split a shell argument string into args, honoring simple single/double quotes. |
| 614 | |
| 615 | This is intentionally minimal: it matches how terminals remove surrounding quotes |
| 616 | before passing args to the spawned process, which our tests need to emulate. |
| 617 | """ |
| 618 | s = str(s) |
| 619 | args = [] |
| 620 | current = [] |
| 621 | quote = None |
| 622 | |
| 623 | def flush(): |
| 624 | if current: |
| 625 | args.append("".join(current)) |
| 626 | current.clear() |
| 627 | |
| 628 | for ch in s: |
| 629 | if quote is None: |
| 630 | if ch.isspace(): |
| 631 | flush() |
| 632 | continue |
| 633 | if ch in ("\"", "'"): |
| 634 | quote = ch |
| 635 | continue |
| 636 | current.append(ch) |
| 637 | else: |
| 638 | if ch == quote: |
| 639 | quote = None |
| 640 | continue |
| 641 | current.append(ch) |
| 642 | flush() |
| 643 | |
| 644 | return [cls._shell_unquote(a) for a in args] |
| 645 | |
| 646 | def _process_request(self, request): |
| 647 | self.timeline.record_request(request, block=False) |
no test coverage detected