A key-value pair argument type used with `argparse`. Parses a key-value arg and constructs a `KeyValueArg` instance. Used for headers, form data, and other key-value pair types.
| 46 | |
| 47 | |
| 48 | class KeyValueArgType: |
| 49 | """A key-value pair argument type used with `argparse`. |
| 50 | |
| 51 | Parses a key-value arg and constructs a `KeyValueArg` instance. |
| 52 | Used for headers, form data, and other key-value pair types. |
| 53 | |
| 54 | """ |
| 55 | |
| 56 | key_value_class = KeyValueArg |
| 57 | |
| 58 | def __init__(self, *separators: str): |
| 59 | self.separators = separators |
| 60 | self.special_characters = set() |
| 61 | for separator in separators: |
| 62 | self.special_characters.update(separator) |
| 63 | |
| 64 | def __call__(self, s: str) -> KeyValueArg: |
| 65 | """Parse raw string arg and return `self.key_value_class` instance. |
| 66 | |
| 67 | The best of `self.separators` is determined (first found, longest). |
| 68 | Back slash escaped characters aren't considered as separators |
| 69 | (or parts thereof). Literal back slash characters have to be escaped |
| 70 | as well (r'\\'). |
| 71 | |
| 72 | """ |
| 73 | tokens = self.tokenize(s) |
| 74 | |
| 75 | # Sorting by length ensures that the longest one will be |
| 76 | # chosen as it will overwrite any shorter ones starting |
| 77 | # at the same position in the `found` dictionary. |
| 78 | separators = sorted(self.separators, key=len) |
| 79 | |
| 80 | for i, token in enumerate(tokens): |
| 81 | |
| 82 | if isinstance(token, Escaped): |
| 83 | continue |
| 84 | |
| 85 | found = {} |
| 86 | for sep in separators: |
| 87 | pos = token.find(sep) |
| 88 | if pos != -1: |
| 89 | found[pos] = sep |
| 90 | |
| 91 | if found: |
| 92 | # Starting first, longest separator found. |
| 93 | sep = found[min(found.keys())] |
| 94 | |
| 95 | key, value = token.split(sep, 1) |
| 96 | |
| 97 | # Any preceding tokens are part of the key. |
| 98 | key = ''.join(tokens[:i]) + key |
| 99 | |
| 100 | # Any following tokens are part of the value. |
| 101 | value += ''.join(tokens[i + 1:]) |
| 102 | |
| 103 | break |
| 104 | |
| 105 | else: |
no outgoing calls
no test coverage detected