open source tools to generate mypy stubs from protobufs

Overview

mypy-protobuf: Generate mypy stub files from protobuf specs

CI pypi license

We just released a new major release mypy-protobuf 2. on 02/02/2021! It includes some backward incompatible changes. See Changelog for recent changes.

Requirements

mypy >= v0.800 protoc 3.14.0 or greater python-protobuf >= 3.14.0 python >= 3.6 - for running mypy-protobuf plugin. Generated stubs will compatible back to python2.

Other configurations may work, but are not supported in testing currently. We would be open to expanding this list if a need arises - file an issue on the issue tracker.

Installation

The plugin can be installed with

pip install mypy-protobuf

To install unreleased

REV=master  # or whichever unreleased git rev you'd like
pip install git+https://github.com/dropbox/mypy-protobuf.git@$REV

# Prior to directory structure flattening, you may need
pip install git+https://github.com/dropbox/mypy-protobuf.git@$REV#subdirectory=python

Implementation

The implementation of the plugin is in mypy_protobuf/main.py, which installs to a posix executable protoc-gen-mypy. On windows you will have to use protoc_gen_mypy.bat for the executable.

On posix, ensure that the protoc-gen-mypy script installed onto your $PATH. Then 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

On windows, provide the bat file:

protoc --plugin=protoc-gen-mypy=path/to/protoc_gen_mypy.bat --python_out=output/location --mypy_out=output/location

Features

See Changelog for full listing

Types enum int values more strongly

Enum int values produce stubs which wrap the int values in NewType

enum MyEnum {
  FOO = 0;
  BAR = 1;
}

Will yield an enum type wrapper whose methods type to MyEnum.V rather than int. This allows mypy to catch bugs where the wrong enum value is being used.

mypy-protobuf autogenerates an instance of the EnumTypeWrapper as follows.

class _MyEnum(google.protobuf.internal.EnumTypeWrapper[MyEnum.V], builtins.type):
    DESCRIPTOR: google___protobuf___descriptor___EnumDescriptor = ...
    FOO = MyEnum.V(0)
    BAR = MyEnum.V(1)
class MyEnum(metaclass=_OuterEnum):
    V = typing___NewType('V', builtins.int)
FOO = MyEnum.V(0)
BAR = MyEnum.V(1)

Calling code may be typed as follows. Note that the type of x must be quoted until upstream protobuf supports V

def f(x: 'MyEnum.V'):
    print(x)

f(MyEnum.Value("FOO"))

Supports generating type wrappers for fields and maps

M.proto

message M {
  uint32 user_id = 1 [(mypy_protobuf.casttype)="mymod.UserId"
  map<uint32, string> email_by_uid = 2 [
    (mypy_protobuf.keytype)="path/to/mymod.UserId",
    (mypy_protobuf.valuetype)="path/to/mymod.Email"
  ];
}

mymod.py

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, and if you intentionally want to use this behavior, set this! We recommend avoiding this, but it may be helpful when migrating existing proto2 code.

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

Contributing

Contributions to the implementation are welcome. Please run tests using ./run_test.sh. Ensure code is formatted using black.

pip3 install black
black mypy_protobuf/main.py test/

Contributors

Dropboxers

Others

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/
Owner
Dropbox
Dropbox
Flashcards - A flash card application with 2 optional command line arguments

Flashcards A flash card application with 2 optional command line arguments impor

Özgür Yildirim 2 Jul 15, 2022
Python classes with types validation at runtime.

typedclasses Python classes with types validation at runtime. (Experimental & Under Development) Installation You can install this library using Pytho

Izhar Ahmad 8 Feb 06, 2022
open source tools to generate mypy stubs from protobufs

mypy-protobuf: Generate mypy stub files from protobuf specs We just released a new major release mypy-protobuf 2. on 02/02/2021! It includes some back

Dropbox 527 Jan 03, 2023
:sparkles: Surface lint errors during code review

✨ Linty Fresh ✨ Keep your codebase sparkly clean with the power of LINT! Linty Fresh parses lint errors and report them back to GitHub as comments on

Lyft 183 Dec 18, 2022
Static type checker for Python

Static type checker for Python Speed Pyright is a fast type checker meant for large Python source bases. It can run in a “watch” mode and performs fas

Microsoft 9.2k Jan 03, 2023
flake8 plugin to catch useless `assert` statements

flake8-useless-assert flake8 plugin to catch useless assert statements Download or install on the PyPI page Violations Code Description Example ULA001

1 Feb 12, 2022
Tool for pinpointing circular imports in Python. Find cyclic imports in any project

Pycycle: Find and fix circular imports in python projects Pycycle is an experimental project that aims to help python developers fix their circular de

Vadim Kravcenko 311 Dec 15, 2022
Flake8 extension for enforcing trailing commas in python

Flake8 Extension to enforce better comma placement. Usage If you are using flake8 it's as easy as: pip install flake8-commas Now you can avoid those a

Python Code Quality Authority 127 Sep 03, 2022
Pymxs, the 3DsMax bindings of Maxscript to Python doesn't come with any stubs

PyMXS Stubs generator What Pymxs, the 3DsMax bindings of Maxscript to Python doe

Frieder Erdmann 19 Dec 27, 2022
An extension for flake8 that forbids some imports statements in some modules.

flake8-obey-import-goat An extension for flake8 that forbids some imports statements in some modules. Important: this project is developed using DDD,

Ilya Lebedev 10 Nov 09, 2022
Utilities for refactoring imports in python-like syntax.

aspy.refactor_imports Utilities for refactoring imports in python-like syntax. Installation pip install aspy.refactor_imports Examples aspy.refactor_i

Anthony Sottile 20 Nov 01, 2022
Enforce the same configuration across multiple projects

Nitpick Flake8 plugin to enforce the same tool configuration (flake8, isort, mypy, Pylint...) across multiple Python projects. Useful if you maintain

Augusto W. Andreoli 315 Dec 25, 2022
A simple plugin that allows running mypy from PyCharm and navigate between errors

mypy-PyCharm-plugin The plugin provides a simple terminal to run fast mypy daemon from PyCharm with a single click or hotkey and easily navigate throu

Dropbox 301 Dec 09, 2022
mypy plugin to type check Kubernetes resources

kubernetes-typed mypy plugin to dynamically define types for Kubernetes objects. Features Type checking for Custom Resources Type checking forkubernet

Artem Yarmoliuk 16 Oct 10, 2022
👻 Phantom types for Python

phantom-types Phantom types for Python will help you make illegal states unrepresentable and avoid shotgun parsing by enabling you to practice "Parse,

Anton Agestam 118 Dec 22, 2022
flake8 plugin that integrates isort

Flake8 meet isort Use isort to check if the imports on your python files are sorted the way you expect. Add an .isort.cfg to define how you want your

Gil Forcada Codinachs 139 Nov 08, 2022
flake8 plugin to run black for checking Python coding style

flake8-black Introduction This is an MIT licensed flake8 plugin for validating Python code style with the command line code formatting tool black. It

Peter Cock 146 Dec 15, 2022
Check for python builtins being used as variables or parameters

Flake8 Builtins plugin Check for python builtins being used as variables or parameters. Imagine some code like this: def max_values(list, list2):

Gil Forcada Codinachs 98 Jan 08, 2023
PEP-484 typing stubs for SQLAlchemy 1.4 and SQLAlchemy 2.0

SQLAlchemy 2 Stubs These are PEP-484 typing stubs for SQLAlchemy 1.4 and 2.0. They are released concurrently along with a Mypy extension which is desi

SQLAlchemy 139 Dec 30, 2022
Mypy stubs for the PyQt5 framework

Mypy stubs for the PyQt5 framework This repository holds the stubs of the PyQt5 framework. It uses the stub files that are produced during compilation

62 Nov 22, 2022