xref: /petsc/src/binding/petsc4py/conf/stubgen.py (revision baca6076736e385493fd849a2765fd1676cb8d6d)
155a74a43SLisandro Dalcinimport os
255a74a43SLisandro Dalcinimport inspect
355a74a43SLisandro Dalcinimport textwrap
455a74a43SLisandro Dalcin
555a74a43SLisandro Dalcin
655a74a43SLisandro Dalcindef is_cyfunction(obj):
755a74a43SLisandro Dalcin    return type(obj).__name__ == 'cython_function_or_method'
855a74a43SLisandro Dalcin
955a74a43SLisandro Dalcin
1055a74a43SLisandro Dalcindef is_function(obj):
1155a74a43SLisandro Dalcin    return (
1255a74a43SLisandro Dalcin        inspect.isbuiltin(obj)
1355a74a43SLisandro Dalcin        or is_cyfunction(obj)
1455a74a43SLisandro Dalcin        or type(obj) is type(ord)
1555a74a43SLisandro Dalcin    )
1655a74a43SLisandro Dalcin
1755a74a43SLisandro Dalcin
1855a74a43SLisandro Dalcindef is_method(obj):
1955a74a43SLisandro Dalcin    return (
2055a74a43SLisandro Dalcin        inspect.ismethoddescriptor(obj)
2155a74a43SLisandro Dalcin        or inspect.ismethod(obj)
2255a74a43SLisandro Dalcin        or is_cyfunction(obj)
2355a74a43SLisandro Dalcin        or type(obj) in (
2455a74a43SLisandro Dalcin            type(str.index),
2555a74a43SLisandro Dalcin            type(str.__add__),
2655a74a43SLisandro Dalcin            type(str.__new__),
2755a74a43SLisandro Dalcin        )
2855a74a43SLisandro Dalcin    )
2955a74a43SLisandro Dalcin
3055a74a43SLisandro Dalcin
3155a74a43SLisandro Dalcindef is_classmethod(obj):
3255a74a43SLisandro Dalcin    return (
3355a74a43SLisandro Dalcin        inspect.isbuiltin(obj)
3455a74a43SLisandro Dalcin        or type(obj).__name__ in (
3555a74a43SLisandro Dalcin            'classmethod',
3655a74a43SLisandro Dalcin            'classmethod_descriptor',
3755a74a43SLisandro Dalcin        )
3855a74a43SLisandro Dalcin    )
3955a74a43SLisandro Dalcin
4055a74a43SLisandro Dalcin
4155a74a43SLisandro Dalcindef is_staticmethod(obj):
4255a74a43SLisandro Dalcin    return (
4355a74a43SLisandro Dalcin        type(obj).__name__ in (
4455a74a43SLisandro Dalcin            'staticmethod',
4555a74a43SLisandro Dalcin        )
4655a74a43SLisandro Dalcin    )
4755a74a43SLisandro Dalcin
4855a74a43SLisandro Dalcin
4955a74a43SLisandro Dalcindef is_constant(obj):
5055a74a43SLisandro Dalcin    return isinstance(obj, (int, float, str))
5155a74a43SLisandro Dalcin
5255a74a43SLisandro Dalcin
5355a74a43SLisandro Dalcindef is_datadescr(obj):
5455a74a43SLisandro Dalcin    return inspect.isdatadescriptor(obj) and not hasattr(obj, 'fget')
5555a74a43SLisandro Dalcin
5655a74a43SLisandro Dalcin
5755a74a43SLisandro Dalcindef is_property(obj):
5855a74a43SLisandro Dalcin    return inspect.isdatadescriptor(obj) and hasattr(obj, 'fget')
5955a74a43SLisandro Dalcin
6055a74a43SLisandro Dalcin
6155a74a43SLisandro Dalcindef is_class(obj):
6255a74a43SLisandro Dalcin    return inspect.isclass(obj) or type(obj) is type(int)
6355a74a43SLisandro Dalcin
6455a74a43SLisandro Dalcin
6555a74a43SLisandro Dalcinclass Lines(list):
6655a74a43SLisandro Dalcin
6755a74a43SLisandro Dalcin    INDENT = " " * 4
6855a74a43SLisandro Dalcin    level = 0
6955a74a43SLisandro Dalcin
7055a74a43SLisandro Dalcin    @property
7155a74a43SLisandro Dalcin    def add(self):
7255a74a43SLisandro Dalcin        return self
7355a74a43SLisandro Dalcin
7455a74a43SLisandro Dalcin    @add.setter
7555a74a43SLisandro Dalcin    def add(self, lines):
7655a74a43SLisandro Dalcin        if lines is None:
7755a74a43SLisandro Dalcin            return
7855a74a43SLisandro Dalcin        if isinstance(lines, str):
7955a74a43SLisandro Dalcin            lines = textwrap.dedent(lines).strip().split("\n")
8055a74a43SLisandro Dalcin        indent = self.INDENT * self.level
8155a74a43SLisandro Dalcin        for line in lines:
8255a74a43SLisandro Dalcin            self.append(indent + line)
8355a74a43SLisandro Dalcin
8455a74a43SLisandro Dalcin
8555a74a43SLisandro Dalcindef signature(obj):
8655a74a43SLisandro Dalcin    doc = obj.__doc__
8755a74a43SLisandro Dalcin    doc = doc or f"{obj.__name__}: Any"  # FIXME remove line
8855a74a43SLisandro Dalcin    sig = doc.split('\n', 1)[0].split('.', 1)[-1]
8955a74a43SLisandro Dalcin    return sig or None
9055a74a43SLisandro Dalcin
9155a74a43SLisandro Dalcindef visit_constant(constant):
9255a74a43SLisandro Dalcin    name, value = constant
9355a74a43SLisandro Dalcin    return f"{name}: Final[{type(value).__name__}] = ..."
9455a74a43SLisandro Dalcin
9555a74a43SLisandro Dalcin
9655a74a43SLisandro Dalcindef visit_function(function):
9755a74a43SLisandro Dalcin    sig = signature(function)
9855a74a43SLisandro Dalcin    return f"def {sig}: ..."
9955a74a43SLisandro Dalcin
10055a74a43SLisandro Dalcin
10155a74a43SLisandro Dalcindef visit_method(method):
10255a74a43SLisandro Dalcin    sig = signature(method)
10355a74a43SLisandro Dalcin    return f"def {sig}: ..."
10455a74a43SLisandro Dalcin
10555a74a43SLisandro Dalcin
10655a74a43SLisandro Dalcindef visit_datadescr(datadescr):
10755a74a43SLisandro Dalcin    sig = signature(datadescr)
10855a74a43SLisandro Dalcin    return f"{sig}"
10955a74a43SLisandro Dalcin
11055a74a43SLisandro Dalcin
11155a74a43SLisandro Dalcindef visit_property(prop, name=None):
11255a74a43SLisandro Dalcin    sig = signature(prop.fget)
11355a74a43SLisandro Dalcin    pname = name or prop.fget.__name__
11455a74a43SLisandro Dalcin    ptype = sig.rsplit('->', 1)[-1].strip()
11555a74a43SLisandro Dalcin    return f"{pname}: {ptype}"
11655a74a43SLisandro Dalcin
11755a74a43SLisandro Dalcin
11855a74a43SLisandro Dalcindef visit_constructor(cls, name='__init__', args=None):
11955a74a43SLisandro Dalcin    init = (name == '__init__')
12055a74a43SLisandro Dalcin    argname = cls.__name__.lower()
12155a74a43SLisandro Dalcin    argtype = cls.__name__
12255a74a43SLisandro Dalcin    initarg = args or f"{argname}: Optional[{argtype}] = None"
12355a74a43SLisandro Dalcin    selfarg = 'self' if init else 'cls'
12455a74a43SLisandro Dalcin    rettype = 'None' if init else argtype
12555a74a43SLisandro Dalcin    arglist = f"{selfarg}, {initarg}"
12655a74a43SLisandro Dalcin    sig = f"{name}({arglist}) -> {rettype}"
12755a74a43SLisandro Dalcin    return f"def {sig}: ..."
12855a74a43SLisandro Dalcin
12955a74a43SLisandro Dalcindef visit_class(cls, outer=None, done=None):
13055a74a43SLisandro Dalcin    skip = {
13155a74a43SLisandro Dalcin        '__doc__',
13255a74a43SLisandro Dalcin        '__dict__',
13355a74a43SLisandro Dalcin        '__module__',
13455a74a43SLisandro Dalcin        '__weakref__',
13555a74a43SLisandro Dalcin        '__pyx_vtable__',
136*baca6076SPierre Jolivet        '__enum2str',  # FIXME refactor implementation
13755a74a43SLisandro Dalcin        '_traceback_', # FIXME maybe refactor?
13855a74a43SLisandro Dalcin        '__lt__',
13955a74a43SLisandro Dalcin        '__le__',
14055a74a43SLisandro Dalcin        '__ge__',
14155a74a43SLisandro Dalcin        '__gt__',
14255a74a43SLisandro Dalcin    }
14355a74a43SLisandro Dalcin    special = {
14455a74a43SLisandro Dalcin        '__len__':   "__len__(self) -> int",
14555a74a43SLisandro Dalcin        '__bool__':  "__bool__(self) -> bool",
14655a74a43SLisandro Dalcin        '__hash__':  "__hash__(self) -> int",
14755a74a43SLisandro Dalcin        '__int__':   "__int__(self) -> int",
14855a74a43SLisandro Dalcin        '__index__': "__int__(self) -> int",
14955a74a43SLisandro Dalcin        '__str__':   "__str__(self) -> str",
15055a74a43SLisandro Dalcin        '__repr__':  "__repr__(self) -> str",
15155a74a43SLisandro Dalcin        '__eq__':    "__eq__(self, other: object) -> bool",
15255a74a43SLisandro Dalcin        '__ne__':    "__ne__(self, other: object) -> bool",
15355a74a43SLisandro Dalcin    }
15455a74a43SLisandro Dalcin    constructor = (
15555a74a43SLisandro Dalcin        '__new__',
15655a74a43SLisandro Dalcin        '__init__',
15755a74a43SLisandro Dalcin    )
15855a74a43SLisandro Dalcin
15955a74a43SLisandro Dalcin    qualname = cls.__name__
16055a74a43SLisandro Dalcin    cls_name = cls.__name__
16155a74a43SLisandro Dalcin    if outer is not None and cls_name.startswith(outer):
16255a74a43SLisandro Dalcin        cls_name = cls_name[len(outer):]
16355a74a43SLisandro Dalcin        qualname = f"{outer}.{cls_name}"
16455a74a43SLisandro Dalcin
16555a74a43SLisandro Dalcin    override = OVERRIDE.get(qualname, {})
16655a74a43SLisandro Dalcin    done = set() if done is None else done
16755a74a43SLisandro Dalcin    lines = Lines()
16855a74a43SLisandro Dalcin
16955a74a43SLisandro Dalcin    try:
17055a74a43SLisandro Dalcin        class sub(cls):
17155a74a43SLisandro Dalcin            pass
17255a74a43SLisandro Dalcin        final = False
17355a74a43SLisandro Dalcin    except TypeError:
17455a74a43SLisandro Dalcin        final = True
17555a74a43SLisandro Dalcin    if final:
17655a74a43SLisandro Dalcin        lines.add = "@final"
17755a74a43SLisandro Dalcin    base = cls.__base__
17855a74a43SLisandro Dalcin    if base is object:
17955a74a43SLisandro Dalcin        lines.add = f"class {cls_name}:"
18055a74a43SLisandro Dalcin    else:
18155a74a43SLisandro Dalcin        lines.add = f"class {cls_name}({base.__name__}):"
18255a74a43SLisandro Dalcin    lines.level += 1
18355a74a43SLisandro Dalcin    start = len(lines)
18455a74a43SLisandro Dalcin
18555a74a43SLisandro Dalcin    for name in constructor:
18655a74a43SLisandro Dalcin        if name in cls.__dict__:
18755a74a43SLisandro Dalcin            done.add(name)
18855a74a43SLisandro Dalcin
18955a74a43SLisandro Dalcin    if '__hash__' in cls.__dict__:
19055a74a43SLisandro Dalcin        if cls.__hash__ is None:
19155a74a43SLisandro Dalcin            done.add('__hash__')
19255a74a43SLisandro Dalcin
19355a74a43SLisandro Dalcin    dct = cls.__dict__
19455a74a43SLisandro Dalcin    keys = list(dct.keys())
19555a74a43SLisandro Dalcin
19655a74a43SLisandro Dalcin    def dunder(name):
19755a74a43SLisandro Dalcin        return name.startswith('__') and name.endswith('__')
19855a74a43SLisandro Dalcin
19955a74a43SLisandro Dalcin    def members(seq):
20055a74a43SLisandro Dalcin        for name in seq:
20155a74a43SLisandro Dalcin            if name in skip:
20255a74a43SLisandro Dalcin                continue
20355a74a43SLisandro Dalcin            if name in done:
20455a74a43SLisandro Dalcin                continue
20555a74a43SLisandro Dalcin            if dunder(name):
20655a74a43SLisandro Dalcin                if name not in special and name not in override:
20755a74a43SLisandro Dalcin                    done.add(name)
20855a74a43SLisandro Dalcin                    continue
20955a74a43SLisandro Dalcin            yield name
21055a74a43SLisandro Dalcin
21155a74a43SLisandro Dalcin    for name in members(keys):
21255a74a43SLisandro Dalcin        attr = getattr(cls, name)
21355a74a43SLisandro Dalcin        if is_class(attr):
21455a74a43SLisandro Dalcin            done.add(name)
21555a74a43SLisandro Dalcin            lines.add = visit_class(attr, outer=cls_name)
21655a74a43SLisandro Dalcin            continue
21755a74a43SLisandro Dalcin
21855a74a43SLisandro Dalcin    for name in members(keys):
21955a74a43SLisandro Dalcin
22055a74a43SLisandro Dalcin        if name in override:
22155a74a43SLisandro Dalcin            done.add(name)
22255a74a43SLisandro Dalcin            lines.add = override[name]
22355a74a43SLisandro Dalcin            continue
22455a74a43SLisandro Dalcin
22555a74a43SLisandro Dalcin        if name in special:
22655a74a43SLisandro Dalcin            done.add(name)
22755a74a43SLisandro Dalcin            sig = special[name]
22855a74a43SLisandro Dalcin            lines.add = f"def {sig}: ..."
22955a74a43SLisandro Dalcin            continue
23055a74a43SLisandro Dalcin
23155a74a43SLisandro Dalcin        attr = getattr(cls, name)
23255a74a43SLisandro Dalcin
23355a74a43SLisandro Dalcin        if is_method(attr):
23455a74a43SLisandro Dalcin            done.add(name)
23555a74a43SLisandro Dalcin            if name == attr.__name__:
23655a74a43SLisandro Dalcin                obj = dct[name]
23755a74a43SLisandro Dalcin                if is_classmethod(obj):
23855a74a43SLisandro Dalcin                    lines.add = "@classmethod"
23955a74a43SLisandro Dalcin                elif is_staticmethod(obj):
24055a74a43SLisandro Dalcin                    lines.add = "@staticmethod"
24155a74a43SLisandro Dalcin                lines.add = visit_method(attr)
24255a74a43SLisandro Dalcin            elif True:
24355a74a43SLisandro Dalcin                lines.add = f"{name} = {attr.__name__}"
24455a74a43SLisandro Dalcin            continue
24555a74a43SLisandro Dalcin
24655a74a43SLisandro Dalcin        if is_datadescr(attr):
24755a74a43SLisandro Dalcin            done.add(name)
24855a74a43SLisandro Dalcin            lines.add = visit_datadescr(attr)
24955a74a43SLisandro Dalcin            continue
25055a74a43SLisandro Dalcin
25155a74a43SLisandro Dalcin        if is_property(attr):
25255a74a43SLisandro Dalcin            done.add(name)
25355a74a43SLisandro Dalcin            lines.add = visit_property(attr, name)
25455a74a43SLisandro Dalcin            continue
25555a74a43SLisandro Dalcin
25655a74a43SLisandro Dalcin        if is_constant(attr):
25755a74a43SLisandro Dalcin            done.add(name)
25855a74a43SLisandro Dalcin            lines.add = visit_constant((name, attr))
25955a74a43SLisandro Dalcin            continue
26055a74a43SLisandro Dalcin
26155a74a43SLisandro Dalcin    leftovers = [name for name in keys if
26255a74a43SLisandro Dalcin                 name not in done and name not in skip]
26355a74a43SLisandro Dalcin    if leftovers:
26455a74a43SLisandro Dalcin        raise RuntimeError(f"leftovers: {leftovers}")
26555a74a43SLisandro Dalcin
26655a74a43SLisandro Dalcin    if len(lines) == start:
26755a74a43SLisandro Dalcin        lines.add = "pass"
26855a74a43SLisandro Dalcin    lines.level -= 1
26955a74a43SLisandro Dalcin    return lines
27055a74a43SLisandro Dalcin
27155a74a43SLisandro Dalcin
27255a74a43SLisandro Dalcindef visit_module(module, done=None):
27355a74a43SLisandro Dalcin    skip = {
27455a74a43SLisandro Dalcin        '__doc__',
27555a74a43SLisandro Dalcin        '__name__',
27655a74a43SLisandro Dalcin        '__loader__',
27755a74a43SLisandro Dalcin        '__spec__',
27855a74a43SLisandro Dalcin        '__file__',
27955a74a43SLisandro Dalcin        '__package__',
28055a74a43SLisandro Dalcin        '__builtins__',
28155a74a43SLisandro Dalcin        '__pyx_unpickle_Enum',  # FIXME review
28255a74a43SLisandro Dalcin    }
28355a74a43SLisandro Dalcin
28455a74a43SLisandro Dalcin    done = set() if done is None else done
28555a74a43SLisandro Dalcin    lines = Lines()
28655a74a43SLisandro Dalcin
28755a74a43SLisandro Dalcin    keys = list(module.__dict__.keys())
28855a74a43SLisandro Dalcin    keys.sort(key=lambda name: name.startswith("_"))
28955a74a43SLisandro Dalcin
29055a74a43SLisandro Dalcin    constants = [
29155a74a43SLisandro Dalcin        (name, getattr(module, name)) for name in keys
29255a74a43SLisandro Dalcin        if all((
29355a74a43SLisandro Dalcin            name not in done and name not in skip,
29455a74a43SLisandro Dalcin            isinstance(getattr(module, name), int),
29555a74a43SLisandro Dalcin        ))
29655a74a43SLisandro Dalcin    ]
29755a74a43SLisandro Dalcin    for name, value in constants:
29855a74a43SLisandro Dalcin        done.add(name)
29955a74a43SLisandro Dalcin        if name in OVERRIDE:
30055a74a43SLisandro Dalcin            lines.add = OVERRIDE[name]
30155a74a43SLisandro Dalcin        else:
30255a74a43SLisandro Dalcin            lines.add = visit_constant((name, value))
30355a74a43SLisandro Dalcin    if constants:
30455a74a43SLisandro Dalcin        lines.add = ""
30555a74a43SLisandro Dalcin
30655a74a43SLisandro Dalcin    for name in keys:
30755a74a43SLisandro Dalcin        if name in done or name in skip:
30855a74a43SLisandro Dalcin            continue
30955a74a43SLisandro Dalcin        value = getattr(module, name)
31055a74a43SLisandro Dalcin
31155a74a43SLisandro Dalcin        if is_class(value):
31255a74a43SLisandro Dalcin            done.add(name)
31355a74a43SLisandro Dalcin            if value.__module__ != module.__name__:
31455a74a43SLisandro Dalcin                continue
31555a74a43SLisandro Dalcin            lines.add = visit_class(value)
31655a74a43SLisandro Dalcin            lines.add = ""
31755a74a43SLisandro Dalcin            instances = [
31855a74a43SLisandro Dalcin                (k, getattr(module, k)) for k in keys
31955a74a43SLisandro Dalcin                if all((
32055a74a43SLisandro Dalcin                    k not in done and k not in skip,
32155a74a43SLisandro Dalcin                    type(getattr(module, k)) is value,
32255a74a43SLisandro Dalcin                ))
32355a74a43SLisandro Dalcin            ]
32455a74a43SLisandro Dalcin            for attrname, attrvalue in instances:
32555a74a43SLisandro Dalcin                done.add(attrname)
32655a74a43SLisandro Dalcin                lines.add = visit_constant((attrname, attrvalue))
32755a74a43SLisandro Dalcin            if instances:
32855a74a43SLisandro Dalcin                lines.add = ""
32955a74a43SLisandro Dalcin            continue
33055a74a43SLisandro Dalcin
33155a74a43SLisandro Dalcin        if is_function(value):
33255a74a43SLisandro Dalcin            done.add(name)
33355a74a43SLisandro Dalcin            if name == value.__name__:
33455a74a43SLisandro Dalcin                lines.add = visit_function(value)
33555a74a43SLisandro Dalcin            else:
33655a74a43SLisandro Dalcin                lines.add = f"{name} = {value.__name__}"
33755a74a43SLisandro Dalcin            continue
33855a74a43SLisandro Dalcin
33955a74a43SLisandro Dalcin    lines.add = ""
34055a74a43SLisandro Dalcin    for name in keys:
34155a74a43SLisandro Dalcin        if name in done or name in skip:
34255a74a43SLisandro Dalcin            continue
34355a74a43SLisandro Dalcin        value = getattr(module, name)
34455a74a43SLisandro Dalcin        done.add(name)
34555a74a43SLisandro Dalcin        if name in OVERRIDE:
34655a74a43SLisandro Dalcin            lines.add = OVERRIDE[name]
34755a74a43SLisandro Dalcin        else:
34855a74a43SLisandro Dalcin            lines.add = visit_constant((name, value))
34955a74a43SLisandro Dalcin
35055a74a43SLisandro Dalcin    leftovers = [name for name in keys if
35155a74a43SLisandro Dalcin                 name not in done and name not in skip]
35255a74a43SLisandro Dalcin    if leftovers:
35355a74a43SLisandro Dalcin        raise RuntimeError(f"leftovers: {leftovers}")
35455a74a43SLisandro Dalcin    return lines
35555a74a43SLisandro Dalcin
35655a74a43SLisandro Dalcin
35755a74a43SLisandro DalcinIMPORTS = """
35855a74a43SLisandro Dalcinfrom __future__ import annotations
35955a74a43SLisandro Dalcinimport sys
36055a74a43SLisandro Dalcinfrom threading import Lock
36155a74a43SLisandro Dalcinfrom typing import (
36255a74a43SLisandro Dalcin    Any,
36355a74a43SLisandro Dalcin    Union,
36455a74a43SLisandro Dalcin    Optional,
36555a74a43SLisandro Dalcin    NoReturn,
36655a74a43SLisandro Dalcin    overload,
36755a74a43SLisandro Dalcin)
36855a74a43SLisandro Dalcinif sys.version_info >= (3, 8):
36955a74a43SLisandro Dalcin    from typing import (
37055a74a43SLisandro Dalcin        final,
37155a74a43SLisandro Dalcin        Final,
37255a74a43SLisandro Dalcin        Literal,
37355a74a43SLisandro Dalcin    )
37455a74a43SLisandro Dalcinelse:
37555a74a43SLisandro Dalcin    from typing_extensions import (
37655a74a43SLisandro Dalcin        final,
37755a74a43SLisandro Dalcin        Final,
37855a74a43SLisandro Dalcin        Literal,
37955a74a43SLisandro Dalcin    )
38055a74a43SLisandro Dalcinif sys.version_info >= (3, 9):
38155a74a43SLisandro Dalcin    from collections.abc import (
38255a74a43SLisandro Dalcin        Callable,
38355a74a43SLisandro Dalcin        Hashable,
38455a74a43SLisandro Dalcin        Iterable,
38555a74a43SLisandro Dalcin        Iterator,
38655a74a43SLisandro Dalcin        Sequence,
38755a74a43SLisandro Dalcin        Mapping,
38855a74a43SLisandro Dalcin    )
38955a74a43SLisandro Dalcinelse:
39055a74a43SLisandro Dalcin    from typing import (
39155a74a43SLisandro Dalcin        Callable,
39255a74a43SLisandro Dalcin        Hashable,
39355a74a43SLisandro Dalcin        Iterable,
39455a74a43SLisandro Dalcin        Iterator,
39555a74a43SLisandro Dalcin        Sequence,
39655a74a43SLisandro Dalcin        Mapping,
39755a74a43SLisandro Dalcin    )
39855a74a43SLisandro Dalcinif sys.version_info >= (3, 11):
39955a74a43SLisandro Dalcin    from typing import Self
40055a74a43SLisandro Dalcinelse:
40155a74a43SLisandro Dalcin    from typing_extensions import Self
40255a74a43SLisandro Dalcinfrom os import PathLike
40355a74a43SLisandro Dalcin
40455a74a43SLisandro Dalcinimport numpy
40555a74a43SLisandro Dalcin
40655a74a43SLisandro DalcinIntType: numpy.dtype = ...
40755a74a43SLisandro DalcinRealType: numpy.dtype = ...
40855a74a43SLisandro DalcinComplexType: numpy.dtype = ...
40955a74a43SLisandro DalcinScalarType: numpy.dtype = ...
41055a74a43SLisandro Dalcin"""
41155a74a43SLisandro Dalcin
41255a74a43SLisandro DalcinOVERRIDE = {
41355a74a43SLisandro Dalcin    'Error': {
41455a74a43SLisandro Dalcin    },
41555a74a43SLisandro Dalcin    '__pyx_capi__': "__pyx_capi__: Final[Dict[str, Any]] = ...",
41655a74a43SLisandro Dalcin    '__type_registry__': "__type_registry__: Final[Dict[int, type[Object]]] = ...",
41755a74a43SLisandro Dalcin}
41855a74a43SLisandro Dalcin
41955a74a43SLisandro DalcinTYPING = """
42055a74a43SLisandro Dalcin"""
42155a74a43SLisandro Dalcin
42255a74a43SLisandro Dalcin
42355a74a43SLisandro Dalcindef visit_petsc4py_PETSc(done=None):
42455a74a43SLisandro Dalcin    from petsc4py import PETSc as module
42555a74a43SLisandro Dalcin    lines = Lines()
42655a74a43SLisandro Dalcin    lines.add = IMPORTS
42755a74a43SLisandro Dalcin    lines.add = ""
42855a74a43SLisandro Dalcin    lines.add = visit_module(module)
42955a74a43SLisandro Dalcin    lines.add = TYPING
43055a74a43SLisandro Dalcin    return lines
43155a74a43SLisandro Dalcin
43255a74a43SLisandro Dalcin
43355a74a43SLisandro Dalcindef generate(filename):
43455a74a43SLisandro Dalcin    dirname = os.path.dirname(filename)
43555a74a43SLisandro Dalcin    os.makedirs(dirname, exist_ok=True)
43655a74a43SLisandro Dalcin    with open(filename, 'w') as f:
43755a74a43SLisandro Dalcin        for line in visit_petsc4py_PETSc():
43855a74a43SLisandro Dalcin            print(line, file=f)
43955a74a43SLisandro Dalcin
44055a74a43SLisandro Dalcin
44155a74a43SLisandro DalcinOUTDIR = os.path.join('src', 'petsc4py')
44255a74a43SLisandro Dalcin
44355a74a43SLisandro Dalcinif __name__ == '__main__':
44455a74a43SLisandro Dalcin    generate(os.path.join(OUTDIR, 'PETSc.pyi'))
445