diff --git a/CHANGELOG.md b/CHANGELOG.md index bb8e3e8b7..6ac3e1d8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ ## Upcoming - Require protobuf 3.18.1 +- Change `EnumTypeWrapper.V` to `EnumTypeWrapper.ValueType` per https://github.com/protocolbuffers/protobuf/pull/8182. +Will allow for unquoted annotations starting with protobuf 3.20.0. `.V` will continue to work for the foreseeable +future for backward compatibility. ## 3.0.0 diff --git a/README.md b/README.md index 3386cff47..4dc5dbd3a 100644 --- a/README.md +++ b/README.md @@ -87,32 +87,33 @@ enum MyEnum { BAR = 1; } ``` -Will yield an [enum type wrapper](https://github.com/python/typeshed/blob/16ae4c61201cd8b96b8b22cdfb2ab9e89ba5bcf2/stubs/protobuf/google/protobuf/internal/enum_type_wrapper.pyi) whose methods type to `MyEnum.V` rather than `int`. +Will yield an [enum type wrapper](https://github.com/python/typeshed/blob/16ae4c61201cd8b96b8b22cdfb2ab9e89ba5bcf2/stubs/protobuf/google/protobuf/internal/enum_type_wrapper.pyi) whose methods type to `MyEnum.ValueType` (a `NewType(int)` rather than `int`. This allows mypy to catch bugs where the wrong enum value is being used. Calling code may be typed as follows. In python >= 3.7 ```python -# Need [PEP 563](https://www.python.org/dev/peps/pep-0563/) to postpone evaluation of annotations -from __future__ import annotations # Not needed with python>=3.10 -def f(x: MyEnum.V): +# May need [PEP 563](https://www.python.org/dev/peps/pep-0563/) to postpone evaluation of annotations +# from __future__ import annotations # Not needed with python>=3.10 or protobuf>=3.20.0 +def f(x: MyEnum.ValueType): print(x) f(MyEnum.Value("FOO")) ``` -For usages of cast, the type of `x` must be quoted -until [upstream protobuf](https://github.com/protocolbuffers/protobuf/pull/8182) includes `V` +With protobuf <= 3.20.0, for usages of cast, the type of `x` must be quoted +After protobuf >= 3.20.0 - `ValueType` exists in the python code and quotes aren't needed +until [upstream protobuf](https://github.com/protocolbuffers/protobuf/pull/8182) includes `ValueType` ```python -cast('MyEnum.V', x) +cast('MyEnum.ValueType', x) ``` -Similarly, for type aliases, you must either quote the type or hide it behind `TYPE_CHECKING` +Similarly, for type aliases with protobuf < 3.20.0, you must either quote the type or hide it behind `TYPE_CHECKING` ```python from typing import Tuple, TYPE_CHECKING -FOO = Tuple['MyEnum.V', 'MyEnum.V'] +FOO = Tuple['MyEnum.ValueType', 'MyEnum.ValueType'] if TYPE_CHECKING: - FOO = Tuple[MyEnum.V, MyEnum.V] + FOO = Tuple[MyEnum.ValueType, MyEnum.ValueType] ``` #### Enum int impl details @@ -123,18 +124,20 @@ mypy-protobuf autogenerates an instance of the EnumTypeWrapper as follows. class MyEnum(_MyEnum, metaclass=_MyEnumEnumTypeWrapper): pass class _MyEnum: - V = typing.NewType('V', builtins.int) -class _MyEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_MyEnum.V], builtins.type): + ValueType = typing.NewType('ValueType', builtins.int) + V = Union[ValueType] +class _MyEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_MyEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor = ... - FOO = MyEnum.V(0) - BAR = MyEnum.V(1) -FOO = MyEnum.V(0) -BAR = MyEnum.V(1) + FOO = MyEnum.ValueType(0) + BAR = MyEnum.ValueType(1) +FOO = MyEnum.ValueType(0) +BAR = MyEnum.ValueType(1) ``` -`_MyEnumEnumTypeWrapper` extends the EnumTypeWrapper to take/return MyEnum.V rather than int +`_MyEnumEnumTypeWrapper` extends the EnumTypeWrapper to take/return MyEnum.ValueType rather than int `MyEnum` is an instance of the `EnumTypeWrapper`. -- Use `_MyEnum` and of metaclass is an implementation detail to make MyEnum.V a valid type w/o a circular dependency +- Use `_MyEnum` and of metaclass is an implementation detail to make MyEnum.ValueType a valid type w/o a circular dependency +- `V` is supported as an alias of `ValueType` for backward compatibility diff --git a/mypy_protobuf/main.py b/mypy_protobuf/main.py index df6d9a801..689ebff77 100644 --- a/mypy_protobuf/main.py +++ b/mypy_protobuf/main.py @@ -118,7 +118,7 @@ def _add_enums( ) -> None: for enum in enums: self.message_to_fd[prefix + enum.name] = _fd - self.message_to_fd[prefix + enum.name + ".V"] = _fd + self.message_to_fd[prefix + enum.name + ".ValueType"] = _fd def _add_messages( messages: "RepeatedCompositeFieldContainer[d.DescriptorProto]", @@ -332,7 +332,7 @@ def write_enums( class_name = ( enum.name if enum.name not in PYTHON_RESERVED else "_r_" + enum.name ) - value_type_fq = prefix + class_name + ".V" + value_type_fq = prefix + class_name + ".ValueType" l( "class {}({}, metaclass={}):", @@ -347,17 +347,21 @@ def write_enums( l("class {}:", "_" + enum.name) with self._indent(): l( - "V = {}('V', {})", + "ValueType = {}('ValueType', {})", self._import("typing", "NewType"), self._builtin("int"), ) + # Ideally this would be `V: TypeAlias = ValueType`, but it appears + # to be buggy in mypy in nested scopes + # Workaround described here https://github.com/python/mypy/issues/7866 + l("V = {}[ValueType]", self._import("typing", "Union")) l( "class {}({}[{}], {}):", "_" + enum.name + "EnumTypeWrapper", self._import( "google.protobuf.internal.enum_type_wrapper", "_EnumTypeWrapper" ), - "_" + enum.name + ".V", + "_" + enum.name + ".ValueType", self._builtin("type"), ) with self._indent(): @@ -864,7 +868,7 @@ def python_type( d.FieldDescriptorProto.TYPE_STRING: lambda: self._import("typing", "Text"), d.FieldDescriptorProto.TYPE_BYTES: lambda: self._builtin("bytes"), d.FieldDescriptorProto.TYPE_ENUM: lambda: self._import_message( - field.type_name + ".V" + field.type_name + ".ValueType" ), d.FieldDescriptorProto.TYPE_MESSAGE: lambda: self._import_message( field.type_name diff --git a/test/generated/testproto/inner/inner_pb2.pyi b/test/generated/testproto/inner/inner_pb2.pyi index 17153cf34..3a5381eb6 100644 --- a/test/generated/testproto/inner/inner_pb2.pyi +++ b/test/generated/testproto/inner/inner_pb2.pyi @@ -13,10 +13,10 @@ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor = ... class Inner(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor = ... A_FIELD_NUMBER: builtins.int - a: testproto.test3_pb2.OuterEnum.V = ... + a: testproto.test3_pb2.OuterEnum.ValueType = ... def __init__(self, *, - a : testproto.test3_pb2.OuterEnum.V = ..., + a : testproto.test3_pb2.OuterEnum.ValueType = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["a",b"a"]) -> None: ... global___Inner = Inner diff --git a/test/generated/testproto/nested/nested_pb2.pyi b/test/generated/testproto/nested/nested_pb2.pyi index df7b85cce..5f417408d 100644 --- a/test/generated/testproto/nested/nested_pb2.pyi +++ b/test/generated/testproto/nested/nested_pb2.pyi @@ -15,10 +15,10 @@ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor = ... class Nested(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor = ... A_FIELD_NUMBER: builtins.int - a: testproto.test3_pb2.OuterEnum.V = ... + a: testproto.test3_pb2.OuterEnum.ValueType = ... def __init__(self, *, - a : testproto.test3_pb2.OuterEnum.V = ..., + a : testproto.test3_pb2.OuterEnum.ValueType = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["a",b"a"]) -> None: ... global___Nested = Nested @@ -28,32 +28,34 @@ class AnotherNested(google.protobuf.message.Message): class NestedEnum(_NestedEnum, metaclass=_NestedEnumEnumTypeWrapper): pass class _NestedEnum: - V = typing.NewType('V', builtins.int) - class _NestedEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_NestedEnum.V], builtins.type): + ValueType = typing.NewType('ValueType', builtins.int) + V = typing.Union[ValueType] + class _NestedEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_NestedEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor = ... - INVALID = AnotherNested.NestedEnum.V(0) - ONE = AnotherNested.NestedEnum.V(1) - TWO = AnotherNested.NestedEnum.V(2) + INVALID = AnotherNested.NestedEnum.ValueType(0) + ONE = AnotherNested.NestedEnum.ValueType(1) + TWO = AnotherNested.NestedEnum.ValueType(2) - INVALID = AnotherNested.NestedEnum.V(0) - ONE = AnotherNested.NestedEnum.V(1) - TWO = AnotherNested.NestedEnum.V(2) + INVALID = AnotherNested.NestedEnum.ValueType(0) + ONE = AnotherNested.NestedEnum.ValueType(1) + TWO = AnotherNested.NestedEnum.ValueType(2) class NestedMessage(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor = ... class NestedEnum2(_NestedEnum2, metaclass=_NestedEnum2EnumTypeWrapper): pass class _NestedEnum2: - V = typing.NewType('V', builtins.int) - class _NestedEnum2EnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_NestedEnum2.V], builtins.type): + ValueType = typing.NewType('ValueType', builtins.int) + V = typing.Union[ValueType] + class _NestedEnum2EnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_NestedEnum2.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor = ... - UNDEFINED = AnotherNested.NestedMessage.NestedEnum2.V(0) - NESTED_ENUM1 = AnotherNested.NestedMessage.NestedEnum2.V(1) - NESTED_ENUM2 = AnotherNested.NestedMessage.NestedEnum2.V(2) + UNDEFINED = AnotherNested.NestedMessage.NestedEnum2.ValueType(0) + NESTED_ENUM1 = AnotherNested.NestedMessage.NestedEnum2.ValueType(1) + NESTED_ENUM2 = AnotherNested.NestedMessage.NestedEnum2.ValueType(2) - UNDEFINED = AnotherNested.NestedMessage.NestedEnum2.V(0) - NESTED_ENUM1 = AnotherNested.NestedMessage.NestedEnum2.V(1) - NESTED_ENUM2 = AnotherNested.NestedMessage.NestedEnum2.V(2) + UNDEFINED = AnotherNested.NestedMessage.NestedEnum2.ValueType(0) + NESTED_ENUM1 = AnotherNested.NestedMessage.NestedEnum2.ValueType(1) + NESTED_ENUM2 = AnotherNested.NestedMessage.NestedEnum2.ValueType(2) S_FIELD_NUMBER: builtins.int B_FIELD_NUMBER: builtins.int @@ -61,14 +63,14 @@ class AnotherNested(google.protobuf.message.Message): NE2_FIELD_NUMBER: builtins.int s: typing.Text = ... b: builtins.bool = ... - ne: global___AnotherNested.NestedEnum.V = ... - ne2: global___AnotherNested.NestedMessage.NestedEnum2.V = ... + ne: global___AnotherNested.NestedEnum.ValueType = ... + ne2: global___AnotherNested.NestedMessage.NestedEnum2.ValueType = ... def __init__(self, *, s : typing.Text = ..., b : builtins.bool = ..., - ne : global___AnotherNested.NestedEnum.V = ..., - ne2 : global___AnotherNested.NestedMessage.NestedEnum2.V = ..., + ne : global___AnotherNested.NestedEnum.ValueType = ..., + ne2 : global___AnotherNested.NestedMessage.NestedEnum2.ValueType = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["b",b"b","ne",b"ne","ne2",b"ne2","s",b"s"]) -> None: ... diff --git a/test/generated/testproto/test3_pb2.pyi b/test/generated/testproto/test3_pb2.pyi index d00fc7774..140186771 100644 --- a/test/generated/testproto/test3_pb2.pyi +++ b/test/generated/testproto/test3_pb2.pyi @@ -15,16 +15,17 @@ DESCRIPTOR: google.protobuf.descriptor.FileDescriptor = ... class OuterEnum(_OuterEnum, metaclass=_OuterEnumEnumTypeWrapper): pass class _OuterEnum: - V = typing.NewType('V', builtins.int) -class _OuterEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OuterEnum.V], builtins.type): + ValueType = typing.NewType('ValueType', builtins.int) + V = typing.Union[ValueType] +class _OuterEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OuterEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor = ... - UNKNOWN = OuterEnum.V(0) - FOO3 = OuterEnum.V(1) - BAR3 = OuterEnum.V(2) + UNKNOWN = OuterEnum.ValueType(0) + FOO3 = OuterEnum.ValueType(1) + BAR3 = OuterEnum.ValueType(2) -UNKNOWN = OuterEnum.V(0) -FOO3 = OuterEnum.V(1) -BAR3 = OuterEnum.V(2) +UNKNOWN = OuterEnum.ValueType(0) +FOO3 = OuterEnum.ValueType(1) +BAR3 = OuterEnum.ValueType(2) global___OuterEnum = OuterEnum @@ -44,14 +45,15 @@ class SimpleProto3(google.protobuf.message.Message): class InnerEnum(_InnerEnum, metaclass=_InnerEnumEnumTypeWrapper): pass class _InnerEnum: - V = typing.NewType('V', builtins.int) - class _InnerEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InnerEnum.V], builtins.type): + ValueType = typing.NewType('ValueType', builtins.int) + V = typing.Union[ValueType] + class _InnerEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InnerEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor = ... - INNER1 = SimpleProto3.InnerEnum.V(0) - INNER2 = SimpleProto3.InnerEnum.V(1) + INNER1 = SimpleProto3.InnerEnum.ValueType(0) + INNER2 = SimpleProto3.InnerEnum.ValueType(1) - INNER1 = SimpleProto3.InnerEnum.V(0) - INNER2 = SimpleProto3.InnerEnum.V(1) + INNER1 = SimpleProto3.InnerEnum.ValueType(0) + INNER2 = SimpleProto3.InnerEnum.ValueType(1) class MapScalarEntry(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor = ... @@ -102,21 +104,21 @@ class SimpleProto3(google.protobuf.message.Message): a_string: typing.Text = ... @property def a_repeated_string(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ... - a_outer_enum: global___OuterEnum.V = ... + a_outer_enum: global___OuterEnum.ValueType = ... @property def outer_message(self) -> global___OuterMessage3: ... - inner_enum: global___SimpleProto3.InnerEnum.V = ... + inner_enum: global___SimpleProto3.InnerEnum.ValueType = ... a_oneof_1: typing.Text = ... a_oneof_2: typing.Text = ... @property def outer_message_in_oneof(self) -> global___OuterMessage3: ... - outer_enum_in_oneof: global___OuterEnum.V = ... - inner_enum_in_oneof: global___SimpleProto3.InnerEnum.V = ... + outer_enum_in_oneof: global___OuterEnum.ValueType = ... + inner_enum_in_oneof: global___SimpleProto3.InnerEnum.ValueType = ... b_oneof_1: typing.Text = ... b_oneof_2: typing.Text = ... @property def bool(self) -> global___OuterMessage3: ... - OuterEnum: global___OuterEnum.V = ... + OuterEnum: global___OuterEnum.ValueType = ... """Test having fieldname match messagename""" @property @@ -132,18 +134,18 @@ class SimpleProto3(google.protobuf.message.Message): *, a_string : typing.Text = ..., a_repeated_string : typing.Optional[typing.Iterable[typing.Text]] = ..., - a_outer_enum : global___OuterEnum.V = ..., + a_outer_enum : global___OuterEnum.ValueType = ..., outer_message : typing.Optional[global___OuterMessage3] = ..., - inner_enum : global___SimpleProto3.InnerEnum.V = ..., + inner_enum : global___SimpleProto3.InnerEnum.ValueType = ..., a_oneof_1 : typing.Text = ..., a_oneof_2 : typing.Text = ..., outer_message_in_oneof : typing.Optional[global___OuterMessage3] = ..., - outer_enum_in_oneof : global___OuterEnum.V = ..., - inner_enum_in_oneof : global___SimpleProto3.InnerEnum.V = ..., + outer_enum_in_oneof : global___OuterEnum.ValueType = ..., + inner_enum_in_oneof : global___SimpleProto3.InnerEnum.ValueType = ..., b_oneof_1 : typing.Text = ..., b_oneof_2 : typing.Text = ..., bool : typing.Optional[global___OuterMessage3] = ..., - OuterEnum : global___OuterEnum.V = ..., + OuterEnum : global___OuterEnum.ValueType = ..., OuterMessage3 : typing.Optional[global___OuterMessage3] = ..., map_scalar : typing.Optional[typing.Mapping[builtins.int, typing.Text]] = ..., map_message : typing.Optional[typing.Mapping[builtins.int, global___OuterMessage3]] = ..., diff --git a/test/generated/testproto/test_extensions3_pb2.pyi b/test/generated/testproto/test_extensions3_pb2.pyi index 9c2830b6d..1dd9a20e3 100644 --- a/test/generated/testproto/test_extensions3_pb2.pyi +++ b/test/generated/testproto/test_extensions3_pb2.pyi @@ -24,9 +24,9 @@ scalar_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor repeated_scalar_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]] = ... -enum_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, testproto.test3_pb2.OuterEnum.V] = ... +enum_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, testproto.test3_pb2.OuterEnum.ValueType] = ... -repeated_enum_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, google.protobuf.internal.containers.RepeatedScalarFieldContainer[testproto.test3_pb2.OuterEnum.V]] = ... +repeated_enum_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, google.protobuf.internal.containers.RepeatedScalarFieldContainer[testproto.test3_pb2.OuterEnum.ValueType]] = ... msg_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, testproto.test3_pb2.OuterMessage3] = ... diff --git a/test/generated/testproto/test_pb2.pyi b/test/generated/testproto/test_pb2.pyi index 3f6500bfc..81e807b50 100644 --- a/test/generated/testproto/test_pb2.pyi +++ b/test/generated/testproto/test_pb2.pyi @@ -25,20 +25,21 @@ class OuterEnum(_OuterEnum, metaclass=_OuterEnumEnumTypeWrapper): """Outer Enum""" pass class _OuterEnum: - V = typing.NewType('V', builtins.int) -class _OuterEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OuterEnum.V], builtins.type): + ValueType = typing.NewType('ValueType', builtins.int) + V = typing.Union[ValueType] +class _OuterEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OuterEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor = ... - FOO = OuterEnum.V(1) + FOO = OuterEnum.ValueType(1) """FOO""" - BAR = OuterEnum.V(2) + BAR = OuterEnum.ValueType(2) """BAR""" -FOO = OuterEnum.V(1) +FOO = OuterEnum.ValueType(1) """FOO""" -BAR = OuterEnum.V(2) +BAR = OuterEnum.ValueType(2) """BAR""" global___OuterEnum = OuterEnum @@ -48,15 +49,16 @@ class NamingConflicts(_NamingConflicts, metaclass=_NamingConflictsEnumTypeWrappe """Naming conflicts!""" pass class _NamingConflicts: - V = typing.NewType('V', builtins.int) -class _NamingConflictsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_NamingConflicts.V], builtins.type): + ValueType = typing.NewType('ValueType', builtins.int) + V = typing.Union[ValueType] +class _NamingConflictsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_NamingConflicts.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor = ... -Name = NamingConflicts.V(1) -Value = NamingConflicts.V(2) -keys = NamingConflicts.V(3) -values = NamingConflicts.V(4) -items = NamingConflicts.V(5) +Name = NamingConflicts.ValueType(1) +Value = NamingConflicts.ValueType(2) +keys = NamingConflicts.ValueType(3) +values = NamingConflicts.ValueType(4) +items = NamingConflicts.ValueType(5) """See https://github.com/protocolbuffers/protobuf/issues/8803 proto itself generates broken code when DESCRIPTOR is there DESCRIPTOR = 8; @@ -72,20 +74,21 @@ class Simple1(google.protobuf.message.Message): """Inner Enum""" pass class _InnerEnum: - V = typing.NewType('V', builtins.int) - class _InnerEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InnerEnum.V], builtins.type): + ValueType = typing.NewType('ValueType', builtins.int) + V = typing.Union[ValueType] + class _InnerEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_InnerEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor = ... - INNER1 = Simple1.InnerEnum.V(1) + INNER1 = Simple1.InnerEnum.ValueType(1) """INNER1""" - INNER2 = Simple1.InnerEnum.V(2) + INNER2 = Simple1.InnerEnum.ValueType(2) """INNER2""" - INNER1 = Simple1.InnerEnum.V(1) + INNER1 = Simple1.InnerEnum.ValueType(1) """INNER1""" - INNER2 = Simple1.InnerEnum.V(2) + INNER2 = Simple1.InnerEnum.ValueType(2) """INNER2""" @@ -136,30 +139,30 @@ class Simple1(google.protobuf.message.Message): def a_repeated_string(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ... a_boolean: builtins.bool = ... a_uint32: builtins.int = ... - a_enum: global___OuterEnum.V = ... - a_external_enum: testproto.test3_pb2.OuterEnum.V = ... + a_enum: global___OuterEnum.ValueType = ... + a_external_enum: testproto.test3_pb2.OuterEnum.ValueType = ... @property def a_inner(self) -> testproto.inner.inner_pb2.Inner: ... @property def a_nested(self) -> testproto.nested.nested_pb2.Nested: ... - inner_enum: global___Simple1.InnerEnum.V = ... + inner_enum: global___Simple1.InnerEnum.ValueType = ... @property - def rep_inner_enum(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___Simple1.InnerEnum.V]: ... + def rep_inner_enum(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[global___Simple1.InnerEnum.ValueType]: ... @property def inner_message(self) -> global___Simple1.InnerMessage: ... @property def rep_inner_message(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Simple1.InnerMessage]: ... @property def no_package(self) -> testproto.nopackage_pb2.NoPackage: ... - nested_enum: testproto.nested.nested_pb2.AnotherNested.NestedEnum.V = ... + nested_enum: testproto.nested.nested_pb2.AnotherNested.NestedEnum.ValueType = ... @property def nested_message(self) -> testproto.nested.nested_pb2.AnotherNested.NestedMessage: ... a_oneof_1: typing.Text = ... a_oneof_2: typing.Text = ... @property def outer_message_in_oneof(self) -> global___Simple2: ... - outer_enum_in_oneof: global___OuterEnum.V = ... - inner_enum_in_oneof: global___Simple1.InnerEnum.V = ... + outer_enum_in_oneof: global___OuterEnum.ValueType = ... + inner_enum_in_oneof: global___Simple1.InnerEnum.ValueType = ... user_id: test.test_generated_mypy.UserId = ... email: test.test_generated_mypy.Email = ... @property @@ -170,22 +173,22 @@ class Simple1(google.protobuf.message.Message): a_repeated_string : typing.Optional[typing.Iterable[typing.Text]] = ..., a_boolean : typing.Optional[builtins.bool] = ..., a_uint32 : typing.Optional[builtins.int] = ..., - a_enum : typing.Optional[global___OuterEnum.V] = ..., - a_external_enum : typing.Optional[testproto.test3_pb2.OuterEnum.V] = ..., + a_enum : typing.Optional[global___OuterEnum.ValueType] = ..., + a_external_enum : typing.Optional[testproto.test3_pb2.OuterEnum.ValueType] = ..., a_inner : typing.Optional[testproto.inner.inner_pb2.Inner] = ..., a_nested : typing.Optional[testproto.nested.nested_pb2.Nested] = ..., - inner_enum : typing.Optional[global___Simple1.InnerEnum.V] = ..., - rep_inner_enum : typing.Optional[typing.Iterable[global___Simple1.InnerEnum.V]] = ..., + inner_enum : typing.Optional[global___Simple1.InnerEnum.ValueType] = ..., + rep_inner_enum : typing.Optional[typing.Iterable[global___Simple1.InnerEnum.ValueType]] = ..., inner_message : typing.Optional[global___Simple1.InnerMessage] = ..., rep_inner_message : typing.Optional[typing.Iterable[global___Simple1.InnerMessage]] = ..., no_package : typing.Optional[testproto.nopackage_pb2.NoPackage] = ..., - nested_enum : typing.Optional[testproto.nested.nested_pb2.AnotherNested.NestedEnum.V] = ..., + nested_enum : typing.Optional[testproto.nested.nested_pb2.AnotherNested.NestedEnum.ValueType] = ..., nested_message : typing.Optional[testproto.nested.nested_pb2.AnotherNested.NestedMessage] = ..., a_oneof_1 : typing.Optional[typing.Text] = ..., a_oneof_2 : typing.Optional[typing.Text] = ..., outer_message_in_oneof : typing.Optional[global___Simple2] = ..., - outer_enum_in_oneof : typing.Optional[global___OuterEnum.V] = ..., - inner_enum_in_oneof : typing.Optional[global___Simple1.InnerEnum.V] = ..., + outer_enum_in_oneof : typing.Optional[global___OuterEnum.ValueType] = ..., + inner_enum_in_oneof : typing.Optional[global___Simple1.InnerEnum.ValueType] = ..., user_id : typing.Optional[test.test_generated_mypy.UserId] = ..., email : typing.Optional[test.test_generated_mypy.Email] = ..., email_by_uid : typing.Optional[typing.Mapping[test.test_generated_mypy.UserId, test.test_generated_mypy.Email]] = ..., @@ -254,12 +257,13 @@ class PythonReservedKeywords(google.protobuf.message.Message): class _r_finally(_finally, metaclass=_finallyEnumTypeWrapper): pass class _finally: - V = typing.NewType('V', builtins.int) - class _finallyEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_finally.V], builtins.type): + ValueType = typing.NewType('ValueType', builtins.int) + V = typing.Union[ValueType] + class _finallyEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_finally.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor = ... - valid_in_finally = PythonReservedKeywords._r_finally.V(2) + valid_in_finally = PythonReservedKeywords._r_finally.ValueType(2) - valid_in_finally = PythonReservedKeywords._r_finally.V(2) + valid_in_finally = PythonReservedKeywords._r_finally.ValueType(2) class _r_lambda(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor = ... @@ -307,11 +311,11 @@ class PythonReservedKeywords(google.protobuf.message.Message): def none(self) -> global____r_None: """Test unreserved identifiers w/ reserved message names""" pass - valid: global___PythonReservedKeywords._r_finally.V = ... + valid: global___PythonReservedKeywords._r_finally.ValueType = ... def __init__(self, *, none : typing.Optional[global____r_None] = ..., - valid : typing.Optional[global___PythonReservedKeywords._r_finally.V] = ..., + valid : typing.Optional[global___PythonReservedKeywords._r_finally.ValueType] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["False",b"False","True",b"True","and",b"and","as",b"as","assert",b"assert","break",b"break","class",b"class","def",b"def","del",b"del","elif",b"elif","else",b"else","except",b"except","for",b"for","from",b"from","global",b"global","if",b"if","import",b"import","in",b"in","is",b"is","none",b"none","nonlocal",b"nonlocal","not",b"not","or",b"or","pass",b"pass","raise",b"raise","try",b"try","valid",b"valid","while",b"while","with",b"with","yield",b"yield"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["False",b"False","True",b"True","and",b"and","as",b"as","assert",b"assert","break",b"break","class",b"class","def",b"def","del",b"del","elif",b"elif","else",b"else","except",b"except","for",b"for","from",b"from","global",b"global","if",b"if","import",b"import","in",b"in","is",b"is","none",b"none","nonlocal",b"nonlocal","not",b"not","or",b"or","pass",b"pass","raise",b"raise","try",b"try","valid",b"valid","while",b"while","with",b"with","yield",b"yield"]) -> None: ... diff --git a/test/test_generated_mypy.py b/test/test_generated_mypy.py index eabd65d9d..4e8b4ad1d 100644 --- a/test/test_generated_mypy.py +++ b/test/test_generated_mypy.py @@ -170,13 +170,17 @@ def test_enum() -> None: assert OuterEnum.items() == [("FOO", 1), ("BAR", 2)] # Make sure we can assure typing with a couple of techniques - e2: test_pb2.OuterEnum.V = OuterEnum.Value("BAR") + e2: test_pb2.OuterEnum.ValueType = OuterEnum.Value("BAR") assert OuterEnum.Name(e2) == "BAR" - e3: OuterEnum.V = OuterEnum.Value("BAR") + e3: OuterEnum.ValueType = OuterEnum.Value("BAR") assert OuterEnum.Name(e3) == "BAR" e4: int = OuterEnum.Value("BAR") assert OuterEnum.Name(e2) == "BAR" + # Legacy .V type + e5: OuterEnum.V = OuterEnum.Value("BAR") + assert OuterEnum.Name(e3) == "BAR" + # Protobuf itself allows both str and bytes here. assert OuterEnum.Value("BAR") == OuterEnum.Value(b"BAR") diff --git a/test_negative/output.expected.3.8 b/test_negative/output.expected.3.8 index ea45f2332..3bd60015f 100644 --- a/test_negative/output.expected.3.8 +++ b/test_negative/output.expected.3.8 @@ -25,7 +25,7 @@ test_negative/negative.py:31: error: Argument 1 to "ParseFromString" of "Message test_negative/negative.py:34: error: Argument 1 to "CopyFrom" of "Message" has incompatible type "bytes"; expected "Simple1" [arg-type] test_negative/negative.py:38: error: Argument 1 to "extend" of "list" has incompatible type "RepeatedScalarFieldContainer[str]"; expected "Iterable[int]" [arg-type] test_negative/negative.py:40: error: Argument "foo" to "TestMessage" has incompatible type "int"; expected "str" [arg-type] -test_negative/negative.py:43: error: Incompatible types in assignment (expression has type "int", variable has type "V") [assignment] +test_negative/negative.py:43: error: Incompatible types in assignment (expression has type "int", variable has type "ValueType") [assignment] test_negative/negative.py:46: error: Argument 1 to "HasField" of "Simple1" has incompatible type "Literal['garbage']"; expected "Union[Literal['a_boolean'], Literal[b'a_boolean'], Literal['a_enum'], Literal[b'a_enum'], Literal['a_external_enum'], Literal[b'a_external_enum'], Literal['a_inner'], Literal[b'a_inner'], Literal['a_nested'], Literal[b'a_nested'], Literal['a_oneof'], Literal[b'a_oneof'], Literal['a_oneof_1'], Literal[b'a_oneof_1'], Literal['a_oneof_2'], Literal[b'a_oneof_2'], Literal['a_string'], Literal[b'a_string'], Literal['a_uint32'], Literal[b'a_uint32'], Literal['email'], Literal[b'email'], Literal['inner_enum'], Literal[b'inner_enum'], Literal['inner_enum_in_oneof'], Literal[b'inner_enum_in_oneof'], Literal['inner_message'], Literal[b'inner_message'], Literal['nested_enum'], Literal[b'nested_enum'], Literal['nested_message'], Literal[b'nested_message'], Literal['no_package'], Literal[b'no_package'], Literal['outer_enum_in_oneof'], Literal[b'outer_enum_in_oneof'], Literal['outer_message_in_oneof'], Literal[b'outer_message_in_oneof'], Literal['user_id'], Literal[b'user_id']]" [arg-type] test_negative/negative.py:47: error: Argument 1 to "HasField" of "Simple1" has incompatible type "Literal['a_repeated_string']"; expected "Union[Literal['a_boolean'], Literal[b'a_boolean'], Literal['a_enum'], Literal[b'a_enum'], Literal['a_external_enum'], Literal[b'a_external_enum'], Literal['a_inner'], Literal[b'a_inner'], Literal['a_nested'], Literal[b'a_nested'], Literal['a_oneof'], Literal[b'a_oneof'], Literal['a_oneof_1'], Literal[b'a_oneof_1'], Literal['a_oneof_2'], Literal[b'a_oneof_2'], Literal['a_string'], Literal[b'a_string'], Literal['a_uint32'], Literal[b'a_uint32'], Literal['email'], Literal[b'email'], Literal['inner_enum'], Literal[b'inner_enum'], Literal['inner_enum_in_oneof'], Literal[b'inner_enum_in_oneof'], Literal['inner_message'], Literal[b'inner_message'], Literal['nested_enum'], Literal[b'nested_enum'], Literal['nested_message'], Literal[b'nested_message'], Literal['no_package'], Literal[b'no_package'], Literal['outer_enum_in_oneof'], Literal[b'outer_enum_in_oneof'], Literal['outer_message_in_oneof'], Literal[b'outer_message_in_oneof'], Literal['user_id'], Literal[b'user_id']]" [arg-type] test_negative/negative.py:51: error: Argument 1 to "HasField" of "SimpleProto3" has incompatible type "Literal['garbage']"; expected "Union[Literal['OuterMessage3'], Literal[b'OuterMessage3'], Literal['_an_optional_string'], Literal[b'_an_optional_string'], Literal['a_oneof'], Literal[b'a_oneof'], Literal['a_oneof_1'], Literal[b'a_oneof_1'], Literal['a_oneof_2'], Literal[b'a_oneof_2'], Literal['an_optional_string'], Literal[b'an_optional_string'], Literal['b_oneof'], Literal[b'b_oneof'], Literal['b_oneof_1'], Literal[b'b_oneof_1'], Literal['b_oneof_2'], Literal[b'b_oneof_2'], Literal['bool'], Literal[b'bool'], Literal['inner_enum_in_oneof'], Literal[b'inner_enum_in_oneof'], Literal['outer_enum_in_oneof'], Literal[b'outer_enum_in_oneof'], Literal['outer_message'], Literal[b'outer_message'], Literal['outer_message_in_oneof'], Literal[b'outer_message_in_oneof']]" [arg-type] @@ -61,11 +61,11 @@ test_negative/negative.py:112: error: "Descriptor" has no attribute "Garbage" [ test_negative/negative.py:113: error: "Descriptor" has no attribute "Garbage" [attr-defined] test_negative/negative.py:116: error: "EnumDescriptor" has no attribute "Garbage" [attr-defined] test_negative/negative.py:119: error: "FileDescriptor" has no attribute "Garbage" [attr-defined] -test_negative/negative.py:126: error: "V" has no attribute "FOO" [attr-defined] -test_negative/negative.py:130: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "int"; expected "V" [arg-type] -test_negative/negative.py:132: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.V"; expected "testproto.test3_pb2._OuterEnum.V" [arg-type] -test_negative/negative.py:134: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.V"; expected "testproto.test3_pb2._OuterEnum.V" [arg-type] -test_negative/negative.py:136: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.V"; expected "testproto.test3_pb2._OuterEnum.V" [arg-type] +test_negative/negative.py:126: error: "ValueType" has no attribute "FOO" [attr-defined] +test_negative/negative.py:130: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "int"; expected "ValueType" [arg-type] +test_negative/negative.py:132: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.ValueType"; expected "testproto.test3_pb2._OuterEnum.ValueType" [arg-type] +test_negative/negative.py:134: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.ValueType"; expected "testproto.test3_pb2._OuterEnum.ValueType" [arg-type] +test_negative/negative.py:136: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.ValueType"; expected "testproto.test3_pb2._OuterEnum.ValueType" [arg-type] test_negative/negative.py:140: error: "ScalarMap[int, str]" has no attribute "get_or_create" [attr-defined] test_negative/negative.py:142: error: No overload variant of "get" of "Mapping" matches argument type "str" [call-overload] test_negative/negative.py:142: note: Possible overload variant: @@ -93,5 +93,5 @@ test_negative/negative.py:169: error: Argument "a_string" to "OuterMessage3" has test_negative/negative.py:174: error: Property "a_repeated_string" defined in "Simple1" is read-only [misc] test_negative/negative.py:175: error: Property "rep_inner_enum" defined in "Simple1" is read-only [misc] test_negative/negative.py:180: error: "_r_None" has no attribute "invalid"; maybe "valid"? [attr-defined] -test_negative/negative.py:184: error: Incompatible types in assignment (expression has type "V", variable has type "str") [assignment] +test_negative/negative.py:184: error: Incompatible types in assignment (expression has type "ValueType", variable has type "str") [assignment] Found 80 errors in 2 files (checked 31 source files) diff --git a/test_negative/output.expected.3.8.omit_linenos b/test_negative/output.expected.3.8.omit_linenos index a52b55d6e..208c34c4b 100644 --- a/test_negative/output.expected.3.8.omit_linenos +++ b/test_negative/output.expected.3.8.omit_linenos @@ -25,7 +25,7 @@ test_negative/negative.py: error: Argument 1 to "ParseFromString" of "Message" h test_negative/negative.py: error: Argument 1 to "CopyFrom" of "Message" has incompatible type "bytes"; expected "Simple1" [arg-type] test_negative/negative.py: error: Argument 1 to "extend" of "list" has incompatible type "RepeatedScalarFieldContainer[str]"; expected "Iterable[int]" [arg-type] test_negative/negative.py: error: Argument "foo" to "TestMessage" has incompatible type "int"; expected "str" [arg-type] -test_negative/negative.py: error: Incompatible types in assignment (expression has type "int", variable has type "V") [assignment] +test_negative/negative.py: error: Incompatible types in assignment (expression has type "int", variable has type "ValueType") [assignment] test_negative/negative.py: error: Argument 1 to "HasField" of "Simple1" has incompatible type "Literal['garbage']"; expected "Union[Literal['a_boolean'], Literal[b'a_boolean'], Literal['a_enum'], Literal[b'a_enum'], Literal['a_external_enum'], Literal[b'a_external_enum'], Literal['a_inner'], Literal[b'a_inner'], Literal['a_nested'], Literal[b'a_nested'], Literal['a_oneof'], Literal[b'a_oneof'], Literal['a_oneof_1'], Literal[b'a_oneof_1'], Literal['a_oneof_2'], Literal[b'a_oneof_2'], Literal['a_string'], Literal[b'a_string'], Literal['a_uint32'], Literal[b'a_uint32'], Literal['email'], Literal[b'email'], Literal['inner_enum'], Literal[b'inner_enum'], Literal['inner_enum_in_oneof'], Literal[b'inner_enum_in_oneof'], Literal['inner_message'], Literal[b'inner_message'], Literal['nested_enum'], Literal[b'nested_enum'], Literal['nested_message'], Literal[b'nested_message'], Literal['no_package'], Literal[b'no_package'], Literal['outer_enum_in_oneof'], Literal[b'outer_enum_in_oneof'], Literal['outer_message_in_oneof'], Literal[b'outer_message_in_oneof'], Literal['user_id'], Literal[b'user_id']]" [arg-type] test_negative/negative.py: error: Argument 1 to "HasField" of "Simple1" has incompatible type "Literal['a_repeated_string']"; expected "Union[Literal['a_boolean'], Literal[b'a_boolean'], Literal['a_enum'], Literal[b'a_enum'], Literal['a_external_enum'], Literal[b'a_external_enum'], Literal['a_inner'], Literal[b'a_inner'], Literal['a_nested'], Literal[b'a_nested'], Literal['a_oneof'], Literal[b'a_oneof'], Literal['a_oneof_1'], Literal[b'a_oneof_1'], Literal['a_oneof_2'], Literal[b'a_oneof_2'], Literal['a_string'], Literal[b'a_string'], Literal['a_uint32'], Literal[b'a_uint32'], Literal['email'], Literal[b'email'], Literal['inner_enum'], Literal[b'inner_enum'], Literal['inner_enum_in_oneof'], Literal[b'inner_enum_in_oneof'], Literal['inner_message'], Literal[b'inner_message'], Literal['nested_enum'], Literal[b'nested_enum'], Literal['nested_message'], Literal[b'nested_message'], Literal['no_package'], Literal[b'no_package'], Literal['outer_enum_in_oneof'], Literal[b'outer_enum_in_oneof'], Literal['outer_message_in_oneof'], Literal[b'outer_message_in_oneof'], Literal['user_id'], Literal[b'user_id']]" [arg-type] test_negative/negative.py: error: Argument 1 to "HasField" of "SimpleProto3" has incompatible type "Literal['garbage']"; expected "Union[Literal['OuterMessage3'], Literal[b'OuterMessage3'], Literal['_an_optional_string'], Literal[b'_an_optional_string'], Literal['a_oneof'], Literal[b'a_oneof'], Literal['a_oneof_1'], Literal[b'a_oneof_1'], Literal['a_oneof_2'], Literal[b'a_oneof_2'], Literal['an_optional_string'], Literal[b'an_optional_string'], Literal['b_oneof'], Literal[b'b_oneof'], Literal['b_oneof_1'], Literal[b'b_oneof_1'], Literal['b_oneof_2'], Literal[b'b_oneof_2'], Literal['bool'], Literal[b'bool'], Literal['inner_enum_in_oneof'], Literal[b'inner_enum_in_oneof'], Literal['outer_enum_in_oneof'], Literal[b'outer_enum_in_oneof'], Literal['outer_message'], Literal[b'outer_message'], Literal['outer_message_in_oneof'], Literal[b'outer_message_in_oneof']]" [arg-type] @@ -61,11 +61,11 @@ test_negative/negative.py: error: "Descriptor" has no attribute "Garbage" [attr test_negative/negative.py: error: "Descriptor" has no attribute "Garbage" [attr-defined] test_negative/negative.py: error: "EnumDescriptor" has no attribute "Garbage" [attr-defined] test_negative/negative.py: error: "FileDescriptor" has no attribute "Garbage" [attr-defined] -test_negative/negative.py: error: "V" has no attribute "FOO" [attr-defined] -test_negative/negative.py: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "int"; expected "V" [arg-type] -test_negative/negative.py: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.V"; expected "testproto.test3_pb2._OuterEnum.V" [arg-type] -test_negative/negative.py: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.V"; expected "testproto.test3_pb2._OuterEnum.V" [arg-type] -test_negative/negative.py: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.V"; expected "testproto.test3_pb2._OuterEnum.V" [arg-type] +test_negative/negative.py: error: "ValueType" has no attribute "FOO" [attr-defined] +test_negative/negative.py: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "int"; expected "ValueType" [arg-type] +test_negative/negative.py: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.ValueType"; expected "testproto.test3_pb2._OuterEnum.ValueType" [arg-type] +test_negative/negative.py: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.ValueType"; expected "testproto.test3_pb2._OuterEnum.ValueType" [arg-type] +test_negative/negative.py: error: Argument 1 to "Name" of "_EnumTypeWrapper" has incompatible type "testproto.test3_pb2.SimpleProto3._InnerEnum.ValueType"; expected "testproto.test3_pb2._OuterEnum.ValueType" [arg-type] test_negative/negative.py: error: "ScalarMap[int, str]" has no attribute "get_or_create" [attr-defined] test_negative/negative.py: error: No overload variant of "get" of "Mapping" matches argument type "str" [call-overload] test_negative/negative.py: note: Possible overload variant: @@ -93,5 +93,5 @@ test_negative/negative.py: error: Argument "a_string" to "OuterMessage3" has inc test_negative/negative.py: error: Property "a_repeated_string" defined in "Simple1" is read-only [misc] test_negative/negative.py: error: Property "rep_inner_enum" defined in "Simple1" is read-only [misc] test_negative/negative.py: error: "_r_None" has no attribute "invalid"; maybe "valid"? [attr-defined] -test_negative/negative.py: error: Incompatible types in assignment (expression has type "V", variable has type "str") [assignment] +test_negative/negative.py: error: Incompatible types in assignment (expression has type "ValueType", variable has type "str") [assignment] Found 80 errors in 2 files (checked 31 source files)