Support deprecated message and fields (#126)
This commit is contained in:
parent
beafc812ff
commit
0cd9510b54
@ -33,6 +33,7 @@ import re
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import field
|
||||
from typing import (
|
||||
Iterator,
|
||||
Union,
|
||||
Type,
|
||||
List,
|
||||
@ -249,6 +250,13 @@ class OutputTemplate:
|
||||
"""
|
||||
return [f.name for f in self.input_files]
|
||||
|
||||
@property
|
||||
def python_module_imports(self) -> Set[str]:
|
||||
imports = set()
|
||||
if any(x for x in self.messages if any(x.deprecated_fields)):
|
||||
imports.add("warnings")
|
||||
return imports
|
||||
|
||||
|
||||
@dataclass
|
||||
class MessageCompiler(ProtoContentBase):
|
||||
@ -261,6 +269,7 @@ class MessageCompiler(ProtoContentBase):
|
||||
fields: List[Union["FieldCompiler", "MessageCompiler"]] = field(
|
||||
default_factory=list
|
||||
)
|
||||
deprecated: bool = field(default=False, init=False)
|
||||
|
||||
def __post_init__(self):
|
||||
# Add message to output file
|
||||
@ -269,6 +278,7 @@ class MessageCompiler(ProtoContentBase):
|
||||
self.output_file.enums.append(self)
|
||||
else:
|
||||
self.output_file.messages.append(self)
|
||||
self.deprecated = self.proto_obj.options.deprecated
|
||||
super().__post_init__()
|
||||
|
||||
@property
|
||||
@ -285,6 +295,12 @@ class MessageCompiler(ProtoContentBase):
|
||||
return f"List[{self.py_name}]"
|
||||
return self.py_name
|
||||
|
||||
@property
|
||||
def deprecated_fields(self) -> Iterator[str]:
|
||||
for f in self.fields:
|
||||
if f.deprecated:
|
||||
yield f.py_name
|
||||
|
||||
|
||||
def is_map(
|
||||
proto_field_obj: FieldDescriptorProto, parent_message: DescriptorProto
|
||||
|
@ -1,6 +1,9 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# sources: {{ ', '.join(description.input_filenames) }}
|
||||
# plugin: python-betterproto
|
||||
{% for i in description.python_module_imports|sort %}
|
||||
import {{ i }}
|
||||
{% endfor %}
|
||||
from dataclasses import dataclass
|
||||
{% if description.datetime_imports %}
|
||||
from datetime import {% for i in description.datetime_imports|sort %}{{ i }}{% if not loop.last %}, {% endif %}{% endfor %}
|
||||
@ -50,6 +53,18 @@ class {{ message.py_name }}(betterproto.Message):
|
||||
pass
|
||||
{% endif %}
|
||||
|
||||
{% if message.deprecated or message.deprecated_fields %}
|
||||
def __post_init__(self) -> None:
|
||||
{% if message.deprecated %}
|
||||
warnings.warn("{{ message.py_name }} is deprecated", DeprecationWarning)
|
||||
{% endif %}
|
||||
super().__post_init__()
|
||||
{% for field in message.deprecated_fields %}
|
||||
if self.{{ field }}:
|
||||
warnings.warn("{{ message.py_name }}.{{ field }} is deprecated", DeprecationWarning)
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endfor %}
|
||||
{% for service in description.services %}
|
||||
|
4
tests/inputs/deprecated/deprecated.json
Normal file
4
tests/inputs/deprecated/deprecated.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"v": 10,
|
||||
"value": 10
|
||||
}
|
9
tests/inputs/deprecated/deprecated.proto
Normal file
9
tests/inputs/deprecated/deprecated.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// Some documentation about the Test message.
|
||||
message Test {
|
||||
// Some documentation about the value.
|
||||
option deprecated = true;
|
||||
int32 v = 1 [deprecated=true];
|
||||
int32 value = 2;
|
||||
}
|
4
tests/inputs/deprecated_field/deprecated_field.json
Normal file
4
tests/inputs/deprecated_field/deprecated_field.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"v": 10,
|
||||
"value": 10
|
||||
}
|
8
tests/inputs/deprecated_field/deprecated_field.proto
Normal file
8
tests/inputs/deprecated_field/deprecated_field.proto
Normal file
@ -0,0 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
// Some documentation about the Test message.
|
||||
message Test {
|
||||
// Some documentation about the value.
|
||||
int32 v = 1 [deprecated=true];
|
||||
int32 value = 2;
|
||||
}
|
26
tests/test_deprecated.py
Normal file
26
tests/test_deprecated.py
Normal file
@ -0,0 +1,26 @@
|
||||
import pytest
|
||||
|
||||
from tests.output_betterproto.deprecated import Test as DeprecatedMessageTest
|
||||
from tests.output_betterproto.deprecated_field import Test as DeprecatedFieldTest
|
||||
|
||||
|
||||
def test_deprecated_message():
|
||||
with pytest.deprecated_call():
|
||||
DeprecatedMessageTest(value=10)
|
||||
|
||||
|
||||
def test_deprecated_message_with_deprecated_field():
|
||||
with pytest.warns(None) as record:
|
||||
DeprecatedMessageTest(v=10, value=10)
|
||||
assert len(record) == 2
|
||||
|
||||
|
||||
def test_deprecated_field_warning():
|
||||
with pytest.deprecated_call():
|
||||
DeprecatedFieldTest(v=10, value=10)
|
||||
|
||||
|
||||
def test_deprecated_field_no_warning():
|
||||
with pytest.warns(None) as record:
|
||||
DeprecatedFieldTest(value=10)
|
||||
assert not record
|
Loading…
x
Reference in New Issue
Block a user