Python stub file generator.
Project description
pygenstub
pygenstub is a utility for generating stub files from Python source files. It takes a source file as input and creates a stub file with the same base name and the .pyi extension.
When installed, a script named pygenstub gets generated which can be used as follows:
$ pygenstub foo.py
This command will generate the file foo.pyi.
This utility can be used with the Unix watch command or PyCharm file watchers to update stub files automatically from source files.
Features
If the docstring of a function or method includes a sig field, this signature is used to generate a prototype.
For example, considering the code given below:
def foo(a, b):
"""Whatever.
:sig: (int, str) -> None
:param a: ...
"""
The generated prototype will be:
def foo(a: int, b: str) -> None: ...
Default values
The stub will contain placeholders for parameter default values.
Code:
def foo(a, b=''):
"""Whatever.
:sig: (int, str) -> None
:param a: ...
"""
Stub:
def foo(a: int, b: str = ...) -> None: ...
Imported names
Imported type names in the source will be used in the stub if needed:
Code:
from x import A, B, C
def foo(a, b):
"""Whatever.
:sig: (A, B) -> A
:param a: ...
"""
Stub (note that the name C is not imported):
from x import A, B
def foo(a: A, b: B) -> A: ...
Dotted names
Dotted type names will generate imports in the stub file.
Code:
def foo(a, b):
"""Whatever.
:sig: (x.y.A, x.y.B) -> x.y.A
:param a: ...
"""
Stub:
import x.y
def foo(a: x.y.A, b: x.y.B) -> x.y.A: ...
Names from the typing module
Unresolved names will be looked up from the typing module.
Code:
def foo(a, b):
"""Whatever.
:sig: (Dict, Tuple) -> Optional[str]
:param a: ...
"""
Stub:
from typing import Dict, Optional, Tuple
def foo(a: Dict, b: Tuple) -> Optional[str]: ...
Classes
Classes are supported including the imports needed for their base classes.
Code:
from x import A
class Foo(A):
def foo(self, a):
"""Whatever.
:sig: (int) -> str
:param a: ...
"""
Stub:
from x import A
class Foo(A):
def foo(self, a: int) -> str: ...
If the docstring of a class has a signature field, it will be used as the signature field of its __init__ method if that method doesn’t have a signature already.
Code:
class Foo:
"""Whatever.
:sig: (int) -> None
:param a: ...
"""
def __init__(self, a):
self.a = a
Stub:
class Foo:
def __init__(self, a: int) -> None: ...
Variables
Module and class level variables can be annotated using # sig: comments.
Code:
x = 42 # sig: int
class Foo:
y = 'spam' # sig: str
Stub:
x = ... # type: int
class Foo:
y = ... # type: str
TODO
class variables
decorators
Sphinx extension for adjusting documentation
Disclaimer
Some of these (or maybe even all of them) are probably in the “not a good idea” category. The whole thing could be pointless. I’m experimenting at the moment. Anyway, if you’re not using .pyi files, it should be harmless.
History
1.0a5 (2017-02-07)
Support for methods.
Support for instance variables.
Support for base classes.
Shortened the field name from “signature” to “sig”.
Use three dots instead of actual value for parameter defaults.
Dropped support for Python 2.
1.0a4 (2017-01-06)
Long stubs are now spread over multiple lines.
Better handling of parameter defaults that are tuples.
Bugfix: handling of parameter defaults that have the value None.
1.0a3 (2017-01-06)
Proper support for names from the typing module in input parameters.
Added parameter default values to stubs.
1.0a2 (2017-01-03)
Support for Python 2.7.
1.0a1 (2017-01-03)
First release on PyPI.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.