Skip to content

Commit a1c50aa

Browse files
jhalemscroggs
andauthored
Attempt at automatic typing for basix (#526)
* Not tested * mypy passes on basix module * Add __version__ to pyi file * types should no longer be needed in wrapper docs * remove types from template * mypy checks * remove pip install ffcx * | * mypy checks * types Co-authored-by: Matthew Scroggs <[email protected]>
1 parent 99b2abc commit a1c50aa

File tree

9 files changed

+492
-157
lines changed

9 files changed

+492
-157
lines changed

.github/workflows/dolfin-tests.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ jobs:
6161
python3 -m pip install git+https://github.com/FEniCS/ufl.git@${{ github.event.inputs.ufl_branch }}
6262
python3 -m pip install git+https://github.com/FEniCS/ffcx.git@${{ github.event.inputs.ffcx_branch }}
6363
64-
- name: Run cpp demos
65-
run: |
66-
python3 -m pytest demo/cpp/test.py
67-
6864
- name: Get DOLFINx
6965
if: github.event_name != 'workflow_dispatch'
7066
uses: actions/checkout@v3
@@ -78,14 +74,16 @@ jobs:
7874
path: ./dolfinx
7975
repository: FEniCS/dolfinx
8076
ref: ${{ github.event.inputs.dolfinx_branch }}
81-
8277
- name: Install DOLFINx
8378
run: |
8479
cmake -G Ninja -DCMAKE_BUILD_TYPE=Developer -B build -S dolfinx/cpp/
8580
cmake --build build
8681
cmake --install build
8782
python3 -m pip -v install --global-option build --global-option --debug dolfinx/python/
8883
84+
- name: Run mypy checks
85+
run: python3 -m mypy dolfinx/python/dolfinx
86+
8987
- name: Build DOLFINx C++ unit tests
9088
run: |
9189
cmake -G Ninja -DCMAKE_BUILD_TYPE=Developer -B build/test/ -S build/test/

.github/workflows/ffcx-tests.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ jobs:
5656
repository: FEniCS/ffcx
5757
ref: ${{ github.event.inputs.ffcx_branch }}
5858

59+
- name: Run mypy checks
60+
run: |
61+
python -m pip install mypy types-setuptools
62+
python -m mypy ffcx/ffcx
63+
5964
- name: Install FFCx
6065
run: pip install ./ffcx[ci]
6166
- name: Run FFCx tests

cpp/docs.template

Lines changed: 145 additions & 145 deletions
Large diffs are not rendered by default.

cpp/generate_docs.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ def get_docstring(matches):
113113
return "\n".join(doclines)
114114

115115
if info_type == "param":
116-
assert typename is not None
117116
params = {}
118117
for i in doc.split("@param")[1:]:
119118
i = i.split("@return")[0]
@@ -127,16 +126,15 @@ def get_docstring(matches):
127126
p = i
128127
pdoc = "TODO: document this"
129128
params[p] = "\n ".join(pdoc.split("\n"))
130-
return f"{info} ({typename}): {params[info]}"
129+
return f"{info}: {params[info]}"
131130

132131
if info_type == "return":
133-
assert typename is not None
134132
returns = [i.split("@param")[0].strip() for i in doc.split("@return")[1:]]
135133
if len(returns) == 0:
136134
returns.append("TODO: document this")
137135
assert len(returns) == 1
138136
returns = "\n ".join(returns[0].split("\n"))
139-
return f"{typename}: {returns}"
137+
return f"{returns}"
140138

141139

142140
def generate_docs():

python/basix/_basixcpp.pyi

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
from typing import Any, ClassVar, List, Tuple
2+
3+
from typing import overload
4+
import numpy
5+
6+
import numpy.typing as npt
7+
8+
__version__: str = ...
9+
10+
class CellType:
11+
__members__: ClassVar[dict] = ... # read-only
12+
__entries: ClassVar[dict] = ...
13+
hexahedron: ClassVar[CellType] = ...
14+
interval: ClassVar[CellType] = ...
15+
point: ClassVar[CellType] = ...
16+
prism: ClassVar[CellType] = ...
17+
pyramid: ClassVar[CellType] = ...
18+
quadrilateral: ClassVar[CellType] = ...
19+
tetrahedron: ClassVar[CellType] = ...
20+
triangle: ClassVar[CellType] = ...
21+
def __init__(self, value: int) -> None: ...
22+
def __eq__(self, other: object) -> bool: ...
23+
def __getstate__(self) -> int: ...
24+
def __hash__(self) -> int: ...
25+
def __index__(self) -> int: ...
26+
def __int__(self) -> int: ...
27+
def __ne__(self, other: object) -> bool: ...
28+
def __setstate__(self, state: int) -> None: ...
29+
@property
30+
def name(self) -> str: ...
31+
@property
32+
def value(self) -> int: ...
33+
34+
class DPCVariant:
35+
__members__: ClassVar[dict] = ... # read-only
36+
__entries: ClassVar[dict] = ...
37+
diagonal_equispaced: ClassVar[DPCVariant] = ...
38+
diagonal_gll: ClassVar[DPCVariant] = ...
39+
horizontal_equispaced: ClassVar[DPCVariant] = ...
40+
horizontal_gll: ClassVar[DPCVariant] = ...
41+
legendre: ClassVar[DPCVariant] = ...
42+
simplex_equispaced: ClassVar[DPCVariant] = ...
43+
simplex_gll: ClassVar[DPCVariant] = ...
44+
unset: ClassVar[DPCVariant] = ...
45+
def __init__(self, value: int) -> None: ...
46+
def __eq__(self, other: object) -> bool: ...
47+
def __getstate__(self) -> int: ...
48+
def __hash__(self) -> int: ...
49+
def __index__(self) -> int: ...
50+
def __int__(self) -> int: ...
51+
def __ne__(self, other: object) -> bool: ...
52+
def __setstate__(self, state: int) -> None: ...
53+
@property
54+
def name(self) -> str: ...
55+
@property
56+
def value(self) -> int: ...
57+
58+
class ElementFamily:
59+
__members__: ClassVar[dict] = ... # read-only
60+
BDM: ClassVar[ElementFamily] = ...
61+
CR: ClassVar[ElementFamily] = ...
62+
DPC: ClassVar[ElementFamily] = ...
63+
HHJ: ClassVar[ElementFamily] = ...
64+
Hermite: ClassVar[ElementFamily] = ...
65+
N1E: ClassVar[ElementFamily] = ...
66+
N2E: ClassVar[ElementFamily] = ...
67+
P: ClassVar[ElementFamily] = ...
68+
RT: ClassVar[ElementFamily] = ...
69+
Regge: ClassVar[ElementFamily] = ...
70+
__entries: ClassVar[dict] = ...
71+
bubble: ClassVar[ElementFamily] = ...
72+
custom: ClassVar[ElementFamily] = ...
73+
serendipity: ClassVar[ElementFamily] = ...
74+
def __init__(self, value: int) -> None: ...
75+
def __eq__(self, other: object) -> bool: ...
76+
def __getstate__(self) -> int: ...
77+
def __hash__(self) -> int: ...
78+
def __index__(self) -> int: ...
79+
def __int__(self) -> int: ...
80+
def __ne__(self, other: object) -> bool: ...
81+
def __setstate__(self, state: int) -> None: ...
82+
@property
83+
def name(self) -> str: ...
84+
@property
85+
def value(self) -> int: ...
86+
87+
class FiniteElement:
88+
def __hash__(self, object, int): ClassVar[None] = ...
89+
def __init__(self, *args, **kwargs) -> None: ...
90+
def apply_dof_transformation(self, arg0: npt.NDArray[numpy.float64], arg1: int, arg2: int) -> npt.NDArray[numpy.float64]: ...
91+
def apply_dof_transformation_to_transpose(self, arg0: npt.NDArray[numpy.float64], arg1: int, arg2: int) -> npt.NDArray[numpy.float64]: ...
92+
def apply_inverse_transpose_dof_transformation(self, arg0: npt.NDArray[numpy.float64], arg1: int, arg2: int) -> npt.NDArray[numpy.float64]: ...
93+
def base_transformations(self) -> npt.NDArray[numpy.float64]: ...
94+
def entity_transformations(self) -> dict: ...
95+
def get_tensor_product_representation(self) -> List[Tuple[List[FiniteElement],List[int]]]: ...
96+
def pull_back(self, arg0: npt.NDArray[numpy.float64], arg1: npt.NDArray[numpy.float64], arg2: npt.NDArray[numpy.float64], arg3: npt.NDArray[numpy.float64]) -> npt.NDArray[numpy.float64]: ...
97+
def push_forward(self, arg0: npt.NDArray[numpy.float64], arg1: npt.NDArray[numpy.float64], arg2: npt.NDArray[numpy.float64], arg3: npt.NDArray[numpy.float64]) -> npt.NDArray[numpy.float64]: ...
98+
def tabulate(self, arg0: int, arg1: npt.NDArray[numpy.float64]) -> npt.NDArray[numpy.float64]: ...
99+
def __eq__(self, arg0: object) -> bool: ...
100+
@property
101+
def M(self) -> List[List[npt.NDArray[numpy.float64]]]: ...
102+
@property
103+
def cell_type(self) -> CellType: ...
104+
@property
105+
def coefficient_matrix(self) -> npt.NDArray[numpy.float64]: ...
106+
@property
107+
def degree(self) -> int: ...
108+
@property
109+
def dim(self) -> int: ...
110+
@property
111+
def discontinuous(self) -> bool: ...
112+
@property
113+
def dof_transformations_are_identity(self) -> bool: ...
114+
@property
115+
def dof_transformations_are_permutations(self) -> bool: ...
116+
@property
117+
def dpc_variant(self) -> Any: ...
118+
@property
119+
def dual_matrix(self) -> npt.NDArray[numpy.float64]: ...
120+
@property
121+
def entity_closure_dofs(self) -> List[List[List[int]]]: ...
122+
@property
123+
def entity_dofs(self) -> List[List[List[int]]]: ...
124+
@property
125+
def family(self) -> ElementFamily: ...
126+
@property
127+
def has_tensor_product_factorisation(self) -> bool: ...
128+
@property
129+
def highest_complete_degree(self) -> int: ...
130+
@property
131+
def highest_degree(self) -> int: ...
132+
@property
133+
def interpolation_is_identity(self) -> bool: ...
134+
@property
135+
def interpolation_matrix(self) -> npt.NDArray[numpy.float64]: ...
136+
@property
137+
def interpolation_nderivs(self) -> int: ...
138+
@property
139+
def lagrange_variant(self) -> Any: ...
140+
@property
141+
def map_type(self) -> MapType: ...
142+
@property
143+
def num_entity_closure_dofs(self) -> List[List[int]]: ...
144+
@property
145+
def num_entity_dofs(self) -> List[List[int]]: ...
146+
@property
147+
def points(self) -> npt.NDArray[numpy.float64]: ...
148+
@property
149+
def value_shape(self) -> List[int]: ...
150+
@property
151+
def value_size(self) -> int: ...
152+
@property
153+
def wcoeffs(self) -> npt.NDArray[numpy.float64]: ...
154+
@property
155+
def x(self) -> List[List[npt.NDArray[numpy.float64]]]: ...
156+
157+
class LagrangeVariant:
158+
__members__: ClassVar[dict] = ... # read-only
159+
__entries: ClassVar[dict] = ...
160+
chebyshev_centroid: ClassVar[LagrangeVariant] = ...
161+
chebyshev_isaac: ClassVar[LagrangeVariant] = ...
162+
chebyshev_warped: ClassVar[LagrangeVariant] = ...
163+
equispaced: ClassVar[LagrangeVariant] = ...
164+
gl_centroid: ClassVar[LagrangeVariant] = ...
165+
gl_isaac: ClassVar[LagrangeVariant] = ...
166+
gl_warped: ClassVar[LagrangeVariant] = ...
167+
gll_centroid: ClassVar[LagrangeVariant] = ...
168+
gll_isaac: ClassVar[LagrangeVariant] = ...
169+
gll_warped: ClassVar[LagrangeVariant] = ...
170+
legendre: ClassVar[LagrangeVariant] = ...
171+
unset: ClassVar[LagrangeVariant] = ...
172+
vtk: ClassVar[LagrangeVariant] = ...
173+
def __init__(self, value: int) -> None: ...
174+
def __eq__(self, other: object) -> bool: ...
175+
def __getstate__(self) -> int: ...
176+
def __hash__(self) -> int: ...
177+
def __index__(self) -> int: ...
178+
def __int__(self) -> int: ...
179+
def __ne__(self, other: object) -> bool: ...
180+
def __setstate__(self, state: int) -> None: ...
181+
@property
182+
def name(self) -> str: ...
183+
@property
184+
def value(self) -> int: ...
185+
186+
class LatticeSimplexMethod:
187+
__members__: ClassVar[dict] = ... # read-only
188+
__entries: ClassVar[dict] = ...
189+
centroid: ClassVar[LatticeSimplexMethod] = ...
190+
isaac: ClassVar[LatticeSimplexMethod] = ...
191+
none: ClassVar[LatticeSimplexMethod] = ...
192+
warp: ClassVar[LatticeSimplexMethod] = ...
193+
def __init__(self, value: int) -> None: ...
194+
def __eq__(self, other: object) -> bool: ...
195+
def __getstate__(self) -> int: ...
196+
def __hash__(self) -> int: ...
197+
def __index__(self) -> int: ...
198+
def __int__(self) -> int: ...
199+
def __ne__(self, other: object) -> bool: ...
200+
def __setstate__(self, state: int) -> None: ...
201+
@property
202+
def name(self) -> str: ...
203+
@property
204+
def value(self) -> int: ...
205+
206+
class LatticeType:
207+
__members__: ClassVar[dict] = ... # read-only
208+
__entries: ClassVar[dict] = ...
209+
chebyshev: ClassVar[LatticeType] = ...
210+
equispaced: ClassVar[LatticeType] = ...
211+
gl: ClassVar[LatticeType] = ...
212+
gll: ClassVar[LatticeType] = ...
213+
def __init__(self, value: int) -> None: ...
214+
def __eq__(self, other: object) -> bool: ...
215+
def __getstate__(self) -> int: ...
216+
def __hash__(self) -> int: ...
217+
def __index__(self) -> int: ...
218+
def __int__(self) -> int: ...
219+
def __ne__(self, other: object) -> bool: ...
220+
def __setstate__(self, state: int) -> None: ...
221+
@property
222+
def name(self) -> str: ...
223+
@property
224+
def value(self) -> int: ...
225+
226+
class MapType:
227+
__members__: ClassVar[dict] = ... # read-only
228+
L2Piola: ClassVar[MapType] = ...
229+
__entries: ClassVar[dict] = ...
230+
contravariantPiola: ClassVar[MapType] = ...
231+
covariantPiola: ClassVar[MapType] = ...
232+
doubleContravariantPiola: ClassVar[MapType] = ...
233+
doubleCovariantPiola: ClassVar[MapType] = ...
234+
identity: ClassVar[MapType] = ...
235+
def __init__(self, value: int) -> None: ...
236+
def __eq__(self, other: object) -> bool: ...
237+
def __getstate__(self) -> int: ...
238+
def __hash__(self) -> int: ...
239+
def __index__(self) -> int: ...
240+
def __int__(self) -> int: ...
241+
def __ne__(self, other: object) -> bool: ...
242+
def __setstate__(self, state: int) -> None: ...
243+
@property
244+
def name(self) -> str: ...
245+
@property
246+
def value(self) -> int: ...
247+
248+
class PolynomialType:
249+
__members__: ClassVar[dict] = ... # read-only
250+
__entries: ClassVar[dict] = ...
251+
legendre: ClassVar[PolynomialType] = ...
252+
def __init__(self, value: int) -> None: ...
253+
def __eq__(self, other: object) -> bool: ...
254+
def __getstate__(self) -> int: ...
255+
def __hash__(self) -> int: ...
256+
def __index__(self) -> int: ...
257+
def __int__(self) -> int: ...
258+
def __ne__(self, other: object) -> bool: ...
259+
def __setstate__(self, state: int) -> None: ...
260+
@property
261+
def name(self) -> str: ...
262+
@property
263+
def value(self) -> int: ...
264+
265+
class QuadratureType:
266+
__members__: ClassVar[dict] = ... # read-only
267+
Default: ClassVar[QuadratureType] = ...
268+
__entries: ClassVar[dict] = ...
269+
gauss_jacobi: ClassVar[QuadratureType] = ...
270+
gll: ClassVar[QuadratureType] = ...
271+
xiao_gimbutas: ClassVar[QuadratureType] = ...
272+
def __init__(self, value: int) -> None: ...
273+
def __eq__(self, other: object) -> bool: ...
274+
def __getstate__(self) -> int: ...
275+
def __hash__(self) -> int: ...
276+
def __index__(self) -> int: ...
277+
def __int__(self) -> int: ...
278+
def __ne__(self, other: object) -> bool: ...
279+
def __setstate__(self, state: int) -> None: ...
280+
@property
281+
def name(self) -> str: ...
282+
@property
283+
def value(self) -> int: ...
284+
285+
def cell_facet_jacobians(arg0: CellType) -> npt.NDArray[numpy.float64]: ...
286+
def cell_facet_normals(arg0: CellType) -> npt.NDArray[numpy.float64]: ...
287+
def cell_facet_orientations(arg0: CellType) -> List[bool]: ...
288+
def cell_facet_outward_normals(arg0: CellType) -> npt.NDArray[numpy.float64]: ...
289+
def cell_facet_reference_volumes(arg0: CellType) -> npt.NDArray[numpy.float64]: ...
290+
def cell_volume(arg0: CellType) -> float: ...
291+
def compute_interpolation_operator(arg0: FiniteElement, arg1: FiniteElement) -> npt.NDArray[numpy.float64]: ...
292+
def create_custom_element(arg0: CellType, arg1: List[int], arg2: npt.NDArray[numpy.float64], arg3: List[List[npt.NDArray[numpy.float64]]], arg4: List[List[npt.NDArray[numpy.float64]]], arg5: int, arg6: MapType, arg7: bool, arg8: int, arg9: int) -> FiniteElement: ...
293+
@overload
294+
def create_element(arg0: ElementFamily, arg1: CellType, arg2: int, arg3: bool) -> FiniteElement: ...
295+
@overload
296+
def create_element(arg0: ElementFamily, arg1: CellType, arg2: int, arg3: LagrangeVariant, arg4: bool) -> FiniteElement: ...
297+
@overload
298+
def create_element(arg0: ElementFamily, arg1: CellType, arg2: int, arg3: DPCVariant, arg4: bool) -> FiniteElement: ...
299+
@overload
300+
def create_element(arg0: ElementFamily, arg1: CellType, arg2: int, arg3: LagrangeVariant, arg4: DPCVariant, arg5: bool) -> FiniteElement: ...
301+
@overload
302+
def create_element(arg0: ElementFamily, arg1: CellType, arg2: int) -> FiniteElement: ...
303+
@overload
304+
def create_element(arg0: ElementFamily, arg1: CellType, arg2: int, arg3: LagrangeVariant) -> FiniteElement: ...
305+
@overload
306+
def create_element(arg0: ElementFamily, arg1: CellType, arg2: int, arg3: DPCVariant) -> FiniteElement: ...
307+
@overload
308+
def create_element(arg0: ElementFamily, arg1: CellType, arg2: int, arg3: LagrangeVariant, arg4: DPCVariant) -> FiniteElement: ...
309+
@overload
310+
def create_lattice(arg0, arg1: int, arg2: LatticeType, arg3: bool) -> npt.NDArray[numpy.float64]: ...
311+
@overload
312+
def create_lattice(arg0, arg1: int, arg2: LatticeType, arg3: bool, arg4: LatticeSimplexMethod) -> npt.NDArray[numpy.float64]: ...
313+
def geometry(arg0) -> npt.NDArray[numpy.float64]: ...
314+
@overload
315+
def index(arg0: int) -> int: ...
316+
@overload
317+
def index(arg0: int, arg1: int) -> int: ...
318+
@overload
319+
def index(arg0: int, arg1: int, arg2: int) -> int: ...
320+
@overload
321+
def make_quadrature(arg0: QuadratureType, arg1: CellType, arg2: int) -> Tuple[npt.NDArray[numpy.float64],npt.NDArray[numpy.float64]]: ...
322+
@overload
323+
def make_quadrature(arg0: CellType, arg1: int) -> Tuple[npt.NDArray[numpy.float64],npt.NDArray[numpy.float64]]: ...
324+
def sub_entity_connectivity(arg0) -> List[List[List[List[int]]]]: ...
325+
def sub_entity_geometry(arg0, arg1: int, arg2: int) -> npt.NDArray[numpy.float64]: ...
326+
def tabulate_polynomial_set(arg0: CellType, arg1: int, arg2: int, arg3: npt.NDArray[numpy.float64]) -> npt.NDArray[numpy.float64]: ...
327+
def tabulate_polynomials(arg0: PolynomialType, arg1, arg2: int, arg3: npt.NDArray[numpy.float64]) -> npt.NDArray[numpy.float64]: ...
328+
@overload
329+
def topology(arg0) -> List[List[List[int]]]: ...
330+
@overload
331+
def topology(vertexindices) -> Any: ...

python/basix/py.typed

Whitespace-only changes.

0 commit comments

Comments
 (0)