{"id": "p001", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `_CompactJSON` in itsdangerous/_json.py most likely do? Variant 1."}]}
{"id": "p002", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `dumps` in itsdangerous/_json.py most likely do? Variant 2."}]}
{"id": "p003", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `loads` in itsdangerous/_json.py most likely do? Variant 3."}]}
{"id": "p004", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `base64_decode` in itsdangerous/encoding.py most likely do? Variant 4."}]}
{"id": "p005", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `base64_encode` in itsdangerous/encoding.py most likely do? Variant 5."}]}
{"id": "p006", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `bytes_to_int` in itsdangerous/encoding.py most likely do? Variant 6."}]}
{"id": "p007", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `int_to_bytes` in itsdangerous/encoding.py most likely do? Variant 7."}]}
{"id": "p008", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `want_bytes` in itsdangerous/encoding.py most likely do? Variant 8."}]}
{"id": "p009", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadData` in itsdangerous/exc.py most likely do? Variant 9."}]}
{"id": "p010", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadHeader` in itsdangerous/exc.py most likely do? Variant 10."}]}
{"id": "p011", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadPayload` in itsdangerous/exc.py most likely do? Variant 11."}]}
{"id": "p012", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadSignature` in itsdangerous/exc.py most likely do? Variant 12."}]}
{"id": "p013", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadTimeSignature` in itsdangerous/exc.py most likely do? Variant 13."}]}
{"id": "p014", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `SignatureExpired` in itsdangerous/exc.py most likely do? Variant 14."}]}
{"id": "p015", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 15."}]}
{"id": "p016", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 16."}]}
{"id": "p017", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 17."}]}
{"id": "p018", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 18."}]}
{"id": "p019", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 19."}]}
{"id": "p020", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__str__` in itsdangerous/exc.py most likely do? Variant 20."}]}
{"id": "p021", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `_PDataSerializer` in itsdangerous/serializer.py most likely do? Variant 21."}]}
{"id": "p022", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 22."}]}
{"id": "p023", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 23."}]}
{"id": "p024", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 24."}]}
{"id": "p025", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 25."}]}
{"id": "p026", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 26."}]}
{"id": "p027", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `_loads_unsafe_impl` in itsdangerous/serializer.py most likely do? Variant 27."}]}
{"id": "p028", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `dump` in itsdangerous/serializer.py most likely do? Variant 28."}]}
{"id": "p029", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `dump_payload` in itsdangerous/serializer.py most likely do? Variant 29."}]}
{"id": "p030", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `dumps` in itsdangerous/serializer.py most likely do? Variant 30."}]}
{"id": "p031", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `dumps` in itsdangerous/serializer.py most likely do? Variant 31."}]}
{"id": "p032", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `is_text_serializer` in itsdangerous/serializer.py most likely do? Variant 32."}]}
{"id": "p033", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `iter_unsigners` in itsdangerous/serializer.py most likely do? Variant 33."}]}
{"id": "p034", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `load` in itsdangerous/serializer.py most likely do? Variant 34."}]}
{"id": "p035", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `load_payload` in itsdangerous/serializer.py most likely do? Variant 35."}]}
{"id": "p036", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `load_unsafe` in itsdangerous/serializer.py most likely do? Variant 36."}]}
{"id": "p037", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `loads` in itsdangerous/serializer.py most likely do? Variant 37."}]}
{"id": "p038", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `loads` in itsdangerous/serializer.py most likely do? Variant 38."}]}
{"id": "p039", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `loads_unsafe` in itsdangerous/serializer.py most likely do? Variant 39."}]}
{"id": "p040", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `make_signer` in itsdangerous/serializer.py most likely do? Variant 40."}]}
{"id": "p041", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `secret_key` in itsdangerous/serializer.py most likely do? Variant 41."}]}
{"id": "p042", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `HMACAlgorithm` in itsdangerous/signer.py most likely do? Variant 42."}]}
{"id": "p043", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `NoneAlgorithm` in itsdangerous/signer.py most likely do? Variant 43."}]}
{"id": "p044", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `SigningAlgorithm` in itsdangerous/signer.py most likely do? Variant 44."}]}
{"id": "p045", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/signer.py most likely do? Variant 45."}]}
{"id": "p046", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `_lazy_sha1` in itsdangerous/signer.py most likely do? Variant 46."}]}
{"id": "p047", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `_make_keys_list` in itsdangerous/signer.py most likely do? Variant 47."}]}
{"id": "p048", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `derive_key` in itsdangerous/signer.py most likely do? Variant 48."}]}
{"id": "p049", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `get_signature` in itsdangerous/signer.py most likely do? Variant 49."}]}
{"id": "p050", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `get_signature` in itsdangerous/signer.py most likely do? Variant 50."}]}
{"id": "p051", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `get_signature` in itsdangerous/signer.py most likely do? Variant 51."}]}
{"id": "p052", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `get_signature` in itsdangerous/signer.py most likely do? Variant 52."}]}
{"id": "p053", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `secret_key` in itsdangerous/signer.py most likely do? Variant 53."}]}
{"id": "p054", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `sign` in itsdangerous/signer.py most likely do? Variant 54."}]}
{"id": "p055", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `unsign` in itsdangerous/signer.py most likely do? Variant 55."}]}
{"id": "p056", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `validate` in itsdangerous/signer.py most likely do? Variant 56."}]}
{"id": "p057", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `verify_signature` in itsdangerous/signer.py most likely do? Variant 57."}]}
{"id": "p058", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `verify_signature` in itsdangerous/signer.py most likely do? Variant 58."}]}
{"id": "p059", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `get_timestamp` in itsdangerous/timed.py most likely do? Variant 59."}]}
{"id": "p060", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `iter_unsigners` in itsdangerous/timed.py most likely do? Variant 60."}]}
{"id": "p061", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `loads` in itsdangerous/timed.py most likely do? Variant 61."}]}
{"id": "p062", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `loads_unsafe` in itsdangerous/timed.py most likely do? Variant 62."}]}
{"id": "p063", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `sign` in itsdangerous/timed.py most likely do? Variant 63."}]}
{"id": "p064", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `timestamp_to_datetime` in itsdangerous/timed.py most likely do? Variant 64."}]}
{"id": "p065", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `unsign` in itsdangerous/timed.py most likely do? Variant 65."}]}
{"id": "p066", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `unsign` in itsdangerous/timed.py most likely do? Variant 66."}]}
{"id": "p067", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `validate` in itsdangerous/timed.py most likely do? Variant 67."}]}
{"id": "p068", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `URLSafeSerializer` in itsdangerous/url_safe.py most likely do? Variant 68."}]}
{"id": "p069", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `URLSafeTimedSerializer` in itsdangerous/url_safe.py most likely do? Variant 69."}]}
{"id": "p070", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `dump_payload` in itsdangerous/url_safe.py most likely do? Variant 70."}]}
{"id": "p071", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `load_payload` in itsdangerous/url_safe.py most likely do? Variant 71."}]}
{"id": "p072", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `_CompactJSON` in itsdangerous/_json.py most likely do? Variant 72."}]}
{"id": "p073", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `dumps` in itsdangerous/_json.py most likely do? Variant 73."}]}
{"id": "p074", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `loads` in itsdangerous/_json.py most likely do? Variant 74."}]}
{"id": "p075", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `base64_decode` in itsdangerous/encoding.py most likely do? Variant 75."}]}
{"id": "p076", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `base64_encode` in itsdangerous/encoding.py most likely do? Variant 76."}]}
{"id": "p077", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `bytes_to_int` in itsdangerous/encoding.py most likely do? Variant 77."}]}
{"id": "p078", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `int_to_bytes` in itsdangerous/encoding.py most likely do? Variant 78."}]}
{"id": "p079", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `want_bytes` in itsdangerous/encoding.py most likely do? Variant 79."}]}
{"id": "p080", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadData` in itsdangerous/exc.py most likely do? Variant 80."}]}
{"id": "p081", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadHeader` in itsdangerous/exc.py most likely do? Variant 81."}]}
{"id": "p082", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadPayload` in itsdangerous/exc.py most likely do? Variant 82."}]}
{"id": "p083", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadSignature` in itsdangerous/exc.py most likely do? Variant 83."}]}
{"id": "p084", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `BadTimeSignature` in itsdangerous/exc.py most likely do? Variant 84."}]}
{"id": "p085", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `SignatureExpired` in itsdangerous/exc.py most likely do? Variant 85."}]}
{"id": "p086", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 86."}]}
{"id": "p087", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 87."}]}
{"id": "p088", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 88."}]}
{"id": "p089", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 89."}]}
{"id": "p090", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/exc.py most likely do? Variant 90."}]}
{"id": "p091", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__str__` in itsdangerous/exc.py most likely do? Variant 91."}]}
{"id": "p092", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `_PDataSerializer` in itsdangerous/serializer.py most likely do? Variant 92."}]}
{"id": "p093", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 93."}]}
{"id": "p094", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 94."}]}
{"id": "p095", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 95."}]}
{"id": "p096", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 96."}]}
{"id": "p097", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `__init__` in itsdangerous/serializer.py most likely do? Variant 97."}]}
{"id": "p098", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `_loads_unsafe_impl` in itsdangerous/serializer.py most likely do? Variant 98."}]}
{"id": "p099", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `dump` in itsdangerous/serializer.py most likely do? Variant 99."}]}
{"id": "p100", "class": "short", "max_tokens": 128, "messages": [{"role": "user", "content": "In one or two sentences, what does `dump_payload` in itsdangerous/serializer.py most likely do? Variant 100."}]}
{"id": "p101", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/_json.py and list one edge case it handles.\n\n```python\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n```"}]}
{"id": "p102", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/_json.py and list one edge case it handles.\n\n```python\ndef dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n```"}]}
{"id": "p103", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/_json.py and list one edge case it handles.\n\n```python\ndef loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n```"}]}
{"id": "p104", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n```"}]}
{"id": "p105", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n```"}]}
{"id": "p106", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n```"}]}
{"id": "p107", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n```"}]}
{"id": "p108", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n```"}]}
{"id": "p109", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n```"}]}
{"id": "p110", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n```"}]}
{"id": "p111", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n```"}]}
{"id": "p112", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n```"}]}
{"id": "p113", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n```"}]}
{"id": "p114", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n```"}]}
{"id": "p115", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n```"}]}
{"id": "p116", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n```"}]}
{"id": "p117", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n```"}]}
{"id": "p118", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n```"}]}
{"id": "p119", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n```"}]}
{"id": "p120", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __str__(self) -> str:\n        return self.message\n```"}]}
{"id": "p121", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n```"}]}
{"id": "p122", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n```"}]}
{"id": "p123", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n```"}]}
{"id": "p124", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n```"}]}
{"id": "p125", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n```"}]}
{"id": "p126", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n```"}]}
{"id": "p127", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n```"}]}
{"id": "p128", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n```"}]}
{"id": "p129", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n```"}]}
{"id": "p130", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n```"}]}
{"id": "p131", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n```"}]}
{"id": "p132", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef dumps(self, obj: t.Any, /) -> _TSerialized: ...\n```"}]}
{"id": "p133", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv\n```"}]}
{"id": "p134", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n```"}]}
{"id": "p135", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n```"}]}
{"id": "p136", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n```"}]}
{"id": "p137", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n```"}]}
{"id": "p138", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n```"}]}
{"id": "p139", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef loads(self, payload: _TSerialized, /) -> t.Any: ...\n```"}]}
{"id": "p140", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n```"}]}
{"id": "p141", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n```"}]}
{"id": "p142", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n```"}]}
{"id": "p143", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\ndef secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n```"}]}
{"id": "p144", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n```"}]}
{"id": "p145", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n```"}]}
{"id": "p146", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n```"}]}
{"id": "p147", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n```"}]}
{"id": "p148", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n```"}]}
{"id": "p149", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n```"}]}
{"id": "p150", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n```"}]}
{"id": "p151", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]\n```"}]}
{"id": "p152", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n```"}]}
{"id": "p153", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n```"}]}
{"id": "p154", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n```"}]}
{"id": "p155", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n```"}]}
{"id": "p156", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n```"}]}
{"id": "p157", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n```"}]}
{"id": "p158", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n```"}]}
{"id": "p159", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n```"}]}
{"id": "p160", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n```"}]}
{"id": "p161", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n```"}]}
{"id": "p162", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/signer.py and list one edge case it handles.\n\n```python\ndef verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n```"}]}
{"id": "p163", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n```"}]}
{"id": "p164", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n```"}]}
{"id": "p165", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n```"}]}
{"id": "p166", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n```"}]}
{"id": "p167", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n```"}]}
{"id": "p168", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n```"}]}
{"id": "p169", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n```"}]}
{"id": "p170", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n```"}]}
{"id": "p171", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n```"}]}
{"id": "p172", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n```"}]}
{"id": "p173", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n```"}]}
{"id": "p174", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/timed.py and list one edge case it handles.\n\n```python\ndef validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n```"}]}
{"id": "p175", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/url_safe.py and list one edge case it handles.\n\n```python\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n```"}]}
{"id": "p176", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/url_safe.py and list one edge case it handles.\n\n```python\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n```"}]}
{"id": "p177", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/url_safe.py and list one edge case it handles.\n\n```python\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n```"}]}
{"id": "p178", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/url_safe.py and list one edge case it handles.\n\n```python\ndef dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n```"}]}
{"id": "p179", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/url_safe.py and list one edge case it handles.\n\n```python\ndef load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n```"}]}
{"id": "p180", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/_json.py and list one edge case it handles.\n\n```python\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n```"}]}
{"id": "p181", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/_json.py and list one edge case it handles.\n\n```python\ndef dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n```"}]}
{"id": "p182", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/_json.py and list one edge case it handles.\n\n```python\ndef loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n```"}]}
{"id": "p183", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n```"}]}
{"id": "p184", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n```"}]}
{"id": "p185", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n```"}]}
{"id": "p186", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n```"}]}
{"id": "p187", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/encoding.py and list one edge case it handles.\n\n```python\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n```"}]}
{"id": "p188", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n```"}]}
{"id": "p189", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n```"}]}
{"id": "p190", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n```"}]}
{"id": "p191", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n```"}]}
{"id": "p192", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n```"}]}
{"id": "p193", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n```"}]}
{"id": "p194", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n```"}]}
{"id": "p195", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n```"}]}
{"id": "p196", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n```"}]}
{"id": "p197", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n```"}]}
{"id": "p198", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n```"}]}
{"id": "p199", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/exc.py and list one edge case it handles.\n\n```python\ndef __str__(self) -> str:\n        return self.message\n```"}]}
{"id": "p200", "class": "medium", "max_tokens": 512, "messages": [{"role": "user", "content": "Explain this Python code from itsdangerous/serializer.py and list one edge case it handles.\n\n```python\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n```"}]}
{"id": "p201", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p202", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p203", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p204", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p205", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p206", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p207", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p208", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p209", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p210", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p211", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p212", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p213", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p214", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p215", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p216", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p217", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p218", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p219", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p220", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p221", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p222", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p223", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p224", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p225", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p226", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p227", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p228", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p229", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p230", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p231", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p232", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p233", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p234", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p235", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p236", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p237", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p238", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p239", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p240", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p241", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p242", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p243", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p244", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p245", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p246", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p247", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p248", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p249", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p250", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p251", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p252", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p253", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p254", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p255", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p256", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p257", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p258", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p259", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p260", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p261", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p262", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p263", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p264", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p265", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p266", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p267", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p268", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p269", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p270", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p271", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p272", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p273", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p274", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p275", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p276", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p277", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p278", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p279", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p280", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p281", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p282", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p283", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p284", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p285", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p286", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p287", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p288", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p289", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p290", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p291", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p292", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
{"id": "p293", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```"}]}
{"id": "p294", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```"}]}
{"id": "p295", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```"}]}
{"id": "p296", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# url_safe.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nimport zlib\n\nfrom ._json import _CompactJSON\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .exc import BadPayload\nfrom .serializer import _PDataSerializer\nfrom .serializer import Serializer\nfrom .timed import TimedSerializer\n\n\nclass URLSafeSerializerMixin(Serializer[str]):\n    \"\"\"Mixed in with a regular serializer it will attempt to zlib\n    compress the string to make it shorter if necessary. It will also\n    base64 encode the string so that it can safely be placed in a URL.\n    \"\"\"\n\n    default_serializer: _PDataSerializer[str] = _CompactJSON\n\n    def load_payload(\n        self,\n        payload: bytes,\n        *args: t.Any,\n        serializer: t.Any | None = None,\n        **kwargs: t.Any,\n    ) -> t.Any:\n        decompress = False\n\n        if payload.startswith(b\".\"):\n            payload = payload[1:]\n            decompress = True\n\n        try:\n            json = base64_decode(payload)\n        except Exception as e:\n            raise BadPayload(\n                \"Could not base64 decode the payload because of an exception\",\n                original_error=e,\n            ) from e\n\n        if decompress:\n            try:\n                json = zlib.decompress(json)\n            except Exception as e:\n                raise BadPayload(\n                    \"Could not zlib decompress the payload before decoding the payload\",\n                    original_error=e,\n                ) from e\n\n        return super().load_payload(json, *args, **kwargs)\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        json = super().dump_payload(obj)\n        is_compressed = False\n        compressed = zlib.compress(json)\n\n        if len(compressed) < (len(json) - 1):\n            json = compressed\n            is_compressed = True\n\n        base64d = base64_encode(json)\n\n        if is_compressed:\n            base64d = b\".\" + base64d\n\n        return base64d\n\n\nclass URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]):\n    \"\"\"Works like :class:`.Serializer` but dumps and loads into a URL\n    safe string consisting of the upper and lowercase character of the\n    alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n\nclass URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]):\n    \"\"\"Works like :class:`.TimedSerializer` but dumps and loads into a\n    URL safe string consisting of the upper and lowercase character of\n    the alphabet as well as ``'_'``, ``'-'`` and ``'.'``.\n    \"\"\"\n\n```\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```"}]}
{"id": "p297", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# __init__.py\n```python\nfrom .encoding import base64_decode as base64_decode\nfrom .encoding import base64_encode as base64_encode\nfrom .encoding import want_bytes as want_bytes\nfrom .exc import BadData as BadData\nfrom .exc import BadHeader as BadHeader\nfrom .exc import BadPayload as BadPayload\nfrom .exc import BadSignature as BadSignature\nfrom .exc import BadTimeSignature as BadTimeSignature\nfrom .exc import SignatureExpired as SignatureExpired\nfrom .serializer import Serializer as Serializer\nfrom .signer import HMACAlgorithm as HMACAlgorithm\nfrom .signer import NoneAlgorithm as NoneAlgorithm\nfrom .signer import Signer as Signer\nfrom .timed import TimedSerializer as TimedSerializer\nfrom .timed import TimestampSigner as TimestampSigner\nfrom .url_safe import URLSafeSerializer as URLSafeSerializer\nfrom .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer\n\n```\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```"}]}
{"id": "p298", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# _json.py\n```python\nfrom __future__ import annotations\n\nimport json as _json\nimport typing as t\n\n\nclass _CompactJSON:\n    \"\"\"Wrapper around json module that strips whitespace.\"\"\"\n\n    @staticmethod\n    def loads(payload: str | bytes) -> t.Any:\n        return _json.loads(payload)\n\n    @staticmethod\n    def dumps(obj: t.Any, **kwargs: t.Any) -> str:\n        kwargs.setdefault(\"ensure_ascii\", False)\n        kwargs.setdefault(\"separators\", (\",\", \":\"))\n        return _json.dumps(obj, **kwargs)\n\n```\n\n# serializer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport json\nimport typing as t\n\nfrom .encoding import want_bytes\nfrom .exc import BadPayload\nfrom .exc import BadSignature\nfrom .signer import _make_keys_list\nfrom .signer import Signer\n\nif t.TYPE_CHECKING:\n    import typing_extensions as te\n\n    # This should be either be str or bytes. To avoid having to specify the\n    # bound type, it falls back to a union if structural matching fails.\n    _TSerialized = te.TypeVar(\"_TSerialized\", bound=str | bytes, default=str | bytes)\nelse:\n    # Still available at runtime on Python < 3.13, but without the default.\n    _TSerialized = t.TypeVar(\"_TSerialized\", bound=str | bytes)\n\n\nclass _PDataSerializer(t.Protocol[_TSerialized]):\n    def loads(self, payload: _TSerialized, /) -> t.Any: ...\n    # A signature with additional arguments is not handled correctly by type\n    # checkers right now, so an overload is used below for serializers that\n    # don't match this strict protocol.\n    def dumps(self, obj: t.Any, /) -> _TSerialized: ...\n\n\n# Use TypeIs once it's available in typing_extensions or 3.13.\ndef is_text_serializer(\n    serializer: _PDataSerializer[t.Any],\n) -> te.TypeGuard[_PDataSerializer[str]]:\n    \"\"\"Checks whether a serializer generates text or binary.\"\"\"\n    return isinstance(serializer.dumps({}), str)\n\n\nclass Serializer(t.Generic[_TSerialized]):\n    \"\"\"A serializer wraps a :class:`~itsdangerous.signer.Signer` to\n    enable serializing and securely signing data other than bytes. It\n    can unsign to verify that the data hasn't been changed.\n\n    The serializer provides :meth:`dumps` and :meth:`loads`, similar to\n    :mod:`json`, and by default uses :mod:`json` internally to serialize\n    the data to bytes.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param serializer: An object that provides ``dumps`` and ``loads``\n        methods for serializing data to a string. Defaults to\n        :attr:`default_serializer`, which defaults to :mod:`json`.\n    :param serializer_kwargs: Keyword arguments to pass when calling\n        ``serializer.dumps``.\n    :param signer: A ``Signer`` class to instantiate when signing data.\n        Defaults to :attr:`default_signer`, which defaults to\n        :class:`~itsdangerous.signer.Signer`.\n    :param signer_kwargs: Keyword arguments to pass when instantiating\n        the ``Signer`` class.\n    :param fallback_signers: List of signer parameters to try when\n        unsigning with the default signer fails. Each item can be a dict\n        of ``signer_kwargs``, a ``Signer`` class, or a tuple of\n        ``(signer, signer_kwargs)``. Defaults to\n        :attr:`default_fallback_signers`.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 2.0\n        Removed the default SHA-512 fallback signer from\n        ``default_fallback_signers``.\n\n    .. versionchanged:: 1.1\n        Added support for ``fallback_signers`` and configured a default\n        SHA-512 fallback. This fallback is for users who used the yanked\n        1.0.0 release which defaulted to SHA-512.\n\n    .. versionchanged:: 0.14\n        The ``signer`` and ``signer_kwargs`` parameters were added to\n        the constructor.\n    \"\"\"\n\n    #: The default serialization module to use to serialize data to a\n    #: string internally. The default is :mod:`json`, but can be changed\n    #: to any object that provides ``dumps`` and ``loads`` methods.\n    default_serializer: _PDataSerializer[t.Any] = json\n\n    #: The default ``Signer`` class to instantiate when signing data.\n    #: The default is :class:`itsdangerous.signer.Signer`.\n    default_signer: type[Signer] = Signer\n\n    #: The default fallback signers to try when unsigning fails.\n    default_fallback_signers: list[\n        dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n    ] = []\n\n    # Serializer[str] if no data serializer is provided, or if it returns str.\n    @t.overload\n    def __init__(\n        self: Serializer[str],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: None | _PDataSerializer[str] = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer positional argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Serializer[bytes] with a bytes data serializer keyword argument.\n    @t.overload\n    def __init__(\n        self: Serializer[bytes],\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: _PDataSerializer[bytes],\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a positional argument. If the strict signature of\n    # _PDataSerializer doesn't match, fall back to a union, requiring the user\n    # to specify the type.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    # Fall back with a keyword argument.\n    @t.overload\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        *,\n        serializer: t.Any,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ): ...\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous\",\n        serializer: t.Any | None = None,\n        serializer_kwargs: dict[str, t.Any] | None = None,\n        signer: type[Signer] | None = None,\n        signer_kwargs: dict[str, t.Any] | None = None,\n        fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ]\n        | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n\n        if salt is not None:\n            salt = want_bytes(salt)\n            # if salt is None then the signer's default is used\n\n        self.salt = salt\n\n        if serializer is None:\n            serializer = self.default_serializer\n\n        self.serializer: _PDataSerializer[_TSerialized] = serializer\n        self.is_text_serializer: bool = is_text_serializer(serializer)\n\n        if signer is None:\n            signer = self.default_signer\n\n        self.signer: type[Signer] = signer\n        self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {}\n\n        if fallback_signers is None:\n            fallback_signers = list(self.default_fallback_signers)\n\n        self.fallback_signers: list[\n            dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer]\n        ] = fallback_signers\n        self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {}\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def load_payload(\n        self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None\n    ) -> t.Any:\n        \"\"\"Loads the encoded object. This function raises\n        :class:`.BadPayload` if the payload is not valid. The\n        ``serializer`` parameter can be used to override the serializer\n        stored on the class. The encoded ``payload`` should always be\n        bytes.\n        \"\"\"\n        if serializer is None:\n            use_serializer = self.serializer\n            is_text = self.is_text_serializer\n        else:\n            use_serializer = serializer\n            is_text = is_text_serializer(serializer)\n\n        try:\n            if is_text:\n                return use_serializer.loads(payload.decode(\"utf-8\"))  # type: ignore[arg-type]\n\n            return use_serializer.loads(payload)  # type: ignore[arg-type]\n        except Exception as e:\n            raise BadPayload(\n                \"Could not load the payload because an exception\"\n                \" occurred on unserializing the data.\",\n                original_error=e,\n            ) from e\n\n    def dump_payload(self, obj: t.Any) -> bytes:\n        \"\"\"Dumps the encoded object. The return value is always bytes.\n        If the internal serializer returns text, the value will be\n        encoded as UTF-8.\n        \"\"\"\n        return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))\n\n    def make_signer(self, salt: str | bytes | None = None) -> Signer:\n        \"\"\"Creates a new instance of the signer to be used. The default\n        implementation uses the :class:`.Signer` base class.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs)\n\n    def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]:\n        \"\"\"Iterates over all signers to be tried for unsigning. Starts\n        with the configured signer, then constructs each signer\n        specified in ``fallback_signers``.\n        \"\"\"\n        if salt is None:\n            salt = self.salt\n\n        yield self.make_signer(salt)\n\n        for fallback in self.fallback_signers:\n            if isinstance(fallback, dict):\n                kwargs = fallback\n                fallback = self.signer\n            elif isinstance(fallback, tuple):\n                fallback, kwargs = fallback\n            else:\n                kwargs = self.signer_kwargs\n\n            for secret_key in self.secret_keys:\n                yield fallback(secret_key, salt=salt, **kwargs)\n\n    def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized:\n        \"\"\"Returns a signed string serialized with the internal\n        serializer. The return value can be either a byte or unicode\n        string depending on the format of the internal serializer.\n        \"\"\"\n        payload = want_bytes(self.dump_payload(obj))\n        rv = self.make_signer(salt).sign(payload)\n\n        if self.is_text_serializer:\n            return rv.decode(\"utf-8\")  # type: ignore[return-value]\n\n        return rv  # type: ignore[return-value]\n\n    def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None:\n        \"\"\"Like :meth:`dumps` but dumps into a file. The file handle has\n        to be compatible with what the internal serializer expects.\n        \"\"\"\n        f.write(self.dumps(obj, salt))\n\n    def loads(\n        self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the\n        signature validation fails.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                return self.load_payload(signer.unsign(s))\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any:\n        \"\"\"Like :meth:`loads` but loads from a file.\"\"\"\n        return self.loads(f.read(), salt)\n\n    def loads_unsafe(\n        self, s: str | bytes, salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads` but without verifying the signature. This\n        is potentially very dangerous to use depending on how your\n        serializer works. The return value is ``(signature_valid,\n        payload)`` instead of just the payload. The first item will be a\n        boolean that indicates if the signature is valid. This function\n        never fails.\n\n        Use it for debugging only and if you know that your serializer\n        module is not exploitable (for example, do not use it with a\n        pickle serializer).\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self._loads_unsafe_impl(s, salt)\n\n    def _loads_unsafe_impl(\n        self,\n        s: str | bytes,\n        salt: str | bytes | None,\n        load_kwargs: dict[str, t.Any] | None = None,\n        load_payload_kwargs: dict[str, t.Any] | None = None,\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Low level helper function to implement :meth:`loads_unsafe`\n        in serializer subclasses.\n        \"\"\"\n        if load_kwargs is None:\n            load_kwargs = {}\n\n        try:\n            return True, self.loads(s, salt=salt, **load_kwargs)\n        except BadSignature as e:\n            if e.payload is None:\n                return False, None\n\n            if load_payload_kwargs is None:\n                load_payload_kwargs = {}\n\n            try:\n                return (\n                    False,\n                    self.load_payload(e.payload, **load_payload_kwargs),\n                )\n            except BadPayload:\n                return False, None\n\n    def load_unsafe(\n        self, f: t.IO[t.Any], salt: str | bytes | None = None\n    ) -> tuple[bool, t.Any]:\n        \"\"\"Like :meth:`loads_unsafe` but loads from a file.\n\n        .. versionadded:: 0.15\n        \"\"\"\n        return self.loads_unsafe(f.read(), salt=salt)\n\n```"}]}
{"id": "p299", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# encoding.py\n```python\nfrom __future__ import annotations\n\nimport base64\nimport string\nimport struct\nimport typing as t\n\nfrom .exc import BadData\n\n\ndef want_bytes(\n    s: str | bytes, encoding: str = \"utf-8\", errors: str = \"strict\"\n) -> bytes:\n    if isinstance(s, str):\n        s = s.encode(encoding, errors)\n\n    return s\n\n\ndef base64_encode(string: str | bytes) -> bytes:\n    \"\"\"Base64 encode a string of bytes or text. The resulting bytes are\n    safe to use in URLs.\n    \"\"\"\n    string = want_bytes(string)\n    return base64.urlsafe_b64encode(string).rstrip(b\"=\")\n\n\ndef base64_decode(string: str | bytes) -> bytes:\n    \"\"\"Base64 decode a URL-safe string of bytes or text. The result is\n    bytes.\n    \"\"\"\n    string = want_bytes(string, encoding=\"ascii\", errors=\"ignore\")\n    string += b\"=\" * (-len(string) % 4)\n\n    try:\n        return base64.urlsafe_b64decode(string)\n    except (TypeError, ValueError) as e:\n        raise BadData(\"Invalid base64-encoded data\") from e\n\n\n# The alphabet used by base64.urlsafe_*\n_base64_alphabet = f\"{string.ascii_letters}{string.digits}-_=\".encode(\"ascii\")\n\n_int64_struct = struct.Struct(\">Q\")\n_int_to_bytes = _int64_struct.pack\n_bytes_to_int = t.cast(\"t.Callable[[bytes], tuple[int]]\", _int64_struct.unpack)\n\n\ndef int_to_bytes(num: int) -> bytes:\n    return _int_to_bytes(num).lstrip(b\"\\x00\")\n\n\ndef bytes_to_int(bytestr: bytes) -> int:\n    return _bytes_to_int(bytestr.rjust(8, b\"\\x00\"))[0]\n\n```\n\n# signer.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport hashlib\nimport hmac\nimport typing as t\n\nfrom .encoding import _base64_alphabet\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\n\n\nclass SigningAlgorithm:\n    \"\"\"Subclasses must implement :meth:`get_signature` to provide\n    signature generation functionality.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        \"\"\"Returns the signature for the given key and value.\"\"\"\n        raise NotImplementedError()\n\n    def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool:\n        \"\"\"Verifies the given signature matches the expected\n        signature.\n        \"\"\"\n        return hmac.compare_digest(sig, self.get_signature(key, value))\n\n\nclass NoneAlgorithm(SigningAlgorithm):\n    \"\"\"Provides an algorithm that does not perform any signing and\n    returns an empty signature.\n    \"\"\"\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        return b\"\"\n\n\ndef _lazy_sha1(string: bytes = b\"\") -> t.Any:\n    \"\"\"Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include\n    SHA-1, in which case the import and use as a default would fail before the\n    developer can configure something else.\n    \"\"\"\n    return hashlib.sha1(string)\n\n\nclass HMACAlgorithm(SigningAlgorithm):\n    \"\"\"Provides signature generation using HMACs.\"\"\"\n\n    #: The digest method to use with the MAC algorithm. This defaults to\n    #: SHA1, but can be changed to any other function in the hashlib\n    #: module.\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    def __init__(self, digest_method: t.Any = None):\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n    def get_signature(self, key: bytes, value: bytes) -> bytes:\n        mac = hmac.new(key, msg=value, digestmod=self.digest_method)\n        return mac.digest()\n\n\ndef _make_keys_list(\n    secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n) -> list[bytes]:\n    if isinstance(secret_key, (str, bytes)):\n        return [want_bytes(secret_key)]\n\n    return [want_bytes(s) for s in secret_key]  # pyright: ignore\n\n\nclass Signer:\n    \"\"\"A signer securely signs bytes, then unsigns them to verify that\n    the value hasn't been changed.\n\n    The secret key should be a random string of ``bytes`` and should not\n    be saved to code or version control. Different salts should be used\n    to distinguish signing in different contexts. See :doc:`/concepts`\n    for information about the security of the secret key and salt.\n\n    :param secret_key: The secret key to sign and verify with. Can be a\n        list of keys, oldest to newest, to support key rotation.\n    :param salt: Extra key to combine with ``secret_key`` to distinguish\n        signatures in different contexts.\n    :param sep: Separator between the signature and value.\n    :param key_derivation: How to derive the signing key from the secret\n        key and salt. Possible values are ``concat``, ``django-concat``,\n        or ``hmac``. Defaults to :attr:`default_key_derivation`, which\n        defaults to ``django-concat``.\n    :param digest_method: Hash function to use when generating the HMAC\n        signature. Defaults to :attr:`default_digest_method`, which\n        defaults to :func:`hashlib.sha1`. Note that the security of the\n        hash alone doesn't apply when used intermediately in HMAC.\n    :param algorithm: A :class:`SigningAlgorithm` instance to use\n        instead of building a default :class:`HMACAlgorithm` with the\n        ``digest_method``.\n\n    .. versionchanged:: 2.0\n        Added support for key rotation by passing a list to\n        ``secret_key``.\n\n    .. versionchanged:: 0.18\n        ``algorithm`` was added as an argument to the class constructor.\n\n    .. versionchanged:: 0.14\n        ``key_derivation`` and ``digest_method`` were added as arguments\n        to the class constructor.\n    \"\"\"\n\n    #: The default digest method to use for the signer. The default is\n    #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or\n    #: compatible object. Note that the security of the hash alone\n    #: doesn't apply when used intermediately in HMAC.\n    #:\n    #: .. versionadded:: 0.14\n    default_digest_method: t.Any = staticmethod(_lazy_sha1)\n\n    #: The default scheme to use to derive the signing key from the\n    #: secret key and salt. The default is ``django-concat``. Possible\n    #: values are ``concat``, ``django-concat``, and ``hmac``.\n    #:\n    #: .. versionadded:: 0.14\n    default_key_derivation: str = \"django-concat\"\n\n    def __init__(\n        self,\n        secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes],\n        salt: str | bytes | None = b\"itsdangerous.Signer\",\n        sep: str | bytes = b\".\",\n        key_derivation: str | None = None,\n        digest_method: t.Any | None = None,\n        algorithm: SigningAlgorithm | None = None,\n    ):\n        #: The list of secret keys to try for verifying signatures, from\n        #: oldest to newest. The newest (last) key is used for signing.\n        #:\n        #: This allows a key rotation system to keep a list of allowed\n        #: keys and remove expired ones.\n        self.secret_keys: list[bytes] = _make_keys_list(secret_key)\n        self.sep: bytes = want_bytes(sep)\n\n        if self.sep in _base64_alphabet:\n            raise ValueError(\n                \"The given separator cannot be used because it may be\"\n                \" contained in the signature itself. ASCII letters,\"\n                \" digits, and '-_=' must not be used.\"\n            )\n\n        if salt is not None:\n            salt = want_bytes(salt)\n        else:\n            salt = b\"itsdangerous.Signer\"\n\n        self.salt = salt\n\n        if key_derivation is None:\n            key_derivation = self.default_key_derivation\n\n        self.key_derivation: str = key_derivation\n\n        if digest_method is None:\n            digest_method = self.default_digest_method\n\n        self.digest_method: t.Any = digest_method\n\n        if algorithm is None:\n            algorithm = HMACAlgorithm(self.digest_method)\n\n        self.algorithm: SigningAlgorithm = algorithm\n\n    @property\n    def secret_key(self) -> bytes:\n        \"\"\"The newest (last) entry in the :attr:`secret_keys` list. This\n        is for compatibility from before key rotation support was added.\n        \"\"\"\n        return self.secret_keys[-1]\n\n    def derive_key(self, secret_key: str | bytes | None = None) -> bytes:\n        \"\"\"This method is called to derive the key. The default key\n        derivation choices can be overridden here. Key derivation is not\n        intended to be used as a security method to make a complex key\n        out of a short password. Instead you should use large random\n        secret keys.\n\n        :param secret_key: A specific secret key to derive from.\n            Defaults to the last item in :attr:`secret_keys`.\n\n        .. versionchanged:: 2.0\n            Added the ``secret_key`` parameter.\n        \"\"\"\n        if secret_key is None:\n            secret_key = self.secret_keys[-1]\n        else:\n            secret_key = want_bytes(secret_key)\n\n        if self.key_derivation == \"concat\":\n            return t.cast(bytes, self.digest_method(self.salt + secret_key).digest())\n        elif self.key_derivation == \"django-concat\":\n            return t.cast(\n                bytes, self.digest_method(self.salt + b\"signer\" + secret_key).digest()\n            )\n        elif self.key_derivation == \"hmac\":\n            mac = hmac.new(secret_key, digestmod=self.digest_method)\n            mac.update(self.salt)\n            return mac.digest()\n        elif self.key_derivation == \"none\":\n            return secret_key\n        else:\n            raise TypeError(\"Unknown key derivation method\")\n\n    def get_signature(self, value: str | bytes) -> bytes:\n        \"\"\"Returns the signature for the given value.\"\"\"\n        value = want_bytes(value)\n        key = self.derive_key()\n        sig = self.algorithm.get_signature(key, value)\n        return base64_encode(sig)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string.\"\"\"\n        value = want_bytes(value)\n        return value + self.sep + self.get_signature(value)\n\n    def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool:\n        \"\"\"Verifies the signature for the given value.\"\"\"\n        try:\n            sig = base64_decode(sig)\n        except Exception:\n            return False\n\n        value = want_bytes(value)\n\n        for secret_key in reversed(self.secret_keys):\n            key = self.derive_key(secret_key)\n\n            if self.algorithm.verify_signature(key, value, sig):\n                return True\n\n        return False\n\n    def unsign(self, signed_value: str | bytes) -> bytes:\n        \"\"\"Unsigns the given string.\"\"\"\n        signed_value = want_bytes(signed_value)\n\n        if self.sep not in signed_value:\n            raise BadSignature(f\"No {self.sep!r} found in value\")\n\n        value, sig = signed_value.rsplit(self.sep, 1)\n\n        if self.verify_signature(value, sig):\n            return value\n\n        raise BadSignature(f\"Signature {sig!r} does not match\", payload=value)\n\n    def validate(self, signed_value: str | bytes) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\n        \"\"\"\n        try:\n            self.unsign(signed_value)\n            return True\n        except BadSignature:\n            return False\n\n```"}]}
{"id": "p300", "class": "long", "max_tokens": 1024, "messages": [{"role": "user", "content": "Summarize how these two modules interact and list any public functions they define.\n\n# exc.py\n```python\nfrom __future__ import annotations\n\nimport typing as t\nfrom datetime import datetime\n\n\nclass BadData(Exception):\n    \"\"\"Raised if bad data of any sort was encountered. This is the base\n    for all exceptions that ItsDangerous defines.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str):\n        super().__init__(message)\n        self.message = message\n\n    def __str__(self) -> str:\n        return self.message\n\n\nclass BadSignature(BadData):\n    \"\"\"Raised if a signature does not match.\"\"\"\n\n    def __init__(self, message: str, payload: t.Any | None = None):\n        super().__init__(message)\n\n        #: The payload that failed the signature test. In some\n        #: situations you might still want to inspect this, even if\n        #: you know it was tampered with.\n        #:\n        #: .. versionadded:: 0.14\n        self.payload: t.Any | None = payload\n\n\nclass BadTimeSignature(BadSignature):\n    \"\"\"Raised if a time-based signature is invalid. This is a subclass\n    of :class:`BadSignature`.\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        date_signed: datetime | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the signature expired this exposes the date of when the\n        #: signature was created. This can be helpful in order to\n        #: tell the user how long a link has been gone stale.\n        #:\n        #: .. versionchanged:: 2.0\n        #:     The datetime value is timezone-aware rather than naive.\n        #:\n        #: .. versionadded:: 0.14\n        self.date_signed = date_signed\n\n\nclass SignatureExpired(BadTimeSignature):\n    \"\"\"Raised if a signature timestamp is older than ``max_age``. This\n    is a subclass of :exc:`BadTimeSignature`.\n    \"\"\"\n\n\nclass BadHeader(BadSignature):\n    \"\"\"Raised if a signed header is invalid in some form. This only\n    happens for serializers that have a header that goes with the\n    signature.\n\n    .. versionadded:: 0.24\n    \"\"\"\n\n    def __init__(\n        self,\n        message: str,\n        payload: t.Any | None = None,\n        header: t.Any | None = None,\n        original_error: Exception | None = None,\n    ):\n        super().__init__(message, payload)\n\n        #: If the header is actually available but just malformed it\n        #: might be stored here.\n        self.header: t.Any | None = header\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n\nclass BadPayload(BadData):\n    \"\"\"Raised if a payload is invalid. This could happen if the payload\n    is loaded despite an invalid signature, or if there is a mismatch\n    between the serializer and deserializer. The original exception\n    that occurred during loading is stored on as :attr:`original_error`.\n\n    .. versionadded:: 0.15\n    \"\"\"\n\n    def __init__(self, message: str, original_error: Exception | None = None):\n        super().__init__(message)\n\n        #: If available, the error that indicates why the payload was\n        #: not valid. This might be ``None``.\n        self.original_error: Exception | None = original_error\n\n```\n\n# timed.py\n```python\nfrom __future__ import annotations\n\nimport collections.abc as cabc\nimport time\nimport typing as t\nfrom datetime import datetime\nfrom datetime import timezone\n\nfrom .encoding import base64_decode\nfrom .encoding import base64_encode\nfrom .encoding import bytes_to_int\nfrom .encoding import int_to_bytes\nfrom .encoding import want_bytes\nfrom .exc import BadSignature\nfrom .exc import BadTimeSignature\nfrom .exc import SignatureExpired\nfrom .serializer import _TSerialized\nfrom .serializer import Serializer\nfrom .signer import Signer\n\n\nclass TimestampSigner(Signer):\n    \"\"\"Works like the regular :class:`.Signer` but also records the time\n    of the signing and can be used to expire signatures. The\n    :meth:`unsign` method can raise :exc:`.SignatureExpired` if the\n    unsigning failed because the signature is expired.\n    \"\"\"\n\n    def get_timestamp(self) -> int:\n        \"\"\"Returns the current timestamp. The function must return an\n        integer.\n        \"\"\"\n        return int(time.time())\n\n    def timestamp_to_datetime(self, ts: int) -> datetime:\n        \"\"\"Convert the timestamp from :meth:`get_timestamp` into an\n        aware :class`datetime.datetime` in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        return datetime.fromtimestamp(ts, tz=timezone.utc)\n\n    def sign(self, value: str | bytes) -> bytes:\n        \"\"\"Signs the given string and also attaches time information.\"\"\"\n        value = want_bytes(value)\n        timestamp = base64_encode(int_to_bytes(self.get_timestamp()))\n        sep = want_bytes(self.sep)\n        value = value + sep + timestamp\n        return value + sep + self.get_signature(value)\n\n    # Ignore overlapping signatures check, return_timestamp is the only\n    # parameter that affects the return type.\n\n    @t.overload\n    def unsign(  # pyright: ignore\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[False] = False,\n    ) -> bytes: ...\n\n    @t.overload\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: t.Literal[True] = True,\n    ) -> tuple[bytes, datetime]: ...\n\n    def unsign(\n        self,\n        signed_value: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n    ) -> tuple[bytes, datetime] | bytes:\n        \"\"\"Works like the regular :meth:`.Signer.unsign` but can also\n        validate the time. See the base docstring of the class for\n        the general behavior. If ``return_timestamp`` is ``True`` the\n        timestamp of the signature will be returned as an aware\n        :class:`datetime.datetime` object in UTC.\n\n        .. versionchanged:: 2.0\n            The timestamp is returned as a timezone-aware ``datetime``\n            in UTC rather than a naive ``datetime`` assumed to be UTC.\n        \"\"\"\n        try:\n            result = super().unsign(signed_value)\n            sig_error = None\n        except BadSignature as e:\n            sig_error = e\n            result = e.payload or b\"\"\n\n        sep = want_bytes(self.sep)\n\n        # If there is no timestamp in the result there is something\n        # seriously wrong. In case there was a signature error, we raise\n        # that one directly, otherwise we have a weird situation in\n        # which we shouldn't have come except someone uses a time-based\n        # serializer on non-timestamp data, so catch that.\n        if sep not in result:\n            if sig_error:\n                raise sig_error\n\n            raise BadTimeSignature(\"timestamp missing\", payload=result)\n\n        value, ts_bytes = result.rsplit(sep, 1)\n        ts_int: int | None = None\n        ts_dt: datetime | None = None\n\n        try:\n            ts_int = bytes_to_int(base64_decode(ts_bytes))\n        except Exception:\n            pass\n\n        # Signature is *not* okay. Raise a proper error now that we have\n        # split the value and the timestamp.\n        if sig_error is not None:\n            if ts_int is not None:\n                try:\n                    ts_dt = self.timestamp_to_datetime(ts_int)\n                except (ValueError, OSError, OverflowError) as exc:\n                    # Windows raises OSError\n                    # 32-bit raises OverflowError\n                    raise BadTimeSignature(\n                        \"Malformed timestamp\", payload=value\n                    ) from exc\n\n            raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt)\n\n        # Signature was okay but the timestamp is actually not there or\n        # malformed. Should not happen, but we handle it anyway.\n        if ts_int is None:\n            raise BadTimeSignature(\"Malformed timestamp\", payload=value)\n\n        # Check timestamp is not older than max_age\n        if max_age is not None:\n            age = self.get_timestamp() - ts_int\n\n            if age > max_age:\n                raise SignatureExpired(\n                    f\"Signature age {age} > {max_age} seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n            if age < 0:\n                raise SignatureExpired(\n                    f\"Signature age {age} < 0 seconds\",\n                    payload=value,\n                    date_signed=self.timestamp_to_datetime(ts_int),\n                )\n\n        if return_timestamp:\n            return value, self.timestamp_to_datetime(ts_int)\n\n        return value\n\n    def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool:\n        \"\"\"Only validates the given signed value. Returns ``True`` if\n        the signature exists and is valid.\"\"\"\n        try:\n            self.unsign(signed_value, max_age=max_age)\n            return True\n        except BadSignature:\n            return False\n\n\nclass TimedSerializer(Serializer[_TSerialized]):\n    \"\"\"Uses :class:`TimestampSigner` instead of the default\n    :class:`.Signer`.\n    \"\"\"\n\n    default_signer: type[TimestampSigner] = TimestampSigner  # pyright: ignore\n\n    def iter_unsigners(\n        self, salt: str | bytes | None = None\n    ) -> cabc.Iterator[TimestampSigner]:\n        return t.cast(\"cabc.Iterator[TimestampSigner]\", super().iter_unsigners(salt))\n\n    # TODO: Signature is incompatible because parameters were added\n    #  before salt.\n\n    def loads(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        return_timestamp: bool = False,\n        salt: str | bytes | None = None,\n    ) -> t.Any:\n        \"\"\"Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the\n        signature validation fails. If a ``max_age`` is provided it will\n        ensure the signature is not older than that time in seconds. In\n        case the signature is outdated, :exc:`.SignatureExpired` is\n        raised. All arguments are forwarded to the signer's\n        :meth:`~TimestampSigner.unsign` method.\n        \"\"\"\n        s = want_bytes(s)\n        last_exception = None\n\n        for signer in self.iter_unsigners(salt):\n            try:\n                base64d, timestamp = signer.unsign(\n                    s, max_age=max_age, return_timestamp=True\n                )\n                payload = self.load_payload(base64d)\n\n                if return_timestamp:\n                    return payload, timestamp\n\n                return payload\n            except SignatureExpired:\n                # The signature was unsigned successfully but was\n                # expired. Do not try the next signer.\n                raise\n            except BadSignature as err:\n                last_exception = err\n\n        raise t.cast(BadSignature, last_exception)\n\n    def loads_unsafe(  # type: ignore[override]\n        self,\n        s: str | bytes,\n        max_age: int | None = None,\n        salt: str | bytes | None = None,\n    ) -> tuple[bool, t.Any]:\n        return self._loads_unsafe_impl(s, salt, load_kwargs={\"max_age\": max_age})\n\n```"}]}
