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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,21 @@ By default mypy-protobuf will output servicer stubs with abstract methods. To ou
protoc --python_out=output/location --mypy_grpc_out=generate_concrete_servicer_stubs:output/location
```

### `sync_only/async_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:

```
protoc --python_out=output/location --mypy_grpc_out=sync_only:output/location
```

or

```
protoc --python_out=output/location --mypy_grpc_out=async_only:output/location
```

### Output suppression

To suppress output, you can run
Expand Down
271 changes: 187 additions & 84 deletions mypy_protobuf/main.py

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ include = [
exclude = [
"**/*_pb2.py",
"**/*_pb2_grpc.py",
"test/test_concrete.py"
"test/test_concrete.py",
]

executionEnvironments = [
# Due to how upb is typed, we need to disable incompatible variable override checks
{ root = "test/generated", extraPaths = ["./"], reportIncompatibleVariableOverride = "none" },
{ root = "test/generated-concrete", extraPaths = ["./"], reportIncompatibleVariableOverride = "none" },
{ root = "test/generated-sync-only", extraPaths = ["./"], reportIncompatibleVariableOverride = "none" },
{ root = "test/generated-async-only", extraPaths = ["./"], reportIncompatibleVariableOverride = "none" },
{ root = "mypy_protobuf/extensions_pb2.pyi", reportIncompatibleVariableOverride = "none" },
]
15 changes: 14 additions & 1 deletion run_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@
find proto -name "*.proto" -print0 | xargs -0 "$PROTOC" "${PROTOC_ARGS[@]}" --mypy_out=generate_concrete_servicer_stubs:test/generated-concrete
find proto/testproto/grpc -name "*.proto" -print0 | xargs -0 "$PROTOC" "${PROTOC_ARGS[@]}" --mypy_grpc_out=generate_concrete_servicer_stubs:test/generated-concrete

# Generate with sync_only stubs for testing
find proto/testproto/grpc -name "*.proto" -print0 | xargs -0 "$PROTOC" "${PROTOC_ARGS[@]}" --mypy_grpc_out=only_sync:test/generated-sync-only
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generated_sync_only


# Generate with async_only stubs for testing
find proto/testproto/grpc -name "*.proto" -print0 | xargs -0 "$PROTOC" "${PROTOC_ARGS[@]}" --mypy_grpc_out=only_async:test/generated-async-only
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generated_async_only


if [[ -n $VALIDATE ]] && ! diff <(echo "$SHA_BEFORE") <(find test/generated -name "*.pyi" -print0 | xargs -0 sha1sum); then
echo -e "${RED}Some .pyi files did not match. Please commit those files${NC}"
Expand All @@ -161,6 +166,14 @@
CONCRETE_MODULES=( -m test.test_concrete )
MYPYPATH=$MYPYPATH:test/generated-concrete mypy ${CUSTOM_TYPESHED_DIR_ARG:+"$CUSTOM_TYPESHED_DIR_ARG"} --python-executable="$UNIT_TESTS_VENV"/bin/python --python-version="$PY_VER_MYPY_TARGET" "${CONCRETE_MODULES[@]}"

# Run sync_only mypy
SYNC_ONLY_MODULES=( -m test.test_sync_only )
MYPYPATH=$MYPYPATH:test/generated-sync-only mypy ${CUSTOM_TYPESHED_DIR_ARG:+"$CUSTOM_TYPESHED_DIR_ARG"} --python-executable="$UNIT_TESTS_VENV"/bin/python --python-version="$PY_VER_MYPY_TARGET" "${SYNC_ONLY_MODULES[@]}"

# Run async_only mypy
ASYNC_ONLY_MODULES=( -m test.test_async_only )
MYPYPATH=$MYPYPATH:test/generated-async-only mypy ${CUSTOM_TYPESHED_DIR_ARG:+"$CUSTOM_TYPESHED_DIR_ARG"} --python-executable="$UNIT_TESTS_VENV"/bin/python --python-version="$PY_VER_MYPY_TARGET" "${ASYNC_ONLY_MODULES[@]}"

export MYPYPATH=$MYPYPATH:test/generated

# Run mypy
Expand Down Expand Up @@ -202,21 +215,21 @@
cp "$MYPY_OUTPUT/mypy_output.omit_linenos" "test_negative/output.expected.$PY_VER_MYPY_TARGET.omit_linenos"

# Record error instead of echoing and exiting
ERRORS+=("test_negative/output.expected.$PY_VER_MYPY_TARGET didnt match. Copying over for you.")

Check warning on line 218 in run_test.sh

View workflow job for this annotation

GitHub Actions / Linting

[shellcheck] reported by reviewdog 🐶 Modification of ERRORS is local (to subshell caused by (..) group). Raw Output: ./run_test.sh:218:13: info: Modification of ERRORS is local (to subshell caused by (..) group). (ShellCheck.SC2030)
fi
)

(
# Run unit tests.
source "$UNIT_TESTS_VENV"/bin/activate
PYTHONPATH=test/generated py.test --ignore=test/generated -v
PYTHONPATH=test/generated py.test --ignore=test/generated --ignore=test/generated-sync-only --ignore=test/generated-async-only -v
)
done

# Report all errors at the end
if [ ${#ERRORS[@]} -gt 0 ]; then

Check warning on line 230 in run_test.sh

View workflow job for this annotation

GitHub Actions / Linting

[shellcheck] reported by reviewdog 🐶 ERRORS was modified in a subshell. That change might be lost. Raw Output: ./run_test.sh:230:6: info: ERRORS was modified in a subshell. That change might be lost. (ShellCheck.SC2031)
echo -e "\n${RED}===============================================${NC}"
for error in "${ERRORS[@]}"; do

Check warning on line 232 in run_test.sh

View workflow job for this annotation

GitHub Actions / Linting

[shellcheck] reported by reviewdog 🐶 ERRORS was modified in a subshell. That change might be lost. Raw Output: ./run_test.sh:232:19: info: ERRORS was modified in a subshell. That change might be lost. (ShellCheck.SC2031)
echo -e "${RED}$error${NC}"
done
echo -e "${RED}Now rerun${NC}"
Expand Down
Empty file.
40 changes: 40 additions & 0 deletions test/generated-async-only/testproto/Capitalized/Capitalized_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""

import builtins
import google.protobuf.descriptor
import google.protobuf.message
import sys
import typing

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

DESCRIPTOR: google.protobuf.descriptor.FileDescriptor

@typing.final
class lower(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor

A_FIELD_NUMBER: builtins.int
a: builtins.int
def __init__(
self,
*,
a: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["a", b"a"]) -> None: ...

Global___lower: typing_extensions.TypeAlias = lower

@typing.final
class Upper(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor

LOWER_FIELD_NUMBER: builtins.int
@property
def Lower(self) -> Global___lower: ...
def __init__(
self,
*,
Lower: Global___lower | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["Lower", b"Lower"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["Lower", b"Lower"]) -> None: ...

Global___Upper: typing_extensions.TypeAlias = Upper

@typing.final
class lower2(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor

UPPER_FIELD_NUMBER: builtins.int
@property
def upper(self) -> Global___Upper: ...
def __init__(
self,
*,
upper: Global___Upper | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["upper", b"upper"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["upper", b"upper"]) -> None: ...

Global___lower2: typing_extensions.TypeAlias = lower2
Empty file.
Empty file.
36 changes: 36 additions & 0 deletions test/generated-async-only/testproto/comment_special_chars_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 82 additions & 0 deletions test/generated-async-only/testproto/comment_special_chars_pb2.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""

import builtins
import google.protobuf.descriptor
import google.protobuf.message
import sys
import typing

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

DESCRIPTOR: google.protobuf.descriptor.FileDescriptor

@typing.final
class Test(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor

A_FIELD_NUMBER: builtins.int
B_FIELD_NUMBER: builtins.int
C_FIELD_NUMBER: builtins.int
D_FIELD_NUMBER: builtins.int
E_FIELD_NUMBER: builtins.int
F_FIELD_NUMBER: builtins.int
G_FIELD_NUMBER: builtins.int
H_FIELD_NUMBER: builtins.int
I_FIELD_NUMBER: builtins.int
J_FIELD_NUMBER: builtins.int
K_FIELD_NUMBER: builtins.int
a: builtins.str
"""Ending with " """
b: builtins.str
"""Ending with "" """
c: builtins.str
"""Ending with \"\"\" """
d: builtins.str
"""Ending with \\ """
e: builtins.str
"""Containing bad escape: \\x"""
f: builtins.str
"""Containing \"\"\"" quadruple"""
g: builtins.str
"""Containing \"\"\""" quintuple"""
h: builtins.str
"""Containing \"\"\"\"\"\" sextuple"""
i: builtins.str
"""\"\"\" Multiple \"\"\" triples \"\"\" """
j: builtins.str
""""quotes" can be a problem in comments.
\"\"\"Triple quotes\"\"\" just as well
"""
k: builtins.str
"""\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"
" "
" Super Duper comments with surrounding edges! "
" "
" Pay attention to me!!!! "
" "
\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"
"""
def __init__(
self,
*,
a: builtins.str = ...,
b: builtins.str = ...,
c: builtins.str = ...,
d: builtins.str = ...,
e: builtins.str = ...,
f: builtins.str = ...,
g: builtins.str = ...,
h: builtins.str = ...,
i: builtins.str = ...,
j: builtins.str = ...,
k: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["a", b"a", "b", b"b", "c", b"c", "d", b"d", "e", b"e", "f", b"f", "g", b"g", "h", b"h", "i", b"i", "j", b"j", "k", b"k"]) -> None: ...

Global___Test: typing_extensions.TypeAlias = Test
Empty file.
Empty file.
36 changes: 36 additions & 0 deletions test/generated-async-only/testproto/dot/com/test_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions test/generated-async-only/testproto/dot/com/test_pb2.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""

import builtins
import google.protobuf.descriptor
import google.protobuf.message
import sys
import typing

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

DESCRIPTOR: google.protobuf.descriptor.FileDescriptor

@typing.final
class TestMessage(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor

FOO_FIELD_NUMBER: builtins.int
foo: builtins.str
def __init__(
self,
*,
foo: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["foo", b"foo"]) -> None: ...

Global___TestMessage: typing_extensions.TypeAlias = TestMessage
Loading
Loading