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