Skip to content

Commit 0992798

Browse files
committed
s/GroupingComponent/BaseGroupingComponent
1 parent 3a789e4 commit 0992798

File tree

13 files changed

+93
-91
lines changed

13 files changed

+93
-91
lines changed

src/sentry/grouping/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
Here an example of how components can be used::
8888
8989
function_name = 'lambda$1234'
90-
threads = GroupingComponent(
90+
threads = BaseGroupingComponent(
9191
id="function",
9292
values=[function_name],
9393
contributes=False,

src/sentry/grouping/api.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import sentry_sdk
99

1010
from sentry import options
11-
from sentry.grouping.component import GroupingComponent
11+
from sentry.grouping.component import BaseGroupingComponent
1212
from sentry.grouping.enhancer import LATEST_VERSION, Enhancements
1313
from sentry.grouping.enhancer.exceptions import InvalidEnhancerConfig
1414
from sentry.grouping.strategies.base import DEFAULT_GROUPING_ENHANCEMENTS_BASE, GroupingContext
@@ -264,10 +264,10 @@ def apply_server_fingerprinting(event, config, allow_custom_title=True):
264264

265265
def _get_calculated_grouping_variants_for_event(
266266
event: Event, context: GroupingContext
267-
) -> dict[str, GroupingComponent]:
267+
) -> dict[str, BaseGroupingComponent]:
268268
winning_strategy: str | None = None
269269
precedence_hint: str | None = None
270-
per_variant_components: dict[str, list[GroupingComponent]] = {}
270+
per_variant_components: dict[str, list[BaseGroupingComponent]] = {}
271271

272272
for strategy in context.config.iter_strategies():
273273
# Defined in src/sentry/grouping/strategies/base.py
@@ -292,7 +292,7 @@ def _get_calculated_grouping_variants_for_event(
292292

293293
rv = {}
294294
for variant, components in per_variant_components.items():
295-
component = GroupingComponent(id=variant, values=components)
295+
component = BaseGroupingComponent(id=variant, values=components)
296296
if not component.contributes and precedence_hint:
297297
component.update(hint=precedence_hint)
298298
rv[variant] = component

src/sentry/grouping/component.py

+17-15
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,29 @@
2323
}
2424

2525

26-
def _calculate_contributes(values: Sequence[str | int | GroupingComponent]) -> bool:
26+
def _calculate_contributes(values: Sequence[str | int | BaseGroupingComponent]) -> bool:
2727
for value in values or ():
28-
if not isinstance(value, GroupingComponent) or value.contributes:
28+
if not isinstance(value, BaseGroupingComponent) or value.contributes:
2929
return True
3030
return False
3131

3232

33-
class GroupingComponent:
33+
class BaseGroupingComponent:
3434
"""A grouping component is a recursive structure that is flattened
3535
into components to make a hash for grouping purposes.
3636
"""
3737

3838
id: str = "default"
3939
hint: str | None = None
4040
contributes: bool = False
41-
values: Sequence[str | int | GroupingComponent]
41+
values: Sequence[str | int | BaseGroupingComponent]
4242

4343
def __init__(
4444
self,
4545
id: str,
4646
hint: str | None = None,
4747
contributes: bool | None = None,
48-
values: Sequence[str | int | GroupingComponent] | None = None,
48+
values: Sequence[str | int | BaseGroupingComponent] | None = None,
4949
variant_provider: bool = False,
5050
):
5151
self.id = id
@@ -72,13 +72,15 @@ def description(self) -> str:
7272
# Keep track of the paths we walk so later we can pick the longest one
7373
paths = []
7474

75-
def _walk_components(component: GroupingComponent, current_path: list[str | None]) -> None:
75+
def _walk_components(
76+
component: BaseGroupingComponent, current_path: list[str | None]
77+
) -> None:
7678
# Keep track of the names of the nodes from the root of the component tree to here
7779
current_path.append(component.name)
7880

7981
# Walk the tree, looking for contributing components.
8082
for value in component.values:
81-
if isinstance(value, GroupingComponent) and value.contributes:
83+
if isinstance(value, BaseGroupingComponent) and value.contributes:
8284
_walk_components(value, current_path)
8385

8486
# Filter out the `None`s (which come from components not in `KNOWN_MAJOR_COMPONENT_NAMES`)
@@ -99,16 +101,16 @@ def _walk_components(component: GroupingComponent, current_path: list[str | None
99101

100102
def get_subcomponent(
101103
self, id: str, only_contributing: bool = False
102-
) -> str | int | GroupingComponent | None:
104+
) -> str | int | BaseGroupingComponent | None:
103105
"""Looks up a subcomponent by the id and returns the first or `None`."""
104106
return next(self.iter_subcomponents(id=id, only_contributing=only_contributing), None)
105107

106108
def iter_subcomponents(
107109
self, id: str, recursive: bool = False, only_contributing: bool = False
108-
) -> Iterator[str | int | GroupingComponent | None]:
110+
) -> Iterator[str | int | BaseGroupingComponent | None]:
109111
"""Finds all subcomponents matching an id, optionally recursively."""
110112
for value in self.values:
111-
if isinstance(value, GroupingComponent):
113+
if isinstance(value, BaseGroupingComponent):
112114
if only_contributing and not value.contributes:
113115
continue
114116
if value.id == id:
@@ -123,7 +125,7 @@ def update(
123125
self,
124126
hint: str | None = None,
125127
contributes: bool | None = None,
126-
values: Sequence[str | int | GroupingComponent] | None = None,
128+
values: Sequence[str | int | BaseGroupingComponent] | None = None,
127129
) -> None:
128130
"""Updates an already existing component with new values."""
129131
if hint is not None:
@@ -135,20 +137,20 @@ def update(
135137
if contributes is not None:
136138
self.contributes = contributes
137139

138-
def shallow_copy(self) -> GroupingComponent:
140+
def shallow_copy(self) -> BaseGroupingComponent:
139141
"""Creates a shallow copy."""
140142
rv = object.__new__(self.__class__)
141143
rv.__dict__.update(self.__dict__)
142144
rv.values = list(self.values)
143145
return rv
144146

145-
def iter_values(self) -> Generator[str | int | GroupingComponent]:
147+
def iter_values(self) -> Generator[str | int | BaseGroupingComponent]:
146148
"""Recursively walks the component and flattens it into a list of
147149
values.
148150
"""
149151
if self.contributes:
150152
for value in self.values:
151-
if isinstance(value, GroupingComponent):
153+
if isinstance(value, BaseGroupingComponent):
152154
yield from value.iter_values()
153155
else:
154156
yield value
@@ -170,7 +172,7 @@ def as_dict(self) -> dict[str, Any]:
170172
"values": [],
171173
}
172174
for value in self.values:
173-
if isinstance(value, GroupingComponent):
175+
if isinstance(value, BaseGroupingComponent):
174176
rv["values"].append(value.as_dict())
175177
else:
176178
# This basically assumes that a value is only a primitive

src/sentry/grouping/enhancer/__init__.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from sentry_ophio.enhancers import Enhancements as RustEnhancements
1616

1717
from sentry import projectoptions
18-
from sentry.grouping.component import GroupingComponent
18+
from sentry.grouping.component import BaseGroupingComponent
1919
from sentry.stacktraces.functions import set_in_app
2020
from sentry.utils.safe import get_path, set_path
2121

@@ -164,11 +164,11 @@ def apply_modifications_to_frame(
164164

165165
def assemble_stacktrace_component(
166166
self,
167-
components: list[GroupingComponent],
167+
components: list[BaseGroupingComponent],
168168
frames: list[dict[str, Any]],
169169
platform: str | None,
170170
exception_data: dict[str, Any] | None = None,
171-
) -> tuple[GroupingComponent, bool]:
171+
) -> tuple[BaseGroupingComponent, bool]:
172172
"""
173173
This assembles a `stacktrace` grouping component out of the given
174174
`frame` components and source frames.
@@ -186,7 +186,7 @@ def assemble_stacktrace_component(
186186
for py_component, rust_component in zip(components, rust_components):
187187
py_component.update(contributes=rust_component.contributes, hint=rust_component.hint)
188188

189-
component = GroupingComponent(
189+
component = BaseGroupingComponent(
190190
id="stacktrace",
191191
values=components,
192192
hint=rust_results.hint,

src/sentry/grouping/strategies/base.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from sentry import projectoptions
66
from sentry.eventstore.models import Event
7-
from sentry.grouping.component import GroupingComponent
7+
from sentry.grouping.component import BaseGroupingComponent
88
from sentry.grouping.enhancer import Enhancements
99
from sentry.interfaces.base import Interface
1010

@@ -24,7 +24,7 @@
2424
DEFAULT_GROUPING_ENHANCEMENTS_BASE = "common:2019-03-23"
2525
DEFAULT_GROUPING_FINGERPRINTING_BASES: list[str] = []
2626

27-
ReturnedVariants = dict[str, GroupingComponent]
27+
ReturnedVariants = dict[str, BaseGroupingComponent]
2828
ConcreteInterface = TypeVar("ConcreteInterface", bound=Interface, contravariant=True)
2929

3030

@@ -117,7 +117,7 @@ def get_grouping_component(
117117

118118
def get_single_grouping_component(
119119
self, interface: Interface, *, event: Event, **kwargs: Any
120-
) -> GroupingComponent:
120+
) -> BaseGroupingComponent:
121121
"""Invokes a delegate grouping strategy. If no such delegate is
122122
configured a fallback grouping component is returned.
123123
"""
@@ -193,7 +193,7 @@ def variant_processor(self, func: VariantProcessor) -> VariantProcessor:
193193

194194
def get_grouping_component(
195195
self, event: Event, context: GroupingContext, variant: str | None = None
196-
) -> None | GroupingComponent | ReturnedVariants:
196+
) -> None | BaseGroupingComponent | ReturnedVariants:
197197
"""Given a specific variant this calculates the grouping component."""
198198
args = []
199199
iface = event.interfaces.get(self.interface)

src/sentry/grouping/strategies/legacy.py

+16-16
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Any
44

55
from sentry.eventstore.models import Event
6-
from sentry.grouping.component import GroupingComponent
6+
from sentry.grouping.component import BaseGroupingComponent
77
from sentry.grouping.strategies.base import (
88
GroupingContext,
99
ReturnedVariants,
@@ -164,17 +164,17 @@ def single_exception_legacy(
164164
interface: SingleException, event: Event, context: GroupingContext, **meta: Any
165165
) -> ReturnedVariants:
166166

167-
type_component = GroupingComponent(
167+
type_component = BaseGroupingComponent(
168168
id="type",
169169
values=[interface.type] if interface.type else [],
170170
contributes=False,
171171
)
172-
value_component = GroupingComponent(
172+
value_component = BaseGroupingComponent(
173173
id="value",
174174
values=[interface.value] if interface.value else [],
175175
contributes=False,
176176
)
177-
stacktrace_component = GroupingComponent(id="stacktrace")
177+
stacktrace_component = BaseGroupingComponent(id="stacktrace")
178178

179179
if interface.stacktrace is not None:
180180
stacktrace_component = context.get_single_grouping_component(
@@ -195,7 +195,7 @@ def single_exception_legacy(
195195
value_component.update(contributes=True)
196196

197197
return {
198-
context["variant"]: GroupingComponent(
198+
context["variant"]: BaseGroupingComponent(
199199
id="exception", values=[stacktrace_component, type_component, value_component]
200200
)
201201
}
@@ -231,7 +231,7 @@ def chained_exception_legacy(
231231
if stacktrace_component is None or not stacktrace_component.contributes:
232232
value.update(contributes=False, hint="exception has no stacktrace")
233233

234-
return {context["variant"]: GroupingComponent(id="chained-exception", values=values)}
234+
return {context["variant"]: BaseGroupingComponent(id="chained-exception", values=values)}
235235

236236

237237
@chained_exception_legacy.variant_processor
@@ -262,7 +262,7 @@ def frame_legacy(
262262
# Safari throws [native code] frames in for calls like ``forEach``
263263
# whereas Chrome ignores these. Let's remove it from the hashing algo
264264
# so that they're more likely to group together
265-
filename_component = GroupingComponent(id="filename")
265+
filename_component = BaseGroupingComponent(id="filename")
266266
if interface.filename == "<anonymous>":
267267
filename_component.update(
268268
contributes=False, values=[interface.filename], hint="anonymous filename discarded"
@@ -293,7 +293,7 @@ def frame_legacy(
293293
# if we have a module we use that for grouping. This will always
294294
# take precedence over the filename, even if the module is
295295
# considered unhashable.
296-
module_component = GroupingComponent(id="module")
296+
module_component = BaseGroupingComponent(id="module")
297297
if interface.module:
298298
if is_unhashable_module_legacy(interface, platform):
299299
module_component.update(values=["<module>"], hint="normalized generated module name")
@@ -306,7 +306,7 @@ def frame_legacy(
306306
)
307307

308308
# Context line when available is the primary contributor
309-
context_line_component = GroupingComponent(id="context-line")
309+
context_line_component = BaseGroupingComponent(id="context-line")
310310
if interface.context_line is not None:
311311
if len(interface.context_line) > 120:
312312
context_line_component.update(hint="discarded because line too long")
@@ -315,9 +315,9 @@ def frame_legacy(
315315
else:
316316
context_line_component.update(values=[interface.context_line])
317317

318-
symbol_component = GroupingComponent(id="symbol")
319-
function_component = GroupingComponent(id="function")
320-
lineno_component = GroupingComponent(id="lineno")
318+
symbol_component = BaseGroupingComponent(id="symbol")
319+
function_component = BaseGroupingComponent(id="function")
320+
lineno_component = BaseGroupingComponent(id="lineno")
321321

322322
# The context line grouping information is the most reliable one.
323323
# If we did not manage to find some information there, we want to
@@ -369,7 +369,7 @@ def frame_legacy(
369369
)
370370

371371
return {
372-
context["variant"]: GroupingComponent(
372+
context["variant"]: BaseGroupingComponent(
373373
id="frame",
374374
values=[
375375
module_component,
@@ -450,7 +450,7 @@ def threads_legacy(
450450
thread_count = len(interface.values)
451451
if thread_count != 1:
452452
return {
453-
context["variant"]: GroupingComponent(
453+
context["variant"]: BaseGroupingComponent(
454454
id="threads",
455455
contributes=False,
456456
hint="ignored because contains %d threads" % thread_count,
@@ -460,13 +460,13 @@ def threads_legacy(
460460
stacktrace: Stacktrace = interface.values[0].get("stacktrace")
461461
if not stacktrace:
462462
return {
463-
context["variant"]: GroupingComponent(
463+
context["variant"]: BaseGroupingComponent(
464464
id="threads", contributes=False, hint="thread has no stacktrace"
465465
)
466466
}
467467

468468
return {
469-
context["variant"]: GroupingComponent(
469+
context["variant"]: BaseGroupingComponent(
470470
id="threads",
471471
values=[context.get_single_grouping_component(stacktrace, event=event, **meta)],
472472
)

src/sentry/grouping/strategies/message.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from sentry import analytics
55
from sentry.eventstore.models import Event
66
from sentry.features.rollout import in_rollout_group
7-
from sentry.grouping.component import GroupingComponent
7+
from sentry.grouping.component import BaseGroupingComponent
88
from sentry.grouping.parameterization import Parameterizer, UniqueIdExperiment
99
from sentry.grouping.strategies.base import (
1010
GroupingContext,
@@ -109,15 +109,15 @@ def message_v1(
109109
normalized = normalize_message_for_grouping(raw, event)
110110
hint = "stripped event-specific values" if raw != normalized else None
111111
return {
112-
context["variant"]: GroupingComponent(
112+
context["variant"]: BaseGroupingComponent(
113113
id="message",
114114
values=[normalized],
115115
hint=hint,
116116
)
117117
}
118118
else:
119119
return {
120-
context["variant"]: GroupingComponent(
120+
context["variant"]: BaseGroupingComponent(
121121
id="message",
122122
values=[interface.message or interface.formatted or ""],
123123
)

0 commit comments

Comments
 (0)