Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ jobs:
with:
# By default, shellcheck tries to make sure any external files referenced actually exist
shellcheck_flags: -e SC1091
exclude: |
*/third_party/*

sanity_check_windows:
name: Sanity Check Windows Executable
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
- Add `_WhichOneofArgType_<oneof_name>` and `_WhichOneofReturnType_<oneof_name>` type aliases
- Use `__new__` overloads for async stubs instead of `TypeVar` based `__init__` overloads.
- https://github.com/nipunn1313/mypy-protobuf/issues/707
- Use `builtins.property` to handle conflicts with fields named `property`
- Mangle all non provided message type imports, this prevents conflicts with field names like `collections`, `builtins`, etc.
- Do not mangle message imports, as that would be a breaking change.
- Export stub methods as properties instead of attributes if deprecated and mark as such
- Export enum fields as properties on class level (not module level) enums if deprecated and mark as such
- Export fields as properties with getters/setters if deprecated and mark as such

## 3.7.0

Expand Down
42 changes: 37 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,19 @@ See [Changelog](CHANGELOG.md) for full listing
* `mypy-protobuf` generates correctly typed `HasField`, `WhichOneof`, and `ClearField` methods.
* There are differences in how `mypy-protobuf` and `pyi_out` generate enums. See [this issue](https://github.com/protocolbuffers/protobuf/issues/8175) for details
* Type aliases exported for `HasField`, `WhichOneof` and `ClearField` arguments
* Parses comments as docstrings
* `mypy-protobuf` marks enums, enum values, messages, message fields, services, and methods with `@warnings.deprecated` if the deprecation option is set to true.

#### Examples

`mypy-protobuf`:

```python
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
Edition version of proto2 file"""

import builtins
import google.protobuf.descriptor
import google.protobuf.message
Expand All @@ -132,8 +139,10 @@ class Editions2024SubMessage(google.protobuf.message.Message):
*,
thing: builtins.str | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["thing", b"thing"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["thing", b"thing"]) -> None: ...
_HasFieldArgType: typing_extensions.TypeAlias = typing.Literal["thing", b"thing"]
def HasField(self, field_name: _HasFieldArgType) -> builtins.bool: ...
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["thing", b"thing"]
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...

Global___Editions2024SubMessage: typing_extensions.TypeAlias = Editions2024SubMessage

Expand Down Expand Up @@ -167,10 +176,13 @@ class Editions2024Test(google.protobuf.message.Message):
implicit_singular: builtins.str = ...,
default_singular: builtins.str | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["default_singular", b"default_singular", "explicit_singular", b"explicit_singular", "legacy", b"legacy", "message_field", b"message_field"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["default_singular", b"default_singular", "explicit_singular", b"explicit_singular", "implicit_singular", b"implicit_singular", "legacy", b"legacy", "message_field", b"message_field"]) -> None: ...
_HasFieldArgType: typing_extensions.TypeAlias = typing.Literal["default_singular", b"default_singular", "explicit_singular", b"explicit_singular", "legacy", b"legacy", "message_field", b"message_field"]
def HasField(self, field_name: _HasFieldArgType) -> builtins.bool: ...
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["default_singular", b"default_singular", "explicit_singular", b"explicit_singular", "implicit_singular", b"implicit_singular", "legacy", b"legacy", "message_field", b"message_field"]
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...

Global___Editions2024Test: typing_extensions.TypeAlias = Editions2024Test

```

Builtin pyi generator:
Expand Down Expand Up @@ -350,7 +362,7 @@ protoc --python_out=output/location --mypy_grpc_out=generate_concrete_servicer_s

### `sync_only/async_only`

By default, generated GRPC stubs are compatible with both sync and async variants. If you only
By default, generated GRPC stubs are compatible with both sync and async variants. If you only
want sync or async GRPC stubs, use this option:

```
Expand Down Expand Up @@ -445,6 +457,26 @@ protoc --python_out=output/location --mypy_out=output/location
mypy --target-version=2.7 {files}
```

## 3rd Party Tests

3rd Party proto files can be added to `third_party` using git subtree. These can be used for large scale testing of changes.

### Adding

```bash
git subtree add --prefix=third_party/googleapis https://github.com/googleapis/googleapis.git master --squash
```

### Updating

```bash
git subtree pull --prefix=third_party/googleapis https://github.com/googleapis/googleapis.git master --squash
```

## 4.0 Breaking change proposals

* De-dot all import statements

## Contributing

Contributions to the implementation are welcome. Please run tests using `./run_test.sh`.
Expand Down
60 changes: 30 additions & 30 deletions mypy_protobuf/extensions_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,53 @@
isort:skip_file
"""

import builtins
import google.protobuf.descriptor
import builtins as _builtins
import google.protobuf.descriptor as _google_protobuf_descriptor
import google.protobuf.descriptor_pb2
import google.protobuf.internal.extension_dict
import google.protobuf.message
import google.protobuf.internal.extension_dict as _google_protobuf_internal_extension_dict
import google.protobuf.message as _google_protobuf_message
import sys
import typing
import typing as _typing

if sys.version_info >= (3, 10):
import typing as typing_extensions
import typing as _typing_extensions
else:
import typing_extensions
import typing_extensions as _typing_extensions

DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
DESCRIPTOR: _google_protobuf_descriptor.FileDescriptor

@typing.final
class FieldOptions(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
@_typing.final
class FieldOptions(_google_protobuf_message.Message):
DESCRIPTOR: _google_protobuf_descriptor.Descriptor

CASTTYPE_FIELD_NUMBER: builtins.int
KEYTYPE_FIELD_NUMBER: builtins.int
VALUETYPE_FIELD_NUMBER: builtins.int
casttype: builtins.str
CASTTYPE_FIELD_NUMBER: _builtins.int
KEYTYPE_FIELD_NUMBER: _builtins.int
VALUETYPE_FIELD_NUMBER: _builtins.int
casttype: _builtins.str
"""Tells mypy-protobuf to use a specific newtype rather than the normal type for this field."""
keytype: builtins.str
keytype: _builtins.str
"""Tells mypy-protobuf to use a specific type for keys; only makes sense on map fields"""
valuetype: builtins.str
valuetype: _builtins.str
"""Tells mypy-protobuf to use a specific type for values; only makes sense on map fields"""
def __init__(
self,
*,
casttype: builtins.str = ...,
keytype: builtins.str = ...,
valuetype: builtins.str = ...,
casttype: _builtins.str = ...,
keytype: _builtins.str = ...,
valuetype: _builtins.str = ...,
) -> None: ...
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["casttype", b"casttype", "keytype", b"keytype", "valuetype", b"valuetype"]
_ClearFieldArgType: _typing_extensions.TypeAlias = _typing.Literal["casttype", b"casttype", "keytype", b"keytype", "valuetype", b"valuetype"] # noqa: Y015
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...

Global___FieldOptions: typing_extensions.TypeAlias = FieldOptions
Global___FieldOptions: _typing_extensions.TypeAlias = FieldOptions # noqa: Y015

OPTIONS_FIELD_NUMBER: builtins.int
CASTTYPE_FIELD_NUMBER: builtins.int
KEYTYPE_FIELD_NUMBER: builtins.int
VALUETYPE_FIELD_NUMBER: builtins.int
options: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, Global___FieldOptions]
OPTIONS_FIELD_NUMBER: _builtins.int
CASTTYPE_FIELD_NUMBER: _builtins.int
KEYTYPE_FIELD_NUMBER: _builtins.int
VALUETYPE_FIELD_NUMBER: _builtins.int
options: _google_protobuf_internal_extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, Global___FieldOptions]
"""Custom field options from mypy-protobuf"""
casttype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, builtins.str]
casttype: _google_protobuf_internal_extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, _builtins.str]
"""Legacy fields. Prefer to use ones within `options` instead."""
keytype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, builtins.str]
valuetype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, builtins.str]
keytype: _google_protobuf_internal_extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, _builtins.str]
valuetype: _google_protobuf_internal_extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, _builtins.str]
Loading
Loading