From 6d8cb8976c4d9eac5a795eca5d67e95ec580e7c2 Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Tue, 27 Feb 2024 13:27:33 +0100 Subject: [PATCH 1/4] ref: Improve scrub_dict typing --- sentry_sdk/scrubber.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sentry_sdk/scrubber.py b/sentry_sdk/scrubber.py index 838ef08b4b..f1bb4d7b25 100644 --- a/sentry_sdk/scrubber.py +++ b/sentry_sdk/scrubber.py @@ -1,3 +1,5 @@ +from typing import cast + from sentry_sdk.utils import ( capture_internal_exceptions, AnnotatedValue, @@ -8,8 +10,6 @@ if TYPE_CHECKING: from sentry_sdk._types import Event - from typing import Any - from typing import Dict from typing import List from typing import Optional @@ -65,12 +65,14 @@ def __init__(self, denylist=None): self.denylist = [x.lower() for x in self.denylist] def scrub_dict(self, d): - # type: (Dict[str, Any]) -> None + # type: (object) -> None if not isinstance(d, dict): return for k in d.keys(): - if isinstance(k, string_types) and k.lower() in self.denylist: + # The cast is needed because mypy is not smart enough to figure out that k must be a + # string after the isinstance check. + if isinstance(k, string_types) and cast(str, k).lower() in self.denylist: d[k] = AnnotatedValue.substituted_because_contains_sensitive_data() def scrub_request(self, event): From 83171ac8271b12aae9c60151a9c2e60673596637 Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Tue, 27 Feb 2024 14:07:08 +0100 Subject: [PATCH 2/4] Removed redundant `isinstance` checks These `isinstance` checks are already performed inside the methods that they were wrapping --- sentry_sdk/scrubber.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sentry_sdk/scrubber.py b/sentry_sdk/scrubber.py index d49ad7f033..b98b745501 100644 --- a/sentry_sdk/scrubber.py +++ b/sentry_sdk/scrubber.py @@ -71,10 +71,8 @@ def scrub_list(self, lst): return for v in lst: - if isinstance(v, dict): - self.scrub_dict(v) - elif isinstance(v, list): - self.scrub_list(v) + self.scrub_dict(v) + self.scrub_list(v) def scrub_dict(self, d): # type: (object) -> None @@ -87,10 +85,8 @@ def scrub_dict(self, d): if isinstance(k, string_types) and cast(str, k).lower() in self.denylist: d[k] = AnnotatedValue.substituted_because_contains_sensitive_data() elif self.recursive: - if isinstance(v, dict): - self.scrub_dict(v) - elif isinstance(v, list): - self.scrub_list(v) + self.scrub_dict(v) + self.scrub_list(v) def scrub_request(self, event): # type: (Event) -> None From 433e615e7343750d437ef2ddb101764dd43448ae Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Fri, 8 Mar 2024 16:01:15 +0100 Subject: [PATCH 3/4] Clarifying comments --- sentry_sdk/scrubber.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sentry_sdk/scrubber.py b/sentry_sdk/scrubber.py index 467501d41d..cac4bf81b8 100644 --- a/sentry_sdk/scrubber.py +++ b/sentry_sdk/scrubber.py @@ -77,11 +77,17 @@ def scrub_list(self, lst): return for v in lst: - self.scrub_dict(v) - self.scrub_list(v) + self.scrub_dict(v) # no-op unless v is a dict + self.scrub_list(v) # no-op unless v is a list def scrub_dict(self, d): # type: (object) -> None + """ + If a dictionary is passed to this method, the method scrubs the dictionary of any + sensitive data. The method calls itself recursively on any nested dictionaries ( + including dictionaries nested in lists) if self.recursive is True. + This method does nothing if the parameter passed to it is not a dictionary. + """ if not isinstance(d, dict): return @@ -91,8 +97,8 @@ def scrub_dict(self, d): if isinstance(k, string_types) and cast(str, k).lower() in self.denylist: d[k] = AnnotatedValue.substituted_because_contains_sensitive_data() elif self.recursive: - self.scrub_dict(v) - self.scrub_list(v) + self.scrub_dict(v) # no-op unless v is a dict + self.scrub_list(v) # no-op unless v is a list def scrub_request(self, event): # type: (Event) -> None From ef8903f12c16235fa203633fe5026b6250f3f490 Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Fri, 8 Mar 2024 16:04:04 +0100 Subject: [PATCH 4/4] Handle `cast` `ImportError` --- sentry_sdk/scrubber.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/scrubber.py b/sentry_sdk/scrubber.py index cac4bf81b8..3f089ab8f6 100644 --- a/sentry_sdk/scrubber.py +++ b/sentry_sdk/scrubber.py @@ -1,4 +1,7 @@ -from typing import cast +try: + from typing import cast +except ImportError: + cast = lambda _, obj: obj from sentry_sdk.utils import ( capture_internal_exceptions,