File tree Expand file tree Collapse file tree 7 files changed +82
-0
lines changed Expand file tree Collapse file tree 7 files changed +82
-0
lines changed Original file line number Diff line number Diff line change 33
33
from dataclasses import dataclass
34
34
from dataclasses import field
35
35
from typing import (
36
+ Iterator ,
36
37
Union ,
37
38
Type ,
38
39
List ,
@@ -249,6 +250,13 @@ def input_filenames(self) -> List[str]:
249
250
"""
250
251
return [f .name for f in self .input_files ]
251
252
253
+ @property
254
+ def python_module_imports (self ) -> Set [str ]:
255
+ imports = set ()
256
+ if any (x for x in self .messages if any (x .deprecated_fields )):
257
+ imports .add ("warnings" )
258
+ return imports
259
+
252
260
253
261
@dataclass
254
262
class MessageCompiler (ProtoContentBase ):
@@ -261,6 +269,7 @@ class MessageCompiler(ProtoContentBase):
261
269
fields : List [Union ["FieldCompiler" , "MessageCompiler" ]] = field (
262
270
default_factory = list
263
271
)
272
+ deprecated : bool = field (default = False , init = False )
264
273
265
274
def __post_init__ (self ):
266
275
# Add message to output file
@@ -269,6 +278,7 @@ def __post_init__(self):
269
278
self .output_file .enums .append (self )
270
279
else :
271
280
self .output_file .messages .append (self )
281
+ self .deprecated = self .proto_obj .options .deprecated
272
282
super ().__post_init__ ()
273
283
274
284
@property
@@ -285,6 +295,12 @@ def annotation(self) -> str:
285
295
return f"List[{ self .py_name } ]"
286
296
return self .py_name
287
297
298
+ @property
299
+ def deprecated_fields (self ) -> Iterator [str ]:
300
+ for f in self .fields :
301
+ if f .deprecated :
302
+ yield f .py_name
303
+
288
304
289
305
def is_map (
290
306
proto_field_obj : FieldDescriptorProto , parent_message : DescriptorProto
Original file line number Diff line number Diff line change 1
1
# Generated by the protocol buffer compiler. DO NOT EDIT!
2
2
# sources: {{ ', '.join(description.input_filenames) }}
3
3
# plugin: python-betterproto
4
+ {% for i in description .python_module_imports |sort %}
5
+ import {{ i }}
6
+ {% endfor %}
4
7
from dataclasses import dataclass
5
8
{% if description .datetime_imports %}
6
9
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):
50
53
pass
51
54
{% endif %}
52
55
56
+ {% if message .deprecated or message .deprecated_fields %}
57
+ def __post_init__(self) -> None:
58
+ {% if message .deprecated %}
59
+ warnings.warn("{{ message.py_name }} is deprecated", DeprecationWarning)
60
+ {% endif %}
61
+ super().__post_init__()
62
+ {% for field in message .deprecated_fields %}
63
+ if self.{{ field }}:
64
+ warnings.warn("{{ message.py_name }}.{{ field }} is deprecated", DeprecationWarning)
65
+ {% endfor %}
66
+ {% endif %}
67
+
53
68
54
69
{% endfor %}
55
70
{% for service in description .services %}
Original file line number Diff line number Diff line change
1
+ {
2
+ "v" : 10 ,
3
+ "value" : 10
4
+ }
Original file line number Diff line number Diff line change
1
+ syntax = "proto3" ;
2
+
3
+ // Some documentation about the Test message.
4
+ message Test {
5
+ // Some documentation about the value.
6
+ option deprecated = true ;
7
+ int32 v = 1 [deprecated =true ];
8
+ int32 value = 2 ;
9
+ }
Original file line number Diff line number Diff line change
1
+ {
2
+ "v" : 10 ,
3
+ "value" : 10
4
+ }
Original file line number Diff line number Diff line change
1
+ syntax = "proto3" ;
2
+
3
+ // Some documentation about the Test message.
4
+ message Test {
5
+ // Some documentation about the value.
6
+ int32 v = 1 [deprecated =true ];
7
+ int32 value = 2 ;
8
+ }
Original file line number Diff line number Diff line change
1
+ import pytest
2
+
3
+ from tests .output_betterproto .deprecated import Test as DeprecatedMessageTest
4
+ from tests .output_betterproto .deprecated_field import Test as DeprecatedFieldTest
5
+
6
+
7
+ def test_deprecated_message ():
8
+ with pytest .deprecated_call ():
9
+ DeprecatedMessageTest (value = 10 )
10
+
11
+
12
+ def test_deprecated_message_with_deprecated_field ():
13
+ with pytest .warns (None ) as record :
14
+ DeprecatedMessageTest (v = 10 , value = 10 )
15
+ assert len (record ) == 2
16
+
17
+
18
+ def test_deprecated_field_warning ():
19
+ with pytest .deprecated_call ():
20
+ DeprecatedFieldTest (v = 10 , value = 10 )
21
+
22
+
23
+ def test_deprecated_field_no_warning ():
24
+ with pytest .warns (None ) as record :
25
+ DeprecatedFieldTest (value = 10 )
26
+ assert not record
You can’t perform that action at this time.
0 commit comments