Skip to content

Commit ff968d4

Browse files
authored
fix(hc): Unwrap lazy objects when passed as RPC args (#60065)
1 parent 6cadcb3 commit ff968d4

File tree

1 file changed

+21
-0
lines changed
  • src/sentry/services/hybrid_cloud

1 file changed

+21
-0
lines changed

src/sentry/services/hybrid_cloud/sig.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import Any, Callable, Iterable, Sequence, Tuple, Type
66

77
import pydantic
8+
from django.utils.functional import LazyObject
89

910
from sentry.services.hybrid_cloud import ArgumentDict
1011

@@ -100,7 +101,27 @@ def _create_return_model(self) -> Type[pydantic.BaseModel] | None:
100101
field_definitions = {self._RETURN_MODEL_ATTR: (return_type, ...)}
101102
return pydantic.create_model(model_name, **field_definitions) # type: ignore[call-overload]
102103

104+
@staticmethod
105+
def _unwrap_lazy_django_object(arg: Any) -> Any:
106+
"""Unwrap any lazy objects before attempting to serialize.
107+
108+
It's possible to receive a SimpleLazyObject initialized by the Django
109+
framework and pass it to an RPC (typically `request.user` as an RpcUser
110+
argument). These objects are supposed to behave seamlessly like the
111+
underlying type, but don't play nice with the reflection that Pydantic uses
112+
to serialize. So, we manually check and force them to unwrap.
113+
"""
114+
115+
if isinstance(arg, LazyObject):
116+
return getattr(arg, "_wrapped")
117+
else:
118+
return arg
119+
103120
def serialize_arguments(self, raw_arguments: ArgumentDict) -> ArgumentDict:
121+
raw_arguments = {
122+
key: self._unwrap_lazy_django_object(arg) for (key, arg) in raw_arguments.items()
123+
}
124+
104125
try:
105126
model_instance = self._parameter_model(**raw_arguments)
106127
except Exception as e:

0 commit comments

Comments
 (0)