Parse an hstore from its literal string representation. Attempts to approximate PG's hstore input parsing rules as closely as possible. Although currently this is not strictly necessary, since the current implementation of hstore's output syntax is stricter than what it accepts as i
(hstore_str: str)
| 360 | |
| 361 | |
| 362 | def _parse_hstore(hstore_str: str) -> _HSTORE_VAL: |
| 363 | """Parse an hstore from its literal string representation. |
| 364 | |
| 365 | Attempts to approximate PG's hstore input parsing rules as closely as |
| 366 | possible. Although currently this is not strictly necessary, since the |
| 367 | current implementation of hstore's output syntax is stricter than what it |
| 368 | accepts as input, the documentation makes no guarantees that will always |
| 369 | be the case. |
| 370 | |
| 371 | |
| 372 | |
| 373 | """ |
| 374 | result: _HSTORE_VAL = {} |
| 375 | pos = 0 |
| 376 | pair_match = HSTORE_PAIR_RE.match(hstore_str) |
| 377 | |
| 378 | while pair_match is not None: |
| 379 | key = pair_match.group("key").replace(r"\"", '"').replace("\\\\", "\\") |
| 380 | if pair_match.group("value_null"): |
| 381 | value = None |
| 382 | else: |
| 383 | value = ( |
| 384 | pair_match.group("value") |
| 385 | .replace(r"\"", '"') |
| 386 | .replace("\\\\", "\\") |
| 387 | ) |
| 388 | result[key] = value |
| 389 | |
| 390 | pos += pair_match.end() |
| 391 | |
| 392 | delim_match = HSTORE_DELIMITER_RE.match(hstore_str[pos:]) |
| 393 | if delim_match is not None: |
| 394 | pos += delim_match.end() |
| 395 | |
| 396 | pair_match = HSTORE_PAIR_RE.match(hstore_str[pos:]) |
| 397 | |
| 398 | if pos != len(hstore_str): |
| 399 | raise ValueError(_parse_error(hstore_str, pos)) |
| 400 | |
| 401 | return result |
| 402 | |
| 403 | |
| 404 | def _serialize_hstore(val: _HSTORE_VAL) -> str: |
no test coverage detected