Skip to content

Commit

Permalink
Merge pull request #2327 from Ericgig/misc.type_hints
Browse files Browse the repository at this point in the history
Add type hints
  • Loading branch information
Ericgig committed May 13, 2024
2 parents 8ab189e + a8b95a9 commit 4acc9f1
Show file tree
Hide file tree
Showing 20 changed files with 518 additions and 202 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
# For the sdist we should be as conservative as possible with our
# Python version. This should be the lowest supported version. This
# means that no unsupported syntax can sneak through.
python-version: '3.9'
python-version: '3.10'

- name: Install pip build
run: |
Expand Down Expand Up @@ -107,8 +107,8 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
env:
# Set up wheels matrix. This is CPython 3.9--3.12 for all OS targets.
CIBW_BUILD: "cp3{9,10,11,12}-*"
# Set up wheels matrix. This is CPython 3.10--3.12 for all OS targets.
CIBW_BUILD: "cp3{10,11,12}-*"
# Numpy and SciPy do not supply wheels for i686 or win32 for
# Python 3.10+, so we skip those:
CIBW_SKIP: "*-musllinux* cp3{10,11,12}-manylinux_i686 cp3{10,11,12}-win32"
Expand All @@ -121,7 +121,7 @@ jobs:
name: Install Python
with:
# This is about the build environment, not the released wheel version.
python-version: '3.9'
python-version: '3.10'

- name: Install cibuildwheel
run: |
Expand Down Expand Up @@ -165,12 +165,12 @@ jobs:
- uses: actions/setup-python@v4
name: Install Python
with:
python-version: '3.9'
python-version: '3.10'

- name: Verify this is not a dev version
shell: bash
run: |
python -m pip install wheels/*-cp39-cp39-manylinux*.whl
python -m pip install wheels/*-cp310-cp310-manylinux*.whl
python -c 'import qutip; print(qutip.__version__); assert "dev" not in qutip.__version__; assert "+" not in qutip.__version__'
# We built the zipfile for convenience distributing to Windows users on
Expand Down Expand Up @@ -198,12 +198,12 @@ jobs:
- uses: actions/setup-python@v4
name: Install Python
with:
python-version: '3.9'
python-version: '3.10'

- name: Verify this is not a dev version
shell: bash
run: |
python -m pip install wheels/*-cp39-cp39-manylinux*.whl
python -m pip install wheels/*-cp310-cp310-manylinux*.whl
python -c 'import qutip; print(qutip.__version__); assert "dev" not in qutip.__version__; assert "+" not in qutip.__version__'
# We built the zipfile for convenience distributing to Windows users on
Expand Down
13 changes: 0 additions & 13 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,6 @@ jobs:
# the lack of a variable is _always_ false-y, and the defaults lack all
# the special cases.
include:
# Python 3.9, Scipy 1.7, numpy 1.22
# On more version than suggested by SPEC 0
# https://scientific-python.org/specs/spec-0000/
# There are deprecation warnings when using cython 0.29.X
- case-name: Old setup
os: ubuntu-latest
python-version: "3.9"
scipy-requirement: ">=1.8,<1.9"
numpy-requirement: ">=1.22,<1.23"
condaforge: 1
oldcython: 1
pytest-extra-options: "-W ignore:dep_util:DeprecationWarning"

# Python 3.10, no mkl, scipy 1.9, numpy 1.23
# Scipy 1.9 did not support cython 3.0 yet.
# cython#17234
Expand Down
5 changes: 4 additions & 1 deletion doc/apidoc/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ Quantum Objects
---------------

.. automodule:: qutip.core.qobj
:members: ptrace, issuper, isoper, isoperket, isoperbra, isket, isbra, isherm
:members: ptrace

.. automodule:: qutip.core.properties
:members: issuper, isoper, isoperket, isoperbra, isket, isbra, isherm


Random Operators and States
Expand Down
1 change: 1 addition & 0 deletions doc/changes/2327.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add types hints in core solvers functions.
14 changes: 14 additions & 0 deletions doc/development/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ This includes using the same variable names, especially if they are function arg

Other than this, general "good-practice" Python standards apply: try not to duplicate code; try to keep functions short, descriptively-named and side-effect free; provide a docstring for every new function; and so on.

Type Hints
----------

Adding type hints to users facing functions is recommended.
QuTiP's approach is such:

- Type hints are *hints* for the users.
- Type hints can show the preferred usage over real implementation, for example:
- ``Qobj.__mul__`` is typed to support product with scalar, not other ``Qobj``, for which ``__matmul__`` should is preferred.
- ``solver.options`` claims it return a dict not ``_SolverOptions`` (which is a subclass of dict).
- Type alias are added to ``qutip.typing``.
- `Any` can be used for input which type can be extended by plugin modules, (``qutip-cupy``, ``qutip-jax``, etc.)


Documenting
-----------

Expand Down
1 change: 1 addition & 0 deletions qutip/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .subsystem_apply import *
from .blochredfield import *
from .energy_restricted import *
from .properties import *
from . import gates

del cy # File in cy are not public facing
17 changes: 14 additions & 3 deletions qutip/core/coefficient.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import numpy as np
from numpy.typing import ArrayLike
import scipy
import scipy.interpolate
import os
Expand All @@ -25,6 +26,7 @@
Coefficient, InterCoefficient, FunctionCoefficient, StrFunctionCoefficient,
ConjCoefficient, NormCoefficient, ConstantCoefficient
)
from qutip.typing import CoefficientLike


__all__ = ["coefficient", "CompilationOptions", "Coefficient",
Expand All @@ -51,9 +53,18 @@ def _return(base, **kwargs):
}


def coefficient(base, *, tlist=None, args={}, args_ctypes={},
order=3, compile_opt=None, function_style=None,
boundary_conditions=None, **kwargs):
def coefficient(
base: CoefficientLike,
*,
tlist: ArrayLike = None,
args: dict = {},
args_ctypes: dict = {},
order: int = 3,
compile_opt: dict = None,
function_style: str = None,
boundary_conditions: tuple | str = None,
**kwargs
):
"""Build ``Coefficient`` for time dependent systems:
```
Expand Down
70 changes: 70 additions & 0 deletions qutip/core/cy/qobjevo.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from qutip.typing import LayerType, ElementType, QobjEvoLike
from qutip.core.qobj import Qobj
from qutip.core.data import Data
from qutip.core.coefficient import Coefficient
from numbers import Number
from numpy.typing import ArrayLike
from typing import Any, overload, Callable


class QobjEvo:
dims: list
isbra: bool
isconstant: bool
isket: bool
isoper: bool
isoperbra: bool
isoperket: bool
issuper: bool
num_elements: int
shape: tuple[int, int]
superrep: str
type: str
def __init__(
self,
Q_object: QobjEvoLike,
args: dict[str, Any] = None,
*,
copy: bool = True,
compress: bool = True,
function_style: str = None,
tlist: ArrayLike = None,
order: int = 3,
boundary_conditions: tuple | str = None,
) -> None: ...
@overload
def arguments(self, new_args: dict[str, Any]) -> None: ...
@overload
def arguments(self, **new_args) -> None: ...
def compress(self) -> QobjEvo: ...
def tidyup(self, atol: Number) -> QobjEvo: ...
def copy(self) -> QobjEvo: ...
def conj(self) -> QobjEvo: ...
def dag(self) -> QobjEvo: ...
def trans(self) -> QobjEvo: ...
def to(self, data_type: LayerType) -> QobjEvo: ...
def linear_map(self, op_mapping: Callable[[Qobj], Qobj]) -> QobjEvo: ...
def expect(self, t: Number, state: Qobj, check_real: bool = True) -> Number: ...
def expect_data(self, t: Number, state: Data) -> Number: ...
def matmul(self, t: Number, state: Qobj) -> Qobj: ...
def matmul_data(self, t: Number, state: Data, out: Data = None) -> Data: ...
def to_list(self) -> list[ElementType]: ...
def __add__(self, other: QobjEvo | Qobj | Number) -> QobjEvo: ...
def __iadd__(self, other: QobjEvo | Qobj | Number) -> QobjEvo: ...
def __radd__(self, other: QobjEvo | Qobj | Number) -> QobjEvo: ...
def __sub__(self, other: QobjEvo | Qobj | Number) -> QobjEvo: ...
def __isub__(self, other: QobjEvo | Qobj | Number) -> QobjEvo: ...
def __rsub__(self, other: QobjEvo | Qobj | Number) -> QobjEvo: ...
def __and__(self, other: Qobj | QobjEvo) -> QobjEvo: ...
def __rand__(self, other: Qobj | QobjEvo) -> QobjEvo: ...
def __call__(self, t: float, **new_args) -> Qobj: ...
def __matmul__(self, other: Qobj | QobjEvo) -> QobjEvo: ...
def __imatmul__(self, other: Qobj | QobjEvo) -> QobjEvo: ...
def __rmatmul__(self, other: Qobj | QobjEvo) -> QobjEvo: ...
def __mul__(self, other: Number | Coefficient) -> QobjEvo: ...
def __imul__(self, other: Number | Coefficient) -> QobjEvo: ...
def __rmul__(self, other: Number | Coefficient) -> QobjEvo: ...
def __truediv__(self, other : Number) -> QobjEvo: ...
def __idiv__(self, other : Number) -> QobjEvo: ...
def __neg__(self) -> QobjEvo: ...
def __reduce__(self): ...
35 changes: 35 additions & 0 deletions qutip/core/properties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from . import Qobj, QobjEvo

__all__ = [
'isbra', 'isket', 'isoper', 'issuper', 'isoperbra', 'isoperket', 'isherm'
]


def isbra(x: Qobj | QobjEvo):
return isinstance(x, (Qobj, QobjEvo)) and x.type in ['bra', 'scalar']


def isket(x: Qobj | QobjEvo):
return isinstance(x, (Qobj, QobjEvo)) and x.type in ['ket', 'scalar']


def isoper(x: Qobj | QobjEvo):
return isinstance(x, (Qobj, QobjEvo)) and x.type in ['oper', 'scalar']


def isoperbra(x: Qobj | QobjEvo):
return isinstance(x, (Qobj, QobjEvo)) and x.type in ['operator-bra']


def isoperket(x: Qobj | QobjEvo):
return isinstance(x, (Qobj, QobjEvo)) and x.type in ['operator-ket']


def issuper(x: Qobj | QobjEvo):
return isinstance(x, (Qobj, QobjEvo)) and x.type in ['super']


def isherm(x: Qobj):
if not isinstance(x, Qobj):
raise TypeError(f"Invalid input type, got {type(x)}, exected Qobj")
return x.isherm

0 comments on commit 4acc9f1

Please sign in to comment.