diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index cec5e767c3..ac8b876010 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -890,7 +890,14 @@ def user(self, value: "Optional[Dict[str, Any]]") -> None: def set_user(self, value: "Optional[Dict[str, Any]]") -> None: """Sets a user for the scope.""" - self._user = value + if value is not None: + self._user = {} + for k, v in value.items(): + if v is not None: + self._user[k] = v + else: + self._user = None + session = self.get_isolation_scope()._session if session is not None: session.update(user=value) diff --git a/tests/test_scope.py b/tests/test_scope.py index 39a162be18..684be5fb6e 100644 --- a/tests/test_scope.py +++ b/tests/test_scope.py @@ -68,6 +68,32 @@ def test_scope_flags_copy(): ] +def test_set_user(sentry_init, capture_events): + sentry_init() + events = capture_events() + + sentry_sdk.get_isolation_scope().set_user({"id": "42", "email": "bob@example.com"}) + capture_exception(NameError()) + assert events[-1]["user"] == {"id": "42", "email": "bob@example.com"} + + sentry_sdk.get_isolation_scope().set_user(None) + capture_exception(NameError()) + assert "user" not in events[-1] + + +def test_set_user_none_values_are_dropped_when_copying_to_attributes( + sentry_init, capture_events +): + sentry_init() + events = capture_events() + + sentry_sdk.get_isolation_scope().set_user( + {"email": "ada@beans.com", "username": None} + ) + capture_exception(NameError()) + assert events[-1]["user"] == {"email": "ada@beans.com"} + + def test_merging(sentry_init, capture_events): sentry_init()