Do the inverse (almost) of the conversion done by split_header_words. Takes a list of lists of (key, value) pairs and produces a single header value. Attribute values are quoted if needed. >>> join_header_words([[("text/plain", None), ("charset", "iso-8859/1")]]) 'text/plain; char
(lists)
| 433 | HEADER_JOIN_TOKEN_RE = re.compile(r"[!#$%&'*+\-.^_`|~0-9A-Za-z]+") |
| 434 | HEADER_JOIN_ESCAPE_RE = re.compile(r"([\"\\])") |
| 435 | def join_header_words(lists): |
| 436 | """Do the inverse (almost) of the conversion done by split_header_words. |
| 437 | |
| 438 | Takes a list of lists of (key, value) pairs and produces a single header |
| 439 | value. Attribute values are quoted if needed. |
| 440 | |
| 441 | >>> join_header_words([[("text/plain", None), ("charset", "iso-8859/1")]]) |
| 442 | 'text/plain; charset="iso-8859/1"' |
| 443 | >>> join_header_words([[("text/plain", None)], [("charset", "iso-8859/1")]]) |
| 444 | 'text/plain, charset="iso-8859/1"' |
| 445 | |
| 446 | """ |
| 447 | headers = [] |
| 448 | for pairs in lists: |
| 449 | attr = [] |
| 450 | for k, v in pairs: |
| 451 | if v is not None: |
| 452 | if not HEADER_JOIN_TOKEN_RE.fullmatch(v): |
| 453 | v = HEADER_JOIN_ESCAPE_RE.sub(r"\\\1", v) # escape " and \ |
| 454 | v = '"%s"' % v |
| 455 | k = "%s=%s" % (k, v) |
| 456 | attr.append(k) |
| 457 | if attr: headers.append("; ".join(attr)) |
| 458 | return ", ".join(headers) |
| 459 | |
| 460 | def strip_quotes(text): |
| 461 | if text.startswith('"'): |
searching dependent graphs…