stubgen-pyx: The stubs mypy can't generate
NVIDIA's cuda-python , the official Python bindings for the CUDA toolkit, recently added automatically-generated .pyi stub files using stubgen-pyx . Their description of why: "This allows IDE auto-completion to work (which is also used by IDE-integrated coding agents). This has also found 2 real bugs in our code already. The ability to catch a certain class of bugs with this will be really helpful going forward, especially since our linting abilities with cython-lint are a bit behind what they are in pure Python." When you commit .pyi stubs alongside a Cython extension, you get an artifact your normal Python linting and type-checking pipeline can analyze. Inconsistencies between what the Cython source does and what the stub claims become visible. NVIDIA found two real bugs this way before they were reported. I'm the author of stubgen-pyx, and this post is a technical walk-through of how those stubs are produced. The problem with existing stub generators When you compile a Cython module, the source disappears. What you get is a .so (or .pyd ) file: a compiled extension with no type information readable by a language server. Tools like mypy's stubgen can generate stubs for these by importing the compiled binary and using runtime introspection. The results are usually disappointing. Take this typed Cython module: """ Mathematical utilities for scientific computing. """ cdef class Matrix : """ A simple matrix class. """ cdef int rows cdef int cols def __init__ ( self , int rows , int cols ): """ Initialize a matrix. """ self . rows = rows self . cols = cols def shape ( self ) -> tuple [ int , int ]: """ Get matrix dimensions. """ return ( self . rows , self . cols ) cpdef scale ( self , double factor ): """ Scale all elements. """ pass cdef int _validate ( self ): """ Internal validation (not exposed). """ return 0 def matrix_product ( Matrix a , Matrix b ) -> Matrix : """ Compute matrix product. """ return Matrix ( a . rows , b . cols ) Running stubgen on the compiled