Skip to content

Commit 83baac3

Browse files
authored
[MAINTENANCE] Require Metric.name instead of using name inference (#10953)
1 parent c8b7792 commit 83baac3

File tree

4 files changed

+20
-56
lines changed

4 files changed

+20
-56
lines changed

great_expectations/metrics/batch/batch.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from great_expectations.metrics.metric_results import MetricResult
44

55

6-
class BatchRowCount(Metric, Batch): ...
6+
class BatchRowCount(Metric, Batch):
7+
name = "table.row_count"
78

89

910
class BatchRowCountResult(MetricResult[int]): ...

great_expectations/metrics/column_values/between.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77

88
class ColumnValuesBetween(Metric, ColumnValues):
9+
name = "column_values.between.condition"
10+
911
min_value: Optional[Comparable] = None
1012
max_value: Optional[Comparable] = None
1113
strict_min: bool = False

great_expectations/metrics/metric.py

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import re
21
from functools import cache
32
from typing import ClassVar, Final
43

54
from typing_extensions import dataclass_transform
65

7-
from great_expectations.compatibility.pydantic import BaseModel, ModelMetaclass
6+
from great_expectations.compatibility.pydantic import BaseModel, ModelMetaclass, StrictStr
87
from great_expectations.metrics.domain import AbstractClassInstantiationError, Domain
98
from great_expectations.validator.metric_configuration import (
109
MetricConfiguration,
@@ -61,7 +60,7 @@ class Metric(BaseModel, metaclass=MetaMetric):
6160
MetricConfiguration: Configuration class for metric computation
6261
"""
6362

64-
name: ClassVar[str]
63+
name: ClassVar[StrictStr]
6564

6665
class Config:
6766
arbitrary_types_allowed = True
@@ -70,7 +69,6 @@ class Config:
7069
def __new__(cls, *args, **kwargs):
7170
if cls is Metric:
7271
raise AbstractClassInstantiationError(cls.__name__)
73-
cls.name = cls._get_metric_name()
7472
return super().__new__(cls)
7573

7674
@property
@@ -84,41 +82,6 @@ def config(self) -> MetricConfiguration:
8482
metric_value_set=frozenset(self.dict().items()),
8583
)
8684

87-
@staticmethod
88-
def _pascal_to_snake(class_name: str) -> str:
89-
# Adds an underscore between a sequence of uppercase letters and an uppercase-lowercase pair
90-
# APIFunctionMetric -> API_FunctionMetric
91-
class_name = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", class_name)
92-
# Adds an underscore between a lowercase letter/digit and an uppercase letter
93-
# APIFunctionMetric -> API_Function_Metric
94-
class_name = re.sub(r"([a-z\d])([A-Z])", r"\1_\2", class_name)
95-
# Convert the entire string to lowercase
96-
# API_Function_Metric -> api_function_metric
97-
return class_name.lower()
98-
99-
@classmethod
100-
def _get_metric_name(cls) -> str:
101-
"""The name of the metric as it exists in the registry."""
102-
for base_type in cls.__bases__:
103-
if issubclass(base_type, Domain):
104-
domain_class_name = str(base_type.__name__)
105-
metric_class_name = str(cls.__name__)
106-
domain_class_snake_case = Metric._pascal_to_snake(domain_class_name)
107-
translated_domain_name = domain_class_snake_case.replace("batch", "table")
108-
metric_class_snake_case = Metric._pascal_to_snake(metric_class_name)
109-
# the convention is that the metric class name includes the domain class name
110-
# but the metric names don't repeat the domain name, so we remove it
111-
return ".".join(
112-
[
113-
translated_domain_name,
114-
metric_class_snake_case.replace(domain_class_snake_case, "").strip("_"),
115-
]
116-
)
117-
118-
# this should never be reached
119-
# that a Domain exists in __bases__ should have been confirmed in MetaMetric.__new__
120-
raise MixinTypeError(cls.__name__, "Domain")
121-
12285
@staticmethod
12386
@cache
12487
def _to_config(

tests/metrics/test_metric.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class TestMetricDefinition:
3434
@pytest.mark.unit
3535
def test_success(self):
3636
class ColumnValuesAbove(Metric, ColumnValues):
37+
name = FULLY_QUALIFIED_METRIC_NAME
38+
3739
min_value: Comparable
3840
strict_min: bool = False
3941

@@ -42,6 +44,8 @@ def test_missing_domain_mixin_raises(self):
4244
with pytest.raises(MixinTypeError):
4345

4446
class ColumnValuesAbove(Metric):
47+
name = FULLY_QUALIFIED_METRIC_NAME
48+
4549
min_value: Comparable
4650
strict_min: bool = False
4751

@@ -50,6 +54,8 @@ def test_more_than_one_domain_mixin_raises(self):
5054
with pytest.raises(MixinTypeError):
5155

5256
class ColumnValuesAbove(Metric, ColumnValues, MockDomain):
57+
name = FULLY_QUALIFIED_METRIC_NAME
58+
5359
min_value: Comparable
5460
strict_min: bool = False
5561

@@ -58,28 +64,16 @@ def test_non_domain_mixin_raises(self):
5864
with pytest.raises(MixinTypeError):
5965

6066
class ColumnValuesAbove(Metric, NotADomain):
67+
name = FULLY_QUALIFIED_METRIC_NAME
68+
6169
min_value: Comparable
6270
strict_min: bool = False
6371

64-
@pytest.mark.unit
65-
def test_metric_name_inference(self):
66-
class ColumnValuesAbove(Metric, ColumnValues):
67-
min_value: Comparable
68-
strict_min: bool = False
69-
70-
assert (
71-
ColumnValuesAbove(
72-
batch_id=BATCH_ID,
73-
table=TABLE,
74-
column=COLUMN,
75-
min_value=42,
76-
).name
77-
== FULLY_QUALIFIED_METRIC_NAME
78-
)
79-
8072

8173
class TestMetricInstantiation:
8274
class ColumnValuesAbove(Metric, ColumnValues):
75+
name = FULLY_QUALIFIED_METRIC_NAME
76+
8377
min_value: Comparable
8478
strict_min: bool = False
8579

@@ -100,6 +94,8 @@ def test_instantiation_missing_domain_parameters_raises(self):
10094

10195
class TestMetricConfig:
10296
class ColumnValuesAbove(Metric, ColumnValues):
97+
name = FULLY_QUALIFIED_METRIC_NAME
98+
10399
min_value: Comparable
104100
strict_min: bool = False
105101

@@ -134,6 +130,8 @@ def test_success(self):
134130

135131
class TestMetricImmutability:
136132
class ColumnValuesAbove(Metric, ColumnValues):
133+
name = FULLY_QUALIFIED_METRIC_NAME
134+
137135
min_value: Comparable
138136
strict_min: bool = False
139137

0 commit comments

Comments
 (0)