Source code for harp.config.asdict

import copy
import dataclasses
import re
from functools import partial
from typing import Literal

from pydantic import RedisDsn
from pydantic_core import MultiHostUrl, Url

mask_password_re = re.compile(r"(://[^:]+:)([^@]+)(@)")


def url_serializer(dsn, secure=True, **kwargs):
    if secure:
        return mask_password_re.sub(r"\1***\3", str(dsn))
    return str(dsn)


ADDITIONAL_SERIALIZERS = {
    Url: url_serializer,
    RedisDsn: url_serializer,
    MultiHostUrl: url_serializer,
}


[docs] def asdict( obj, /, *, secure=True, verbose=False, mode: Literal["json", "python"] | str = "json", ): if type(obj) in ADDITIONAL_SERIALIZERS: return ADDITIONAL_SERIALIZERS[type(obj)](obj, secure=secure, verbose=verbose) if hasattr(obj, "_asdict"): return obj._asdict(secure=secure) _asdict = partial(asdict, secure=secure, verbose=verbose, mode=mode) if hasattr(obj, "model_dump"): return _asdict(obj.model_dump(mode=mode, exclude_unset=not verbose, exclude_defaults=not verbose)) if type(obj) in dataclasses._ATOMIC_TYPES: return obj if dataclasses._is_dataclass_instance(obj): # fast path for the common case return {f.name: _asdict(getattr(obj, f.name)) for f in dataclasses.fields(obj)} if isinstance(obj, tuple) and hasattr(obj, "_fields"): return type(obj)(*[_asdict(v) for v in obj]) if isinstance(obj, (list, tuple)): return type(obj)(_asdict(v) for v in obj) if isinstance(obj, dict): if hasattr(type(obj), "default_factory"): # obj is a defaultdict, which has a different constructor from # dict as it requires the default_factory as its first arg. result = type(obj)(getattr(obj, "default_factory")) for k, v in obj.items(): result[_asdict(k)] = asdict(v, secure=secure) return result return type(obj)((_asdict(k), _asdict(v)) for k, v in obj.items()) return copy.deepcopy(obj)