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 dataclass
|
||||||
from dataclasses import field
|
from dataclasses import field
|
||||||
from typing import (
|
from typing import (
|
||||||
|
Iterator,
|
||||||
Union,
|
Union,
|
||||||
Type,
|
Type,
|
||||||
List,
|
List,
|
||||||
@ -249,6 +250,13 @@ class OutputTemplate:
|
|||||||
"""
|
"""
|
||||||
return [f.name for f in self.input_files]
|
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
|
@dataclass
|
||||||
class MessageCompiler(ProtoContentBase):
|
class MessageCompiler(ProtoContentBase):
|
||||||
@ -261,6 +269,7 @@ class MessageCompiler(ProtoContentBase):
|
|||||||
fields: List[Union["FieldCompiler", "MessageCompiler"]] = field(
|
fields: List[Union["FieldCompiler", "MessageCompiler"]] = field(
|
||||||
default_factory=list
|
default_factory=list
|
||||||
)
|
)
|
||||||
|
deprecated: bool = field(default=False, init=False)
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
# Add message to output file
|
# Add message to output file
|
||||||
@ -269,6 +278,7 @@ class MessageCompiler(ProtoContentBase):
|
|||||||
self.output_file.enums.append(self)
|
self.output_file.enums.append(self)
|
||||||
else:
|
else:
|
||||||
self.output_file.messages.append(self)
|
self.output_file.messages.append(self)
|
||||||
|
self.deprecated = self.proto_obj.options.deprecated
|
||||||
super().__post_init__()
|
super().__post_init__()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -285,6 +295,12 @@ class MessageCompiler(ProtoContentBase):
|
|||||||
return f"List[{self.py_name}]"
|
return f"List[{self.py_name}]"
|
||||||
return 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(
|
def is_map(
|
||||||
proto_field_obj: FieldDescriptorProto, parent_message: DescriptorProto
|
proto_field_obj: FieldDescriptorProto, parent_message: DescriptorProto
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||||
# sources: {{ ', '.join(description.input_filenames) }}
|
# sources: {{ ', '.join(description.input_filenames) }}
|
||||||
# plugin: python-betterproto
|
# plugin: python-betterproto
|
||||||
|
{% for i in description.python_module_imports|sort %}
|
||||||
|
import {{ i }}
|
||||||
|
{% endfor %}
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
{% if description.datetime_imports %}
|
{% if description.datetime_imports %}
|
||||||
from datetime import {% for i in description.datetime_imports|sort %}{{ i }}{% if not loop.last %}, {% endif %}{% endfor %}
|
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
|
pass
|
||||||
{% endif %}
|
{% 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 %}
|
{% endfor %}
|
||||||
{% for service in description.services %}
|
{% 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