pax_global_header00006660000000000000000000000064141733521450014517gustar00rootroot0000000000000052 comment=985382c073b338b91bd0adbc354b64b27ba5f8c3 mypy-protobuf-3.2.0/000077500000000000000000000000001417335214500143555ustar00rootroot00000000000000mypy-protobuf-3.2.0/.gitattributes000066400000000000000000000001641417335214500172510ustar00rootroot00000000000000test_negative/output.expected.2.7 linguist-generated=true test_negative/output.expected.3.8 linguist-generated=true mypy-protobuf-3.2.0/.github/000077500000000000000000000000001417335214500157155ustar00rootroot00000000000000mypy-protobuf-3.2.0/.github/dependabot.yml000066400000000000000000000010111417335214500205360ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "pip" directory: "/" schedule: interval: "daily" - package-ecosystem: "npm" directory: ".github" schedule: interval: "daily" mypy-protobuf-3.2.0/.github/package.json000066400000000000000000000002151417335214500202010ustar00rootroot00000000000000{ "name": "fake_package_json_for_github_action_to_read_version", "private": true, "devDependencies": { "pyright": "1.1.213", } } mypy-protobuf-3.2.0/.github/workflows/000077500000000000000000000000001417335214500177525ustar00rootroot00000000000000mypy-protobuf-3.2.0/.github/workflows/main.yml000066400000000000000000000074501417335214500214270ustar00rootroot00000000000000name: CI # Run on git push, PR, or manually from the Actions tab on: [push, pull_request, workflow_dispatch] jobs: run_test: name: ${{ matrix.py-ver-mypy-protobuf }} runs-on: ubuntu-latest env: PY_VER_MYPY: 3.8.11 PY_VER_UNIT_TESTS_3: 3.8.11 strategy: matrix: # Running mypy-protobuf itself py-ver-mypy-protobuf: [ 3.7.12, 3.8.12, 3.9.9, 3.10.1, ] steps: - uses: actions/checkout@v2 - name: Read version numbers run: | echo ::set-output name=PROTOBUF_VERSION::$(grep "^protobuf>=" test_requirements.txt | cut -f2 -d=) echo ::set-output name=PYRIGHT_VERSION::$(grep '"pyright"' .github/package.json | cut -d\" -f4) id: read_versions - name: Install Protoc uses: arduino/setup-protoc@v1 with: version: "${{ steps.read_versions.outputs.PROTOBUF_VERSION }}" - name: Cache pyenv uses: actions/cache@v2 with: path: | ~/.pyenv !~/.pyenv/versions key: pyenv-installation-2 - name: Cache pyenv mypy-protobuf ver uses: actions/cache@v2 with: path: ~/.pyenv/versions/${{matrix.py-ver-mypy-protobuf}} key: pyenv-${{matrix.py-ver-mypy-protobuf}}-${{hashFiles('setup.py')}} - name: Cache pyenv unit tests 3 ver uses: actions/cache@v2 with: path: ~/.pyenv/versions/${{env.PY_VER_UNIT_TESTS_3}} key: pyenv-${{env.PY_VER_UNIT_TESTS_3}}-${{hashFiles('setup.py')}} - name: Cache pyenv mypy ver uses: actions/cache@v2 with: path: ~/.pyenv/versions/${{env.PY_VER_MYPY}} key: pyenv-${{env.PY_VER_MYPY}}-${{hashFiles('setup.py')}} - name: Install pyenv run: | if [ ! -e ~/.pyenv/bin/pyenv ]; then rm -rf ~/.pyenv curl https://pyenv.run | bash fi export PATH="$HOME/.pyenv/bin:$PATH" eval "$(pyenv init -)" eval "$(pyenv init --path)" eval "$(pyenv virtualenv-init -)" for PY in ${{matrix.py-ver-mypy-protobuf}} ${{env.PY_VER_MYPY}} ${{env.PY_VER_UNIT_TESTS_3}}; do if [ ! -e ~/.pyenv/versions/$PY ]; then pyenv install --skip-existing $PY pyenv shell $PY python -m pip install virtualenv fi done - name: Run Tests (./run_test.sh) env: PY_VER_MYPY_PROTOBUF: ${{matrix.py-ver-mypy-protobuf}} VALIDATE: 1 run: | export PATH="$HOME/.pyenv/bin:$PATH" eval "$(pyenv init -)" eval "$(pyenv init --path)" eval "$(pyenv virtualenv-init -)" ./run_test.sh - name: Run Pyright uses: jakebailey/pyright-action@v1 with: version: "${{ steps.read_versions.outputs.PYRIGHT_VERSION }}" black: name: Black formatting runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - name: Run black run: | pip3 install black black --check . sanity_check_windows: name: Sanity Check Windows Executable runs-on: windows-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - name: Read versions run: echo ::set-output name=PROTOBUF_VERSION::$(grep "^protobuf>=" test_requirements.txt | cut -f2 -d=) id: read_versions - name: Install Protoc uses: arduino/setup-protoc@v1 with: version: "${{ steps.read_versions.outputs.PROTOBUF_VERSION }}" - name: Run Protoc run: | pip3 install -e . mkdir wintestout protoc --python_out=wintestout --mypy_out=wintestout proto\mypy_protobuf\extensions.proto mypy-protobuf-3.2.0/.gitignore000066400000000000000000000003311417335214500163420ustar00rootroot00000000000000/go/src/github.com /main .*.swp __pycache__/ .cache .mypy_cache/ /env/ /mypy_env/ *.pyc /test/generated/**/*.py !/test/generated/**/__init__.py .pytest_cache /build/ /dist/ *.egg-info .idea/ *.DS_Store *venv* /runenv mypy-protobuf-3.2.0/.travis.yml000066400000000000000000000014711417335214500164710ustar00rootroot00000000000000# Config file for automatic testing at travis-ci.org dist: bionic language: python python: - "2.7" - "3.5" - "3.6" - "3.7" - "3.8" before_install: - PROTOBUF_VERSION=3.13.0 - PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip - wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME} - unzip $PROTOC_FILENAME -d $HOME/.local # We have to install protoc, and python libs for both python and python3, since mypy runs py3 - sudo apt-get install -qq python3-pip python3-setuptools - python -m pip install virtualenv - python3 -m pip install virtualenv script: - ./run_test.sh jobs: include: - python: 3.8 before_install: python3 -m pip install black script: black --check python/ test/ mypy-protobuf-3.2.0/CHANGELOG.md000066400000000000000000000325531417335214500161760ustar00rootroot00000000000000## Upcoming ## 3.2.0 - Drop support for Python 3.6 [EOL] - Remove unnecessary `...` in generated files. - Reorder/reference enum classes to avoid forward references. - Support `*_FIELD_NUMBER` for extensions - Bump types-protobuf dependency to 3.19 - Require protobuf 3.19.3 - Support DESCRIPTOR: ServiceDescriptor in py generic services - More accurately represent method names in py generic services (done -> callback, self -> inst) - More accurately represent method names in grpc services (`request` -> `request_iterator`) - Internal: Get tests to pass on pure-python protobuf impl (minor semantic differences) - Internal: Bump pyright in testing to 1.1.206 - Internal: Use stubtest to validate generated stubs match generated runtime ## 3.1.0 - Require protobuf 3.19.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. - suppress pyright warning reportSelfClsParameterName when a proto field is named `self` - Allow optional constructor keywords for primitive field types in proto3, following this [chart](https://github.com/protocolbuffers/protobuf/blob/master/docs/field_presence.md#presence-in-proto3-apis). - Reorder Enum helper classes to eliminate pycharm errors ## 3.0.0 - Drop support for targeting python 2.7 - Generate py3 specific syntax for unicode strings (`""` rather than `u""`) - Now requires protobuf 3.18.0 - Handle escaping properly in docstrings and attribute strings (#296) - Use three-digit version number 3.0.0 for minor and patch releases - Codify pyright support in README ## 2.10 - Switch from setup.py to pyproject.toml and setup.cfg per https://packaging.python.org/tutorials/packaging-projects/ - Remove dependency on grpcio-tools. mypy-protobuf doesn't need it to run. It's only needed to run mypy afterward. - Avoid relative imports in `_grpc_pb2.pyi` stubs. grpc stubs themselves don't use relative imports, nor `__init__.py` files - Use `"""` docstring style comments in generated code rather than `#` style so it shows up in IDEs. - Disambiguate messages from reserved python keywords (eg `None`) with prefix `_r_` rather than `__` - since `__` is considered private. - Bump tests to use pyright 1.1.169, types-protobuf 3.17.4, pytest 6.2.5, grpc-stubs 1.24.7, grpcio-tools 1.40.0 - Since upstream protobuf has dropped support with 3.18.0, 2.10 will be the last mypy-protobuf that supports targeting python 2.7. Updated docs for this. ## 2.9 - [Rename master branch to main](https://github.com/github/renaming) - Make `install_requires` requirements for grpcio-tools and types-protobuf use >= ## 2.8 - Propagate comments from .proto files to .pyi files - Add protobuf type stubs to the setup requirements - Fix [#239](https://github.com/dropbox/mypy-protobuf/issues/239) Remove type: ignore used in enum by pulling `V` into a separate class. - Use pytest 6.2.4 for internal test suites on python3 - Remove `protoc_gen_mypy.bat` as the entry-points method creates protoc-gen-mypy.exe. Add test confirming. ## 2.7 - Fix [#244](https://github.com/dropbox/mypy-protobuf/issues/244) - support extensions defined at module scope with proper types, matching extensions defined within Messages. See [`_ExtensionDict`](https://github.com/python/typeshed/blob/4765978f6ceeb24e10bdf93c0d4b72dfb35836d4/stubs/protobuf/google/protobuf/internal/extension_dict.pyi#L9) ```proto extend google.protobuf.MessageOptions { string test_message_option = 51234; } ``` ```python # Used to generate test_message_option: google.protobuf.descriptor.FieldDescriptor = ... # Now generates test_message_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, typing.Text] = ... ``` Fix repeated extensions as well - to generate RepeatedScalarFieldContainer and RepeatedCompositeFieldContainer - Now requires [types-protobuf](https://pypi.org/project/types-protobuf/) 3.17.3 - Fix [#238](https://github.com/dropbox/mypy-protobuf/issues/238) - handling enum variants that name conflict with EnumTypeWrapper methods - Improve mypy-protobuf testsuite expected-errors file to make insertions/deletions easier to code review - Fix [#227](https://github.com/dropbox/mypy-protobuf/issues/227) - improve support for messages/enums with python reserved keyword names - Order fields within a message in original .proto file order Previously, they were grouped by scalar/nonscalar. Remove that grouping to make it a bit easier to correlate .proto files to .pyi files. ## 2.6 - Bump protoc support to 3.17.3 - Use latest python versions in tests (3.6.14 3.7.11 3.8.11 3.9.6) - Support reserved names for message types. Previously generated invalid mypy. ```proto message M { message None {} None none = 1; } ``` - Support `protoc-gen-mypy -V` and `protoc-gen-mypy --version` to print version number - Return `Optional[Literal[...]]` instead of `Literal[...]` from WhichOneof to support cases in which none of the fields of the WhichOneof are set. See the following example. ```python def hello(name: str) -> None: ... n = proto.WhichOneof("name") hello(n) # Will now result in a mypy error. assert n is not None hello(n) # Should work ok ``` - Bump mypy version to 0.910, utilizing stubs types-protobuf==0.1.14. See https://mypy-lang.blogspot.com/2021/05/the-upcoming-switch-to-modular-typeshed.html - Bump grpcio version tested to 1.38.1 and grpc-stubs to 1.24.6 - Generate a `# type: ignore` for enum generated stubs to avoid circular dependency described in #214. Bandaid solution. ## 2.5 - Organized generated enum code to prevent definition ordering issues in Pyright-based linters - Changed type generation for `grpcio` stubs to use the `MultiCallable` API ([see here](https://grpc.github.io/grpc/python/grpc.html#multi-callable-interfaces)) . This requires using the `grpc-stubs` typings for grpcio. This change should allow calling stub methods with common parameters (`timeout`, `metadata`, etc.) as well as calling methods on the `MultiCallable` object (e.g. `my_stub.MyRpcMethod.future()`). - Update stubs to mark repeated scalar and repeated enum fields as read-only ## 2.4 - Add support for `_FIELD_NUMBER` generated fields on messages as specified [in the spec](https://developers.google.com/protocol-buffers/docs/reference/python-generated#fields) ## 2.3 - Fix CI caching across version updates. - Added unit testing for EnumTypeWrapper.Value usage - Reexport of top level enum values when using `import public` ## 2.2 - Fix bug where module level `DESCRIPTOR: FileDescriptor` was not being generated for files w public imports ## 2.1 - Fix crash when a import public reexport when dependent proto file is not listed on command line for generation ## 2.0 Non Backward Compatible Changes - Dropping support for running mypy-protobuf in python <= 3.5. Note you can still generate stubs target-compatible to python2 - Type proto Enum values for as `MyEnum.V` rather than `MyEnumValue` for import ergonomics, allowing the caller to import `MyEnum` rather than conditionally importing `MyEnumValue` - Default disallow `None` as argument for primitive fields of constructors in proto3. Provided `relax_strict_optional_primitives` flag to relax this strictness if you prefer. New Features - Support for `grpcio` stubs generation - Allow `mypy_protobuf.py` to be run directly as a script - Add support for proto's [`well_known_types`](https://developers.google.com/protocol-buffers/docs/reference/python-generated#wkt) - Support message fields named `self` - by renaming the constructor's `self` to `self_` - Rename extensions proto from `mypy/mypy.proto` to `mypy_protobuf/extensions.proto` - Add support for mypy-proto extensions `mypy_protobuf.casttype`, `mypy_protobuf.keytype`, and `mypy_protobuf.valuetype` - Add support for `import public` proto imports - by reexporting in generated code Output Format - Generate fully qualified references rather than mangling - Import builtins library rather than mangling builtins - Use fully qualified names rather than mangling imports - Only mangle-alias top-level identifiers w/ `global___` to avoid conflict w/ fields of same name [previously was mangling inner messages as well] - Add support for `readable_stubs` parameter for mangle-free output code w/o fully-qualified references to message. (in many cases this is good enough and easier to read) - Generate `arg: Optional[type] = ...` instead of `arg: Optional[type] = None` - Avoid importing google.protobuf.message.Message unless it's needed Internal Improvements - Add support for python 3.9 to CI - Update mypy-protobuf CI to target 3.8 rather than 3.5 - Inline mypy annotations, eliminate six, and remove `__future__` import in `mypy_protobuf_lib.py` - Flatten directory structure (remove python subdirectory). Updated unreleased installation instructions. - Deprecate and delete the go/ implementation ## 1.24 - Bump required mypy version to 0.800 - Bump required protobuf version to 3.14 (pi!!) - Update the autogenerated `.pyi` file header to cite `mypy-protobuf` - Reorganize mypy-protobuf testsuite files to more closely match autogeneration into a `generated` directory - Remove incorrect `type___` prefixed alias for inner enum type wrappers - Add support for extension fields in proto2 messages - Overwrite typing for `Message.Extensions` mapping to support better type inference for proto2 message extensions - Support `Message.HasExtension` and `Message.ClearExtension` - Bump python-protobuf from 3.11.3 to 3.13.0 - Add support for optional proto3 fields - Support ScalarMap and MessageMap generated types for map types in proto. This will allow us to support `get_or_create` ```proto message Message { map map_message = 17 } ``` and ```python message.map_message.get_or_create(0) ``` Before (1.23) ``` main.py:4: error: "MutableMapping[str, Nested]" has no attribute "get_or_create" [attr-defined] ``` After (1.24) - there is no error ## 1.23 - Inherit FromString from superclass Message - rather than re-generating here. Fixes bug in python2 usage `google/protobuf/type_pb2.pyi:92: error: Argument 1 of "FromString" is incompatible with supertype "Message"; supertype defines the argument type as "ByteString" [override]` ## 1.22 - Update tested/required mypy version to 0.780 (picks up new typeshed annotations). Includes improved typing/error messages on Message. Before (mypy < 0.780): ``` test_negative/negative.py:26: error: Argument 1 to "CopyFrom" of "Message" has incompatible type "str"; expected "Message" ``` After (mypy >= 0.780: ``` test_negative/negative.py:26: error: Argument 1 to "CopyFrom" of "Message" has incompatible type "str"; expected "Simple1" ``` - Update generated EnumTypeWrapper to be instances of EnumTypeWrapper - for more consistency with generated python code. Most caller code should not require mypy type changes. Egh `ProtoEnum.Value('first')` should work either way. Generated Before (in 1.21) ```python class ProtoEnum(object): @classmethod def Value(cls, name: str) -> ProtoEnumValue ``` Generated After (in 1.22) ```python ProtoEnum: _ProtoEnum class _ProtoEnum(google.protobuf.EnumTypeWrapper): def Value(self, name: str) -> ProtoEnumValue ``` - Remove autogenerated EnumTypeWrapper methods that are redundant to the typeshed parent class. Added testing for these. ## 1.21 - Support for module descriptor. - Update mangling from `global__` to `message__` - Fix bug in message typing for nested enums. Split EnumValue from EnumTypeWrapper. Enforces that constructing an enum value must happen via a NewType wrapper to the int. Example: ```proto enum ProtoEnum { FIRST = 1; SECOND = 2; } mesage ProtoMsg { ProtoEnum enum = 1; } ``` Generated Before (in 1.20): ```python class ProtoEnum(object): @classmethod def Value(cls, name: str) -> ProtoEnum class ProtoMsg(Message): def __init__(self, enum: ProtoEnum) -> None ``` Generated After (in 1.21): ```python ProtoEnumValue = NewType('ProtoEnumValue', int) class ProtoEnum(object): @classmethod def Value(cls, name: str) -> ProtoEnumValue class ProtoMsg(Message): def __init__(self, enum: ProtoEnumValue) -> None ``` Migration Guide (with example calling code) Before (with 1.20) ```python from msg_pb2 import ProtoEnum, ProtoMsg def make_proto_msg(enum: ProtoEnum) -> ProtoMsg: return ProtoMsg(enum) make_proto_msg(ProtoMsg.FIRST) ``` After (with 1.21) ```python from msg_pb2 import ProtoEnum, ProtoMsg def make_proto_msg(enum: 'msg_pb2.ProtoEnumValue') -> ProtoMsg: return ProtoMsg(enum) make_proto_msg(ProtoMsg.FIRST) ``` - Use inline-style rather than comment-style typing in the pyi file - Remove MergeFrom/CopyFrom from generated code as it is in the Message superclass ## 1.20 - Black code formatting - Fix message/field name aliasing when field name matches a message/enum name ## 1.19 - Allow omitting required proto2 fields from constructor parameters - Support and testing for python 3.8 - Support for python-protobuf to 3.11.3 ## 1.18 - Use `entry_points:console_scripts` to support long paths to the python interpreter ## 1.17 - Update to newer mypy version - including minor changes to typeshed ## 1.16 - Absolute path to necessary python - Add forward reference string literal support for enums - Alias builtin types to avoid collision with field name ## 1.15 - Add `class` to set of python keywords ## 1.14 - Add `Message.DESCRIPTOR` ## Older changelogs not available. Check git log if you need them! mypy-protobuf-3.2.0/LICENSE000066400000000000000000000261241417335214500153670ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright (c) 2017 Dropbox, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. mypy-protobuf-3.2.0/README.md000066400000000000000000000243701417335214500156420ustar00rootroot00000000000000mypy-protobuf: Generate mypy stub files from protobuf specs [![CI](https://github.com/dropbox/mypy-protobuf/workflows/CI/badge.svg)](https://github.com/dropbox/mypy-protobuf/actions?query=branch%3Amain) [![pypi](https://img.shields.io/pypi/v/mypy-protobuf?logo=Pypi)](https://pypi.org/project/mypy-protobuf/) [![license](https://img.shields.io/github/license/dropbox/mypy-protobuf)](https://github.com/dropbox/mypy-protobuf/blob/main/LICENSE) =========================================================== Starting in mypy-protobuf 3.0.0, only python3 targeting is supported 2.10 is the last version of mypy-protobuf which supports targeting python 2.7. See [Changelog](CHANGELOG.md) for recent changes. ## Requirements to run mypy-protobuf Earlier releases might work, but aren't tested - [protoc >= 3.19.3](https://github.com/protocolbuffers/protobuf/releases) - [python-protobuf >= 3.19.3](https://pypi.org/project/protobuf/) - matching protoc release - [python >= 3.7](https://www.python.org/downloads/source/) - for running mypy-protobuf plugin. ## Requirements to run typecheckers on stubs generated by mypy-protobuf Earlier releases might work, but aren't tested - [mypy >= v0.931](https://pypi.org/project/mypy) or [pyright >= 1.1.206](https://github.com/microsoft/pyright) - [python-protobuf >= 3.19.3](https://pypi.org/project/protobuf/) - matching protoc release - [types-protobuf >= 3.19.5](https://pypi.org/project/types-protobuf/) - for stubs from the google.protobuf library ### To run typecheckers on code generated with grpc plugin - you'll additionally need Earlier releases might work, but aren't tested - [grpcio>=1.40.0](https://pypi.org/project/grpcio/) - [grpcio-tools>=1.40.0](https://pypi.org/project/grpcio-tools/) - [grpc-stubs>=1.24.7](https://pypi.org/project/grpc-stubs/) Other configurations may work, but are not continuously tested currently. We would be open to expanding this list - file an issue on the issue tracker. ## Installation The plugin can be installed with ``` pip3 install mypy-protobuf ``` To install unreleased ``` REV=main # or whichever unreleased git rev you'd like pip3 install git+https://github.com/dropbox/mypy-protobuf.git@$REV # For older (1.x) versions of mypy protobuf - you may need pip3 install git+https://github.com/dropbox/mypy-protobuf.git@$REV#subdirectory=python ``` In order to run mypy on the generated code, you'll need to install ``` pip3 install mypy>=0.910 types-protobuf>=0.1.14 ``` # Usage On posix, protoc-gen-mypy is installed to python's executable bin. Assuming that's on your $PATH, you can run ``` protoc --python_out=output/location --mypy_out=output/location ``` Alternately, you can explicitly provide the path: ``` protoc --plugin=protoc-gen-mypy=path/to/protoc-gen-mypy --python_out=output/location --mypy_out=output/location ``` Check the version number with ``` > protoc-gen-mypy --version ``` ## Implementation The implementation of the plugin is in `mypy_protobuf/main.py`, which installs to an executable protoc-gen-mypy. On windows it installs to `protoc-gen-mypy.exe` ## Features See [Changelog](CHANGELOG.md) for full listing ### Bring comments from .proto files to docstrings in .pyi files Comments in the .proto files on messages, fields, enums, enum variants, extensions, services, and methods will appear as docstrings in .pyi files. Useful in IDEs for showing completions with comments. ### Types enum int values more strongly Enum int values produce stubs which wrap the int values in NewType ```proto enum MyEnum { HELLO = 0; WORLD = 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.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 # 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("HELLO")) ``` 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.ValueType', x) ``` 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 HELLO = Tuple['MyEnum.ValueType', 'MyEnum.ValueType'] if TYPE_CHECKING: HELLO = Tuple[MyEnum.ValueType, MyEnum.ValueType] ``` #### Enum int impl details mypy-protobuf autogenerates an instance of the EnumTypeWrapper as follows. ```python class _MyEnum: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _MyEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_MyEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor HELLO: _MyEnum.ValueType # 0 WORLD: _MyEnum.ValueType # 1 class MyEnum(_MyEnum, metaclass=_MyEnumEnumTypeWrapper): pass HELLO: MyEnum.ValueType # 0 WORLD: MyEnum.ValueType # 1 ``` `_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.ValueType a valid type w/o a circular dependency - `V` is supported as an alias of `ValueType` for backward compatibility ### Supports generating type wrappers for fields and maps M.proto ```proto message M { uint32 user_id = 1 [(mypy_protobuf.casttype)="mymod.UserId"]; map email_by_uid = 2 [ (mypy_protobuf.keytype)="path/to/mymod.UserId", (mypy_protobuf.valuetype)="path/to/mymod.Email" ]; } ``` mymod.py ```python UserId = NewType("UserId", int) Email = NewType("Email", Text) ``` ### `py_generic_services` If `py_generic_services` is set in your proto file, then mypy-protobuf will generate service stubs. If you want GRPC stubs instead - use the GRPC instructions. ### `readable_stubs` If `readable_stubs` is set, mypy-protobuf will generate easier-to-read stubs. The downside to this approach - is that it's possible to generate stubs which do not pass mypy - particularly in the case of name collisions. mypy-protobuf defaults to generating stubs with fully qualified imports and mangled global-level identifiers to defend against name collisions between global identifiers and field names. If you're ok with this risk, try it out! ``` protoc --python_out=output/location --mypy_out=readable_stubs:output/location ``` ### `relax_strict_optional_primitives` If you are using proto3, then primitives cannot be represented as NULL on the wire - only as their zero value. By default mypy-protobuf types message constructors to have non-nullable primitives (eg `int` instead of `Optional[int]`). python-protobuf itself will internally convert None -> zero value. If you intentionally want to use this behavior, set this flag! We recommend avoiding this, as it can lead to developer error - confusing NULL and 0 as distinct on the wire. However, it may be helpful when migrating existing proto2 code, where the distinction is meaningful ``` protoc --python_out=output/location --mypy_out=relax_strict_optional_primitives:output/location ``` ### Output suppression To suppress output, you can run ``` protoc --python_out=output/location --mypy_out=quiet:output/location ``` ### GRPC This plugin provides stubs generation for grpcio generated code. ``` protoc \ --python_out=output/location \ --mypy_out=output/location \ --grpc_out=output/location \ --mypy_grpc_out=output/location ``` Note that generated code for grpc will work only together with code for python and locations should be the same. If you need stubs for grpc internal code we suggest using this package https://github.com/shabbyrobe/grpc-stubs ### Targeting python2 support mypy-protobuf's drops support for targeting python2 with version 3.0. If you still need python2 support - ``` python3 -m pip install mypy_protobuf==2.10 protoc --python_out=output/location --mypy_out=output/location mypy --target-version=2.7 {files} ``` ## Contributing Contributions to the implementation are welcome. Please run tests using `./run_test.sh`. Ensure code is formatted using black. ``` pip3 install black black . ``` ## Contributors ### Dropboxers - [@nipunn1313](https://github.com/nipunn1313) - [@dzbarsky](https://github.com/dzbarsky) - [@gvanrossum](https://github.com/gvanrossum) - [@peterlvilim](https://github.com/peterlvilim) - [@msullivan](https://github.com/msullivan) - [@bradenaw](https://github.com/bradenaw) - [@ilevkivskyi](https://github.com/ilevkivskyi) ### Others - [@Ketouem](https://github.com/Ketouem) - [@nmiculinic](https://github.com/nmiculinic) - [@onto](https://github.com/onto) - [@jcppkkk](https://github.com/jcppkkk) - [@drather19](https://github.com/drather19) - [@smessmer](https://github.com/smessmer) - [@pcorpet](https://github.com/pcorpet) - [@zozoens31](https://github.com/zozoens31) - [@abhishekrb19](https://github.com/abhishekrb19) - [@jaens](https://github.com/jaens) - [@arussellsaw](https://github.com/arussellsaw) - [@shabbyrobe](https://github.com/shabbyrobe) - [@reorx](https://github.com/reorx) - [@zifter](https://github.com/zifter) - [@juzna](https://github.com/juzna) - [@mikolajz](https://github.com/mikolajz) - [@chadrik](https://github.com/chadrik) - [@EPronovost](https://github.com/EPronovost) - [@chrislawlor](https://github.com/chrislawlor) - [@henribru](https://github.com/henribru) - [@Evgenus](https://github.com/Evgenus) - [@MHDante](https://github.com/MHDante) - [@nelfin](https://github.com/nelfin) - [@alkasm](https://github.com/alkasm) - [@tarmath](https://github.com/tarmath) - [@jaredkhan](https://github.com/jaredkhan) - [@sodul](https://github.com/sodul) Licence etc. ------------ 1. License: Apache 2.0. 2. Copyright attribution: Copyright (c) 2017 Dropbox, Inc. 3. External contributions to the project should be subject to Dropbox's Contributor License Agreement (CLA): https://opensource.dropbox.com/cla/ mypy-protobuf-3.2.0/mypy_protobuf/000077500000000000000000000000001417335214500172735ustar00rootroot00000000000000mypy-protobuf-3.2.0/mypy_protobuf/__init__.py000066400000000000000000000000001417335214500213720ustar00rootroot00000000000000mypy-protobuf-3.2.0/mypy_protobuf/extensions_pb2.py000066400000000000000000000031201417335214500226030ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: mypy_protobuf/extensions.proto """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emypy_protobuf/extensions.proto\x12\rmypy_protobuf\x1a google/protobuf/descriptor.proto:1\n\x08\x63\x61sttype\x12\x1d.google.protobuf.FieldOptions\x18\xe0\xd4\x03 \x01(\t:0\n\x07keytype\x12\x1d.google.protobuf.FieldOptions\x18\xe2\xd4\x03 \x01(\t:2\n\tvaluetype\x12\x1d.google.protobuf.FieldOptions\x18\xe3\xd4\x03 \x01(\t') CASTTYPE_FIELD_NUMBER = 60000 casttype = DESCRIPTOR.extensions_by_name['casttype'] KEYTYPE_FIELD_NUMBER = 60002 keytype = DESCRIPTOR.extensions_by_name['keytype'] VALUETYPE_FIELD_NUMBER = 60003 valuetype = DESCRIPTOR.extensions_by_name['valuetype'] if _descriptor._USE_C_DESCRIPTORS == False: google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(casttype) google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(keytype) google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(valuetype) DESCRIPTOR._options = None # @@protoc_insertion_point(module_scope) mypy-protobuf-3.2.0/mypy_protobuf/extensions_pb2.pyi000066400000000000000000000020241417335214500227560ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.descriptor_pb2 import google.protobuf.internal.extension_dict import typing DESCRIPTOR: google.protobuf.descriptor.FileDescriptor CASTTYPE_FIELD_NUMBER: builtins.int KEYTYPE_FIELD_NUMBER: builtins.int VALUETYPE_FIELD_NUMBER: builtins.int casttype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, typing.Text] """Tells mypy to use a specific newtype rather than the normal type for this field.""" keytype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, typing.Text] """Tells mypy to use a specific type for keys; only makes sense on map fields""" valuetype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, typing.Text] """Tells mypy to use a specific type for values; only makes sense on map fields""" mypy-protobuf-3.2.0/mypy_protobuf/main.py000066400000000000000000001157501417335214500206020ustar00rootroot00000000000000#!/usr/bin/env python """Protoc Plugin to generate mypy stubs. Loosely based on @zbarsky's go implementation""" import os import sys from collections import defaultdict from contextlib import contextmanager from functools import wraps from typing import ( Any, Callable, Dict, Iterable, Iterator, List, Optional, Set, Sequence, Tuple, ) import google.protobuf.descriptor_pb2 as d from google.protobuf.compiler import plugin_pb2 as plugin_pb2 from google.protobuf.internal.containers import RepeatedCompositeFieldContainer from google.protobuf.internal.well_known_types import WKTBASES from . import extensions_pb2 __version__ = "3.2.0" # SourceCodeLocation is defined by `message Location` here # https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto SourceCodeLocation = List[int] # So phabricator doesn't think mypy_protobuf.py is generated GENERATED = "@ge" + "nerated" HEADER = f"""\"\"\" {GENERATED} by mypy-protobuf. Do not edit manually! isort:skip_file \"\"\" """ # See https://github.com/dropbox/mypy-protobuf/issues/73 for details PYTHON_RESERVED = { "False", "None", "True", "and", "as", "async", "await", "assert", "break", "class", "continue", "def", "del", "elif", "else", "except", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass", "raise", "return", "try", "while", "with", "yield", } PROTO_ENUM_RESERVED = { "Name", "Value", "keys", "values", "items", } def _mangle_global_identifier(name: str) -> str: """ Module level identifiers are mangled and aliased so that they can be disambiguated from fields/enum variants with the same name within the file. Eg: Enum variant `Name` or message field `Name` might conflict with a top level message or enum named `Name`, so mangle it with a global___ prefix for internal references. Note that this doesn't affect inner enums/messages because they get fuly qualified when referenced within a file""" return f"global___{name}" class Descriptors(object): def __init__(self, request: plugin_pb2.CodeGeneratorRequest) -> None: files = {f.name: f for f in request.proto_file} to_generate = {n: files[n] for n in request.file_to_generate} self.files: Dict[str, d.FileDescriptorProto] = files self.to_generate: Dict[str, d.FileDescriptorProto] = to_generate self.messages: Dict[str, d.DescriptorProto] = {} self.message_to_fd: Dict[str, d.FileDescriptorProto] = {} def _add_enums( enums: "RepeatedCompositeFieldContainer[d.EnumDescriptorProto]", prefix: str, _fd: d.FileDescriptorProto, ) -> None: for enum in enums: self.message_to_fd[prefix + enum.name] = _fd self.message_to_fd[prefix + enum.name + ".ValueType"] = _fd def _add_messages( messages: "RepeatedCompositeFieldContainer[d.DescriptorProto]", prefix: str, _fd: d.FileDescriptorProto, ) -> None: for message in messages: self.messages[prefix + message.name] = message self.message_to_fd[prefix + message.name] = _fd sub_prefix = prefix + message.name + "." _add_messages(message.nested_type, sub_prefix, _fd) _add_enums(message.enum_type, sub_prefix, _fd) for fd in request.proto_file: start_prefix = "." + fd.package + "." if fd.package else "." _add_messages(fd.message_type, start_prefix, fd) _add_enums(fd.enum_type, start_prefix, fd) class PkgWriter(object): """Writes a single pyi file""" def __init__( self, fd: d.FileDescriptorProto, descriptors: Descriptors, readable_stubs: bool, relax_strict_optional_primitives: bool, grpc: bool, ) -> None: self.fd = fd self.descriptors = descriptors self.readable_stubs = readable_stubs self.relax_strict_optional_primitives = relax_strict_optional_primitives self.grpc = grpc self.lines: List[str] = [] self.indent = "" # Set of {x}, where {x} corresponds to to `import {x}` self.imports: Set[str] = set() # dictionary of x->(y,z) for `from {x} import {y} as {z}` # if {z} is None, then it shortens to `from {x} import {y}` self.from_imports: Dict[str, Set[Tuple[str, Optional[str]]]] = defaultdict(set) # Comments self.source_code_info_by_scl = { tuple(location.path): location for location in fd.source_code_info.location } def _import(self, path: str, name: str) -> str: """Imports a stdlib path and returns a handle to it eg. self._import("typing", "Optional") -> "Optional" """ imp = path.replace("/", ".") if self.readable_stubs: self.from_imports[imp].add((name, None)) return name else: self.imports.add(imp) return imp + "." + name def _import_message(self, name: str) -> str: """Import a referenced message and return a handle""" message_fd = self.descriptors.message_to_fd[name] assert message_fd.name.endswith(".proto") # Strip off package name if message_fd.package: assert name.startswith("." + message_fd.package + ".") name = name[len("." + message_fd.package + ".") :] else: assert name.startswith(".") name = name[1:] # Use prepended "_r_" to disambiguate message names that alias python reserved keywords split = name.split(".") for i, part in enumerate(split): if part in PYTHON_RESERVED: split[i] = "_r_" + part name = ".".join(split) # Message defined in this file. Note: GRPC stubs in same .proto are generated into separate files if not self.grpc and message_fd.name == self.fd.name: return name if self.readable_stubs else _mangle_global_identifier(name) # Not in file. Must import # Python generated code ignores proto packages, so the only relevant factor is # whether it is in the file or not. import_name = self._import( message_fd.name[:-6].replace("-", "_") + "_pb2", split[0] ) remains = ".".join(split[1:]) if not remains: return import_name # remains could either be a direct import of a nested enum or message # from another package. return import_name + "." + remains def _builtin(self, name: str) -> str: return self._import("builtins", name) @contextmanager def _indent(self) -> Iterator[None]: self.indent = self.indent + " " yield self.indent = self.indent[:-4] def _write_line(self, line: str, *args: Any) -> None: if args: line = line.format(*args) if line == "": self.lines.append(line) else: self.lines.append(self.indent + line) def _break_text(self, text_block: str) -> List[str]: if text_block == "": return [] return [ l[1:] if l.startswith(" ") else l for l in text_block.rstrip().split("\n") ] def _has_comments(self, scl: SourceCodeLocation) -> bool: sci_loc = self.source_code_info_by_scl.get(tuple(scl)) return sci_loc is not None and bool( sci_loc.leading_detached_comments or sci_loc.leading_comments or sci_loc.trailing_comments ) def _write_comments(self, scl: SourceCodeLocation) -> bool: """Return true if any comments were written""" if not self._has_comments(scl): return False sci_loc = self.source_code_info_by_scl.get(tuple(scl)) assert sci_loc is not None lines = [] for leading_detached_comment in sci_loc.leading_detached_comments: lines.extend(self._break_text(leading_detached_comment)) lines.append("") if sci_loc.leading_comments is not None: lines.extend(self._break_text(sci_loc.leading_comments)) # Trailing comments also go in the header - to make sure it gets into the docstring if sci_loc.trailing_comments is not None: lines.extend(self._break_text(sci_loc.trailing_comments)) lines = [ # Escape triple-quotes that would otherwise end the docstring early. line.replace("\\", "\\\\").replace('"""', r"\"\"\"") for line in lines ] if len(lines) == 1: line = lines[0] if line.endswith(('"', "\\")): # Docstrings are terminated with triple-quotes, so if the documentation itself ends in a quote, # insert some whitespace to separate it from the closing quotes. # This is not necessary with multiline comments # because in that case we always insert a newline before the trailing triple-quotes. line = line + " " self._write_line(f'"""{line}"""') else: for i, line in enumerate(lines): if i == 0: self._write_line(f'"""{line}') else: self._write_line(f"{line}") self._write_line('"""') return True def write_enum_values( self, values: Iterable[Tuple[int, d.EnumValueDescriptorProto]], value_type: str, scl_prefix: SourceCodeLocation, ) -> None: for i, val in values: if val.name in PYTHON_RESERVED: continue scl = scl_prefix + [i] self._write_line( f"{val.name}: {value_type} # {val.number}", ) if self._write_comments(scl): self._write_line("") # Extra newline to separate def write_module_attributes(self) -> None: l = self._write_line fd_type = self._import("google.protobuf.descriptor", "FileDescriptor") l(f"DESCRIPTOR: {fd_type}") l("") def write_enums( self, enums: Iterable[d.EnumDescriptorProto], prefix: str, scl_prefix: SourceCodeLocation, ) -> None: l = self._write_line for i, enum in enumerate(enums): class_name = ( enum.name if enum.name not in PYTHON_RESERVED else "_r_" + enum.name ) value_type_fq = prefix + class_name + ".ValueType" enum_helper_class = "_" + enum.name value_type_helper_fq = prefix + enum_helper_class + ".ValueType" etw_helper_class = "_" + enum.name + "EnumTypeWrapper" scl = scl_prefix + [i] l(f"class {enum_helper_class}:") with self._indent(): l( "ValueType = {}('ValueType', {})", self._import("typing", "NewType"), self._builtin("int"), ) # Alias to the classic shorter definition "V" l("V: {} = ValueType", self._import("typing_extensions", "TypeAlias")) l( "class {}({}[{}], {}):", etw_helper_class, self._import( "google.protobuf.internal.enum_type_wrapper", "_EnumTypeWrapper" ), value_type_helper_fq, self._builtin("type"), ) with self._indent(): ed = self._import("google.protobuf.descriptor", "EnumDescriptor") l(f"DESCRIPTOR: {ed}") self.write_enum_values( [ (i, v) for i, v in enumerate(enum.value) if v.name not in PROTO_ENUM_RESERVED ], value_type_helper_fq, scl + [d.EnumDescriptorProto.VALUE_FIELD_NUMBER], ) l(f"class {class_name}({enum_helper_class}, metaclass={etw_helper_class}):") with self._indent(): self._write_comments(scl) l("pass") l("") self.write_enum_values( enumerate(enum.value), value_type_fq, scl + [d.EnumDescriptorProto.VALUE_FIELD_NUMBER], ) if prefix == "" and not self.readable_stubs: l(f"{_mangle_global_identifier(class_name)} = {class_name}") l("") l("") def write_messages( self, messages: Iterable[d.DescriptorProto], prefix: str, scl_prefix: SourceCodeLocation, ) -> None: l = self._write_line for i, desc in enumerate(messages): qualified_name = prefix + desc.name # Reproduce some hardcoded logic from the protobuf implementation - where # some specific "well_known_types" generated protos to have additional # base classes addl_base = "" if self.fd.package + "." + desc.name in WKTBASES: # chop off the .proto - and import the well known type # eg `from google.protobuf.duration import Duration` well_known_type = WKTBASES[self.fd.package + "." + desc.name] addl_base = ", " + self._import( "google.protobuf.internal.well_known_types", well_known_type.__name__, ) class_name = ( desc.name if desc.name not in PYTHON_RESERVED else "_r_" + desc.name ) message_class = self._import("google.protobuf.message", "Message") l(f"class {class_name}({message_class}{addl_base}):") with self._indent(): scl = scl_prefix + [i] self._write_comments(scl) desc_type = self._import("google.protobuf.descriptor", "Descriptor") l(f"DESCRIPTOR: {desc_type}") # Nested enums/messages self.write_enums( desc.enum_type, qualified_name + ".", scl + [d.DescriptorProto.ENUM_TYPE_FIELD_NUMBER], ) self.write_messages( desc.nested_type, qualified_name + ".", scl + [d.DescriptorProto.NESTED_TYPE_FIELD_NUMBER], ) # integer constants for field numbers for f in desc.field: l(f"{f.name.upper()}_FIELD_NUMBER: {self._builtin('int')}") for idx, field in enumerate(desc.field): if field.name in PYTHON_RESERVED: continue field_type = self.python_type(field) if ( is_scalar(field) and field.label != d.FieldDescriptorProto.LABEL_REPEATED ): # Scalar non repeated fields are r/w l(f"{field.name}: {field_type}") if self._write_comments( scl + [d.DescriptorProto.FIELD_FIELD_NUMBER, idx] ): l("") else: # r/o Getters for non-scalar fields and scalar-repeated fields scl_field = scl + [d.DescriptorProto.FIELD_FIELD_NUMBER, idx] l("@property") body = " ..." if not self._has_comments(scl_field) else "" l(f"def {field.name}(self) -> {field_type}:{body}") if self._has_comments(scl_field): with self._indent(): self._write_comments(scl_field) l("pass") self.write_extensions( desc.extension, scl + [d.DescriptorProto.EXTENSION_FIELD_NUMBER] ) # Constructor if any(f.name == "self" for f in desc.field): l("# pyright: reportSelfClsParameterName=false") l(f"def __init__(self_,") else: l(f"def __init__(self,") with self._indent(): constructor_fields = [ f for f in desc.field if f.name not in PYTHON_RESERVED ] if len(constructor_fields) > 0: # Only positional args allowed # See https://github.com/dropbox/mypy-protobuf/issues/71 l("*,") for field in constructor_fields: field_type = self.python_type(field, generic_container=True) if ( self.fd.syntax == "proto3" and is_scalar(field) and field.label != d.FieldDescriptorProto.LABEL_REPEATED and not self.relax_strict_optional_primitives and not field.proto3_optional ): l(f"{field.name}: {field_type} = ...,") else: opt = self._import("typing", "Optional") l(f"{field.name}: {opt}[{field_type}] = ...,") l(") -> None: ...") self.write_stringly_typed_fields(desc) if prefix == "" and not self.readable_stubs: l(f"{_mangle_global_identifier(class_name)} = {class_name}") l("") def write_stringly_typed_fields(self, desc: d.DescriptorProto) -> None: """Type the stringly-typed methods as a Union[Literal, Literal ...]""" l = self._write_line # HasField, ClearField, WhichOneof accepts both bytes/str # HasField only supports singular. ClearField supports repeated as well # In proto3, HasField only supports message fields and optional fields # HasField always supports oneof fields hf_fields = [ f.name for f in desc.field if f.HasField("oneof_index") or ( f.label != d.FieldDescriptorProto.LABEL_REPEATED and ( self.fd.syntax != "proto3" or f.type == d.FieldDescriptorProto.TYPE_MESSAGE or f.proto3_optional ) ) ] cf_fields = [f.name for f in desc.field] wo_fields = { oneof.name: [ f.name for f in desc.field if f.HasField("oneof_index") and f.oneof_index == idx ] for idx, oneof in enumerate(desc.oneof_decl) } hf_fields.extend(wo_fields.keys()) cf_fields.extend(wo_fields.keys()) hf_fields_text = ",".join(sorted(f'"{name}",b"{name}"' for name in hf_fields)) cf_fields_text = ",".join(sorted(f'"{name}",b"{name}"' for name in cf_fields)) if not hf_fields and not cf_fields and not wo_fields: return if hf_fields: l( "def HasField(self, field_name: {}[{}]) -> {}: ...", self._import("typing_extensions", "Literal"), hf_fields_text, self._builtin("bool"), ) if cf_fields: l( "def ClearField(self, field_name: {}[{}]) -> None: ...", self._import("typing_extensions", "Literal"), cf_fields_text, ) for wo_field, members in sorted(wo_fields.items()): if len(wo_fields) > 1: l("@{}", self._import("typing", "overload")) l( "def WhichOneof(self, oneof_group: {}[{}]) -> {}[{}[{}]]: ...", self._import("typing_extensions", "Literal"), # Accepts both str and bytes f'"{wo_field}",b"{wo_field}"', self._import("typing", "Optional"), self._import("typing_extensions", "Literal"), # Returns `str` ",".join(f'"{m}"' for m in members), ) def write_extensions( self, extensions: Sequence[d.FieldDescriptorProto], scl_prefix: SourceCodeLocation, ) -> None: l = self._write_line for ext in extensions: l(f"{ext.name.upper()}_FIELD_NUMBER: {self._builtin('int')}") for i, ext in enumerate(extensions): scl = scl_prefix + [i] l( "{}: {}[{}, {}]", ext.name, self._import( "google.protobuf.internal.extension_dict", "_ExtensionFieldDescriptor", ), self._import_message(ext.extendee), self.python_type(ext), ) self._write_comments(scl) l("") def write_methods( self, service: d.ServiceDescriptorProto, class_name: str, is_abstract: bool, scl_prefix: SourceCodeLocation, ) -> None: l = self._write_line l( "DESCRIPTOR: {}", self._import("google.protobuf.descriptor", "ServiceDescriptor"), ) methods = [ (i, m) for i, m in enumerate(service.method) if m.name not in PYTHON_RESERVED ] if not methods: l("pass") for i, method in methods: if is_abstract: l("@{}", self._import("abc", "abstractmethod")) l(f"def {method.name}(") with self._indent(): l(f"inst: {class_name},") l( "rpc_controller: {},", self._import("google.protobuf.service", "RpcController"), ) l("request: {},", self._import_message(method.input_type)) l( "callback: {}[{}[[{}], None]]{},", self._import("typing", "Optional"), self._import("typing", "Callable"), self._import_message(method.output_type), "" if is_abstract else " = None", ) scl_method = scl_prefix + [d.ServiceDescriptorProto.METHOD_FIELD_NUMBER, i] l( ") -> {}[{}]:{}", self._import("concurrent.futures", "Future"), self._import_message(method.output_type), " ..." if not self._has_comments(scl_method) else "", ) if self._has_comments(scl_method): with self._indent(): self._write_comments(scl_method) l("pass") def write_services( self, services: Iterable[d.ServiceDescriptorProto], scl_prefix: SourceCodeLocation, ) -> None: l = self._write_line for i, service in enumerate(services): scl = scl_prefix + [i] class_name = ( service.name if service.name not in PYTHON_RESERVED else "_r_" + service.name ) # The service definition interface l( "class {}({}, metaclass={}):", class_name, self._import("google.protobuf.service", "Service"), self._import("abc", "ABCMeta"), ) with self._indent(): self._write_comments(scl) self.write_methods( service, class_name, is_abstract=True, scl_prefix=scl ) # The stub client stub_class_name = service.name + "_Stub" l("class {}({}):", stub_class_name, class_name) with self._indent(): self._write_comments(scl) l( "def __init__(self, rpc_channel: {}) -> None: ...", self._import("google.protobuf.service", "RpcChannel"), ) self.write_methods( service, stub_class_name, is_abstract=False, scl_prefix=scl ) def _import_casttype(self, casttype: str) -> str: split = casttype.split(".") assert ( len(split) == 2 ), "mypy_protobuf.[casttype,keytype,valuetype] is expected to be of format path/to/file.TypeInFile" pkg = split[0].replace("/", ".") return self._import(pkg, split[1]) def _map_key_value_types( self, map_field: d.FieldDescriptorProto, key_field: d.FieldDescriptorProto, value_field: d.FieldDescriptorProto, ) -> Tuple[str, str]: key_casttype = map_field.options.Extensions[extensions_pb2.keytype] ktype = ( self._import_casttype(key_casttype) if key_casttype else self.python_type(key_field) ) value_casttype = map_field.options.Extensions[extensions_pb2.valuetype] vtype = ( self._import_casttype(value_casttype) if value_casttype else self.python_type(value_field) ) return ktype, vtype def _callable_type(self, method: d.MethodDescriptorProto) -> str: if method.client_streaming: if method.server_streaming: return self._import("grpc", "StreamStreamMultiCallable") else: return self._import("grpc", "StreamUnaryMultiCallable") else: if method.server_streaming: return self._import("grpc", "UnaryStreamMultiCallable") else: return self._import("grpc", "UnaryUnaryMultiCallable") def _input_type( self, method: d.MethodDescriptorProto, use_stream_iterator: bool = True ) -> str: result = self._import_message(method.input_type) if use_stream_iterator and method.client_streaming: result = f"{self._import('typing', 'Iterator')}[{result}]" return result def _output_type( self, method: d.MethodDescriptorProto, use_stream_iterator: bool = True ) -> str: result = self._import_message(method.output_type) if use_stream_iterator and method.server_streaming: result = f"{self._import('typing', 'Iterator')}[{result}]" return result def write_grpc_methods( self, service: d.ServiceDescriptorProto, scl_prefix: SourceCodeLocation ) -> None: l = self._write_line methods = [ (i, m) for i, m in enumerate(service.method) if m.name not in PYTHON_RESERVED ] if not methods: l("pass") l("") for i, method in methods: scl = scl_prefix + [d.ServiceDescriptorProto.METHOD_FIELD_NUMBER, i] l("@{}", self._import("abc", "abstractmethod")) l("def {}(self,", method.name) with self._indent(): input_name = ( "request_iterator" if method.client_streaming else "request" ) input_type = self._input_type(method) l(f"{input_name}: {input_type},") l("context: {},", self._import("grpc", "ServicerContext")) l( ") -> {}:{}", self._output_type(method), " ..." if not self._has_comments(scl) else "", ), if self._has_comments(scl): with self._indent(): self._write_comments(scl) l("pass") l("") def write_grpc_stub_methods( self, service: d.ServiceDescriptorProto, scl_prefix: SourceCodeLocation ) -> None: l = self._write_line methods = [ (i, m) for i, m in enumerate(service.method) if m.name not in PYTHON_RESERVED ] if not methods: l("pass") l("") for i, method in methods: scl = scl_prefix + [d.ServiceDescriptorProto.METHOD_FIELD_NUMBER, i] l("{}: {}[", method.name, self._callable_type(method)) with self._indent(): l("{},", self._input_type(method, False)) l("{}]", self._output_type(method, False)) self._write_comments(scl) l("") def write_grpc_services( self, services: Iterable[d.ServiceDescriptorProto], scl_prefix: SourceCodeLocation, ) -> None: l = self._write_line for i, service in enumerate(services): if service.name in PYTHON_RESERVED: continue scl = scl_prefix + [i] # The stub client l(f"class {service.name}Stub:") with self._indent(): self._write_comments(scl) l( "def __init__(self, channel: {}) -> None: ...", self._import("grpc", "Channel"), ) self.write_grpc_stub_methods(service, scl) l("") # The service definition interface l( "class {}Servicer(metaclass={}):", service.name, self._import("abc", "ABCMeta"), ) with self._indent(): self._write_comments(scl) self.write_grpc_methods(service, scl) l("") l( "def add_{}Servicer_to_server(servicer: {}Servicer, server: {}) -> None: ...", service.name, service.name, self._import("grpc", "Server"), ) l("") def python_type( self, field: d.FieldDescriptorProto, generic_container: bool = False ) -> str: """ generic_container if set, type the field with generic interfaces. Eg. - Iterable[int] rather than RepeatedScalarFieldContainer[int] - Mapping[k, v] rather than MessageMap[k, v] Can be useful for input types (eg constructor) """ casttype = field.options.Extensions[extensions_pb2.casttype] if casttype: return self._import_casttype(casttype) mapping: Dict[d.FieldDescriptorProto.Type.V, Callable[[], str]] = { d.FieldDescriptorProto.TYPE_DOUBLE: lambda: self._builtin("float"), d.FieldDescriptorProto.TYPE_FLOAT: lambda: self._builtin("float"), d.FieldDescriptorProto.TYPE_INT64: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_UINT64: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_FIXED64: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_SFIXED64: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_SINT64: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_INT32: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_UINT32: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_FIXED32: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_SFIXED32: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_SINT32: lambda: self._builtin("int"), d.FieldDescriptorProto.TYPE_BOOL: lambda: self._builtin("bool"), 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 + ".ValueType" ), d.FieldDescriptorProto.TYPE_MESSAGE: lambda: self._import_message( field.type_name ), d.FieldDescriptorProto.TYPE_GROUP: lambda: self._import_message( field.type_name ), } assert field.type in mapping, "Unrecognized type: " + repr(field.type) field_type = mapping[field.type]() # For non-repeated fields, we're done! if field.label != d.FieldDescriptorProto.LABEL_REPEATED: return field_type # Scalar repeated fields go in RepeatedScalarFieldContainer if is_scalar(field): container = ( self._import("typing", "Iterable") if generic_container else self._import( "google.protobuf.internal.containers", "RepeatedScalarFieldContainer", ) ) return f"{container}[{field_type}]" # non-scalar repeated map fields go in ScalarMap/MessageMap msg = self.descriptors.messages[field.type_name] if msg.options.map_entry: # map generates a special Entry wrapper message if generic_container: container = self._import("typing", "Mapping") elif is_scalar(msg.field[1]): container = self._import( "google.protobuf.internal.containers", "ScalarMap" ) else: container = self._import( "google.protobuf.internal.containers", "MessageMap" ) ktype, vtype = self._map_key_value_types(field, msg.field[0], msg.field[1]) return f"{container}[{ktype}, {vtype}]" # non-scalar repetated fields go in RepeatedCompositeFieldContainer container = ( self._import("typing", "Iterable") if generic_container else self._import( "google.protobuf.internal.containers", "RepeatedCompositeFieldContainer", ) ) return f"{container}[{field_type}]" def write(self) -> str: for reexport_idx in self.fd.public_dependency: reexport_file = self.fd.dependency[reexport_idx] reexport_fd = self.descriptors.files[reexport_file] reexport_imp = ( reexport_file[:-6].replace("-", "_").replace("/", ".") + "_pb2" ) names = ( [m.name for m in reexport_fd.message_type] + [m.name for m in reexport_fd.enum_type] + [v.name for m in reexport_fd.enum_type for v in m.value] + [m.name for m in reexport_fd.extension] ) if reexport_fd.options.py_generic_services: names.extend(m.name for m in reexport_fd.service) if names: # n,n to force a reexport (from x import y as y) self.from_imports[reexport_imp].update((n, n) for n in names) import_lines = [] for pkg in sorted(self.imports): import_lines.append(f"import {pkg}") for pkg, items in sorted(self.from_imports.items()): import_lines.append(f"from {pkg} import (") for (name, reexport_name) in sorted(items): if reexport_name is None: import_lines.append(f" {name},") else: import_lines.append(f" {name} as {reexport_name},") import_lines.append(")\n") import_lines.append("") return "\n".join(import_lines + self.lines) def is_scalar(fd: d.FieldDescriptorProto) -> bool: return not ( fd.type == d.FieldDescriptorProto.TYPE_MESSAGE or fd.type == d.FieldDescriptorProto.TYPE_GROUP ) def generate_mypy_stubs( descriptors: Descriptors, response: plugin_pb2.CodeGeneratorResponse, quiet: bool, readable_stubs: bool, relax_strict_optional_primitives: bool, ) -> None: for name, fd in descriptors.to_generate.items(): pkg_writer = PkgWriter( fd, descriptors, readable_stubs, relax_strict_optional_primitives, grpc=False, ) pkg_writer.write_module_attributes() pkg_writer.write_enums( fd.enum_type, "", [d.FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER] ) pkg_writer.write_messages( fd.message_type, "", [d.FileDescriptorProto.MESSAGE_TYPE_FIELD_NUMBER] ) pkg_writer.write_extensions( fd.extension, [d.FileDescriptorProto.EXTENSION_FIELD_NUMBER] ) if fd.options.py_generic_services: pkg_writer.write_services( fd.service, [d.FileDescriptorProto.SERVICE_FIELD_NUMBER] ) assert name == fd.name assert fd.name.endswith(".proto") output = response.file.add() output.name = fd.name[:-6].replace("-", "_").replace(".", "/") + "_pb2.pyi" output.content = HEADER + pkg_writer.write() if not quiet: print("Writing mypy to", output.name, file=sys.stderr) def generate_mypy_grpc_stubs( descriptors: Descriptors, response: plugin_pb2.CodeGeneratorResponse, quiet: bool, readable_stubs: bool, relax_strict_optional_primitives: bool, ) -> None: for name, fd in descriptors.to_generate.items(): pkg_writer = PkgWriter( fd, descriptors, readable_stubs, relax_strict_optional_primitives, grpc=True, ) pkg_writer.write_grpc_services( fd.service, [d.FileDescriptorProto.SERVICE_FIELD_NUMBER] ) assert name == fd.name assert fd.name.endswith(".proto") output = response.file.add() output.name = fd.name[:-6].replace("-", "_").replace(".", "/") + "_pb2_grpc.pyi" output.content = HEADER + pkg_writer.write() if not quiet: print("Writing mypy to", output.name, file=sys.stderr) @contextmanager def code_generation() -> Iterator[ Tuple[plugin_pb2.CodeGeneratorRequest, plugin_pb2.CodeGeneratorResponse], ]: if len(sys.argv) > 1 and sys.argv[1] in ("-V", "--version"): print("mypy-protobuf " + __version__) sys.exit(0) # Read request message from stdin data = sys.stdin.buffer.read() # Parse request request = plugin_pb2.CodeGeneratorRequest() request.ParseFromString(data) # Create response response = plugin_pb2.CodeGeneratorResponse() # Declare support for optional proto3 fields response.supported_features |= ( plugin_pb2.CodeGeneratorResponse.FEATURE_PROTO3_OPTIONAL ) yield request, response # Serialise response message output = response.SerializeToString() # Write to stdout sys.stdout.buffer.write(output) def main() -> None: # Generate mypy with code_generation() as (request, response): generate_mypy_stubs( Descriptors(request), response, "quiet" in request.parameter, "readable_stubs" in request.parameter, "relax_strict_optional_primitives" in request.parameter, ) def grpc() -> None: # Generate grpc mypy with code_generation() as (request, response): generate_mypy_grpc_stubs( Descriptors(request), response, "quiet" in request.parameter, "readable_stubs" in request.parameter, "relax_strict_optional_primitives" in request.parameter, ) if __name__ == "__main__": main() mypy-protobuf-3.2.0/mypy_protobuf/protoc_gen_mypy.bat000066400000000000000000000000601417335214500231740ustar00rootroot00000000000000@echo off %~dp0\python -u %0\..\protoc-gen-mypy mypy-protobuf-3.2.0/mypy_requirements.txt000066400000000000000000000001321417335214500207130ustar00rootroot00000000000000# Requirements to run mypy itself. Mypy executable exists in a separate venv. mypy==0.931 mypy-protobuf-3.2.0/proto/000077500000000000000000000000001417335214500155205ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/google/000077500000000000000000000000001417335214500167745ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/google/protobuf/000077500000000000000000000000001417335214500206345ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/google/protobuf/duration.proto000066400000000000000000000114301417335214500235450ustar00rootroot00000000000000// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. syntax = "proto3"; package google.protobuf; option csharp_namespace = "Google.Protobuf.WellKnownTypes"; option cc_enable_arenas = true; option go_package = "github.com/golang/protobuf/ptypes/duration"; option java_package = "com.google.protobuf"; option java_outer_classname = "DurationProto"; option java_multiple_files = true; option objc_class_prefix = "GPB"; // A Duration represents a signed, fixed-length span of time represented // as a count of seconds and fractions of seconds at nanosecond // resolution. It is independent of any calendar and concepts like "day" // or "month". It is related to Timestamp in that the difference between // two Timestamp values is a Duration and it can be added or subtracted // from a Timestamp. Range is approximately +-10,000 years. // // # Examples // // Example 1: Compute Duration from two Timestamps in pseudo code. // // Timestamp start = ...; // Timestamp end = ...; // Duration duration = ...; // // duration.seconds = end.seconds - start.seconds; // duration.nanos = end.nanos - start.nanos; // // if (duration.seconds < 0 && duration.nanos > 0) { // duration.seconds += 1; // duration.nanos -= 1000000000; // } else if (duration.seconds > 0 && duration.nanos < 0) { // duration.seconds -= 1; // duration.nanos += 1000000000; // } // // Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. // // Timestamp start = ...; // Duration duration = ...; // Timestamp end = ...; // // end.seconds = start.seconds + duration.seconds; // end.nanos = start.nanos + duration.nanos; // // if (end.nanos < 0) { // end.seconds -= 1; // end.nanos += 1000000000; // } else if (end.nanos >= 1000000000) { // end.seconds += 1; // end.nanos -= 1000000000; // } // // Example 3: Compute Duration from datetime.timedelta in Python. // // td = datetime.timedelta(days=3, minutes=10) // duration = Duration() // duration.FromTimedelta(td) // // # JSON Mapping // // In JSON format, the Duration type is encoded as a string rather than an // object, where the string ends in the suffix "s" (indicating seconds) and // is preceded by the number of seconds, with nanoseconds expressed as // fractional seconds. For example, 3 seconds with 0 nanoseconds should be // encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should // be expressed in JSON format as "3.000000001s", and 3 seconds and 1 // microsecond should be expressed in JSON format as "3.000001s". // // message Duration { // Signed seconds of the span of time. Must be from -315,576,000,000 // to +315,576,000,000 inclusive. Note: these bounds are computed from: // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years int64 seconds = 1; // Signed fractions of a second at nanosecond resolution of the span // of time. Durations less than one second are represented with a 0 // `seconds` field and a positive or negative `nanos` field. For durations // of one second or more, a non-zero value for the `nanos` field must be // of the same sign as the `seconds` field. Must be from -999,999,999 // to +999,999,999 inclusive. int32 nanos = 2; } mypy-protobuf-3.2.0/proto/mypy_protobuf/000077500000000000000000000000001417335214500204365ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/mypy_protobuf/extensions.proto000066400000000000000000000007611417335214500237260ustar00rootroot00000000000000syntax = "proto2"; package mypy_protobuf; import "google/protobuf/descriptor.proto"; extend google.protobuf.FieldOptions { // Tells mypy to use a specific newtype rather than the normal type for this field. optional string casttype = 60000; // Tells mypy to use a specific type for keys; only makes sense on map fields optional string keytype = 60002; // Tells mypy to use a specific type for values; only makes sense on map fields optional string valuetype = 60003; } mypy-protobuf-3.2.0/proto/testproto/000077500000000000000000000000001417335214500175635ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/testproto/Capitalized/000077500000000000000000000000001417335214500220145ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/testproto/Capitalized/Capitalized.proto000066400000000000000000000002361417335214500253330ustar00rootroot00000000000000syntax = "proto3"; package Capitalized; message lower { int64 a = 1; } message Upper { lower Lower = 1; } message lower2 { Upper upper = 1; } mypy-protobuf-3.2.0/proto/testproto/comment_special_chars.proto000066400000000000000000000016621417335214500251770ustar00rootroot00000000000000syntax = "proto3"; package comment_special_chars; message Test { // Ending with " string a = 1; // Ending with "" string b = 2; // Ending with """ string c = 3; // Ending with \ string d = 4; // Containing bad escape: \x string e = 5; // Containing """" quadruple string f = 6; // Containing """"" quintuple string g = 7; // Containing """""" sextuple string h = 8; // """ Multiple """ triples """ string i = 9; // "quotes" can be a problem in comments. // """Triple quotes""" just as well string j = 10; // """""""""""""""""""""""""""""""""""""""""""""""" // " " // " Super Duper comments with surrounding edges! " // " " // " Pay attention to me!!!! " // " " // """""""""""""""""""""""""""""""""""""""""""""""" string k = 11; } mypy-protobuf-3.2.0/proto/testproto/dot.com/000077500000000000000000000000001417335214500211265ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/testproto/dot.com/test.proto000066400000000000000000000001161417335214500231700ustar00rootroot00000000000000syntax = "proto3"; package test; message TestMessage { string foo = 1; } mypy-protobuf-3.2.0/proto/testproto/grpc/000077500000000000000000000000001417335214500205165ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/testproto/grpc/dummy.proto000066400000000000000000000010621417335214500227350ustar00rootroot00000000000000// https://github.com/vmagamedov/grpclib/blob/master/tests/dummy.proto syntax = "proto3"; package dummy; message DummyRequest { string value = 1; } message DummyReply { string value = 1; } // DummyService service DummyService { // UnaryUnary rpc UnaryUnary (DummyRequest) returns (DummyReply) {} // UnaryStream rpc UnaryStream (DummyRequest) returns (stream DummyReply) {} // StreamUnary rpc StreamUnary (stream DummyRequest) returns (DummyReply) {} // StreamStream rpc StreamStream (stream DummyRequest) returns (stream DummyReply) {} } mypy-protobuf-3.2.0/proto/testproto/grpc/import.proto000066400000000000000000000006031417335214500231140ustar00rootroot00000000000000syntax = "proto2"; import "testproto/test.proto"; import "google/protobuf/empty.proto"; package test.grpc; // SimpleService service SimpleService { // UnaryUnary rpc UnaryUnary (google.protobuf.Empty) returns (test.Simple1) {} // UnaryStream rpc UnaryStream (test.Simple1) returns (google.protobuf.Empty) {} rpc NoComment (test.Simple1) returns (google.protobuf.Empty) {} } mypy-protobuf-3.2.0/proto/testproto/inner/000077500000000000000000000000001417335214500206765ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/testproto/inner/inner.proto000066400000000000000000000001621417335214500230750ustar00rootroot00000000000000syntax = "proto3"; package inner; import "testproto/test3.proto"; message Inner { test3.OuterEnum a = 1; } mypy-protobuf-3.2.0/proto/testproto/nested/000077500000000000000000000000001417335214500210455ustar00rootroot00000000000000mypy-protobuf-3.2.0/proto/testproto/nested/nested.proto000066400000000000000000000007701417335214500234200ustar00rootroot00000000000000syntax = "proto3"; package test.nested_package; import "testproto/test3.proto"; message Nested { test3.OuterEnum a = 1; } message AnotherNested { enum NestedEnum { INVALID = 0; ONE = 1; TWO = 2; } message NestedMessage { enum NestedEnum2 { UNDEFINED = 0; NESTED_ENUM1 = 1; NESTED_ENUM2 = 2; } string s = 1; bool b = 2; NestedEnum ne = 3; NestedEnum2 ne2 = 4; } } mypy-protobuf-3.2.0/proto/testproto/nopackage.proto000066400000000000000000000003011417335214500225720ustar00rootroot00000000000000syntax = "proto3"; // Intentionally don't set a package - just to make sure we can handle it. message NoPackage {} message NoPackage2 { NoPackage np = 1; repeated NoPackage np_rep = 2; } mypy-protobuf-3.2.0/proto/testproto/readme_enum.proto000066400000000000000000000001151417335214500231260ustar00rootroot00000000000000syntax = "proto3"; package test; enum MyEnum { HELLO = 0; WORLD = 1; } mypy-protobuf-3.2.0/proto/testproto/reexport.proto000066400000000000000000000003101417335214500225120ustar00rootroot00000000000000syntax = "proto3"; package test3; // Should be reexported import public "testproto/test3.proto"; import public "google/protobuf/empty.proto"; // Not reexported import "testproto/inner/inner.proto"; mypy-protobuf-3.2.0/proto/testproto/test.proto000066400000000000000000000104001417335214500216220ustar00rootroot00000000000000syntax = "proto2"; package test; import "mypy_protobuf/extensions.proto"; import "testproto/inner/inner.proto"; import "testproto/nested/nested.proto"; import "testproto/nopackage.proto"; import "testproto/test3.proto"; // Outer Enum enum OuterEnum { // FOO FOO = 1; // BAR BAR = 2; } // Naming conflicts! enum NamingConflicts { Name = 1; Value = 2; keys = 3; values = 4; items = 5; // See https://github.com/protocolbuffers/protobuf/issues/8803 // proto itself generates broken code when DESCRIPTOR is there // DESCRIPTOR = 8; } // Message with one of everything message Simple1 { // Inner Enum enum InnerEnum { // INNER1 INNER1 = 1; // INNER2 INNER2 = 2; } message InnerMessage {} optional string a_string = 1; repeated string a_repeated_string = 2; optional bool a_boolean = 3; optional uint32 a_uint32 = 4; optional OuterEnum a_enum = 5; optional test3.OuterEnum a_external_enum = 6; optional inner.Inner a_inner = 7; optional test.nested_package.Nested a_nested = 12; optional InnerEnum inner_enum = 8; repeated InnerEnum rep_inner_enum = 9; optional InnerMessage inner_message = 10; repeated InnerMessage rep_inner_message = 11; optional NoPackage no_package = 13; optional test.nested_package.AnotherNested.NestedEnum nested_enum = 14; optional test.nested_package.AnotherNested.NestedMessage nested_message = 15; oneof a_oneof { string a_oneof_1 = 16; string a_oneof_2 = 17; Simple2 outer_message_in_oneof = 18; OuterEnum outer_enum_in_oneof = 19; InnerEnum inner_enum_in_oneof = 20; } optional uint32 user_id = 21 [(mypy_protobuf.casttype)="test/test_generated_mypy.UserId"]; optional string email = 22 [(mypy_protobuf.casttype)="test/test_generated_mypy.Email"]; map email_by_uid = 23 [ (mypy_protobuf.keytype)="test/test_generated_mypy.UserId", (mypy_protobuf.valuetype)="test/test_generated_mypy.Email" ]; extensions 1000 to max; } message Simple2 { required string a_string = 1; extensions 1000 to max; } message Extensions1 { extend Simple1 { // ext optional Extensions1 ext = 1000; } optional string ext1_string = 1; } message Extensions2 { extend Simple1 { // foo optional Extensions2 foo = 2020; } optional bool flag = 1; } message None { optional int64 valid = 1; } message PythonReservedKeywords { enum finally { continue = 1; valid_in_finally = 2; } message lambda { optional int64 continue = 1; optional int64 valid = 2; } required int64 from = 1; optional Simple2 in = 2; optional finally is = 3; optional int64 for = 5; optional int64 try = 6; optional int64 def = 7; optional int64 nonlocal = 8; optional int64 while = 9; optional int64 and = 10; optional int64 del = 11; optional int64 global = 12; optional int64 not = 13; optional int64 with = 14; optional int64 as = 15; optional int64 elif = 16; optional int64 if = 17; optional int64 or = 18; optional int64 yield = 19; optional int64 assert = 20; optional int64 else = 21; optional int64 import = 22; optional int64 pass = 23; optional int64 break = 24; optional int64 except = 25; optional int64 raise = 26; optional int64 False = 27; optional int64 True = 29; optional int64 class = 30; // Test unreserved identifiers w/ reserved message names optional None none = 28; optional finally valid = 31; } // Do one with just one arg - to make sure it's syntactically correct message PythonReservedKeywordsSmall { required int64 from = 1; } // Method name is reserved service PythonReservedKeywordsService { // lambda rpc lambda(Simple1) returns (PythonReservedKeywords.lambda) {} // valid_method_name1 rpc valid_method_name1(Simple1) returns (None) {} // valid_method_name2 rpc valid_method_name2(Simple1) returns (PythonReservedKeywords.lambda) {} } // when service name itself is reserved - generated code was found to be invalid // in protoc 3.17.3 //service global { // rpc Echo(Simple1) returns (Simple2) {} //} option py_generic_services = true; service ATestService { rpc Echo(Simple1) returns (Simple2) {} } message SelfField { // Field self -> must generate an __init__ method w/ different name optional int64 self = 1; } mypy-protobuf-3.2.0/proto/testproto/test3.proto000066400000000000000000000017111417335214500217120ustar00rootroot00000000000000syntax = "proto3"; package test3; enum OuterEnum { UNKNOWN = 0; FOO3 = 1; BAR3 = 2; } message OuterMessage3 { string a_string = 1; } message SimpleProto3 { enum InnerEnum { INNER1 = 0; INNER2 = 1; } string a_string = 1; repeated string a_repeated_string = 2; OuterEnum a_outer_enum = 3; OuterMessage3 outer_message = 4; InnerEnum inner_enum = 15; oneof a_oneof { string a_oneof_1 = 5; string a_oneof_2 = 6; OuterMessage3 outer_message_in_oneof = 12; OuterEnum outer_enum_in_oneof = 13; InnerEnum inner_enum_in_oneof = 14; } oneof b_oneof { string b_oneof_1 = 7; string b_oneof_2 = 8; } OuterMessage3 bool = 9; // Test having fieldname match messagename OuterEnum OuterEnum = 10; OuterMessage3 OuterMessage3 = 11; // Test generation of map map map_scalar = 16; map map_message = 17; optional string an_optional_string = 18; } mypy-protobuf-3.2.0/proto/testproto/test_extensions2.proto000066400000000000000000000002771417335214500241760ustar00rootroot00000000000000syntax = "proto2"; import "testproto/test.proto"; package test; message SeparateFileExtension { extend Simple2 { optional SeparateFileExtension ext = 1001; } optional bool flag = 1; }mypy-protobuf-3.2.0/proto/testproto/test_extensions3.proto000066400000000000000000000017741417335214500242020ustar00rootroot00000000000000syntax = "proto3"; import "google/protobuf/descriptor.proto"; import "testproto/test3.proto"; package test3; extend google.protobuf.FieldOptions { string test_field_extension = 50000; } extend google.protobuf.MessageOptions { string scalar_option = 51234; repeated string repeated_scalar_option = 51235; OuterEnum enum_option = 51236; repeated OuterEnum repeated_enum_option = 51237; OuterMessage3 msg_option = 51238; repeated OuterMessage3 repeated_msg_option = 51239; } message MessageOptionsTestMsg { option (scalar_option) = "Hello world!"; option (repeated_scalar_option) = "A"; option (repeated_scalar_option) = "B"; option (repeated_scalar_option) = "C"; option (enum_option) = FOO3; option (repeated_enum_option) = FOO3; option (repeated_enum_option) = BAR3; option (msg_option).a_string = "Hello OuterMessage3"; option (repeated_msg_option) = {a_string: "Hello OuterMessage3 A"}; option (repeated_msg_option) = {a_string: "Hello OuterMessage3 B"}; } mypy-protobuf-3.2.0/proto/testproto/test_no_generic_services.proto000066400000000000000000000002351417335214500257220ustar00rootroot00000000000000syntax = "proto2"; package test; message Simple3 { required string a_string = 1; } service ATestService2 { rpc Echo(Simple3) returns (Simple3) {} } mypy-protobuf-3.2.0/pyproject.toml000066400000000000000000000006551417335214500172770ustar00rootroot00000000000000[build-system] requires = [ "setuptools>=42", "wheel", ] build-backend = "setuptools.build_meta" [tool.black] extend-exclude = "(_pb2.pyi?$|_pb2_grpc.pyi?$)" [tool.mypy] strict = true show_error_codes = true [tool.pyright] venvPath = "." venv = "venv_3.8.11" # verboseOutput = true extraPaths = ["test/generated"] include = [ "mypy_protobuf/", "test/" ] exclude = [ "**/*_pb2.py", "**/*_pb2_grpc.py" ] mypy-protobuf-3.2.0/run_test.sh000077500000000000000000000146231417335214500165650ustar00rootroot00000000000000#!/bin/bash -ex RED="\033[0;31m" NC='\033[0m' PROTOC=${PROTOC:=protoc} PY_VER_MYPY_PROTOBUF=${PY_VER_MYPY_PROTOBUF:=3.10.1} PY_VER_MYPY_PROTOBUF_SHORT=$(echo $PY_VER_MYPY_PROTOBUF | cut -d. -f1-2) PY_VER_MYPY=${PY_VER_MYPY:=3.8.11} PY_VER_UNIT_TESTS="${PY_VER_UNIT_TESTS_3:=3.8.11}" PROTOC_ARGS="--proto_path=proto/ --experimental_allow_proto3_optional" GRPC_PROTOS=$(find proto/testproto/grpc -name "*.proto") if [ -e $CUSTOM_TYPESHED_DIR ]; then export MYPYPATH=$CUSTOM_TYPESHED_DIR/stubs/protobuf fi # Create mypy venv MYPY_VENV=venv_$PY_VER_MYPY ( eval "$(pyenv init --path)" eval "$(pyenv init -)" pyenv shell $PY_VER_MYPY if [[ -z $SKIP_CLEAN ]] || [[ ! -e $MYPY_VENV ]]; then python3 --version python3 -m pip --version python -m pip install virtualenv python3 -m virtualenv $MYPY_VENV $MYPY_VENV/bin/python3 -m pip install -r mypy_requirements.txt fi $MYPY_VENV/bin/mypy --version ) # Create unit tests venvs for PY_VER in $PY_VER_UNIT_TESTS; do ( UNIT_TESTS_VENV=venv_$PY_VER eval "$(pyenv init --path)" eval "$(pyenv init -)" pyenv shell $PY_VER if [[ -z $SKIP_CLEAN ]] || [[ ! -e $UNIT_TESTS_VENV ]]; then python -m pip install virtualenv python -m virtualenv $UNIT_TESTS_VENV $UNIT_TESTS_VENV/bin/python -m pip install -r test_requirements.txt fi $UNIT_TESTS_VENV/bin/py.test --version ) done # Create mypy-protobuf venv MYPY_PROTOBUF_VENV=venv_$PY_VER_MYPY_PROTOBUF ( eval "$(pyenv init --path)" eval "$(pyenv init -)" pyenv shell $PY_VER_MYPY_PROTOBUF # Create virtualenv + Install requirements for mypy-protobuf if [[ -z $SKIP_CLEAN ]] || [[ ! -e $MYPY_PROTOBUF_VENV ]]; then python -m pip install virtualenv python -m virtualenv $MYPY_PROTOBUF_VENV $MYPY_PROTOBUF_VENV/bin/python -m pip install -e . fi ) # Run mypy-protobuf ( source $MYPY_PROTOBUF_VENV/bin/activate # Confirm version number test "$(protoc-gen-mypy -V)" = "mypy-protobuf 3.2.0" test "$(protoc-gen-mypy --version)" = "mypy-protobuf 3.2.0" test "$(protoc-gen-mypy_grpc -V)" = "mypy-protobuf 3.2.0" test "$(protoc-gen-mypy_grpc --version)" = "mypy-protobuf 3.2.0" # Run mypy on mypy-protobuf internal code for developers to catch issues FILES="mypy_protobuf/main.py" $MYPY_VENV/bin/mypy --custom-typeshed-dir=$CUSTOM_TYPESHED_DIR --python-executable=$MYPY_PROTOBUF_VENV/bin/python3 --python-version=$PY_VER_MYPY_PROTOBUF_SHORT $FILES # Generate protos python --version $PROTOC --version expected="libprotoc 3.19.3" if [[ $($PROTOC --version) != $expected ]]; then echo -e "${RED}For tests - must install protoc version ${expected} ${NC}" exit 1 fi # CI Check to make sure generated files are committed SHA_BEFORE=$(find test/generated -name "*.pyi" | xargs sha1sum) # Clean out generated/ directory - except for __init__.py find test/generated -type f -not -name "__init__.py" -delete # Compile protoc -> python $PROTOC $PROTOC_ARGS --python_out=test/generated `find proto -name "*.proto"` # Compile protoc -> mypy using mypy_protobuf # Prereq - create the mypy.proto python proto $PROTOC $PROTOC_ARGS --python_out=. `find proto/mypy_protobuf -name "*.proto"` $PROTOC $PROTOC_ARGS --mypy_out=. `find proto/mypy_protobuf -name "*.proto"` # Sanity check that our flags work $PROTOC $PROTOC_ARGS --mypy_out=quiet:test/generated `find proto -name "*.proto"` $PROTOC $PROTOC_ARGS --mypy_out=readable_stubs:test/generated `find proto -name "*.proto"` $PROTOC $PROTOC_ARGS --mypy_out=relax_strict_optional_primitives:test/generated `find proto -name "*.proto"` # Overwrite w/ run with mypy-protobuf without flags $PROTOC $PROTOC_ARGS --mypy_out=test/generated `find proto -name "*.proto"` # Generate grpc protos $PROTOC $PROTOC_ARGS --mypy_grpc_out=test/generated $GRPC_PROTOS if [[ -n $VALIDATE ]] && ! diff <(echo "$SHA_BEFORE") <(find test/generated -name "*.pyi" | xargs sha1sum); then echo -e "${RED}Some .pyi files did not match. Please commit those files${NC}" exit 1 fi ) for PY_VER in $PY_VER_UNIT_TESTS; do UNIT_TESTS_VENV=venv_$PY_VER PY_VER_MYPY_TARGET=$(echo $PY_VER | cut -d. -f1-2) # Generate GRPC protos for mypy / tests ( source $UNIT_TESTS_VENV/bin/activate python -m grpc_tools.protoc $PROTOC_ARGS --grpc_python_out=test/generated $GRPC_PROTOS ) # Run mypy on unit tests / generated output ( source $MYPY_VENV/bin/activate # Run mypy FILES="test/" mypy --custom-typeshed-dir=$CUSTOM_TYPESHED_DIR --python-executable=$UNIT_TESTS_VENV/bin/python --python-version=$PY_VER_MYPY_TARGET $FILES PYTHONPATH=test/generated MYPYPATH=$MYPYPATH:test/generated python3 -m mypy.stubtest --custom-typeshed-dir=$CUSTOM_TYPESHED_DIR --allowlist stubtest_allowlist.txt testproto # run mypy on negative-tests (expected mypy failures) NEGATIVE_FILES="test_negative/negative.py test_negative/negative_3.8.py $FILES" MYPY_OUTPUT=`mktemp -d` call_mypy() { # Write output to file. Make variant w/ omitted line numbers for easy diffing / CR PY_VER_MYPY_TARGET=$(echo $1 | cut -d. -f1-2) mypy --custom-typeshed-dir=$CUSTOM_TYPESHED_DIR --python-executable=venv_$1/bin/python --python-version=$PY_VER_MYPY_TARGET ${@: 2} > $MYPY_OUTPUT/mypy_output || true cut -d: -f1,3- $MYPY_OUTPUT/mypy_output > $MYPY_OUTPUT/mypy_output.omit_linenos } call_mypy $PY_VER $NEGATIVE_FILES if ! diff $MYPY_OUTPUT/mypy_output test_negative/output.expected.$PY_VER_MYPY_TARGET || ! diff $MYPY_OUTPUT/mypy_output.omit_linenos test_negative/output.expected.$PY_VER_MYPY_TARGET.omit_linenos; then echo -e "${RED}test_negative/output.expected.$PY_VER_MYPY_TARGET didnt match. Copying over for you. Now rerun${NC}" # Copy over all the mypy results for the developer. call_mypy 3.8.11 $NEGATIVE_FILES cp $MYPY_OUTPUT/mypy_output test_negative/output.expected.3.8 cp $MYPY_OUTPUT/mypy_output.omit_linenos test_negative/output.expected.3.8.omit_linenos exit 1 fi ) ( # Run unit tests. source $UNIT_TESTS_VENV/bin/activate PYTHONPATH=test/generated py.test --ignore=test/generated -v ) done mypy-protobuf-3.2.0/setup.cfg000066400000000000000000000012731417335214500162010ustar00rootroot00000000000000[metadata] name = mypy-protobuf version = attr: mypy_protobuf.main.__version__ description = Generate mypy stub files from protobuf specs keywords = mypy proto dropbox license = Apache License 2.0 author = Nipunn Koorapati author_email = nipunn1313@gmail.com url = https://github.com/dropbox/mypy-protobuf download_url = https://github.com/dropbox/mypy-protobuf/releases [options] py_modules = mypy_protobuf mypy_protobuf.main mypy_protobuf.extensions_pb2 install_requires = protobuf>=3.19.3 types-protobuf>=3.19.5 python_requires = >=3.6 [options.entry_points] console_scripts = protoc-gen-mypy = mypy_protobuf.main:main protoc-gen-mypy_grpc = mypy_protobuf.main:grpc mypy-protobuf-3.2.0/stubtest_allowlist.txt000066400000000000000000000043421417335214500210700ustar00rootroot00000000000000# Generated pb2 __init__ methods diverge because the runtime # has *args, **kwargs - and we're trying to do better testproto\..*_pb2\..*\.__init__$ # stubtest is confused by these edge cases testproto.test_pb2.PythonReservedKeywords.* testproto.test_pb2.None # Enum variants - stubtest doesn't like int varying from a NewType testproto.test_pb2.FOO testproto.test_pb2.BAR testproto.test_pb2.Simple1.INNER1 testproto.test_pb2.Simple1.INNER2 testproto.test_pb2.Name testproto.test_pb2.Value testproto.test_pb2.items testproto.test_pb2.keys testproto.test_pb2.values testproto.test3_pb2.SimpleProto3.INNER1 testproto.test3_pb2.SimpleProto3.INNER2 testproto.reexport_pb2.SimpleProto3.INNER1 testproto.reexport_pb2.SimpleProto3.INNER2 testproto.reexport_pb2.UNKNOWN testproto.reexport_pb2.FOO3 testproto.reexport_pb2.BAR3 testproto.test3_pb2.UNKNOWN testproto.test3_pb2.FOO3 testproto.test3_pb2.BAR3 testproto.nested.nested_pb2.AnotherNested.ONE testproto.nested.nested_pb2.AnotherNested.TWO testproto.readme_enum_pb2.HELLO testproto.readme_enum_pb2.WORLD testproto.nested.nested_pb2.AnotherNested.NestedMessage.UNDEFINED testproto.nested.nested_pb2.AnotherNested.NestedMessage.NESTED_ENUM1 testproto.nested.nested_pb2.AnotherNested.NestedMessage.NESTED_ENUM2 testproto.nested.nested_pb2.AnotherNested.INVALID # Our enum types and helper types aren't there at runtime (Dynamic EnumTypeWrapper at runtime) # .*\..*EnumTypeWrapper$ testproto.test_pb2.Simple1._?InnerEnum(EnumTypeWrapper)? testproto.test_pb2._?OuterEnum(EnumTypeWrapper)? testproto.test_pb2._?NamingConflicts(EnumTypeWrapper)? testproto.test3_pb2.SimpleProto3._?InnerEnum(EnumTypeWrapper)? testproto.test3_pb2._?OuterEnum(EnumTypeWrapper)? testproto.reexport_pb2.SimpleProto3._?InnerEnum(EnumTypeWrapper)? testproto.reexport_pb2._?OuterEnum(EnumTypeWrapper)? testproto.readme_enum_pb2._?MyEnum(EnumTypeWrapper)? testproto.nested.nested_pb2.AnotherNested._?NestedEnum(EnumTypeWrapper)? testproto.nested.nested_pb2.AnotherNested.NestedMessage._?NestedEnum2(EnumTypeWrapper)? # Some issues with our service stubs for now testproto.test_pb2.ATestService.* # Part of an "EXPERIMENTAL API" according to comment. Not documented. testproto.grpc.dummy_pb2_grpc.DummyService testproto.grpc.import_pb2_grpc.SimpleService mypy-protobuf-3.2.0/test/000077500000000000000000000000001417335214500153345ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/__init__.py000066400000000000000000000000001417335214500174330ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/000077500000000000000000000000001417335214500172725ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/google/000077500000000000000000000000001417335214500205465ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/google/protobuf/000077500000000000000000000000001417335214500224065ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/google/protobuf/duration_pb2.pyi000066400000000000000000000071411417335214500255240ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.internal.well_known_types import google.protobuf.message import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class Duration(google.protobuf.message.Message, google.protobuf.internal.well_known_types.Duration): """A Duration represents a signed, fixed-length span of time represented as a count of seconds and fractions of seconds at nanosecond resolution. It is independent of any calendar and concepts like "day" or "month". It is related to Timestamp in that the difference between two Timestamp values is a Duration and it can be added or subtracted from a Timestamp. Range is approximately +-10,000 years. # Examples Example 1: Compute Duration from two Timestamps in pseudo code. Timestamp start = ...; Timestamp end = ...; Duration duration = ...; duration.seconds = end.seconds - start.seconds; duration.nanos = end.nanos - start.nanos; if (duration.seconds < 0 && duration.nanos > 0) { duration.seconds += 1; duration.nanos -= 1000000000; } else if (duration.seconds > 0 && duration.nanos < 0) { duration.seconds -= 1; duration.nanos += 1000000000; } Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. Timestamp start = ...; Duration duration = ...; Timestamp end = ...; end.seconds = start.seconds + duration.seconds; end.nanos = start.nanos + duration.nanos; if (end.nanos < 0) { end.seconds -= 1; end.nanos += 1000000000; } else if (end.nanos >= 1000000000) { end.seconds += 1; end.nanos -= 1000000000; } Example 3: Compute Duration from datetime.timedelta in Python. td = datetime.timedelta(days=3, minutes=10) duration = Duration() duration.FromTimedelta(td) # JSON Mapping In JSON format, the Duration type is encoded as a string rather than an object, where the string ends in the suffix "s" (indicating seconds) and is preceded by the number of seconds, with nanoseconds expressed as fractional seconds. For example, 3 seconds with 0 nanoseconds should be encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should be expressed in JSON format as "3.000000001s", and 3 seconds and 1 microsecond should be expressed in JSON format as "3.000001s". """ DESCRIPTOR: google.protobuf.descriptor.Descriptor SECONDS_FIELD_NUMBER: builtins.int NANOS_FIELD_NUMBER: builtins.int seconds: builtins.int """Signed seconds of the span of time. Must be from -315,576,000,000 to +315,576,000,000 inclusive. Note: these bounds are computed from: 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years """ nanos: builtins.int """Signed fractions of a second at nanosecond resolution of the span of time. Durations less than one second are represented with a 0 `seconds` field and a positive or negative `nanos` field. For durations of one second or more, a non-zero value for the `nanos` field must be of the same sign as the `seconds` field. Must be from -999,999,999 to +999,999,999 inclusive. """ def __init__(self, *, seconds: builtins.int = ..., nanos: builtins.int = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["nanos",b"nanos","seconds",b"seconds"]) -> None: ... global___Duration = Duration mypy-protobuf-3.2.0/test/generated/mypy_protobuf/000077500000000000000000000000001417335214500222105ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/mypy_protobuf/__init__.py000066400000000000000000000000001417335214500243070ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/mypy_protobuf/extensions_pb2.pyi000066400000000000000000000020241417335214500256730ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.descriptor_pb2 import google.protobuf.internal.extension_dict import typing DESCRIPTOR: google.protobuf.descriptor.FileDescriptor CASTTYPE_FIELD_NUMBER: builtins.int KEYTYPE_FIELD_NUMBER: builtins.int VALUETYPE_FIELD_NUMBER: builtins.int casttype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, typing.Text] """Tells mypy to use a specific newtype rather than the normal type for this field.""" keytype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, typing.Text] """Tells mypy to use a specific type for keys; only makes sense on map fields""" valuetype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, typing.Text] """Tells mypy to use a specific type for values; only makes sense on map fields""" mypy-protobuf-3.2.0/test/generated/testproto/000077500000000000000000000000001417335214500213355ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/Capitalized/000077500000000000000000000000001417335214500235665ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/Capitalized/Capitalized_pb2.pyi000066400000000000000000000031721417335214500273100ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.message import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor 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_extensions.Literal["a",b"a"]) -> None: ... global___lower = lower 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: typing.Optional[global___lower] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["Lower",b"Lower"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["Lower",b"Lower"]) -> None: ... global___Upper = Upper 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: typing.Optional[global___Upper] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["upper",b"upper"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["upper",b"upper"]) -> None: ... global___lower2 = lower2 mypy-protobuf-3.2.0/test/generated/testproto/Capitalized/__init__.py000066400000000000000000000000001417335214500256650ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/__init__.py000066400000000000000000000000001417335214500234340ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/__pycache__/000077500000000000000000000000001417335214500235455ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/__pycache__/__init__.py000066400000000000000000000000001417335214500256440ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/comment_special_chars_pb2.pyi000066400000000000000000000045511417335214500271520ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.message import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor 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: typing.Text """Ending with " """ b: typing.Text """Ending with "" """ c: typing.Text """Ending with \"\"\" """ d: typing.Text """Ending with \\ """ e: typing.Text """Containing bad escape: \\x""" f: typing.Text """Containing \"\"\"" quadruple""" g: typing.Text """Containing \"\"\""" quintuple""" h: typing.Text """Containing \"\"\"\"\"\" sextuple""" i: typing.Text """\"\"\" Multiple \"\"\" triples \"\"\" """ j: typing.Text """"quotes" can be a problem in comments. \"\"\"Triple quotes\"\"\" just as well """ k: typing.Text """\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" " " " Super Duper comments with surrounding edges! " " " " Pay attention to me!!!! " " " \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\" """ def __init__(self, *, a: typing.Text = ..., b: typing.Text = ..., c: typing.Text = ..., d: typing.Text = ..., e: typing.Text = ..., f: typing.Text = ..., g: typing.Text = ..., h: typing.Text = ..., i: typing.Text = ..., j: typing.Text = ..., k: typing.Text = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.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 = Test mypy-protobuf-3.2.0/test/generated/testproto/dot/000077500000000000000000000000001417335214500221235ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/dot/__init__.py000066400000000000000000000000001417335214500242220ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/dot/com/000077500000000000000000000000001417335214500227015ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/dot/com/__init__.py000066400000000000000000000000001417335214500250000ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/dot/com/__pycache__/000077500000000000000000000000001417335214500251115ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/dot/com/__pycache__/__init__.py000066400000000000000000000000001417335214500272100ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/dot/com/test_pb2.pyi000066400000000000000000000011651417335214500251510ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.message import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class TestMessage(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor FOO_FIELD_NUMBER: builtins.int foo: typing.Text def __init__(self, *, foo: typing.Text = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["foo",b"foo"]) -> None: ... global___TestMessage = TestMessage mypy-protobuf-3.2.0/test/generated/testproto/grpc/000077500000000000000000000000001417335214500222705ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/grpc/__init__.py000066400000000000000000000000001417335214500243670ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/grpc/dummy_pb2.pyi000066400000000000000000000020031417335214500247040ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.message import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class DummyRequest(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor VALUE_FIELD_NUMBER: builtins.int value: typing.Text def __init__(self, *, value: typing.Text = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["value",b"value"]) -> None: ... global___DummyRequest = DummyRequest class DummyReply(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor VALUE_FIELD_NUMBER: builtins.int value: typing.Text def __init__(self, *, value: typing.Text = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["value",b"value"]) -> None: ... global___DummyReply = DummyReply mypy-protobuf-3.2.0/test/generated/testproto/grpc/dummy_pb2_grpc.pyi000066400000000000000000000040571417335214500257320ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import abc import grpc import testproto.grpc.dummy_pb2 import typing class DummyServiceStub: """DummyService""" def __init__(self, channel: grpc.Channel) -> None: ... UnaryUnary: grpc.UnaryUnaryMultiCallable[ testproto.grpc.dummy_pb2.DummyRequest, testproto.grpc.dummy_pb2.DummyReply] """UnaryUnary""" UnaryStream: grpc.UnaryStreamMultiCallable[ testproto.grpc.dummy_pb2.DummyRequest, testproto.grpc.dummy_pb2.DummyReply] """UnaryStream""" StreamUnary: grpc.StreamUnaryMultiCallable[ testproto.grpc.dummy_pb2.DummyRequest, testproto.grpc.dummy_pb2.DummyReply] """StreamUnary""" StreamStream: grpc.StreamStreamMultiCallable[ testproto.grpc.dummy_pb2.DummyRequest, testproto.grpc.dummy_pb2.DummyReply] """StreamStream""" class DummyServiceServicer(metaclass=abc.ABCMeta): """DummyService""" @abc.abstractmethod def UnaryUnary(self, request: testproto.grpc.dummy_pb2.DummyRequest, context: grpc.ServicerContext, ) -> testproto.grpc.dummy_pb2.DummyReply: """UnaryUnary""" pass @abc.abstractmethod def UnaryStream(self, request: testproto.grpc.dummy_pb2.DummyRequest, context: grpc.ServicerContext, ) -> typing.Iterator[testproto.grpc.dummy_pb2.DummyReply]: """UnaryStream""" pass @abc.abstractmethod def StreamUnary(self, request_iterator: typing.Iterator[testproto.grpc.dummy_pb2.DummyRequest], context: grpc.ServicerContext, ) -> testproto.grpc.dummy_pb2.DummyReply: """StreamUnary""" pass @abc.abstractmethod def StreamStream(self, request_iterator: typing.Iterator[testproto.grpc.dummy_pb2.DummyRequest], context: grpc.ServicerContext, ) -> typing.Iterator[testproto.grpc.dummy_pb2.DummyReply]: """StreamStream""" pass def add_DummyServiceServicer_to_server(servicer: DummyServiceServicer, server: grpc.Server) -> None: ... mypy-protobuf-3.2.0/test/generated/testproto/grpc/import_pb2.pyi000066400000000000000000000002451417335214500250710ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import google.protobuf.descriptor DESCRIPTOR: google.protobuf.descriptor.FileDescriptor mypy-protobuf-3.2.0/test/generated/testproto/grpc/import_pb2_grpc.pyi000066400000000000000000000027041417335214500261060ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import abc import google.protobuf.empty_pb2 import grpc import testproto.test_pb2 class SimpleServiceStub: """SimpleService""" def __init__(self, channel: grpc.Channel) -> None: ... UnaryUnary: grpc.UnaryUnaryMultiCallable[ google.protobuf.empty_pb2.Empty, testproto.test_pb2.Simple1] """UnaryUnary""" UnaryStream: grpc.UnaryUnaryMultiCallable[ testproto.test_pb2.Simple1, google.protobuf.empty_pb2.Empty] """UnaryStream""" NoComment: grpc.UnaryUnaryMultiCallable[ testproto.test_pb2.Simple1, google.protobuf.empty_pb2.Empty] class SimpleServiceServicer(metaclass=abc.ABCMeta): """SimpleService""" @abc.abstractmethod def UnaryUnary(self, request: google.protobuf.empty_pb2.Empty, context: grpc.ServicerContext, ) -> testproto.test_pb2.Simple1: """UnaryUnary""" pass @abc.abstractmethod def UnaryStream(self, request: testproto.test_pb2.Simple1, context: grpc.ServicerContext, ) -> google.protobuf.empty_pb2.Empty: """UnaryStream""" pass @abc.abstractmethod def NoComment(self, request: testproto.test_pb2.Simple1, context: grpc.ServicerContext, ) -> google.protobuf.empty_pb2.Empty: ... def add_SimpleServiceServicer_to_server(servicer: SimpleServiceServicer, server: grpc.Server) -> None: ... mypy-protobuf-3.2.0/test/generated/testproto/inner/000077500000000000000000000000001417335214500224505ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/inner/__init__.py000066400000000000000000000000001417335214500245470ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/inner/inner_pb2.pyi000066400000000000000000000012361417335214500250530ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.message import testproto.test3_pb2 import typing_extensions 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.ValueType def __init__(self, *, a: testproto.test3_pb2.OuterEnum.ValueType = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["a",b"a"]) -> None: ... global___Inner = Inner mypy-protobuf-3.2.0/test/generated/testproto/nested/000077500000000000000000000000001417335214500226175ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/nested/__init__.py000066400000000000000000000000001417335214500247160ustar00rootroot00000000000000mypy-protobuf-3.2.0/test/generated/testproto/nested/nested_pb2.pyi000066400000000000000000000066521417335214500254000ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.internal.enum_type_wrapper import google.protobuf.message import testproto.test3_pb2 import typing import typing_extensions 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.ValueType def __init__(self, *, a: testproto.test3_pb2.OuterEnum.ValueType = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["a",b"a"]) -> None: ... global___Nested = Nested class AnotherNested(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor class _NestedEnum: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _NestedEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[AnotherNested._NestedEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor INVALID: AnotherNested._NestedEnum.ValueType # 0 ONE: AnotherNested._NestedEnum.ValueType # 1 TWO: AnotherNested._NestedEnum.ValueType # 2 class NestedEnum(_NestedEnum, metaclass=_NestedEnumEnumTypeWrapper): pass 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: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _NestedEnum2EnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[AnotherNested.NestedMessage._NestedEnum2.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor UNDEFINED: AnotherNested.NestedMessage._NestedEnum2.ValueType # 0 NESTED_ENUM1: AnotherNested.NestedMessage._NestedEnum2.ValueType # 1 NESTED_ENUM2: AnotherNested.NestedMessage._NestedEnum2.ValueType # 2 class NestedEnum2(_NestedEnum2, metaclass=_NestedEnum2EnumTypeWrapper): pass 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 NE_FIELD_NUMBER: builtins.int NE2_FIELD_NUMBER: builtins.int s: typing.Text b: builtins.bool ne: global___AnotherNested.NestedEnum.ValueType ne2: global___AnotherNested.NestedMessage.NestedEnum2.ValueType def __init__(self, *, s: typing.Text = ..., b: builtins.bool = ..., 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: ... def __init__(self, ) -> None: ... global___AnotherNested = AnotherNested mypy-protobuf-3.2.0/test/generated/testproto/nopackage_pb2.pyi000066400000000000000000000025141417335214500245550ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.message import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class NoPackage(google.protobuf.message.Message): """Intentionally don't set a package - just to make sure we can handle it. """ DESCRIPTOR: google.protobuf.descriptor.Descriptor def __init__(self, ) -> None: ... global___NoPackage = NoPackage class NoPackage2(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor NP_FIELD_NUMBER: builtins.int NP_REP_FIELD_NUMBER: builtins.int @property def np(self) -> global___NoPackage: ... @property def np_rep(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NoPackage]: ... def __init__(self, *, np: typing.Optional[global___NoPackage] = ..., np_rep: typing.Optional[typing.Iterable[global___NoPackage]] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["np",b"np"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["np",b"np","np_rep",b"np_rep"]) -> None: ... global___NoPackage2 = NoPackage2 mypy-protobuf-3.2.0/test/generated/testproto/readme_enum_pb2.pyi000066400000000000000000000014311417335214500251030ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.internal.enum_type_wrapper import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class _MyEnum: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _MyEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_MyEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor HELLO: _MyEnum.ValueType # 0 WORLD: _MyEnum.ValueType # 1 class MyEnum(_MyEnum, metaclass=_MyEnumEnumTypeWrapper): pass HELLO: MyEnum.ValueType # 0 WORLD: MyEnum.ValueType # 1 global___MyEnum = MyEnum mypy-protobuf-3.2.0/test/generated/testproto/reexport_pb2.pyi000066400000000000000000000006471417335214500245020ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import google.protobuf.descriptor from google.protobuf.empty_pb2 import ( Empty as Empty, ) from testproto.test3_pb2 import ( BAR3 as BAR3, FOO3 as FOO3, OuterEnum as OuterEnum, OuterMessage3 as OuterMessage3, SimpleProto3 as SimpleProto3, UNKNOWN as UNKNOWN, ) DESCRIPTOR: google.protobuf.descriptor.FileDescriptor mypy-protobuf-3.2.0/test/generated/testproto/test3_pb2.pyi000066400000000000000000000204171417335214500236710ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.internal.enum_type_wrapper import google.protobuf.message import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class _OuterEnum: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _OuterEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OuterEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor UNKNOWN: _OuterEnum.ValueType # 0 FOO3: _OuterEnum.ValueType # 1 BAR3: _OuterEnum.ValueType # 2 class OuterEnum(_OuterEnum, metaclass=_OuterEnumEnumTypeWrapper): pass UNKNOWN: OuterEnum.ValueType # 0 FOO3: OuterEnum.ValueType # 1 BAR3: OuterEnum.ValueType # 2 global___OuterEnum = OuterEnum class OuterMessage3(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor A_STRING_FIELD_NUMBER: builtins.int a_string: typing.Text def __init__(self, *, a_string: typing.Text = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["a_string",b"a_string"]) -> None: ... global___OuterMessage3 = OuterMessage3 class SimpleProto3(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor class _InnerEnum: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _InnerEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[SimpleProto3._InnerEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor INNER1: SimpleProto3._InnerEnum.ValueType # 0 INNER2: SimpleProto3._InnerEnum.ValueType # 1 class InnerEnum(_InnerEnum, metaclass=_InnerEnumEnumTypeWrapper): pass INNER1: SimpleProto3.InnerEnum.ValueType # 0 INNER2: SimpleProto3.InnerEnum.ValueType # 1 class MapScalarEntry(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor KEY_FIELD_NUMBER: builtins.int VALUE_FIELD_NUMBER: builtins.int key: builtins.int value: typing.Text def __init__(self, *, key: builtins.int = ..., value: typing.Text = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ... class MapMessageEntry(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor KEY_FIELD_NUMBER: builtins.int VALUE_FIELD_NUMBER: builtins.int key: builtins.int @property def value(self) -> global___OuterMessage3: ... def __init__(self, *, key: builtins.int = ..., value: typing.Optional[global___OuterMessage3] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["value",b"value"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ... A_STRING_FIELD_NUMBER: builtins.int A_REPEATED_STRING_FIELD_NUMBER: builtins.int A_OUTER_ENUM_FIELD_NUMBER: builtins.int OUTER_MESSAGE_FIELD_NUMBER: builtins.int INNER_ENUM_FIELD_NUMBER: builtins.int A_ONEOF_1_FIELD_NUMBER: builtins.int A_ONEOF_2_FIELD_NUMBER: builtins.int OUTER_MESSAGE_IN_ONEOF_FIELD_NUMBER: builtins.int OUTER_ENUM_IN_ONEOF_FIELD_NUMBER: builtins.int INNER_ENUM_IN_ONEOF_FIELD_NUMBER: builtins.int B_ONEOF_1_FIELD_NUMBER: builtins.int B_ONEOF_2_FIELD_NUMBER: builtins.int BOOL_FIELD_NUMBER: builtins.int OUTERENUM_FIELD_NUMBER: builtins.int OUTERMESSAGE3_FIELD_NUMBER: builtins.int MAP_SCALAR_FIELD_NUMBER: builtins.int MAP_MESSAGE_FIELD_NUMBER: builtins.int AN_OPTIONAL_STRING_FIELD_NUMBER: builtins.int a_string: typing.Text @property def a_repeated_string(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ... a_outer_enum: global___OuterEnum.ValueType @property def outer_message(self) -> global___OuterMessage3: ... 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.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.ValueType """Test having fieldname match messagename""" @property def OuterMessage3(self) -> global___OuterMessage3: ... @property def map_scalar(self) -> google.protobuf.internal.containers.ScalarMap[builtins.int, typing.Text]: """Test generation of map""" pass @property def map_message(self) -> google.protobuf.internal.containers.MessageMap[builtins.int, global___OuterMessage3]: ... an_optional_string: typing.Text def __init__(self, *, a_string: typing.Text = ..., a_repeated_string: typing.Optional[typing.Iterable[typing.Text]] = ..., a_outer_enum: global___OuterEnum.ValueType = ..., outer_message: typing.Optional[global___OuterMessage3] = ..., 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.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.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]] = ..., an_optional_string: typing.Optional[typing.Text] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["OuterMessage3",b"OuterMessage3","_an_optional_string",b"_an_optional_string","a_oneof",b"a_oneof","a_oneof_1",b"a_oneof_1","a_oneof_2",b"a_oneof_2","an_optional_string",b"an_optional_string","b_oneof",b"b_oneof","b_oneof_1",b"b_oneof_1","b_oneof_2",b"b_oneof_2","bool",b"bool","inner_enum_in_oneof",b"inner_enum_in_oneof","outer_enum_in_oneof",b"outer_enum_in_oneof","outer_message",b"outer_message","outer_message_in_oneof",b"outer_message_in_oneof"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["OuterEnum",b"OuterEnum","OuterMessage3",b"OuterMessage3","_an_optional_string",b"_an_optional_string","a_oneof",b"a_oneof","a_oneof_1",b"a_oneof_1","a_oneof_2",b"a_oneof_2","a_outer_enum",b"a_outer_enum","a_repeated_string",b"a_repeated_string","a_string",b"a_string","an_optional_string",b"an_optional_string","b_oneof",b"b_oneof","b_oneof_1",b"b_oneof_1","b_oneof_2",b"b_oneof_2","bool",b"bool","inner_enum",b"inner_enum","inner_enum_in_oneof",b"inner_enum_in_oneof","map_message",b"map_message","map_scalar",b"map_scalar","outer_enum_in_oneof",b"outer_enum_in_oneof","outer_message",b"outer_message","outer_message_in_oneof",b"outer_message_in_oneof"]) -> None: ... @typing.overload def WhichOneof(self, oneof_group: typing_extensions.Literal["_an_optional_string",b"_an_optional_string"]) -> typing.Optional[typing_extensions.Literal["an_optional_string"]]: ... @typing.overload def WhichOneof(self, oneof_group: typing_extensions.Literal["a_oneof",b"a_oneof"]) -> typing.Optional[typing_extensions.Literal["a_oneof_1","a_oneof_2","outer_message_in_oneof","outer_enum_in_oneof","inner_enum_in_oneof"]]: ... @typing.overload def WhichOneof(self, oneof_group: typing_extensions.Literal["b_oneof",b"b_oneof"]) -> typing.Optional[typing_extensions.Literal["b_oneof_1","b_oneof_2"]]: ... global___SimpleProto3 = SimpleProto3 mypy-protobuf-3.2.0/test/generated/testproto/test_extensions2_pb2.pyi000066400000000000000000000020051417335214500261400ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.internal.extension_dict import google.protobuf.message import testproto.test_pb2 import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class SeparateFileExtension(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor FLAG_FIELD_NUMBER: builtins.int flag: builtins.bool EXT_FIELD_NUMBER: builtins.int ext: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[testproto.test_pb2.Simple2, global___SeparateFileExtension] def __init__(self, *, flag: typing.Optional[builtins.bool] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["flag",b"flag"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["flag",b"flag"]) -> None: ... global___SeparateFileExtension = SeparateFileExtension mypy-protobuf-3.2.0/test/generated/testproto/test_extensions3_pb2.pyi000066400000000000000000000042631417335214500261510ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.descriptor_pb2 import google.protobuf.internal.containers import google.protobuf.internal.extension_dict import google.protobuf.message import testproto.test3_pb2 import typing DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class MessageOptionsTestMsg(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor def __init__(self, ) -> None: ... global___MessageOptionsTestMsg = MessageOptionsTestMsg TEST_FIELD_EXTENSION_FIELD_NUMBER: builtins.int SCALAR_OPTION_FIELD_NUMBER: builtins.int REPEATED_SCALAR_OPTION_FIELD_NUMBER: builtins.int ENUM_OPTION_FIELD_NUMBER: builtins.int REPEATED_ENUM_OPTION_FIELD_NUMBER: builtins.int MSG_OPTION_FIELD_NUMBER: builtins.int REPEATED_MSG_OPTION_FIELD_NUMBER: builtins.int test_field_extension: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, typing.Text] scalar_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, typing.Text] 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.ValueType] 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] repeated_msg_option: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, google.protobuf.internal.containers.RepeatedCompositeFieldContainer[testproto.test3_pb2.OuterMessage3]] mypy-protobuf-3.2.0/test/generated/testproto/test_no_generic_services_pb2.pyi000066400000000000000000000013771417335214500277050ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import builtins import google.protobuf.descriptor import google.protobuf.message import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class Simple3(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor A_STRING_FIELD_NUMBER: builtins.int a_string: typing.Text def __init__(self, *, a_string: typing.Optional[typing.Text] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["a_string",b"a_string"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["a_string",b"a_string"]) -> None: ... global___Simple3 = Simple3 mypy-protobuf-3.2.0/test/generated/testproto/test_pb2.pyi000066400000000000000000000477201417335214500236140ustar00rootroot00000000000000""" @generated by mypy-protobuf. Do not edit manually! isort:skip_file """ import abc import builtins import concurrent.futures import google.protobuf.descriptor import google.protobuf.internal.containers import google.protobuf.internal.enum_type_wrapper import google.protobuf.internal.extension_dict import google.protobuf.message import google.protobuf.service import test.test_generated_mypy import testproto.inner.inner_pb2 import testproto.nested.nested_pb2 import testproto.nopackage_pb2 import testproto.test3_pb2 import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class _OuterEnum: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _OuterEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_OuterEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor FOO: _OuterEnum.ValueType # 1 """FOO""" BAR: _OuterEnum.ValueType # 2 """BAR""" class OuterEnum(_OuterEnum, metaclass=_OuterEnumEnumTypeWrapper): """Outer Enum""" pass FOO: OuterEnum.ValueType # 1 """FOO""" BAR: OuterEnum.ValueType # 2 """BAR""" global___OuterEnum = OuterEnum class _NamingConflicts: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _NamingConflictsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_NamingConflicts.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor class NamingConflicts(_NamingConflicts, metaclass=_NamingConflictsEnumTypeWrapper): """Naming conflicts!""" pass 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; """ global___NamingConflicts = NamingConflicts class Simple1(google.protobuf.message.Message): """Message with one of everything""" DESCRIPTOR: google.protobuf.descriptor.Descriptor class _InnerEnum: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _InnerEnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Simple1._InnerEnum.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor INNER1: Simple1._InnerEnum.ValueType # 1 """INNER1""" INNER2: Simple1._InnerEnum.ValueType # 2 """INNER2""" class InnerEnum(_InnerEnum, metaclass=_InnerEnumEnumTypeWrapper): """Inner Enum""" pass INNER1: Simple1.InnerEnum.ValueType # 1 """INNER1""" INNER2: Simple1.InnerEnum.ValueType # 2 """INNER2""" class InnerMessage(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor def __init__(self, ) -> None: ... class EmailByUidEntry(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor KEY_FIELD_NUMBER: builtins.int VALUE_FIELD_NUMBER: builtins.int key: builtins.int value: typing.Text def __init__(self, *, key: typing.Optional[builtins.int] = ..., value: typing.Optional[typing.Text] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ... A_STRING_FIELD_NUMBER: builtins.int A_REPEATED_STRING_FIELD_NUMBER: builtins.int A_BOOLEAN_FIELD_NUMBER: builtins.int A_UINT32_FIELD_NUMBER: builtins.int A_ENUM_FIELD_NUMBER: builtins.int A_EXTERNAL_ENUM_FIELD_NUMBER: builtins.int A_INNER_FIELD_NUMBER: builtins.int A_NESTED_FIELD_NUMBER: builtins.int INNER_ENUM_FIELD_NUMBER: builtins.int REP_INNER_ENUM_FIELD_NUMBER: builtins.int INNER_MESSAGE_FIELD_NUMBER: builtins.int REP_INNER_MESSAGE_FIELD_NUMBER: builtins.int NO_PACKAGE_FIELD_NUMBER: builtins.int NESTED_ENUM_FIELD_NUMBER: builtins.int NESTED_MESSAGE_FIELD_NUMBER: builtins.int A_ONEOF_1_FIELD_NUMBER: builtins.int A_ONEOF_2_FIELD_NUMBER: builtins.int OUTER_MESSAGE_IN_ONEOF_FIELD_NUMBER: builtins.int OUTER_ENUM_IN_ONEOF_FIELD_NUMBER: builtins.int INNER_ENUM_IN_ONEOF_FIELD_NUMBER: builtins.int USER_ID_FIELD_NUMBER: builtins.int EMAIL_FIELD_NUMBER: builtins.int EMAIL_BY_UID_FIELD_NUMBER: builtins.int a_string: typing.Text @property def a_repeated_string(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[typing.Text]: ... a_boolean: builtins.bool a_uint32: builtins.int 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.ValueType @property 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.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.ValueType inner_enum_in_oneof: global___Simple1.InnerEnum.ValueType user_id: test.test_generated_mypy.UserId email: test.test_generated_mypy.Email @property def email_by_uid(self) -> google.protobuf.internal.containers.ScalarMap[test.test_generated_mypy.UserId, test.test_generated_mypy.Email]: ... def __init__(self, *, a_string: typing.Optional[typing.Text] = ..., 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.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.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.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.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]] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["a_boolean",b"a_boolean","a_enum",b"a_enum","a_external_enum",b"a_external_enum","a_inner",b"a_inner","a_nested",b"a_nested","a_oneof",b"a_oneof","a_oneof_1",b"a_oneof_1","a_oneof_2",b"a_oneof_2","a_string",b"a_string","a_uint32",b"a_uint32","email",b"email","inner_enum",b"inner_enum","inner_enum_in_oneof",b"inner_enum_in_oneof","inner_message",b"inner_message","nested_enum",b"nested_enum","nested_message",b"nested_message","no_package",b"no_package","outer_enum_in_oneof",b"outer_enum_in_oneof","outer_message_in_oneof",b"outer_message_in_oneof","user_id",b"user_id"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["a_boolean",b"a_boolean","a_enum",b"a_enum","a_external_enum",b"a_external_enum","a_inner",b"a_inner","a_nested",b"a_nested","a_oneof",b"a_oneof","a_oneof_1",b"a_oneof_1","a_oneof_2",b"a_oneof_2","a_repeated_string",b"a_repeated_string","a_string",b"a_string","a_uint32",b"a_uint32","email",b"email","email_by_uid",b"email_by_uid","inner_enum",b"inner_enum","inner_enum_in_oneof",b"inner_enum_in_oneof","inner_message",b"inner_message","nested_enum",b"nested_enum","nested_message",b"nested_message","no_package",b"no_package","outer_enum_in_oneof",b"outer_enum_in_oneof","outer_message_in_oneof",b"outer_message_in_oneof","rep_inner_enum",b"rep_inner_enum","rep_inner_message",b"rep_inner_message","user_id",b"user_id"]) -> None: ... def WhichOneof(self, oneof_group: typing_extensions.Literal["a_oneof",b"a_oneof"]) -> typing.Optional[typing_extensions.Literal["a_oneof_1","a_oneof_2","outer_message_in_oneof","outer_enum_in_oneof","inner_enum_in_oneof"]]: ... global___Simple1 = Simple1 class Simple2(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor A_STRING_FIELD_NUMBER: builtins.int a_string: typing.Text def __init__(self, *, a_string: typing.Optional[typing.Text] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["a_string",b"a_string"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["a_string",b"a_string"]) -> None: ... global___Simple2 = Simple2 class Extensions1(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor EXT1_STRING_FIELD_NUMBER: builtins.int ext1_string: typing.Text EXT_FIELD_NUMBER: builtins.int ext: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[global___Simple1, global___Extensions1] """ext""" def __init__(self, *, ext1_string: typing.Optional[typing.Text] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["ext1_string",b"ext1_string"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["ext1_string",b"ext1_string"]) -> None: ... global___Extensions1 = Extensions1 class Extensions2(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor FLAG_FIELD_NUMBER: builtins.int flag: builtins.bool FOO_FIELD_NUMBER: builtins.int foo: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[global___Simple1, global___Extensions2] """foo""" def __init__(self, *, flag: typing.Optional[builtins.bool] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["flag",b"flag"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["flag",b"flag"]) -> None: ... global___Extensions2 = Extensions2 class _r_None(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor VALID_FIELD_NUMBER: builtins.int valid: builtins.int def __init__(self, *, valid: typing.Optional[builtins.int] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["valid",b"valid"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["valid",b"valid"]) -> None: ... global____r_None = _r_None class PythonReservedKeywords(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor class _finally: ValueType = typing.NewType('ValueType', builtins.int) V: typing_extensions.TypeAlias = ValueType class _finallyEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[PythonReservedKeywords._finally.ValueType], builtins.type): DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor valid_in_finally: PythonReservedKeywords._finally.ValueType # 2 class _r_finally(_finally, metaclass=_finallyEnumTypeWrapper): pass valid_in_finally: PythonReservedKeywords._r_finally.ValueType # 2 class _r_lambda(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor CONTINUE_FIELD_NUMBER: builtins.int VALID_FIELD_NUMBER: builtins.int valid: builtins.int def __init__(self, *, valid: typing.Optional[builtins.int] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["continue",b"continue","valid",b"valid"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["continue",b"continue","valid",b"valid"]) -> None: ... FROM_FIELD_NUMBER: builtins.int IN_FIELD_NUMBER: builtins.int IS_FIELD_NUMBER: builtins.int FOR_FIELD_NUMBER: builtins.int TRY_FIELD_NUMBER: builtins.int DEF_FIELD_NUMBER: builtins.int NONLOCAL_FIELD_NUMBER: builtins.int WHILE_FIELD_NUMBER: builtins.int AND_FIELD_NUMBER: builtins.int DEL_FIELD_NUMBER: builtins.int GLOBAL_FIELD_NUMBER: builtins.int NOT_FIELD_NUMBER: builtins.int WITH_FIELD_NUMBER: builtins.int AS_FIELD_NUMBER: builtins.int ELIF_FIELD_NUMBER: builtins.int IF_FIELD_NUMBER: builtins.int OR_FIELD_NUMBER: builtins.int YIELD_FIELD_NUMBER: builtins.int ASSERT_FIELD_NUMBER: builtins.int ELSE_FIELD_NUMBER: builtins.int IMPORT_FIELD_NUMBER: builtins.int PASS_FIELD_NUMBER: builtins.int BREAK_FIELD_NUMBER: builtins.int EXCEPT_FIELD_NUMBER: builtins.int RAISE_FIELD_NUMBER: builtins.int FALSE_FIELD_NUMBER: builtins.int TRUE_FIELD_NUMBER: builtins.int CLASS_FIELD_NUMBER: builtins.int NONE_FIELD_NUMBER: builtins.int VALID_FIELD_NUMBER: builtins.int @property def none(self) -> global____r_None: """Test unreserved identifiers w/ reserved message names""" pass valid: global___PythonReservedKeywords._r_finally.ValueType def __init__(self, *, none: typing.Optional[global____r_None] = ..., 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: ... global___PythonReservedKeywords = PythonReservedKeywords class PythonReservedKeywordsSmall(google.protobuf.message.Message): """Do one with just one arg - to make sure it's syntactically correct""" DESCRIPTOR: google.protobuf.descriptor.Descriptor FROM_FIELD_NUMBER: builtins.int def __init__(self, ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["from",b"from"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["from",b"from"]) -> None: ... global___PythonReservedKeywordsSmall = PythonReservedKeywordsSmall class SelfField(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor SELF_FIELD_NUMBER: builtins.int self: builtins.int """Field self -> must generate an __init__ method w/ different name""" # pyright: reportSelfClsParameterName=false def __init__(self_, *, self: typing.Optional[builtins.int] = ..., ) -> None: ... def HasField(self, field_name: typing_extensions.Literal["self",b"self"]) -> builtins.bool: ... def ClearField(self, field_name: typing_extensions.Literal["self",b"self"]) -> None: ... global___SelfField = SelfField class PythonReservedKeywordsService(google.protobuf.service.Service, metaclass=abc.ABCMeta): """Method name is reserved""" DESCRIPTOR: google.protobuf.descriptor.ServiceDescriptor @abc.abstractmethod def valid_method_name1( inst: PythonReservedKeywordsService, rpc_controller: google.protobuf.service.RpcController, request: global___Simple1, callback: typing.Optional[typing.Callable[[global____r_None], None]], ) -> concurrent.futures.Future[global____r_None]: """valid_method_name1""" pass @abc.abstractmethod def valid_method_name2( inst: PythonReservedKeywordsService, rpc_controller: google.protobuf.service.RpcController, request: global___Simple1, callback: typing.Optional[typing.Callable[[global___PythonReservedKeywords._r_lambda], None]], ) -> concurrent.futures.Future[global___PythonReservedKeywords._r_lambda]: """valid_method_name2""" pass class PythonReservedKeywordsService_Stub(PythonReservedKeywordsService): """Method name is reserved""" def __init__(self, rpc_channel: google.protobuf.service.RpcChannel) -> None: ... DESCRIPTOR: google.protobuf.descriptor.ServiceDescriptor def valid_method_name1( inst: PythonReservedKeywordsService_Stub, rpc_controller: google.protobuf.service.RpcController, request: global___Simple1, callback: typing.Optional[typing.Callable[[global____r_None], None]] = None, ) -> concurrent.futures.Future[global____r_None]: """valid_method_name1""" pass def valid_method_name2( inst: PythonReservedKeywordsService_Stub, rpc_controller: google.protobuf.service.RpcController, request: global___Simple1, callback: typing.Optional[typing.Callable[[global___PythonReservedKeywords._r_lambda], None]] = None, ) -> concurrent.futures.Future[global___PythonReservedKeywords._r_lambda]: """valid_method_name2""" pass class ATestService(google.protobuf.service.Service, metaclass=abc.ABCMeta): DESCRIPTOR: google.protobuf.descriptor.ServiceDescriptor @abc.abstractmethod def Echo( inst: ATestService, rpc_controller: google.protobuf.service.RpcController, request: global___Simple1, callback: typing.Optional[typing.Callable[[global___Simple2], None]], ) -> concurrent.futures.Future[global___Simple2]: ... class ATestService_Stub(ATestService): def __init__(self, rpc_channel: google.protobuf.service.RpcChannel) -> None: ... DESCRIPTOR: google.protobuf.descriptor.ServiceDescriptor def Echo( inst: ATestService_Stub, rpc_controller: google.protobuf.service.RpcController, request: global___Simple1, callback: typing.Optional[typing.Callable[[global___Simple2], None]] = None, ) -> concurrent.futures.Future[global___Simple2]: ...mypy-protobuf-3.2.0/test/test_generated_mypy.py000066400000000000000000000425511417335214500217700ustar00rootroot00000000000000""" This is a file which should mypy with success. See test_negative for a file that should have failures. This file contains a test to ensure that the test_negative failures are the expected failures These tests can be set up and run by the run_test.sh script """ import glob import os import pytest import sys from google.protobuf.descriptor import FieldDescriptor from google.protobuf.internal import api_implementation from google.protobuf.message import Message import testproto.test_pb2 as test_pb2 from testproto.reexport_pb2 import ( SimpleProto3 as ReexportedSimpleProto3, FOO3 as ReexportedFOO3, ) from testproto.test_extensions2_pb2 import SeparateFileExtension from testproto.test_pb2 import ( DESCRIPTOR, Extensions1, Extensions2, FOO, Name as NamingConflicts_Name, NamingConflicts, OuterEnum, PythonReservedKeywords, Simple1, Simple2, ) from testproto.test3_pb2 import ( BAR3, FOO3, OuterMessage3, SimpleProto3, ) from testproto.test_extensions3_pb2 import ( MessageOptionsTestMsg, scalar_option, SCALAR_OPTION_FIELD_NUMBER, repeated_scalar_option, enum_option, repeated_enum_option, msg_option, repeated_msg_option, ) from testproto.Capitalized.Capitalized_pb2 import lower, lower2, Upper from typing import ( Any, NewType, Optional, Generator, Tuple, Type, ) # C++ python API implementation has some semantic differences from pure python # We mainly focus on testing the C++ impl - but just have some flags here # to flag off tests that only work on cpp impl CPP_IMPL = api_implementation.Type() == "cpp" UserId = NewType("UserId", int) class Email(str): pass def _is_summary(l: str) -> bool: """Checks if the line is the summary line 'Found X errors in Y files (checked Z source files)'""" return l.startswith("Found ") and l.endswith("source files)\n") def test_generate_mypy_matches() -> None: proto_files = glob.glob("proto/**/*.proto", recursive=True) assert len(proto_files) == 17 # Just a sanity check that all the files show up pyi_files = glob.glob("test/generated/**/*.pyi", recursive=True) assert ( len(pyi_files) == 19 ) # Should be higher - because grpc files generate extra pyis failure_check_results = [] for fn in proto_files: assert fn.endswith(".proto") fn_split = fn.split(os.sep) # Eg. [proto, testproto, dot.com, test.proto] assert fn_split[-1].endswith(".proto") last = fn_split[-1][: -len(".proto")] + "_pb2.pyi" # Eg [test_pb2.proto] components = fn_split[1:-1] # Eg. [testproto, dot.com] components = [ c.replace(".", os.sep) for c in components ] # Eg. [testproto, dot/com] components.append(last) # Eg. [testproto, dot/com, test_pb2.proto] output = os.path.join("test", "generated", *components) assert os.path.exists(output) failure_check_results.append(output) if "grpc" in components: grpc_output = output[:-4] + "_grpc.pyi" assert os.path.exists(grpc_output) failure_check_results.append(grpc_output) # Make sure we checked everything assert len(failure_check_results) == len(pyi_files) def test_generate_negative_matches() -> None: """Confirm that the test_negative expected file matches an error for each line""" def grab_errors(filename: str) -> Generator[Tuple[str, int], None, None]: for line in open(filename).readlines(): if _is_summary(line): continue parts = line.split(":") yield parts[0], int(parts[1]) def grab_expectations( filename: str, marker: str ) -> Generator[Tuple[str, int], None, None]: for idx, line in enumerate(open(filename).readlines()): if "#" in line and marker in line: yield filename, idx + 1 errors_38 = set(grab_errors("test_negative/output.expected.3.8")) expected_errors_38 = set( grab_expectations("test_negative/negative.py", "E:3.8") ) | set(grab_expectations("test_negative/negative_3.8.py", "E:3.8")) assert errors_38 == expected_errors_38 # Some sanity checks to make sure we don't mess this up. Please update as necessary. assert len(errors_38) == 74 def test_func() -> None: s = Simple1(a_string="hello") s = Simple1() s.a_string = "Hello" s.a_repeated_string.append("Hello") s2 = Simple1.FromString(s.SerializeToString()) assert s2.a_string == "Hello" assert s2.A_STRING_FIELD_NUMBER == 1 assert s2.USER_ID_FIELD_NUMBER == 21 s3 = Simple1() s3.ParseFromString(s.SerializeToString()) assert s3.a_string == "Hello" s4 = Simple1() s4.CopyFrom(s) assert s4.a_string == "Hello" l = lower2() l.upper.Lower.a = 2 assert l == lower2(upper=Upper(Lower=lower(a=2))) def test_enum() -> None: e = FOO e = OuterEnum.Value("BAR") assert OuterEnum.Value("BAR") == 2 assert OuterEnum.Name(e) == "BAR" assert OuterEnum.keys() == ["FOO", "BAR"] assert OuterEnum.values() == [1, 2] assert OuterEnum.items() == [("FOO", 1), ("BAR", 2)] # Make sure we can assure typing with a couple of techniques e2: test_pb2.OuterEnum.ValueType = OuterEnum.Value("BAR") assert OuterEnum.Name(e2) == "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. if CPP_IMPL: assert OuterEnum.Value("BAR") == OuterEnum.Value(b"BAR") def test_enum_naming_conflicts() -> None: assert NamingConflicts.Name(NamingConflicts_Name) == "Name" assert NamingConflicts.Value("Name") == 1 assert NamingConflicts_Name == 1 def test_has_field_proto2() -> None: """For HasField which is typed with Literal""" s = Simple1() s.a_string = "Hello" # Proto2 tests assert s.HasField("a_string") assert not s.HasField("a_inner") assert not s.HasField("a_enum") assert not s.HasField("a_oneof") # Erase the types to verify that incorrect inputs fail at runtime # Each test here should be duplicated in test_negative to ensure mypy fails it too if CPP_IMPL: s_untyped: Any = s with pytest.raises( ValueError, match="Protocol message Simple1 has no field garbage." ): s_untyped.HasField("garbage") with pytest.raises( ValueError, match='Protocol message Simple1 has no singular "a_repeated_string" field', ): s_untyped.HasField("a_repeated_string") with pytest.raises(TypeError, match="bad argument type for built-in operation"): s_untyped.HasField(b"a_string") none_err = "bad argument type for built-in operation" with pytest.raises(TypeError, match=none_err): s_untyped.HasField(None) def test_has_field_proto3() -> None: s = SimpleProto3() assert not s.HasField("outer_message") assert not s.HasField("a_oneof") assert not s.HasField("an_optional_string") # synthetic oneof from optional field, see https://github.com/protocolbuffers/protobuf/blob/v3.12.0/docs/implementing_proto3_presence.md#updating-a-code-generator assert not s.HasField("_an_optional_string") s = SimpleProto3(an_optional_string=None) assert not s.HasField("an_optional_string") # synthetic oneof from optional field assert not s.HasField("_an_optional_string") s = SimpleProto3(an_optional_string="") assert s.HasField("an_optional_string") # synthetic oneof from optional field assert s.HasField("_an_optional_string") # Erase the types to verify that incorrect inputs fail at runtime # Each test here should be duplicated in test_negative to ensure mypy fails it too if CPP_IMPL: s_untyped: Any = s with pytest.raises( ValueError, match="Protocol message SimpleProto3 has no field garbage." ): s_untyped.HasField("garbage") with pytest.raises( ValueError, match='Can\'t test non-optional, non-submessage field "SimpleProto3.a_string" for presence in proto3.', ): s_untyped.HasField("a_string") with pytest.raises( ValueError, match='Can\'t test non-optional, non-submessage field "SimpleProto3.a_outer_enum" for presence in proto3.', ): s_untyped.HasField("a_outer_enum") with pytest.raises( ValueError, match='Protocol message SimpleProto3 has no singular "a_repeated_string" field', ): s_untyped.HasField("a_repeated_string") with pytest.raises(TypeError, match="bad argument type for built-in operation"): s_untyped.HasField(b"outer_message") none_err = "bad argument type for built-in operation" with pytest.raises(TypeError, match=none_err): s_untyped.HasField(None) def test_clear_field_proto2() -> None: """For ClearField which is typed with Literal""" s = Simple1() s.a_string = "Hello" # Proto2 tests s.ClearField("a_string") s.ClearField("a_inner") s.ClearField("a_repeated_string") s.ClearField("a_oneof") if CPP_IMPL: s.ClearField(b"a_string") # Erase the types to verify that incorrect inputs fail at runtime # Each test here should be duplicated in test_negative to ensure mypy fails it too s_untyped: Any = s with pytest.raises( ValueError, match='Protocol message has no "garbage" field.' ): s_untyped.ClearField("garbage") def test_clear_field_proto3() -> None: """For ClearField which is typed with Literal""" s = SimpleProto3() s.a_string = "Hello" # Proto2 tests s.ClearField("a_string") s.ClearField("a_outer_enum") s.ClearField("outer_message") s.ClearField("a_repeated_string") s.ClearField("a_oneof") if CPP_IMPL: s.ClearField(b"a_string") s.ClearField("an_optional_string") # synthetic oneof from optional field s.ClearField("_an_optional_string") # Erase the types to verify that incorrect inputs fail at runtime # Each test here should be duplicated in test_negative to ensure mypy fails it too s_untyped: Any = s if CPP_IMPL: with pytest.raises( ValueError, match='Protocol message has no "garbage" field.' ): s_untyped.ClearField("garbage") def test_which_oneof_proto2() -> None: s = Simple1() assert s.WhichOneof("a_oneof") is None s.a_oneof_1 = "hello" assert s.WhichOneof("a_oneof") == "a_oneof_1" if CPP_IMPL: assert s.WhichOneof(b"a_oneof") == "a_oneof_1" assert type(s.WhichOneof("a_oneof")) == str field = s.WhichOneof("a_oneof") assert field is not None assert s.HasField(field) # Erase the types to verify that incorrect inputs fail at runtime # Each test here should be duplicated in test_negative to ensure mypy fails it too s_untyped: Any = s with pytest.raises( ValueError, match='Protocol message has no oneof "garbage" field.' ): s_untyped.WhichOneof("garbage") def test_which_oneof_proto3() -> None: s = SimpleProto3() assert s.WhichOneof("a_oneof") is None s.a_oneof_1 = "hello" s.b_oneof_1 = "world" assert s.WhichOneof("a_oneof") == "a_oneof_1" if CPP_IMPL: assert s.WhichOneof(b"a_oneof") == "a_oneof_1" assert type(s.WhichOneof("a_oneof")) == str field_a = s.WhichOneof("a_oneof") assert field_a is not None assert s.HasField(field_a) field_b = s.WhichOneof("b_oneof") assert field_b is not None assert s.HasField(field_b) # synthetic oneof from optional field assert s.WhichOneof("_an_optional_string") is None s.an_optional_string = "foo" field_aos = s.WhichOneof("_an_optional_string") assert field_aos is not None assert s.HasField(field_aos) # Erase the types to verify that incorrect inputs fail at runtime # Each test here should be duplicated in test_negative to ensure mypy fails it too s_untyped: Any = s with pytest.raises( ValueError, match='Protocol message has no oneof "garbage" field.' ): s_untyped.WhichOneof("garbage") def test_extensions_proto2() -> None: s1 = Simple1() s2 = Simple2() assert isinstance(Extensions1.ext, FieldDescriptor) assert test_pb2.Extensions1.EXT_FIELD_NUMBER == 1000 assert isinstance(Extensions2.foo, FieldDescriptor) assert isinstance(SeparateFileExtension.ext, FieldDescriptor) assert s1.HasExtension(Extensions1.ext) is False s1.ClearExtension(Extensions1.ext) e1 = s1.Extensions[Extensions1.ext] e1.ext1_string = "first extension" assert isinstance(e1, Extensions1) e2 = s1.Extensions[Extensions2.foo] e2.flag = True assert isinstance(e2, Extensions2) e3 = s2.Extensions[SeparateFileExtension.ext] e3.flag = True assert isinstance(e3, SeparateFileExtension) del s1.Extensions[Extensions2.foo] # Using __iter__, x is a FieldDescriptor but the type of the message that # s1.Extensions[x] yields is unknown (it could be any of the extension messages). # Hence, s1.Extensions[x] is typed as Any. for x in s1.Extensions: assert isinstance(x, FieldDescriptor) assert x.is_extension y = s1.Extensions[x] assert y.ext1_string == "first extension" assert Extensions1.ext in s1.Extensions assert len(s2.Extensions) == 1 def test_extensions_proto3() -> None: assert ( MessageOptionsTestMsg.DESCRIPTOR.GetOptions().Extensions[scalar_option] == "Hello world!" ) assert SCALAR_OPTION_FIELD_NUMBER == 51234 assert MessageOptionsTestMsg.DESCRIPTOR.GetOptions().Extensions[ repeated_scalar_option ] == ["A", "B", "C"] assert MessageOptionsTestMsg.DESCRIPTOR.GetOptions().Extensions[enum_option] == FOO3 assert MessageOptionsTestMsg.DESCRIPTOR.GetOptions().Extensions[ repeated_enum_option ] == [FOO3, BAR3] assert MessageOptionsTestMsg.DESCRIPTOR.GetOptions().Extensions[ msg_option ] == OuterMessage3(a_string="Hello OuterMessage3") assert list( MessageOptionsTestMsg.DESCRIPTOR.GetOptions().Extensions[repeated_msg_option] ) == [ OuterMessage3(a_string="Hello OuterMessage3 A"), OuterMessage3(a_string="Hello OuterMessage3 B"), ] def test_constructor_proto2() -> None: x = Simple2() # It's OK to omit a required field from the constructor. assert not x.HasField("a_string") x = Simple2(a_string=None) # It's OK to pass None for a required field. assert not x.HasField("a_string") x = Simple2(a_string="") assert x.HasField("a_string") x = Simple2(a_string="hello") assert x.HasField("a_string") def test_constructor_proto3() -> None: x = SimpleProto3() assert x.a_string == "" assert not x.HasField("an_optional_string") # an_optional_string has optional keyword so None is allowed x = SimpleProto3(an_optional_string=None) assert not x.HasField("an_optional_string") x = SimpleProto3(a_string="", an_optional_string="") assert x.a_string == "" assert x.HasField("an_optional_string") x = SimpleProto3(a_string="hello", an_optional_string="hello") assert x.a_string == "hello" assert x.HasField("an_optional_string") def test_message_descriptor_proto2() -> None: assert Simple1().DESCRIPTOR.full_name == "test.Simple1" assert Simple1.DESCRIPTOR.full_name == "test.Simple1" def test_message_descriptor_proto3() -> None: assert SimpleProto3().DESCRIPTOR.full_name == "test3.SimpleProto3" assert SimpleProto3.DESCRIPTOR.full_name == "test3.SimpleProto3" def test_reexport_identical() -> None: assert SimpleProto3 is ReexportedSimpleProto3 assert FOO3 is ReexportedFOO3 def test_enum_descriptor() -> None: assert OuterEnum.DESCRIPTOR.name == "OuterEnum" def test_module_descriptor() -> None: assert DESCRIPTOR.name == "testproto/test.proto" def test_mapping_type() -> None: s = SimpleProto3() s.map_scalar[5] = "abcd" assert s.map_scalar[5] == "abcd" s.map_message[5].a_string = "hi" assert s.map_message[5] == OuterMessage3(a_string="hi") assert s.map_message.get_or_create(6) == OuterMessage3() assert s.map_message[6] == OuterMessage3() assert s.map_message.get_or_create(6) == OuterMessage3() s2 = SimpleProto3( map_scalar={5: "abcd"}, map_message={5: OuterMessage3(a_string="hi")} ) def test_casttype() -> None: s = Simple1() s.user_id = UserId(33) assert s.user_id == 33 s.email = Email("abcd@gmail.com") assert s.email == "abcd@gmail.com" s.email_by_uid[UserId(33)] = Email("abcd@gmail.com") def test_reserved_keywords() -> None: with pytest.raises(AttributeError, match="module.*has no attribute 'asdf'"): getattr(test_pb2, "asdf") # Confirm that "None" is a Message none_cls: Type[test_pb2._r_None] = getattr(test_pb2, "None") none_instance = none_cls(valid=5) assert isinstance(none_instance, Message) # Confirm that messages and enums w/ reserved names type properly prk = PythonReservedKeywords( none=none_instance, valid=PythonReservedKeywords.valid_in_finally ) assert prk.none.valid == 5 assert prk.valid == PythonReservedKeywords.valid_in_finally mypy-protobuf-3.2.0/test/test_grpc_usage.py000066400000000000000000000051211417335214500210630ustar00rootroot00000000000000import grpc import typing from concurrent import futures from testproto.grpc import dummy_pb2, dummy_pb2_grpc ADDRESS = "localhost:22222" class Servicer(dummy_pb2_grpc.DummyServiceServicer): def UnaryUnary( self, request: dummy_pb2.DummyRequest, context: grpc.ServicerContext, ) -> dummy_pb2.DummyReply: return dummy_pb2.DummyReply(value=request.value[::-1]) def UnaryStream( self, request: dummy_pb2.DummyRequest, context: grpc.ServicerContext, ) -> typing.Iterator[dummy_pb2.DummyReply]: for char in request.value: yield dummy_pb2.DummyReply(value=char) def StreamUnary( self, request: typing.Iterator[dummy_pb2.DummyRequest], context: grpc.ServicerContext, ) -> dummy_pb2.DummyReply: return dummy_pb2.DummyReply(value="".join(data.value for data in request)) def StreamStream( self, request: typing.Iterator[dummy_pb2.DummyRequest], context: grpc.ServicerContext, ) -> typing.Iterator[dummy_pb2.DummyReply]: for data in request: yield dummy_pb2.DummyReply(value=data.value.upper()) def make_server() -> grpc.Server: server = grpc.server(futures.ThreadPoolExecutor()) servicer = Servicer() server.add_insecure_port(ADDRESS) dummy_pb2_grpc.add_DummyServiceServicer_to_server(servicer, server) return server def test_grpc() -> None: server = make_server() server.start() channel = grpc.insecure_channel(ADDRESS) client = dummy_pb2_grpc.DummyServiceStub(channel) request = dummy_pb2.DummyRequest(value="cprg") result1 = client.UnaryUnary(request) result2 = client.UnaryStream(dummy_pb2.DummyRequest(value=result1.value)) result2_list = list(result2) assert len(result2_list) == 4 result3 = client.StreamStream( dummy_pb2.DummyRequest(value=part.value) for part in result2_list ) result3_list = list(result3) assert len(result3_list) == 4 result4 = client.StreamUnary( dummy_pb2.DummyRequest(value=part.value) for part in result3_list ) assert result4.value == "GRPC" # test future() in MultiCallable future_test: grpc.CallFuture[dummy_pb2.DummyReply] = client.UnaryUnary.future( request ) result5 = future_test.result() print(result5) assert result5.value == "grpc" # test params on __call__ in MultiCallable result6: dummy_pb2.DummyReply = client.UnaryUnary( request, timeout=4, metadata=(("test", "metadata"), ("cheems", "many")) ) assert result6.value == "grpc" server.stop(None) mypy-protobuf-3.2.0/test_negative/000077500000000000000000000000001417335214500172165ustar00rootroot00000000000000mypy-protobuf-3.2.0/test_negative/__init__.py000066400000000000000000000000001417335214500213150ustar00rootroot00000000000000mypy-protobuf-3.2.0/test_negative/negative.py000066400000000000000000000130511417335214500213720ustar00rootroot00000000000000""" This code is intended to have mypy failures which we will ensure show up in the output. """ from typing import ( List, Text, ) from testproto.test_extensions2_pb2 import SeparateFileExtension from testproto.test_pb2 import ( DESCRIPTOR, Extensions1, Extensions2, FOO, PythonReservedKeywords, Simple1, Simple2, ) from testproto.test3_pb2 import OuterEnum, OuterMessage3, SimpleProto3 from testproto.dot.com.test_pb2 import TestMessage from test.test_generated_mypy import Email, UserId s = Simple1() s.a_string = "Hello" s2 = Simple1.FromString(s.SerializeToStringg()) # E:2.7 E:3.8 s3 = Simple1() s3.ParseFromString(s) # E:2.7 E:3.8 s4 = Simple1() s4.CopyFrom(s.SerializeToString()) # E:2.7 E:3.8 s5 = Simple1() l: List[int] = [] l.extend(s5.a_repeated_string) # E:2.7 E:3.8 tm = TestMessage(foo=55) # E:2.7 E:3.8 e = FOO e = 3 # E:2.7 E:3.8 # Proto2 s.HasField("garbage") # E:2.7 E:3.8 s.HasField("a_repeated_string") # E:2.7 E:3.8 # Proto3 s6 = SimpleProto3() s6.HasField("garbage") # E:2.7 E:3.8 s6.HasField("a_string") # E:2.7 E:3.8 s6.HasField("outer_enum") # E:2.7 E:3.8 s6.HasField("a_repeated_string") # E:2.7 E:3.8 # Proto2 s.ClearField("garbage") # E:2.7 E:3.8 # Proto3 s6.ClearField("garbage") # E:2.7 E:3.8 # Proto2 WhichOneof s.WhichOneof("garbage") # E:2.7 E:3.8 a = 5 a = s.WhichOneof("a_oneof") # E:2.7 E:3.8 b = s.WhichOneof("a_oneof") assert b is not None s.HasField(b) # allowed simple2 = Simple2(a_string="abc") simple2.HasField(b) # E:2.7 E:3.8 # WhichOneof should return optional str var_of_type_str: str = "" var_of_type_str = s.WhichOneof("a_oneof") # E:2.7 E:3.8 # Proto3 WhichOneof s6.WhichOneof("garbage") # E:2.7 E:3.8 a3 = 5 a3 = s6.WhichOneof("a_oneof") # E:2.7 E:3.8 b3 = s6.WhichOneof("a_oneof") assert b3 is not None s6.HasField(b3) # allowed simple2.HasField(b3) # E:2.7 E:3.8 - it's a text but not one of the literals # Proto2 Extensions an_int = 5 an_int = Extensions1.ext # E:2.7 E:3.8 _ = s.Extensions[Extensions1.bad] # E:2.7 E:3.8 e1 = s.Extensions[Extensions1.ext] e1.foo = 4 # E:2.7 E:3.8 e1 = s.Extensions[Extensions2.foo] # E:2.7 E:3.8 # The following 5 extension lines will error once we undo some compat # changes to typeshed a few months after the 1.24 release # See https://github.com/python/typeshed/pull/4833 _ = s.Extensions["foo"] # E:2.7 E:3.8 _ = s.Extensions[SeparateFileExtension.ext] # E:2.7 E:3.8 _ = SeparateFileExtension.ext in s.Extensions # E:2.7 E:3.8 del s.Extensions[SeparateFileExtension.ext] # E:2.7 E:3.8 s.HasExtension(SeparateFileExtension.ext) # E:2.7 E:3.8 simple2.ClearExtension(Extensions1.ext) # E:2.7 E:3.8 for x in s.Extensions: pass x = 4 # E:2.7 E:3.8 # Overload WhichOneof c = s6.WhichOneof("a_oneof") c = s6.WhichOneof("b_oneof") # E:2.7 E:3.8 # Message DESCRIPTOR should detect invalid access via instance or class: SimpleProto3.DESCRIPTOR.Garbage() # E:2.7 E:3.8 SimpleProto3().DESCRIPTOR.Garbage() # E:2.7 E:3.8 # Enum DESCRIPTOR should detect invalid access: OuterEnum.DESCRIPTOR.Garbage() # E:2.7 E:3.8 # Module DESCRIPTOR should detect invalid access: DESCRIPTOR.Garbage() # E:2.7 E:3.8 # Enum value type should be an EnumValueType convertible to int enum = OuterEnum.V(5) enum = s6.a_outer_enum as_int = 5 as_int = s6.a_outer_enum s6.a_outer_enum.FOO # E:2.7 E:3.8 # Name/Value/items should inherit value type from _EnumTypeWrapper OuterEnum.Name(OuterEnum.V(5)) OuterEnum.Name(5) # E:2.7 E:3.8 OuterEnum.Name(OuterEnum.Value("BAR")) OuterEnum.Name(SimpleProto3.InnerEnum.Value("BAR")) # E:2.7 E:3.8 OuterEnum.Name(OuterEnum.values()[0]) OuterEnum.Name(SimpleProto3.InnerEnum.values()[0]) # E:2.7 E:3.8 OuterEnum.Name(OuterEnum.items()[0][1]) OuterEnum.Name(SimpleProto3.InnerEnum.items()[0][1]) # E:2.7 E:3.8 # Map field does not have get_or_create when mapping to a scalar type s7 = SimpleProto3() s7.map_scalar.get_or_create(0) # E:2.7 E:3.8 # Incorrect key type should error s7.map_scalar.get("abcd") # E:2.7 E:3.8 s7.map_message.get("abcd") # E:2.7 E:3.8 # Incorrect value type should error map_val = 5 map_val = s7.map_scalar.get(0) # E:2.7 E:3.8 map_val = s7.map_message.get(0) # E:2.7 E:3.8 # Incorrect constructor type should error s7 = SimpleProto3(map_scalar={"abcd": 5}, map_message={"abcd": "abcd"}) # E:2.7 E:3.8 # Castable types are typed as their cast, not the base type s8 = Simple1() s8.user_id = 55 # E:2.7 E:3.8 s8.email = "abcd@gmail.com" # E:2.7 E:3.8 s8.email_by_uid[55] = "abcd@gmail.com" # E:2.7 E:3.8 s8.email_by_uid[UserId(55)] = "abcd@gmail.com" # E:2.7 E:3.8 s8.email_by_uid[55] = Email("abcd@gmail.com") # E:2.7 E:3.8 s8 = Simple1( user_id=55, # E:2.7 E:3.8 email="abcd@gmail.com", # E:2.7 E:3.8 email_by_uid={55: "abcd@gmail.com"}, # E:2.7 E:3.8 ) # Should not reexport inner.proto, since it doesn't have public tag. from testproto.reexport_pb2 import Inner # E:2.7 E:3.8 # In proto2 - you can pass in None for primitive, but not in proto3 Simple2(a_string=None) OuterMessage3(a_string=None) # E:2.7 E:3.8 # Repeated scalar fields are not assignable only extendable s9 = Simple1() s10 = Simple1() s9.a_repeated_string = s10.a_repeated_string # E:2.7 E:3.8 s9.rep_inner_enum = s10.rep_inner_enum # E:2.7 E:3.8 # Some reserved keywored testing # Confirm that messages and enums w/ reserved names type properly PythonReservedKeywords().none.valid PythonReservedKeywords().none.invalid # E:2.7 E:3.8 # Enum should be int, even on enum with invalid name assert PythonReservedKeywords().valid == PythonReservedKeywords.valid_in_finally a_string = "hi" a_string = PythonReservedKeywords().valid # E:2.7 E:3.8 mypy-protobuf-3.2.0/test_negative/negative_3.8.py000066400000000000000000000052231417335214500217640ustar00rootroot00000000000000""" This code is intended to have mypy failures which we will ensure show up in the output. """ import typing import grpc from testproto.grpc.dummy_pb2 import ( DummyRequest, DummyReply, ) from testproto.grpc.dummy_pb2_grpc import ( DummyServiceServicer, DummyServiceStub, ) stub0 = DummyServiceStub() # E:3.8 channel = grpc.insecure_channel("127.0.0.1:8080") stub1 = DummyServiceStub(channel) request1 = DummyRequest() response1 = stub1.UnaryUnary(request1) value = response1.value value2 = response1.not_exists # E:3.8 for result1 in stub1.UnaryUnary(request1): # E:3.8 pass for result2 in stub1.UnaryStream(request1): value = result2.value value2 = result2.not_exists # E:3.8 response2 = stub1.UnaryStream(request1) value = response2.value # E:3.8 def iter_requests() -> typing.Generator[DummyRequest, None, None]: yield request1 response3 = stub1.StreamUnary(request1) # E:3.8 response4 = stub1.StreamUnary(iter_requests()) for result3 in stub1.StreamUnary(request1): # E:3.8 pass for result4 in stub1.StreamStream(request1): # E:3.8 pass for result5 in stub1.StreamStream(iter_requests()): value = result5.value value2 = result5.not_exists # E:3.8 class GoodServicer(DummyServiceServicer): def UnaryUnary( self, request: DummyRequest, context: grpc.ServicerContext, ) -> DummyReply: return DummyReply() def UnaryStream( self, request: DummyRequest, context: grpc.ServicerContext, ) -> typing.Iterator[DummyReply]: yield DummyReply() def StreamUnary( self, request: typing.Iterator[DummyRequest], context: grpc.ServicerContext, ) -> DummyReply: for data in request: pass return DummyReply() def StreamStream( self, request: typing.Iterator[DummyRequest], context: grpc.ServicerContext, ) -> typing.Iterator[DummyReply]: for data in request: yield DummyReply() class BadServicer(DummyServiceServicer): def UnaryUnary( # E:3.8 self, request: typing.Iterator[DummyRequest], context: grpc.ServicerContext, ) -> typing.Iterator[DummyReply]: for data in request: yield DummyReply() def UnaryStream( # E:3.8 self, request: typing.Iterator[DummyRequest], context: grpc.ServicerContext, ) -> DummyReply: for data in request: pass return DummyReply() def StreamUnary( # E:3.8 self, request: DummyRequest, context: grpc.ServicerContext, ) -> typing.Iterator[DummyReply]: yield DummyReply() mypy-protobuf-3.2.0/test_negative/output.expected.3.8000066400000000000000000000524671417335214500226260ustar00rootroot00000000000000test_negative/negative_3.8.py:19: error: Missing positional argument "channel" in call to "DummyServiceStub" [call-arg] test_negative/negative_3.8.py:26: error: "DummyReply" has no attribute "not_exists" [attr-defined] test_negative/negative_3.8.py:27: error: "DummyReply" has no attribute "__iter__" (not iterable) [attr-defined] test_negative/negative_3.8.py:32: error: "DummyReply" has no attribute "not_exists" [attr-defined] test_negative/negative_3.8.py:34: error: "CallIterator[DummyReply]" has no attribute "value" [attr-defined] test_negative/negative_3.8.py:41: error: Argument 1 to "__call__" of "StreamUnaryMultiCallable" has incompatible type "DummyRequest"; expected "Iterable[DummyRequest]" [arg-type] test_negative/negative_3.8.py:43: error: "DummyReply" has no attribute "__iter__" (not iterable) [attr-defined] test_negative/negative_3.8.py:43: error: Argument 1 to "__call__" of "StreamUnaryMultiCallable" has incompatible type "DummyRequest"; expected "Iterable[DummyRequest]" [arg-type] test_negative/negative_3.8.py:46: error: Argument 1 to "__call__" of "StreamStreamMultiCallable" has incompatible type "DummyRequest"; expected "Iterable[DummyRequest]" [arg-type] test_negative/negative_3.8.py:50: error: "DummyReply" has no attribute "not_exists" [attr-defined] test_negative/negative_3.8.py:87: error: Argument 1 of "UnaryUnary" is incompatible with supertype "DummyServiceServicer"; supertype defines the argument type as "DummyRequest" [override] test_negative/negative_3.8.py:87: note: This violates the Liskov substitution principle test_negative/negative_3.8.py:87: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides test_negative/negative_3.8.py:87: error: Return type "Iterator[DummyReply]" of "UnaryUnary" incompatible with return type "DummyReply" in supertype "DummyServiceServicer" [override] test_negative/negative_3.8.py:95: error: Argument 1 of "UnaryStream" is incompatible with supertype "DummyServiceServicer"; supertype defines the argument type as "DummyRequest" [override] test_negative/negative_3.8.py:95: note: This violates the Liskov substitution principle test_negative/negative_3.8.py:95: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides test_negative/negative_3.8.py:95: error: Return type "DummyReply" of "UnaryStream" incompatible with return type "Iterator[DummyReply]" in supertype "DummyServiceServicer" [override] test_negative/negative_3.8.py:104: error: Argument 1 of "StreamUnary" is incompatible with supertype "DummyServiceServicer"; supertype defines the argument type as "Iterator[DummyRequest]" [override] test_negative/negative_3.8.py:104: note: This violates the Liskov substitution principle test_negative/negative_3.8.py:104: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides test_negative/negative_3.8.py:104: error: Return type "Iterator[DummyReply]" of "StreamUnary" incompatible with return type "DummyReply" in supertype "DummyServiceServicer" [override] test_negative/negative.py:28: error: "Simple1" has no attribute "SerializeToStringg" [attr-defined] test_negative/negative.py:31: error: Argument 1 to "ParseFromString" of "Message" has incompatible type "Simple1"; expected "bytes" [arg-type] 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 "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] test_negative/negative.py:52: error: Argument 1 to "HasField" of "SimpleProto3" has incompatible type "Literal['a_string']"; 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] test_negative/negative.py:53: error: Argument 1 to "HasField" of "SimpleProto3" has incompatible type "Literal['outer_enum']"; 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] test_negative/negative.py:54: error: Argument 1 to "HasField" of "SimpleProto3" has incompatible type "Literal['a_repeated_string']"; 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] test_negative/negative.py:57: error: Argument 1 to "ClearField" 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_repeated_string'], Literal[b'a_repeated_string'], Literal['a_string'], Literal[b'a_string'], Literal['a_uint32'], Literal[b'a_uint32'], Literal['email'], Literal[b'email'], Literal['email_by_uid'], Literal[b'email_by_uid'], 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['rep_inner_enum'], Literal[b'rep_inner_enum'], Literal['rep_inner_message'], Literal[b'rep_inner_message'], Literal['user_id'], Literal[b'user_id']]" [arg-type] test_negative/negative.py:60: error: Argument 1 to "ClearField" of "SimpleProto3" has incompatible type "Literal['garbage']"; expected "Union[Literal['OuterEnum'], Literal[b'OuterEnum'], 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['a_outer_enum'], Literal[b'a_outer_enum'], Literal['a_repeated_string'], Literal[b'a_repeated_string'], Literal['a_string'], Literal[b'a_string'], 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'], Literal[b'inner_enum'], Literal['inner_enum_in_oneof'], Literal[b'inner_enum_in_oneof'], Literal['map_message'], Literal[b'map_message'], Literal['map_scalar'], Literal[b'map_scalar'], 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] test_negative/negative.py:63: error: Argument 1 to "WhichOneof" of "Simple1" has incompatible type "Literal['garbage']"; expected "Union[Literal['a_oneof'], Literal[b'a_oneof']]" [arg-type] test_negative/negative.py:65: error: Incompatible types in assignment (expression has type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None]", variable has type "int") [assignment] test_negative/negative.py:70: error: Argument 1 to "HasField" of "Simple2" has incompatible type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof']]"; expected "Union[Literal['a_string'], Literal[b'a_string']]" [arg-type] test_negative/negative.py:74: error: Incompatible types in assignment (expression has type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None]", variable has type "str") [assignment] test_negative/negative.py:77: error: No overload variant of "WhichOneof" of "SimpleProto3" matches argument type "str" [call-overload] test_negative/negative.py:77: note: Possible overload variants: test_negative/negative.py:77: note: def WhichOneof(self, oneof_group: Union[Literal['_an_optional_string'], Literal[b'_an_optional_string']]) -> Optional[Literal['an_optional_string']] test_negative/negative.py:77: note: def WhichOneof(self, oneof_group: Union[Literal['a_oneof'], Literal[b'a_oneof']]) -> Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None] test_negative/negative.py:77: note: def WhichOneof(self, oneof_group: Union[Literal['b_oneof'], Literal[b'b_oneof']]) -> Union[Literal['b_oneof_1'], Literal['b_oneof_2'], None] test_negative/negative.py:79: error: Incompatible types in assignment (expression has type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None]", variable has type "int") [assignment] test_negative/negative.py:83: error: Argument 1 to "HasField" of "Simple2" has incompatible type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof']]"; expected "Union[Literal['a_string'], Literal[b'a_string']]" [arg-type] test_negative/negative.py:87: error: Incompatible types in assignment (expression has type "_ExtensionFieldDescriptor[Simple1, Extensions1]", variable has type "int") [assignment] test_negative/negative.py:88: error: "Type[Extensions1]" has no attribute "bad" [attr-defined] test_negative/negative.py:90: error: "Extensions1" has no attribute "foo" [attr-defined] test_negative/negative.py:91: error: Incompatible types in assignment (expression has type "Extensions2", variable has type "Extensions1") [assignment] test_negative/negative.py:95: error: Invalid index type "str" for "_ExtensionDict[Simple1]"; expected type "_ExtensionFieldDescriptor[Simple1, ]" [index] test_negative/negative.py:96: error: Invalid index type "_ExtensionFieldDescriptor[Simple2, SeparateFileExtension]" for "_ExtensionDict[Simple1]"; expected type "_ExtensionFieldDescriptor[Simple1, SeparateFileExtension]" [index] test_negative/negative.py:97: error: Unsupported operand types for in ("_ExtensionFieldDescriptor[Simple2, SeparateFileExtension]" and "_ExtensionDict[Simple1]") [operator] test_negative/negative.py:98: error: Argument 1 to "__delitem__" of "_ExtensionDict" has incompatible type "_ExtensionFieldDescriptor[Simple2, SeparateFileExtension]"; expected "_ExtensionFieldDescriptor[Simple1, SeparateFileExtension]" [arg-type] test_negative/negative.py:99: error: Argument 1 to "HasExtension" of "Message" has incompatible type "_ExtensionFieldDescriptor[Simple2, SeparateFileExtension]"; expected "_ExtensionFieldDescriptor[Simple1, Any]" [arg-type] test_negative/negative.py:100: error: Argument 1 to "ClearExtension" of "Message" has incompatible type "_ExtensionFieldDescriptor[Simple1, Extensions1]"; expected "_ExtensionFieldDescriptor[Simple2, Any]" [arg-type] test_negative/negative.py:105: error: Incompatible types in assignment (expression has type "int", variable has type "_ExtensionFieldDescriptor[Simple1, Any]") [assignment] test_negative/negative.py:109: error: Incompatible types in assignment (expression has type "Union[Literal['b_oneof_1'], Literal['b_oneof_2'], None]", variable has type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None]") [assignment] test_negative/negative.py:112: error: "Descriptor" has no attribute "Garbage" [attr-defined] 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: "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 variants: test_negative/negative.py:142: note: def get(self, key: int) -> Optional[str] test_negative/negative.py:142: note: def [_T] get(self, int, Union[str, _T]) -> Union[str, _T] test_negative/negative.py:143: error: No overload variant of "get" of "Mapping" matches argument type "str" [call-overload] test_negative/negative.py:143: note: Possible overload variants: test_negative/negative.py:143: note: def get(self, key: int) -> Optional[OuterMessage3] test_negative/negative.py:143: note: def [_T] get(self, int, Union[OuterMessage3, _T]) -> Union[OuterMessage3, _T] test_negative/negative.py:146: error: Incompatible types in assignment (expression has type "Optional[str]", variable has type "int") [assignment] test_negative/negative.py:147: error: Incompatible types in assignment (expression has type "Optional[OuterMessage3]", variable has type "int") [assignment] test_negative/negative.py:149: error: Dict entry 0 has incompatible type "str": "int"; expected "int": "str" [dict-item] test_negative/negative.py:149: error: Dict entry 0 has incompatible type "str": "str"; expected "int": "OuterMessage3" [dict-item] test_negative/negative.py:153: error: Incompatible types in assignment (expression has type "int", variable has type "UserId") [assignment] test_negative/negative.py:154: error: Incompatible types in assignment (expression has type "str", variable has type "Email") [assignment] test_negative/negative.py:155: error: Invalid index type "int" for "ScalarMap[UserId, Email]"; expected type "UserId" [index] test_negative/negative.py:155: error: Incompatible types in assignment (expression has type "str", target has type "Email") [assignment] test_negative/negative.py:156: error: Incompatible types in assignment (expression has type "str", target has type "Email") [assignment] test_negative/negative.py:157: error: Invalid index type "int" for "ScalarMap[UserId, Email]"; expected type "UserId" [index] test_negative/negative.py:159: error: Argument "user_id" to "Simple1" has incompatible type "int"; expected "Optional[UserId]" [arg-type] test_negative/negative.py:160: error: Argument "email" to "Simple1" has incompatible type "str"; expected "Optional[Email]" [arg-type] test_negative/negative.py:161: error: Dict entry 0 has incompatible type "int": "str"; expected "UserId": "Email" [dict-item] test_negative/negative.py:165: error: Module "testproto.reexport_pb2" has no attribute "Inner" [attr-defined] test_negative/negative.py:169: error: Argument "a_string" to "OuterMessage3" has incompatible type "None"; expected "str" [arg-type] 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 "ValueType", variable has type "str") [assignment] Found 80 errors in 2 files (checked 32 source files) mypy-protobuf-3.2.0/test_negative/output.expected.3.8.omit_linenos000066400000000000000000000517531417335214500253210ustar00rootroot00000000000000test_negative/negative_3.8.py: error: Missing positional argument "channel" in call to "DummyServiceStub" [call-arg] test_negative/negative_3.8.py: error: "DummyReply" has no attribute "not_exists" [attr-defined] test_negative/negative_3.8.py: error: "DummyReply" has no attribute "__iter__" (not iterable) [attr-defined] test_negative/negative_3.8.py: error: "DummyReply" has no attribute "not_exists" [attr-defined] test_negative/negative_3.8.py: error: "CallIterator[DummyReply]" has no attribute "value" [attr-defined] test_negative/negative_3.8.py: error: Argument 1 to "__call__" of "StreamUnaryMultiCallable" has incompatible type "DummyRequest"; expected "Iterable[DummyRequest]" [arg-type] test_negative/negative_3.8.py: error: "DummyReply" has no attribute "__iter__" (not iterable) [attr-defined] test_negative/negative_3.8.py: error: Argument 1 to "__call__" of "StreamUnaryMultiCallable" has incompatible type "DummyRequest"; expected "Iterable[DummyRequest]" [arg-type] test_negative/negative_3.8.py: error: Argument 1 to "__call__" of "StreamStreamMultiCallable" has incompatible type "DummyRequest"; expected "Iterable[DummyRequest]" [arg-type] test_negative/negative_3.8.py: error: "DummyReply" has no attribute "not_exists" [attr-defined] test_negative/negative_3.8.py: error: Argument 1 of "UnaryUnary" is incompatible with supertype "DummyServiceServicer"; supertype defines the argument type as "DummyRequest" [override] test_negative/negative_3.8.py: note: This violates the Liskov substitution principle test_negative/negative_3.8.py: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides test_negative/negative_3.8.py: error: Return type "Iterator[DummyReply]" of "UnaryUnary" incompatible with return type "DummyReply" in supertype "DummyServiceServicer" [override] test_negative/negative_3.8.py: error: Argument 1 of "UnaryStream" is incompatible with supertype "DummyServiceServicer"; supertype defines the argument type as "DummyRequest" [override] test_negative/negative_3.8.py: note: This violates the Liskov substitution principle test_negative/negative_3.8.py: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides test_negative/negative_3.8.py: error: Return type "DummyReply" of "UnaryStream" incompatible with return type "Iterator[DummyReply]" in supertype "DummyServiceServicer" [override] test_negative/negative_3.8.py: error: Argument 1 of "StreamUnary" is incompatible with supertype "DummyServiceServicer"; supertype defines the argument type as "Iterator[DummyRequest]" [override] test_negative/negative_3.8.py: note: This violates the Liskov substitution principle test_negative/negative_3.8.py: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides test_negative/negative_3.8.py: error: Return type "Iterator[DummyReply]" of "StreamUnary" incompatible with return type "DummyReply" in supertype "DummyServiceServicer" [override] test_negative/negative.py: error: "Simple1" has no attribute "SerializeToStringg" [attr-defined] test_negative/negative.py: error: Argument 1 to "ParseFromString" of "Message" has incompatible type "Simple1"; expected "bytes" [arg-type] 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 "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] test_negative/negative.py: error: Argument 1 to "HasField" of "SimpleProto3" has incompatible type "Literal['a_string']"; 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] test_negative/negative.py: error: Argument 1 to "HasField" of "SimpleProto3" has incompatible type "Literal['outer_enum']"; 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] test_negative/negative.py: error: Argument 1 to "HasField" of "SimpleProto3" has incompatible type "Literal['a_repeated_string']"; 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] test_negative/negative.py: error: Argument 1 to "ClearField" 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_repeated_string'], Literal[b'a_repeated_string'], Literal['a_string'], Literal[b'a_string'], Literal['a_uint32'], Literal[b'a_uint32'], Literal['email'], Literal[b'email'], Literal['email_by_uid'], Literal[b'email_by_uid'], 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['rep_inner_enum'], Literal[b'rep_inner_enum'], Literal['rep_inner_message'], Literal[b'rep_inner_message'], Literal['user_id'], Literal[b'user_id']]" [arg-type] test_negative/negative.py: error: Argument 1 to "ClearField" of "SimpleProto3" has incompatible type "Literal['garbage']"; expected "Union[Literal['OuterEnum'], Literal[b'OuterEnum'], 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['a_outer_enum'], Literal[b'a_outer_enum'], Literal['a_repeated_string'], Literal[b'a_repeated_string'], Literal['a_string'], Literal[b'a_string'], 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'], Literal[b'inner_enum'], Literal['inner_enum_in_oneof'], Literal[b'inner_enum_in_oneof'], Literal['map_message'], Literal[b'map_message'], Literal['map_scalar'], Literal[b'map_scalar'], 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] test_negative/negative.py: error: Argument 1 to "WhichOneof" of "Simple1" has incompatible type "Literal['garbage']"; expected "Union[Literal['a_oneof'], Literal[b'a_oneof']]" [arg-type] test_negative/negative.py: error: Incompatible types in assignment (expression has type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None]", variable has type "int") [assignment] test_negative/negative.py: error: Argument 1 to "HasField" of "Simple2" has incompatible type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof']]"; expected "Union[Literal['a_string'], Literal[b'a_string']]" [arg-type] test_negative/negative.py: error: Incompatible types in assignment (expression has type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None]", variable has type "str") [assignment] test_negative/negative.py: error: No overload variant of "WhichOneof" of "SimpleProto3" matches argument type "str" [call-overload] test_negative/negative.py: note: Possible overload variants: test_negative/negative.py: note: def WhichOneof(self, oneof_group: Union[Literal['_an_optional_string'], Literal[b'_an_optional_string']]) -> Optional[Literal['an_optional_string']] test_negative/negative.py: note: def WhichOneof(self, oneof_group: Union[Literal['a_oneof'], Literal[b'a_oneof']]) -> Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None] test_negative/negative.py: note: def WhichOneof(self, oneof_group: Union[Literal['b_oneof'], Literal[b'b_oneof']]) -> Union[Literal['b_oneof_1'], Literal['b_oneof_2'], None] test_negative/negative.py: error: Incompatible types in assignment (expression has type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None]", variable has type "int") [assignment] test_negative/negative.py: error: Argument 1 to "HasField" of "Simple2" has incompatible type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof']]"; expected "Union[Literal['a_string'], Literal[b'a_string']]" [arg-type] test_negative/negative.py: error: Incompatible types in assignment (expression has type "_ExtensionFieldDescriptor[Simple1, Extensions1]", variable has type "int") [assignment] test_negative/negative.py: error: "Type[Extensions1]" has no attribute "bad" [attr-defined] test_negative/negative.py: error: "Extensions1" has no attribute "foo" [attr-defined] test_negative/negative.py: error: Incompatible types in assignment (expression has type "Extensions2", variable has type "Extensions1") [assignment] test_negative/negative.py: error: Invalid index type "str" for "_ExtensionDict[Simple1]"; expected type "_ExtensionFieldDescriptor[Simple1, ]" [index] test_negative/negative.py: error: Invalid index type "_ExtensionFieldDescriptor[Simple2, SeparateFileExtension]" for "_ExtensionDict[Simple1]"; expected type "_ExtensionFieldDescriptor[Simple1, SeparateFileExtension]" [index] test_negative/negative.py: error: Unsupported operand types for in ("_ExtensionFieldDescriptor[Simple2, SeparateFileExtension]" and "_ExtensionDict[Simple1]") [operator] test_negative/negative.py: error: Argument 1 to "__delitem__" of "_ExtensionDict" has incompatible type "_ExtensionFieldDescriptor[Simple2, SeparateFileExtension]"; expected "_ExtensionFieldDescriptor[Simple1, SeparateFileExtension]" [arg-type] test_negative/negative.py: error: Argument 1 to "HasExtension" of "Message" has incompatible type "_ExtensionFieldDescriptor[Simple2, SeparateFileExtension]"; expected "_ExtensionFieldDescriptor[Simple1, Any]" [arg-type] test_negative/negative.py: error: Argument 1 to "ClearExtension" of "Message" has incompatible type "_ExtensionFieldDescriptor[Simple1, Extensions1]"; expected "_ExtensionFieldDescriptor[Simple2, Any]" [arg-type] test_negative/negative.py: error: Incompatible types in assignment (expression has type "int", variable has type "_ExtensionFieldDescriptor[Simple1, Any]") [assignment] test_negative/negative.py: error: Incompatible types in assignment (expression has type "Union[Literal['b_oneof_1'], Literal['b_oneof_2'], None]", variable has type "Union[Literal['a_oneof_1'], Literal['a_oneof_2'], Literal['outer_message_in_oneof'], Literal['outer_enum_in_oneof'], Literal['inner_enum_in_oneof'], None]") [assignment] test_negative/negative.py: error: "Descriptor" has no attribute "Garbage" [attr-defined] 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: "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 variants: test_negative/negative.py: note: def get(self, key: int) -> Optional[str] test_negative/negative.py: note: def [_T] get(self, int, Union[str, _T]) -> Union[str, _T] 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 variants: test_negative/negative.py: note: def get(self, key: int) -> Optional[OuterMessage3] test_negative/negative.py: note: def [_T] get(self, int, Union[OuterMessage3, _T]) -> Union[OuterMessage3, _T] test_negative/negative.py: error: Incompatible types in assignment (expression has type "Optional[str]", variable has type "int") [assignment] test_negative/negative.py: error: Incompatible types in assignment (expression has type "Optional[OuterMessage3]", variable has type "int") [assignment] test_negative/negative.py: error: Dict entry 0 has incompatible type "str": "int"; expected "int": "str" [dict-item] test_negative/negative.py: error: Dict entry 0 has incompatible type "str": "str"; expected "int": "OuterMessage3" [dict-item] test_negative/negative.py: error: Incompatible types in assignment (expression has type "int", variable has type "UserId") [assignment] test_negative/negative.py: error: Incompatible types in assignment (expression has type "str", variable has type "Email") [assignment] test_negative/negative.py: error: Invalid index type "int" for "ScalarMap[UserId, Email]"; expected type "UserId" [index] test_negative/negative.py: error: Incompatible types in assignment (expression has type "str", target has type "Email") [assignment] test_negative/negative.py: error: Incompatible types in assignment (expression has type "str", target has type "Email") [assignment] test_negative/negative.py: error: Invalid index type "int" for "ScalarMap[UserId, Email]"; expected type "UserId" [index] test_negative/negative.py: error: Argument "user_id" to "Simple1" has incompatible type "int"; expected "Optional[UserId]" [arg-type] test_negative/negative.py: error: Argument "email" to "Simple1" has incompatible type "str"; expected "Optional[Email]" [arg-type] test_negative/negative.py: error: Dict entry 0 has incompatible type "int": "str"; expected "UserId": "Email" [dict-item] test_negative/negative.py: error: Module "testproto.reexport_pb2" has no attribute "Inner" [attr-defined] test_negative/negative.py: error: Argument "a_string" to "OuterMessage3" has incompatible type "None"; expected "str" [arg-type] 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 "ValueType", variable has type "str") [assignment] Found 80 errors in 2 files (checked 32 source files) mypy-protobuf-3.2.0/test_requirements.txt000066400000000000000000000002441417335214500207000ustar00rootroot00000000000000# Requirements to run unit tests. Tests import from # generated code. protobuf>=3.19.3 pytest==6.2.5 grpc-stubs==1.24.7 grpcio-tools==1.43.0 types-protobuf>=3.19.5