diff --git a/.changelog/5402.fixed b/.changelog/5402.fixed new file mode 100644 index 00000000000..7ba5f9b424b --- /dev/null +++ b/.changelog/5402.fixed @@ -0,0 +1 @@ +`opentelemetry-codegen-json`: support decoding enums from names diff --git a/codegen/opentelemetry-codegen-json/src/opentelemetry/codegen/json/generator.py b/codegen/opentelemetry-codegen-json/src/opentelemetry/codegen/json/generator.py index b8be0355246..76ba0c712dd 100644 --- a/codegen/opentelemetry-codegen-json/src/opentelemetry/codegen/json/generator.py +++ b/codegen/opentelemetry-codegen-json/src/opentelemetry/codegen/json/generator.py @@ -325,7 +325,6 @@ def _generate_imports( std_imports = [ "builtins", "dataclasses", - "functools", "typing", ] if include_enum: @@ -336,12 +335,6 @@ def _generate_imports( writer.blank_line() - writer.assignment( - "_dataclass", - "functools.partial(dataclasses.dataclass, slots=True)", - ) - writer.blank_line() - # Collect all imports needed imports = self._collect_imports(proto_file) imports.add(f"import {self._get_codec_module_path()}") @@ -428,7 +421,7 @@ def _generate_message_class( msg_desc.name, bases=(f"{codec}.JsonMessage",), decorators=("typing.final",), - decorator_name="_dataclass", + slots=True, ): if msg_desc.field or msg_desc.nested_type or msg_desc.enum_type: writer.docstring( @@ -770,12 +763,9 @@ def _generate_deserialization_statements( enum_type = self._resolve_enum_type( field_desc.type_name, proto_file ) - writer.writeln( - f'{codec}.validate_type({var_name}, builtins.int, "{field_desc.name}")' - ) writer.assignment( f'{target_dict}["{field_desc.name}"]', - f"{enum_type}({var_name})", + f'{codec}.decode_enum({var_name}, {enum_type}, "{field_desc.name}")', ) elif is_hex_encoded_field(field_desc.name): writer.assignment( @@ -837,7 +827,7 @@ def _get_deserialization_expr( enum_type = self._resolve_enum_type( field_desc.type_name, proto_file ) - return f"{enum_type}({var_name})" + return f'{codec}.decode_enum({var_name}, {enum_type}, "{field_desc.name}")' if is_hex_encoded_field(field_desc.name): return f'{codec}.decode_hex({var_name}, "{field_desc.name}")' if is_int64_type(field_desc.type): diff --git a/codegen/opentelemetry-codegen-json/src/opentelemetry/codegen/json/runtime/json_codec.py b/codegen/opentelemetry-codegen-json/src/opentelemetry/codegen/json/runtime/json_codec.py index 72c315d1eaa..67f52c1370c 100644 --- a/codegen/opentelemetry-codegen-json/src/opentelemetry/codegen/json/runtime/json_codec.py +++ b/codegen/opentelemetry-codegen-json/src/opentelemetry/codegen/json/runtime/json_codec.py @@ -6,12 +6,14 @@ import abc import base64 import collections.abc +import enum import json import math import typing T = typing.TypeVar("T") M = typing.TypeVar("M", bound="JsonMessage") +EnumT = typing.TypeVar("EnumT", bound=enum.IntEnum) class JsonMessage(abc.ABC): @@ -246,3 +248,27 @@ def validate_type( f"Field '{field_name}' expected {expected_types}, " f"got {type(value).__name__}" ) + + +def decode_enum( + value: typing.Any, + enum_type: type[EnumT], + field_name: str, +) -> EnumT: + """ + Decode a JSON enum value into an enum member. + + Per the ProtoJSON spec, parsers must accept both enum names (str) + and integer values (int). + + Args: + value: The enum name or integer value to decode. + enum_type: The enum class to decode into. + field_name: The name of the field being decoded (for error messages). + Returns: + The corresponding enum member. + """ + validate_type(value, (int, str), field_name) + if isinstance(value, str): + return enum_type[value] + return enum_type(value) diff --git a/codegen/opentelemetry-codegen-json/tests/test_json_codec.py b/codegen/opentelemetry-codegen-json/tests/test_json_codec.py index aa24f838d51..432e2b8e661 100644 --- a/codegen/opentelemetry-codegen-json/tests/test_json_codec.py +++ b/codegen/opentelemetry-codegen-json/tests/test_json_codec.py @@ -1,12 +1,15 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 +import enum import math +from typing import Any import pytest # type: ignore from opentelemetry.codegen.json.runtime.json_codec import ( decode_base64, + decode_enum, decode_float, decode_hex, decode_int64, @@ -20,6 +23,12 @@ ) +class _Color(enum.IntEnum): + RED = 0 + GREEN = 1 + BLUE = 2 + + @pytest.mark.parametrize( "value, expected", [ @@ -189,3 +198,31 @@ def test_validate_type() -> None: match=r"Field 'field' expected \(, \), got str", ): validate_type("s", (int, float), "field") + + +@pytest.mark.parametrize( + "value, expected", + [ + (1, _Color.GREEN), + ("GREEN", _Color.GREEN), + (0, _Color.RED), + ("RED", _Color.RED), + ], +) +def test_decode_enum(value: int | str, expected: _Color) -> None: + assert decode_enum(value, _Color, "field") is expected + + +@pytest.mark.parametrize( + "value, expected_error", + [ + ([], TypeError), + (99, ValueError), + ("NOT_A_COLOR", KeyError), + ], +) +def test_decode_enum_errors( + value: Any, expected_error: type[Exception] +) -> None: + with pytest.raises(expected_error): + decode_enum(value, _Color, "field") diff --git a/codegen/opentelemetry-codegen-json/tests/test_serde.py b/codegen/opentelemetry-codegen-json/tests/test_serde.py index e89453ea6a6..962417261a0 100644 --- a/codegen/opentelemetry-codegen-json/tests/test_serde.py +++ b/codegen/opentelemetry-codegen-json/tests/test_serde.py @@ -105,6 +105,19 @@ def test_generated_message_roundtrip( assert new_msg == msg +def test_enum_field_accepts_name_and_int( + test_v1_types: tuple[type[Any], type[Any]], +) -> None: + TestMessage, _ = test_v1_types + + from_name = TestMessage.from_dict({"enumValue": "SUCCESS"}) + from_int = TestMessage.from_dict({"enumValue": 1}) + + assert from_name.enum_value == TestMessage.TestEnum.SUCCESS + assert from_int.enum_value == TestMessage.TestEnum.SUCCESS + assert from_name == from_int + + def test_cross_reference( common_v1_types: type[Any], trace_v1_types: type[Any] ) -> None: @@ -256,6 +269,25 @@ def test_nested_enum_suite(complex_v1_types: tuple[type[Any], ...]) -> None: assert new_msg.repeated_nested == msg.repeated_nested +def test_nested_enum_suite_accepts_names( + complex_v1_types: tuple[type[Any], ...], +) -> None: + NestedEnumSuite = complex_v1_types[3] + + msg = NestedEnumSuite.from_dict( + { + "nested": "NESTED_FOO", + "repeatedNested": ["NESTED_FOO", "NESTED_BAR"], + } + ) + + assert msg.nested == NestedEnumSuite.NestedEnum.NESTED_FOO + assert msg.repeated_nested == [ + NestedEnumSuite.NestedEnum.NESTED_FOO, + NestedEnumSuite.NestedEnum.NESTED_BAR, + ] + + def test_deeply_nested(complex_v1_types: tuple[type[Any], ...]) -> None: DeeplyNested = complex_v1_types[4] @@ -304,7 +336,8 @@ def test_defaults_and_none( ({"listStrings": "not a list"}, TypeError, "expected "), ({"name": 123}, TypeError, "expected "), ({"subMessage": "not a dict"}, TypeError, "expected "), - ({"enumValue": "SUCCESS"}, TypeError, "expected "), + ({"enumValue": []}, TypeError, "expected"), + ({"enumValue": "NOT_A_NAME"}, KeyError, None), ({"listMessages": [None]}, TypeError, "expected "), ], ) diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/_json_codec.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/_json_codec.py index 72c315d1eaa..67f52c1370c 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/_json_codec.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/_json_codec.py @@ -6,12 +6,14 @@ import abc import base64 import collections.abc +import enum import json import math import typing T = typing.TypeVar("T") M = typing.TypeVar("M", bound="JsonMessage") +EnumT = typing.TypeVar("EnumT", bound=enum.IntEnum) class JsonMessage(abc.ABC): @@ -246,3 +248,27 @@ def validate_type( f"Field '{field_name}' expected {expected_types}, " f"got {type(value).__name__}" ) + + +def decode_enum( + value: typing.Any, + enum_type: type[EnumT], + field_name: str, +) -> EnumT: + """ + Decode a JSON enum value into an enum member. + + Per the ProtoJSON spec, parsers must accept both enum names (str) + and integer values (int). + + Args: + value: The enum name or integer value to decode. + enum_type: The enum class to decode into. + field_name: The name of the field being decoded (for error messages). + Returns: + The corresponding enum member. + """ + validate_type(value, (int, str), field_name) + if isinstance(value, str): + return enum_type[value] + return enum_type(value) diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/logs/v1/logs_service.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/logs/v1/logs_service.py index 899c965fa3c..8ff1dda343e 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/logs/v1/logs_service.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/logs/v1/logs_service.py @@ -8,17 +8,14 @@ import builtins import dataclasses -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec import opentelemetry.proto_json.logs.v1.logs @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportLogsServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportLogsServiceRequest @@ -59,7 +56,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ExportLogs @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportLogsServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportLogsServiceResponse @@ -100,7 +97,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ExportLogs @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportLogsPartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportLogsPartialSuccess diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py index 6537d1031f4..6603920e9d2 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py @@ -8,17 +8,14 @@ import builtins import dataclasses -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec import opentelemetry.proto_json.metrics.v1.metrics @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportMetricsServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportMetricsServiceRequest @@ -59,7 +56,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ExportMetr @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportMetricsServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportMetricsServiceResponse @@ -100,7 +97,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ExportMetr @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportMetricsPartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportMetricsPartialSuccess diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py index faaaa6105c1..ab73f0fc1ab 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py @@ -8,17 +8,14 @@ import builtins import dataclasses -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec import opentelemetry.proto_json.profiles.v1development.profiles @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportProfilesServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportProfilesServiceRequest @@ -64,7 +61,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ExportProf @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportProfilesServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportProfilesServiceResponse @@ -105,7 +102,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ExportProf @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportProfilesPartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportProfilesPartialSuccess diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/trace/v1/trace_service.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/trace/v1/trace_service.py index 27d3a1a1e0a..39175e2b1e4 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/trace/v1/trace_service.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/collector/trace/v1/trace_service.py @@ -8,17 +8,14 @@ import builtins import dataclasses -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec import opentelemetry.proto_json.trace.v1.trace @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportTraceServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportTraceServiceRequest @@ -59,7 +56,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ExportTrac @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportTraceServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportTraceServiceResponse @@ -100,7 +97,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ExportTrac @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExportTracePartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExportTracePartialSuccess diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/common/v1/common.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/common/v1/common.py index 6942227f98b..b3adcb8f477 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/common/v1/common.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/common/v1/common.py @@ -8,16 +8,13 @@ import builtins import dataclasses -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class AnyValue(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message AnyValue @@ -96,7 +93,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "AnyValue": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ArrayValue(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ArrayValue @@ -137,7 +134,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ArrayValue @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class KeyValueList(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message KeyValueList @@ -178,7 +175,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "KeyValueLi @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class KeyValue(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message KeyValue @@ -231,7 +228,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "KeyValue": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class InstrumentationScope(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message InstrumentationScope @@ -290,7 +287,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Instrument @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class EntityRef(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message EntityRef diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/logs/v1/logs.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/logs/v1/logs.py index e978df472f3..ca4486b221f 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/logs/v1/logs.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/logs/v1/logs.py @@ -9,11 +9,8 @@ import builtins import dataclasses import enum -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec import opentelemetry.proto_json.common.v1.common import opentelemetry.proto_json.resource.v1.resource @@ -61,7 +58,7 @@ class LogRecordFlags(enum.IntEnum): LOG_RECORD_FLAGS_TRACE_FLAGS_MASK = 255 @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class LogsData(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message LogsData @@ -102,7 +99,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "LogsData": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ResourceLogs(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ResourceLogs @@ -154,7 +151,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ResourceLo @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ScopeLogs(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ScopeLogs @@ -206,7 +203,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ScopeLogs" @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class LogRecord(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message LogRecord @@ -275,8 +272,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "LogRecord" if (_value := data.get("observedTimeUnixNano")) is not None: _args["observed_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "observed_time_unix_nano") if (_value := data.get("severityNumber")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "severity_number") - _args["severity_number"] = SeverityNumber(_value) + _args["severity_number"] = opentelemetry.proto_json._json_codec.decode_enum(_value, SeverityNumber, "severity_number") if (_value := data.get("severityText")) is not None: opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "severity_text") _args["severity_text"] = _value diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/metrics/v1/metrics.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/metrics/v1/metrics.py index a5f63651352..51c0798cbad 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/metrics/v1/metrics.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/metrics/v1/metrics.py @@ -9,11 +9,8 @@ import builtins import dataclasses import enum -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec import opentelemetry.proto_json.common.v1.common import opentelemetry.proto_json.resource.v1.resource @@ -39,7 +36,7 @@ class DataPointFlags(enum.IntEnum): DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK = 1 @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class MetricsData(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message MetricsData @@ -80,7 +77,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "MetricsDat @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ResourceMetrics(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ResourceMetrics @@ -132,7 +129,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ResourceMe @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ScopeMetrics(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ScopeMetrics @@ -184,7 +181,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ScopeMetri @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Metric(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Metric @@ -268,7 +265,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Metric": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Gauge(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Gauge @@ -309,7 +306,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Gauge": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Sum(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Sum @@ -352,8 +349,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Sum": if (_value := data.get("dataPoints")) is not None: _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: NumberDataPoint.from_dict(_v), "data_points") if (_value := data.get("aggregationTemporality")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "aggregation_temporality") - _args["aggregation_temporality"] = AggregationTemporality(_value) + _args["aggregation_temporality"] = opentelemetry.proto_json._json_codec.decode_enum(_value, AggregationTemporality, "aggregation_temporality") if (_value := data.get("isMonotonic")) is not None: opentelemetry.proto_json._json_codec.validate_type(_value, builtins.bool, "is_monotonic") _args["is_monotonic"] = _value @@ -362,7 +358,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Sum": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Histogram(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Histogram @@ -402,14 +398,13 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Histogram" if (_value := data.get("dataPoints")) is not None: _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: HistogramDataPoint.from_dict(_v), "data_points") if (_value := data.get("aggregationTemporality")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "aggregation_temporality") - _args["aggregation_temporality"] = AggregationTemporality(_value) + _args["aggregation_temporality"] = opentelemetry.proto_json._json_codec.decode_enum(_value, AggregationTemporality, "aggregation_temporality") return cls(**_args) @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExponentialHistogram(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExponentialHistogram @@ -449,14 +444,13 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Exponentia if (_value := data.get("dataPoints")) is not None: _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ExponentialHistogramDataPoint.from_dict(_v), "data_points") if (_value := data.get("aggregationTemporality")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "aggregation_temporality") - _args["aggregation_temporality"] = AggregationTemporality(_value) + _args["aggregation_temporality"] = opentelemetry.proto_json._json_codec.decode_enum(_value, AggregationTemporality, "aggregation_temporality") return cls(**_args) @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Summary(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Summary @@ -497,7 +491,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Summary": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class NumberDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message NumberDataPoint @@ -569,7 +563,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "NumberData @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class HistogramDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message HistogramDataPoint @@ -661,14 +655,14 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "HistogramD @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ExponentialHistogramDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ExponentialHistogramDataPoint """ @typing.final - @_dataclass + @dataclasses.dataclass(slots=True) class Buckets(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Buckets @@ -815,14 +809,14 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Exponentia @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class SummaryDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message SummaryDataPoint """ @typing.final - @_dataclass + @dataclasses.dataclass(slots=True) class ValueAtQuantile(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ValueAtQuantile @@ -932,7 +926,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "SummaryDat @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Exemplar(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Exemplar diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/profiles/v1development/profiles.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/profiles/v1development/profiles.py index 3d3bd90d22f..b769e9a6ca4 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/profiles/v1development/profiles.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/profiles/v1development/profiles.py @@ -8,18 +8,15 @@ import builtins import dataclasses -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec import opentelemetry.proto_json.common.v1.common import opentelemetry.proto_json.resource.v1.resource @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ProfilesDictionary(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ProfilesDictionary @@ -90,7 +87,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ProfilesDi @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ProfilesData(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ProfilesData @@ -136,7 +133,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ProfilesDa @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ResourceProfiles(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ResourceProfiles @@ -188,7 +185,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ResourcePr @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ScopeProfiles(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ScopeProfiles @@ -240,7 +237,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ScopeProfi @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Profile(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Profile @@ -333,7 +330,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Profile": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Link(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Link @@ -379,7 +376,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Link": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ValueType(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ValueType @@ -427,7 +424,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ValueType" @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Sample(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Sample @@ -490,7 +487,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Sample": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Mapping(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Mapping @@ -552,7 +549,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Mapping": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Stack(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Stack @@ -593,7 +590,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Stack": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Location(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Location @@ -650,7 +647,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Location": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Line(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Line @@ -702,7 +699,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Line": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Function(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Function @@ -761,7 +758,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Function": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class KeyValueAndUnit(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message KeyValueAndUnit diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/resource/v1/resource.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/resource/v1/resource.py index 3c76082759f..ce29a7e2748 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/resource/v1/resource.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/resource/v1/resource.py @@ -8,17 +8,14 @@ import builtins import dataclasses -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec import opentelemetry.proto_json.common.v1.common @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Resource(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Resource diff --git a/opentelemetry-proto-json/src/opentelemetry/proto_json/trace/v1/trace.py b/opentelemetry-proto-json/src/opentelemetry/proto_json/trace/v1/trace.py index 16112213715..c800b70d3de 100644 --- a/opentelemetry-proto-json/src/opentelemetry/proto_json/trace/v1/trace.py +++ b/opentelemetry-proto-json/src/opentelemetry/proto_json/trace/v1/trace.py @@ -9,11 +9,8 @@ import builtins import dataclasses import enum -import functools import typing -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - import opentelemetry.proto_json._json_codec import opentelemetry.proto_json.common.v1.common import opentelemetry.proto_json.resource.v1.resource @@ -31,7 +28,7 @@ class SpanFlags(enum.IntEnum): SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = 512 @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class TracesData(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message TracesData @@ -72,7 +69,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "TracesData @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ResourceSpans(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ResourceSpans @@ -124,7 +121,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ResourceSp @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class ScopeSpans(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message ScopeSpans @@ -176,7 +173,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "ScopeSpans @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Span(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Span @@ -196,7 +193,7 @@ class SpanKind(enum.IntEnum): SPAN_KIND_CONSUMER = 5 @typing.final - @_dataclass + @dataclasses.dataclass(slots=True) class Event(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Event @@ -253,7 +250,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Span.Event return cls(**_args) @typing.final - @_dataclass + @dataclasses.dataclass(slots=True) class Link(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Link @@ -409,8 +406,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Span": opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "name") _args["name"] = _value if (_value := data.get("kind")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "kind") - _args["kind"] = Span.SpanKind(_value) + _args["kind"] = opentelemetry.proto_json._json_codec.decode_enum(_value, Span.SpanKind, "kind") if (_value := data.get("startTimeUnixNano")) is not None: _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") if (_value := data.get("endTimeUnixNano")) is not None: @@ -437,7 +433,7 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Span": @typing.final -@_dataclass +@dataclasses.dataclass(slots=True) class Status(opentelemetry.proto_json._json_codec.JsonMessage): """ Generated from protobuf message Status @@ -488,7 +484,6 @@ def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> "Status": opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "message") _args["message"] = _value if (_value := data.get("code")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "code") - _args["code"] = Status.StatusCode(_value) + _args["code"] = opentelemetry.proto_json._json_codec.decode_enum(_value, Status.StatusCode, "code") return cls(**_args)