Problem
Several public API symbols in pytensor.tensor.linalg are bare Op instances (or Blockwise(Op()) instances), not functions with real signatures. This causes three issues:
- LSPs (pyright, mypy, jedi) can only show the generic
Op.__call__ signature (*inputs, name=None, return_list=False, **kwargs) — no parameter names, types, or docstrings.
- Sphinx autodoc renders the same generic signature and pulls the docstring from
Blockwise instead of the actual operation.
- "Source" links in the docs point to
pytensor/tensor/blockwise.py rather than the operation's actual home (e.g. products.py, summary.py, inverse.py).
Affected symbols:
| Symbol |
File |
Current definition |
Docs source link points to |
expm |
products.py:81 |
expm = Blockwise(Expm()) |
blockwise.py |
det |
summary.py:81 |
det = Blockwise(Det()) |
blockwise.py |
inv, matrix_inverse |
inverse.py:166 |
inv = matrix_inverse = Blockwise(MatrixInverse()) |
blockwise.py |
lstsq |
solvers/lstsq.py:36 |
lstsq = Lstsq() |
solvers/lstsq.py |
Documentation examples:
Compare with properly wrapped functions like solve, cholesky, svd, norm, tensorsolve which all show their actual parameter signatures, domain-specific docstrings, and correct source links.
Possible approaches
A) Function wrapper — The codebase already uses this pattern in tensor/math.py:
_matmul = Blockwise(_dot, name="Matmul") # private Op instance
def matmul(x1, x2, dtype=None): # public function with real signature
"""Compute the matrix product of two tensor variables.
...
"""
return _matmul(x1, x2)
For each affected symbol, this would mean keeping the Op instance private and exposing a wrapper function with proper annotations and docstring.
B) .pyi stub files — Add products.pyi, summary.pyi, etc. with typed signatures. Helps LSPs but doesn't fix Sphinx autodoc, and adds maintenance burden keeping stubs in sync.
C) typing.cast with a Callable annotation — Helps LSPs but doesn't fix Sphinx.
D) Instance __doc__ — e.g. a docstring after the assignment. Fixes the rendered description in Sphinx but not the signature, source link, or LSP behavior.
Problem
Several public API symbols in
pytensor.tensor.linalgare bareOpinstances (orBlockwise(Op())instances), not functions with real signatures. This causes three issues:Op.__call__signature(*inputs, name=None, return_list=False, **kwargs)— no parameter names, types, or docstrings.Blockwiseinstead of the actual operation.pytensor/tensor/blockwise.pyrather than the operation's actual home (e.g.products.py,summary.py,inverse.py).Affected symbols:
expmproducts.py:81expm = Blockwise(Expm())blockwise.pydetsummary.py:81det = Blockwise(Det())blockwise.pyinv,matrix_inverseinverse.py:166inv = matrix_inverse = Blockwise(MatrixInverse())blockwise.pylstsqsolvers/lstsq.py:36lstsq = Lstsq()solvers/lstsq.pyDocumentation examples:
expm(*inputs, name=None, return_list=False, **kwargs)with theBlockwisedocstring, source link goes toblockwise.pyCompare with properly wrapped functions like
solve,cholesky,svd,norm,tensorsolvewhich all show their actual parameter signatures, domain-specific docstrings, and correct source links.Possible approaches
A) Function wrapper — The codebase already uses this pattern in
tensor/math.py:For each affected symbol, this would mean keeping the
Opinstance private and exposing a wrapper function with proper annotations and docstring.B)
.pyistub files — Addproducts.pyi,summary.pyi, etc. with typed signatures. Helps LSPs but doesn't fix Sphinx autodoc, and adds maintenance burden keeping stubs in sync.C)
typing.castwith aCallableannotation — Helps LSPs but doesn't fix Sphinx.D) Instance
__doc__— e.g. a docstring after the assignment. Fixes the rendered description in Sphinx but not the signature, source link, or LSP behavior.