1010from functools import lru_cache
1111
1212import uvicorn .config
13- from pydantic .v1 .utils import deep_update
1413from rich .text import Text
1514
1615from constants import (
@@ -27,6 +26,20 @@ def _ms_time_format(dt: datetime) -> Text:
2726 return Text (dt .strftime ("%Y-%m-%d %H:%M:%S." ) + f"{ dt .microsecond // 1000 :03d} " )
2827
2928
29+ def _deep_merge (
30+ mapping : dict [t .Any , t .Any ], updates : dict [t .Any , t .Any ]
31+ ) -> dict [t .Any , t .Any ]:
32+ """Recursively merge updates into mapping"""
33+ merged = mapping .copy ()
34+ for k , v in updates .items ():
35+ if k in merged and isinstance (merged [k ], dict ) and isinstance (v , dict ):
36+ merged [k ] = _deep_merge (merged [k ], v )
37+ else :
38+ merged [k ] = v
39+
40+ return merged
41+
42+
3043def resolve_log_level () -> int :
3144 """
3245 Resolve and validate the log level from environment variable.
@@ -114,7 +127,7 @@ def setup_logging() -> dict[t.Any, t.Any]:
114127 }
115128
116129 # Create a deep copy of uvicorn's logging config to avoid mutating global state.
117- merged_config = deep_update (deepcopy (uvicorn .config .LOGGING_CONFIG ), logging_conf )
130+ merged_config = _deep_merge (deepcopy (uvicorn .config .LOGGING_CONFIG ), logging_conf )
118131
119132 if handler == "rich" :
120133 merged_config ["loggers" ]["uvicorn" ]["handlers" ] = [handler ]
0 commit comments