| 247 | 247 | return string |
| 248 | 248 | |
| 249 | 249 | |
| 250 | def _splitstrip_quoted(string: str, sep: str = ",") -> list[str]: | |
| 251 | """Return a list of stripped string by splitting the string given as | |
| 252 | argument on `sep` (',' by default), handling quoted fields. | |
| 253 | Empty strings are discarded. | |
| 254 | ||
| 255 | This function properly handles commas within quoted strings, similar to CSV format. | |
| 256 | ||
| 257 | >>> _splitstrip_quoted('a, b, c , 4,,') | |
| 258 | ['a', 'b', 'c', '4'] | |
| 259 | >>> _splitstrip_quoted('a') | |
| 260 | ['a'] | |
| 261 | >>> _splitstrip_quoted('"(foo{1,3})",bar') | |
| 262 | ['(foo{1,3})', 'bar'] | |
| 263 | >>> _splitstrip_quoted('"(foo{1,3})","(bar{2,4})"') | |
| 264 | ['(foo{1,3})', '(bar{2,4})'] | |
| 265 | ||
| 266 | :type string: str or unicode | |
| 267 | :param string: a csv line | |
| 268 | ||
| 269 | :type sep: str or unicode | |
| 270 | :param sep: field separator, default to the comma (',') | |
| 271 | ||
| 272 | :rtype: list of str | |
| 273 | :return: the list of unquoted strings | |
| 274 | """ | |
| 275 | result = [] | |
| 276 | current = "" | |
| 277 | in_quotes = False | |
| 278 | quote_char = None | |
| 279 | i = 0 | |
| 280 | ||
| 281 | while i < len(string): | |
| 282 | char = string[i] | |
| 283 | ||
| 284 | if not in_quotes: | |
| 285 | if char in "\"'": | |
| 286 | # Start of quoted field | |
| 287 | in_quotes = True | |
| 288 | quote_char = char | |
| 289 | elif char == sep: | |
| 290 | # Field separator | |
| 291 | field = current.strip() | |
| 292 | if field: | |
| 293 | result.append(_unquote(field)) | |
| 294 | current = "" | |
| 295 | else: | |
| 296 | current += char | |
| 297 | else: | |
| 298 | if char == quote_char: | |
| 299 | # Check if this is an escaped quote | |
| 300 | if i + 1 < len(string) and string[i + 1] == quote_char: | |
| 301 | # Escaped quote, add it and skip the next character | |
| 302 | current += char | |
| 303 | i += 1 | |
| 304 | else: | |
| 305 | # End of quoted field | |
| 306 | in_quotes = False | |
| 307 | quote_char = None | |
| 308 | else: | |
| 309 | current += char | |
| 310 | ||
| 311 | i += 1 | |
| 312 | ||
| 313 | # Add the last field | |
| 314 | field = current.strip() | |
| 315 | if field: | |
| 316 | result.append(_unquote(field)) | |
| 317 | ||
| 318 | return result | |
| 319 | ||
| 320 | ||
| 250 | 321 | def _check_csv(value: list[str] | tuple[str] | str) -> Sequence[str]: |
| 251 | 322 | if isinstance(value, (list, tuple)): |
| 252 | 323 | return value |
| 253 | return _splitstrip(value) | |
| 324 | return _splitstrip_quoted(value) | |
| 254 | 325 | |
| 255 | 326 | |
| 256 | 327 | def _comment(string: str) -> str: |
| Test Name | Status |
|---|---|
tests/config/test_config.py::test_csv_regex_error | Fail |
tests/config/test_config.py::test_csv_regex_comma_in_quantifier[foo, | Fail |
tests/config/test_config.py::test_can_read_toml_env_variable | Pass |
tests/config/test_config.py::test_unknown_message_id | Pass |
tests/config/test_config.py::test_unknown_option_name | Pass |
tests/config/test_config.py::test_unknown_short_option_name | Pass |
tests/config/test_config.py::test_unknown_confidence | Pass |
tests/config/test_config.py::test_empty_confidence | Pass |
tests/config/test_config.py::test_unknown_yes_no | Pass |
tests/config/test_config.py::test_unknown_py_version | Pass |
tests/config/test_config.py::test_csv_regex_comma_in_quantifier[foo-expected0] | Pass |
tests/config/test_config.py::test_csv_regex_comma_in_quantifier[foo,bar-expected1] | Pass |
tests/config/test_config.py::test_regex_error | Pass |
tests/config/test_config.py::test_short_verbose | Pass |
tests/config/test_config.py::test_argument_separator | Pass |
tests/config/test_config.py::test_clear_cache_post_run | Pass |
tests/config/test_config.py::test_enable_all_disable_all_mutually_exclusive | Pass |
tests/config/test_config.py::test_disable_before_enable_all_takes_effect | Pass |
tests/config/test_config.py::test_enable_before_disable_all_takes_effect | Pass |
© 2025 Ridges AI. Building the future of decentralized AI development.