Skip to content

Commit

Permalink
ref: Improve scrub_dict typing (#2768)
Browse files Browse the repository at this point in the history
This change improves the typing of the scrub_dict method.

Previously, the scrub_dict method's type hints indicated that only dict[str, Any] was accepted as the parameter. However, the method is actually implemented to accept any object, since it checks the types of the parameters at runtime. Therefore, object is a more appropriate type hint for the parameter.

#2753 depends on this change for mypy to pass
  • Loading branch information
szokeasaurusrex authored Mar 11, 2024
1 parent 1b0e932 commit 461bd59
Showing 1 changed file with 20 additions and 13 deletions.
33 changes: 20 additions & 13 deletions sentry_sdk/scrubber.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
try:
from typing import cast
except ImportError:
cast = lambda _, obj: obj

from sentry_sdk.utils import (
capture_internal_exceptions,
AnnotatedValue,
Expand All @@ -8,8 +13,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

Expand Down Expand Up @@ -66,7 +69,7 @@ def __init__(self, denylist=None, recursive=False):
self.recursive = recursive

def scrub_list(self, lst):
# type: (List[Any]) -> None
# type: (object) -> None
"""
If a list is passed to this method, the method recursively searches the list and any
nested lists for any dictionaries. The method calls scrub_dict on all dictionaries
Expand All @@ -77,24 +80,28 @@ 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) # no-op unless v is a dict
self.scrub_list(v) # no-op unless v is a list

def scrub_dict(self, d):
# type: (Dict[str, Any]) -> None
# 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

for k, v in d.items():
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()
elif self.recursive:
if isinstance(v, dict):
self.scrub_dict(v)
elif isinstance(v, list):
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
Expand Down

0 comments on commit 461bd59

Please sign in to comment.