1*55a74a43SLisandro Dalcinimport os 2*55a74a43SLisandro Dalcinimport inspect 3*55a74a43SLisandro Dalcinimport textwrap 4*55a74a43SLisandro Dalcin 5*55a74a43SLisandro Dalcin 6*55a74a43SLisandro Dalcindef is_cyfunction(obj): 7*55a74a43SLisandro Dalcin return type(obj).__name__ == 'cython_function_or_method' 8*55a74a43SLisandro Dalcin 9*55a74a43SLisandro Dalcin 10*55a74a43SLisandro Dalcindef is_function(obj): 11*55a74a43SLisandro Dalcin return ( 12*55a74a43SLisandro Dalcin inspect.isbuiltin(obj) 13*55a74a43SLisandro Dalcin or is_cyfunction(obj) 14*55a74a43SLisandro Dalcin or type(obj) is type(ord) 15*55a74a43SLisandro Dalcin ) 16*55a74a43SLisandro Dalcin 17*55a74a43SLisandro Dalcin 18*55a74a43SLisandro Dalcindef is_method(obj): 19*55a74a43SLisandro Dalcin return ( 20*55a74a43SLisandro Dalcin inspect.ismethoddescriptor(obj) 21*55a74a43SLisandro Dalcin or inspect.ismethod(obj) 22*55a74a43SLisandro Dalcin or is_cyfunction(obj) 23*55a74a43SLisandro Dalcin or type(obj) in ( 24*55a74a43SLisandro Dalcin type(str.index), 25*55a74a43SLisandro Dalcin type(str.__add__), 26*55a74a43SLisandro Dalcin type(str.__new__), 27*55a74a43SLisandro Dalcin ) 28*55a74a43SLisandro Dalcin ) 29*55a74a43SLisandro Dalcin 30*55a74a43SLisandro Dalcin 31*55a74a43SLisandro Dalcindef is_classmethod(obj): 32*55a74a43SLisandro Dalcin return ( 33*55a74a43SLisandro Dalcin inspect.isbuiltin(obj) 34*55a74a43SLisandro Dalcin or type(obj).__name__ in ( 35*55a74a43SLisandro Dalcin 'classmethod', 36*55a74a43SLisandro Dalcin 'classmethod_descriptor', 37*55a74a43SLisandro Dalcin ) 38*55a74a43SLisandro Dalcin ) 39*55a74a43SLisandro Dalcin 40*55a74a43SLisandro Dalcin 41*55a74a43SLisandro Dalcindef is_staticmethod(obj): 42*55a74a43SLisandro Dalcin return ( 43*55a74a43SLisandro Dalcin type(obj).__name__ in ( 44*55a74a43SLisandro Dalcin 'staticmethod', 45*55a74a43SLisandro Dalcin ) 46*55a74a43SLisandro Dalcin ) 47*55a74a43SLisandro Dalcin 48*55a74a43SLisandro Dalcin 49*55a74a43SLisandro Dalcindef is_constant(obj): 50*55a74a43SLisandro Dalcin return isinstance(obj, (int, float, str)) 51*55a74a43SLisandro Dalcin 52*55a74a43SLisandro Dalcin 53*55a74a43SLisandro Dalcindef is_datadescr(obj): 54*55a74a43SLisandro Dalcin return inspect.isdatadescriptor(obj) and not hasattr(obj, 'fget') 55*55a74a43SLisandro Dalcin 56*55a74a43SLisandro Dalcin 57*55a74a43SLisandro Dalcindef is_property(obj): 58*55a74a43SLisandro Dalcin return inspect.isdatadescriptor(obj) and hasattr(obj, 'fget') 59*55a74a43SLisandro Dalcin 60*55a74a43SLisandro Dalcin 61*55a74a43SLisandro Dalcindef is_class(obj): 62*55a74a43SLisandro Dalcin return inspect.isclass(obj) or type(obj) is type(int) 63*55a74a43SLisandro Dalcin 64*55a74a43SLisandro Dalcin 65*55a74a43SLisandro Dalcinclass Lines(list): 66*55a74a43SLisandro Dalcin 67*55a74a43SLisandro Dalcin INDENT = " " * 4 68*55a74a43SLisandro Dalcin level = 0 69*55a74a43SLisandro Dalcin 70*55a74a43SLisandro Dalcin @property 71*55a74a43SLisandro Dalcin def add(self): 72*55a74a43SLisandro Dalcin return self 73*55a74a43SLisandro Dalcin 74*55a74a43SLisandro Dalcin @add.setter 75*55a74a43SLisandro Dalcin def add(self, lines): 76*55a74a43SLisandro Dalcin if lines is None: 77*55a74a43SLisandro Dalcin return 78*55a74a43SLisandro Dalcin if isinstance(lines, str): 79*55a74a43SLisandro Dalcin lines = textwrap.dedent(lines).strip().split("\n") 80*55a74a43SLisandro Dalcin indent = self.INDENT * self.level 81*55a74a43SLisandro Dalcin for line in lines: 82*55a74a43SLisandro Dalcin self.append(indent + line) 83*55a74a43SLisandro Dalcin 84*55a74a43SLisandro Dalcin 85*55a74a43SLisandro Dalcindef signature(obj): 86*55a74a43SLisandro Dalcin doc = obj.__doc__ 87*55a74a43SLisandro Dalcin doc = doc or f"{obj.__name__}: Any" # FIXME remove line 88*55a74a43SLisandro Dalcin sig = doc.split('\n', 1)[0].split('.', 1)[-1] 89*55a74a43SLisandro Dalcin return sig or None 90*55a74a43SLisandro Dalcin 91*55a74a43SLisandro Dalcindef visit_constant(constant): 92*55a74a43SLisandro Dalcin name, value = constant 93*55a74a43SLisandro Dalcin return f"{name}: Final[{type(value).__name__}] = ..." 94*55a74a43SLisandro Dalcin 95*55a74a43SLisandro Dalcin 96*55a74a43SLisandro Dalcindef visit_function(function): 97*55a74a43SLisandro Dalcin sig = signature(function) 98*55a74a43SLisandro Dalcin return f"def {sig}: ..." 99*55a74a43SLisandro Dalcin 100*55a74a43SLisandro Dalcin 101*55a74a43SLisandro Dalcindef visit_method(method): 102*55a74a43SLisandro Dalcin sig = signature(method) 103*55a74a43SLisandro Dalcin return f"def {sig}: ..." 104*55a74a43SLisandro Dalcin 105*55a74a43SLisandro Dalcin 106*55a74a43SLisandro Dalcindef visit_datadescr(datadescr): 107*55a74a43SLisandro Dalcin sig = signature(datadescr) 108*55a74a43SLisandro Dalcin return f"{sig}" 109*55a74a43SLisandro Dalcin 110*55a74a43SLisandro Dalcin 111*55a74a43SLisandro Dalcindef visit_property(prop, name=None): 112*55a74a43SLisandro Dalcin sig = signature(prop.fget) 113*55a74a43SLisandro Dalcin pname = name or prop.fget.__name__ 114*55a74a43SLisandro Dalcin ptype = sig.rsplit('->', 1)[-1].strip() 115*55a74a43SLisandro Dalcin return f"{pname}: {ptype}" 116*55a74a43SLisandro Dalcin 117*55a74a43SLisandro Dalcin 118*55a74a43SLisandro Dalcindef visit_constructor(cls, name='__init__', args=None): 119*55a74a43SLisandro Dalcin init = (name == '__init__') 120*55a74a43SLisandro Dalcin argname = cls.__name__.lower() 121*55a74a43SLisandro Dalcin argtype = cls.__name__ 122*55a74a43SLisandro Dalcin initarg = args or f"{argname}: Optional[{argtype}] = None" 123*55a74a43SLisandro Dalcin selfarg = 'self' if init else 'cls' 124*55a74a43SLisandro Dalcin rettype = 'None' if init else argtype 125*55a74a43SLisandro Dalcin arglist = f"{selfarg}, {initarg}" 126*55a74a43SLisandro Dalcin sig = f"{name}({arglist}) -> {rettype}" 127*55a74a43SLisandro Dalcin return f"def {sig}: ..." 128*55a74a43SLisandro Dalcin 129*55a74a43SLisandro Dalcindef visit_class(cls, outer=None, done=None): 130*55a74a43SLisandro Dalcin skip = { 131*55a74a43SLisandro Dalcin '__doc__', 132*55a74a43SLisandro Dalcin '__dict__', 133*55a74a43SLisandro Dalcin '__module__', 134*55a74a43SLisandro Dalcin '__weakref__', 135*55a74a43SLisandro Dalcin '__pyx_vtable__', 136*55a74a43SLisandro Dalcin '__enum2str', # FIXME refactor implemetation 137*55a74a43SLisandro Dalcin '_traceback_', # FIXME maybe refactor? 138*55a74a43SLisandro Dalcin '__lt__', 139*55a74a43SLisandro Dalcin '__le__', 140*55a74a43SLisandro Dalcin '__ge__', 141*55a74a43SLisandro Dalcin '__gt__', 142*55a74a43SLisandro Dalcin } 143*55a74a43SLisandro Dalcin special = { 144*55a74a43SLisandro Dalcin '__len__': "__len__(self) -> int", 145*55a74a43SLisandro Dalcin '__bool__': "__bool__(self) -> bool", 146*55a74a43SLisandro Dalcin '__hash__': "__hash__(self) -> int", 147*55a74a43SLisandro Dalcin '__int__': "__int__(self) -> int", 148*55a74a43SLisandro Dalcin '__index__': "__int__(self) -> int", 149*55a74a43SLisandro Dalcin '__str__': "__str__(self) -> str", 150*55a74a43SLisandro Dalcin '__repr__': "__repr__(self) -> str", 151*55a74a43SLisandro Dalcin '__eq__': "__eq__(self, other: object) -> bool", 152*55a74a43SLisandro Dalcin '__ne__': "__ne__(self, other: object) -> bool", 153*55a74a43SLisandro Dalcin } 154*55a74a43SLisandro Dalcin constructor = ( 155*55a74a43SLisandro Dalcin '__new__', 156*55a74a43SLisandro Dalcin '__init__', 157*55a74a43SLisandro Dalcin ) 158*55a74a43SLisandro Dalcin 159*55a74a43SLisandro Dalcin qualname = cls.__name__ 160*55a74a43SLisandro Dalcin cls_name = cls.__name__ 161*55a74a43SLisandro Dalcin if outer is not None and cls_name.startswith(outer): 162*55a74a43SLisandro Dalcin cls_name = cls_name[len(outer):] 163*55a74a43SLisandro Dalcin qualname = f"{outer}.{cls_name}" 164*55a74a43SLisandro Dalcin 165*55a74a43SLisandro Dalcin override = OVERRIDE.get(qualname, {}) 166*55a74a43SLisandro Dalcin done = set() if done is None else done 167*55a74a43SLisandro Dalcin lines = Lines() 168*55a74a43SLisandro Dalcin 169*55a74a43SLisandro Dalcin try: 170*55a74a43SLisandro Dalcin class sub(cls): 171*55a74a43SLisandro Dalcin pass 172*55a74a43SLisandro Dalcin final = False 173*55a74a43SLisandro Dalcin except TypeError: 174*55a74a43SLisandro Dalcin final = True 175*55a74a43SLisandro Dalcin if final: 176*55a74a43SLisandro Dalcin lines.add = "@final" 177*55a74a43SLisandro Dalcin base = cls.__base__ 178*55a74a43SLisandro Dalcin if base is object: 179*55a74a43SLisandro Dalcin lines.add = f"class {cls_name}:" 180*55a74a43SLisandro Dalcin else: 181*55a74a43SLisandro Dalcin lines.add = f"class {cls_name}({base.__name__}):" 182*55a74a43SLisandro Dalcin lines.level += 1 183*55a74a43SLisandro Dalcin start = len(lines) 184*55a74a43SLisandro Dalcin 185*55a74a43SLisandro Dalcin for name in constructor: 186*55a74a43SLisandro Dalcin if name in cls.__dict__: 187*55a74a43SLisandro Dalcin done.add(name) 188*55a74a43SLisandro Dalcin 189*55a74a43SLisandro Dalcin if '__hash__' in cls.__dict__: 190*55a74a43SLisandro Dalcin if cls.__hash__ is None: 191*55a74a43SLisandro Dalcin done.add('__hash__') 192*55a74a43SLisandro Dalcin 193*55a74a43SLisandro Dalcin dct = cls.__dict__ 194*55a74a43SLisandro Dalcin keys = list(dct.keys()) 195*55a74a43SLisandro Dalcin 196*55a74a43SLisandro Dalcin def dunder(name): 197*55a74a43SLisandro Dalcin return name.startswith('__') and name.endswith('__') 198*55a74a43SLisandro Dalcin 199*55a74a43SLisandro Dalcin def members(seq): 200*55a74a43SLisandro Dalcin for name in seq: 201*55a74a43SLisandro Dalcin if name in skip: 202*55a74a43SLisandro Dalcin continue 203*55a74a43SLisandro Dalcin if name in done: 204*55a74a43SLisandro Dalcin continue 205*55a74a43SLisandro Dalcin if dunder(name): 206*55a74a43SLisandro Dalcin if name not in special and name not in override: 207*55a74a43SLisandro Dalcin done.add(name) 208*55a74a43SLisandro Dalcin continue 209*55a74a43SLisandro Dalcin yield name 210*55a74a43SLisandro Dalcin 211*55a74a43SLisandro Dalcin for name in members(keys): 212*55a74a43SLisandro Dalcin attr = getattr(cls, name) 213*55a74a43SLisandro Dalcin if is_class(attr): 214*55a74a43SLisandro Dalcin done.add(name) 215*55a74a43SLisandro Dalcin lines.add = visit_class(attr, outer=cls_name) 216*55a74a43SLisandro Dalcin continue 217*55a74a43SLisandro Dalcin 218*55a74a43SLisandro Dalcin for name in members(keys): 219*55a74a43SLisandro Dalcin 220*55a74a43SLisandro Dalcin if name in override: 221*55a74a43SLisandro Dalcin done.add(name) 222*55a74a43SLisandro Dalcin lines.add = override[name] 223*55a74a43SLisandro Dalcin continue 224*55a74a43SLisandro Dalcin 225*55a74a43SLisandro Dalcin if name in special: 226*55a74a43SLisandro Dalcin done.add(name) 227*55a74a43SLisandro Dalcin sig = special[name] 228*55a74a43SLisandro Dalcin lines.add = f"def {sig}: ..." 229*55a74a43SLisandro Dalcin continue 230*55a74a43SLisandro Dalcin 231*55a74a43SLisandro Dalcin attr = getattr(cls, name) 232*55a74a43SLisandro Dalcin 233*55a74a43SLisandro Dalcin if is_method(attr): 234*55a74a43SLisandro Dalcin done.add(name) 235*55a74a43SLisandro Dalcin if name == attr.__name__: 236*55a74a43SLisandro Dalcin obj = dct[name] 237*55a74a43SLisandro Dalcin if is_classmethod(obj): 238*55a74a43SLisandro Dalcin lines.add = "@classmethod" 239*55a74a43SLisandro Dalcin elif is_staticmethod(obj): 240*55a74a43SLisandro Dalcin lines.add = "@staticmethod" 241*55a74a43SLisandro Dalcin lines.add = visit_method(attr) 242*55a74a43SLisandro Dalcin elif True: 243*55a74a43SLisandro Dalcin lines.add = f"{name} = {attr.__name__}" 244*55a74a43SLisandro Dalcin continue 245*55a74a43SLisandro Dalcin 246*55a74a43SLisandro Dalcin if is_datadescr(attr): 247*55a74a43SLisandro Dalcin done.add(name) 248*55a74a43SLisandro Dalcin lines.add = visit_datadescr(attr) 249*55a74a43SLisandro Dalcin continue 250*55a74a43SLisandro Dalcin 251*55a74a43SLisandro Dalcin if is_property(attr): 252*55a74a43SLisandro Dalcin done.add(name) 253*55a74a43SLisandro Dalcin lines.add = visit_property(attr, name) 254*55a74a43SLisandro Dalcin continue 255*55a74a43SLisandro Dalcin 256*55a74a43SLisandro Dalcin if is_constant(attr): 257*55a74a43SLisandro Dalcin done.add(name) 258*55a74a43SLisandro Dalcin lines.add = visit_constant((name, attr)) 259*55a74a43SLisandro Dalcin continue 260*55a74a43SLisandro Dalcin 261*55a74a43SLisandro Dalcin leftovers = [name for name in keys if 262*55a74a43SLisandro Dalcin name not in done and name not in skip] 263*55a74a43SLisandro Dalcin if leftovers: 264*55a74a43SLisandro Dalcin raise RuntimeError(f"leftovers: {leftovers}") 265*55a74a43SLisandro Dalcin 266*55a74a43SLisandro Dalcin if len(lines) == start: 267*55a74a43SLisandro Dalcin lines.add = "pass" 268*55a74a43SLisandro Dalcin lines.level -= 1 269*55a74a43SLisandro Dalcin return lines 270*55a74a43SLisandro Dalcin 271*55a74a43SLisandro Dalcin 272*55a74a43SLisandro Dalcindef visit_module(module, done=None): 273*55a74a43SLisandro Dalcin skip = { 274*55a74a43SLisandro Dalcin '__doc__', 275*55a74a43SLisandro Dalcin '__name__', 276*55a74a43SLisandro Dalcin '__loader__', 277*55a74a43SLisandro Dalcin '__spec__', 278*55a74a43SLisandro Dalcin '__file__', 279*55a74a43SLisandro Dalcin '__package__', 280*55a74a43SLisandro Dalcin '__builtins__', 281*55a74a43SLisandro Dalcin '__pyx_unpickle_Enum', # FIXME review 282*55a74a43SLisandro Dalcin } 283*55a74a43SLisandro Dalcin 284*55a74a43SLisandro Dalcin done = set() if done is None else done 285*55a74a43SLisandro Dalcin lines = Lines() 286*55a74a43SLisandro Dalcin 287*55a74a43SLisandro Dalcin keys = list(module.__dict__.keys()) 288*55a74a43SLisandro Dalcin keys.sort(key=lambda name: name.startswith("_")) 289*55a74a43SLisandro Dalcin 290*55a74a43SLisandro Dalcin constants = [ 291*55a74a43SLisandro Dalcin (name, getattr(module, name)) for name in keys 292*55a74a43SLisandro Dalcin if all(( 293*55a74a43SLisandro Dalcin name not in done and name not in skip, 294*55a74a43SLisandro Dalcin isinstance(getattr(module, name), int), 295*55a74a43SLisandro Dalcin )) 296*55a74a43SLisandro Dalcin ] 297*55a74a43SLisandro Dalcin for name, value in constants: 298*55a74a43SLisandro Dalcin done.add(name) 299*55a74a43SLisandro Dalcin if name in OVERRIDE: 300*55a74a43SLisandro Dalcin lines.add = OVERRIDE[name] 301*55a74a43SLisandro Dalcin else: 302*55a74a43SLisandro Dalcin lines.add = visit_constant((name, value)) 303*55a74a43SLisandro Dalcin if constants: 304*55a74a43SLisandro Dalcin lines.add = "" 305*55a74a43SLisandro Dalcin 306*55a74a43SLisandro Dalcin for name in keys: 307*55a74a43SLisandro Dalcin if name in done or name in skip: 308*55a74a43SLisandro Dalcin continue 309*55a74a43SLisandro Dalcin value = getattr(module, name) 310*55a74a43SLisandro Dalcin 311*55a74a43SLisandro Dalcin if is_class(value): 312*55a74a43SLisandro Dalcin done.add(name) 313*55a74a43SLisandro Dalcin if value.__module__ != module.__name__: 314*55a74a43SLisandro Dalcin continue 315*55a74a43SLisandro Dalcin lines.add = visit_class(value) 316*55a74a43SLisandro Dalcin lines.add = "" 317*55a74a43SLisandro Dalcin instances = [ 318*55a74a43SLisandro Dalcin (k, getattr(module, k)) for k in keys 319*55a74a43SLisandro Dalcin if all(( 320*55a74a43SLisandro Dalcin k not in done and k not in skip, 321*55a74a43SLisandro Dalcin type(getattr(module, k)) is value, 322*55a74a43SLisandro Dalcin )) 323*55a74a43SLisandro Dalcin ] 324*55a74a43SLisandro Dalcin for attrname, attrvalue in instances: 325*55a74a43SLisandro Dalcin done.add(attrname) 326*55a74a43SLisandro Dalcin lines.add = visit_constant((attrname, attrvalue)) 327*55a74a43SLisandro Dalcin if instances: 328*55a74a43SLisandro Dalcin lines.add = "" 329*55a74a43SLisandro Dalcin continue 330*55a74a43SLisandro Dalcin 331*55a74a43SLisandro Dalcin if is_function(value): 332*55a74a43SLisandro Dalcin done.add(name) 333*55a74a43SLisandro Dalcin if name == value.__name__: 334*55a74a43SLisandro Dalcin lines.add = visit_function(value) 335*55a74a43SLisandro Dalcin else: 336*55a74a43SLisandro Dalcin lines.add = f"{name} = {value.__name__}" 337*55a74a43SLisandro Dalcin continue 338*55a74a43SLisandro Dalcin 339*55a74a43SLisandro Dalcin lines.add = "" 340*55a74a43SLisandro Dalcin for name in keys: 341*55a74a43SLisandro Dalcin if name in done or name in skip: 342*55a74a43SLisandro Dalcin continue 343*55a74a43SLisandro Dalcin value = getattr(module, name) 344*55a74a43SLisandro Dalcin done.add(name) 345*55a74a43SLisandro Dalcin if name in OVERRIDE: 346*55a74a43SLisandro Dalcin lines.add = OVERRIDE[name] 347*55a74a43SLisandro Dalcin else: 348*55a74a43SLisandro Dalcin lines.add = visit_constant((name, value)) 349*55a74a43SLisandro Dalcin 350*55a74a43SLisandro Dalcin leftovers = [name for name in keys if 351*55a74a43SLisandro Dalcin name not in done and name not in skip] 352*55a74a43SLisandro Dalcin if leftovers: 353*55a74a43SLisandro Dalcin raise RuntimeError(f"leftovers: {leftovers}") 354*55a74a43SLisandro Dalcin return lines 355*55a74a43SLisandro Dalcin 356*55a74a43SLisandro Dalcin 357*55a74a43SLisandro DalcinIMPORTS = """ 358*55a74a43SLisandro Dalcinfrom __future__ import annotations 359*55a74a43SLisandro Dalcinimport sys 360*55a74a43SLisandro Dalcinfrom threading import Lock 361*55a74a43SLisandro Dalcinfrom typing import ( 362*55a74a43SLisandro Dalcin Any, 363*55a74a43SLisandro Dalcin Union, 364*55a74a43SLisandro Dalcin Optional, 365*55a74a43SLisandro Dalcin NoReturn, 366*55a74a43SLisandro Dalcin overload, 367*55a74a43SLisandro Dalcin) 368*55a74a43SLisandro Dalcinif sys.version_info >= (3, 8): 369*55a74a43SLisandro Dalcin from typing import ( 370*55a74a43SLisandro Dalcin final, 371*55a74a43SLisandro Dalcin Final, 372*55a74a43SLisandro Dalcin Literal, 373*55a74a43SLisandro Dalcin ) 374*55a74a43SLisandro Dalcinelse: 375*55a74a43SLisandro Dalcin from typing_extensions import ( 376*55a74a43SLisandro Dalcin final, 377*55a74a43SLisandro Dalcin Final, 378*55a74a43SLisandro Dalcin Literal, 379*55a74a43SLisandro Dalcin ) 380*55a74a43SLisandro Dalcinif sys.version_info >= (3, 9): 381*55a74a43SLisandro Dalcin from collections.abc import ( 382*55a74a43SLisandro Dalcin Callable, 383*55a74a43SLisandro Dalcin Hashable, 384*55a74a43SLisandro Dalcin Iterable, 385*55a74a43SLisandro Dalcin Iterator, 386*55a74a43SLisandro Dalcin Sequence, 387*55a74a43SLisandro Dalcin Mapping, 388*55a74a43SLisandro Dalcin ) 389*55a74a43SLisandro Dalcinelse: 390*55a74a43SLisandro Dalcin from typing import ( 391*55a74a43SLisandro Dalcin Callable, 392*55a74a43SLisandro Dalcin Hashable, 393*55a74a43SLisandro Dalcin Iterable, 394*55a74a43SLisandro Dalcin Iterator, 395*55a74a43SLisandro Dalcin Sequence, 396*55a74a43SLisandro Dalcin Mapping, 397*55a74a43SLisandro Dalcin ) 398*55a74a43SLisandro Dalcinif sys.version_info >= (3, 11): 399*55a74a43SLisandro Dalcin from typing import Self 400*55a74a43SLisandro Dalcinelse: 401*55a74a43SLisandro Dalcin from typing_extensions import Self 402*55a74a43SLisandro Dalcinfrom os import PathLike 403*55a74a43SLisandro Dalcin 404*55a74a43SLisandro Dalcinimport numpy 405*55a74a43SLisandro Dalcin 406*55a74a43SLisandro DalcinIntType: numpy.dtype = ... 407*55a74a43SLisandro DalcinRealType: numpy.dtype = ... 408*55a74a43SLisandro DalcinComplexType: numpy.dtype = ... 409*55a74a43SLisandro DalcinScalarType: numpy.dtype = ... 410*55a74a43SLisandro Dalcin""" 411*55a74a43SLisandro Dalcin 412*55a74a43SLisandro DalcinOVERRIDE = { 413*55a74a43SLisandro Dalcin 'Error': { 414*55a74a43SLisandro Dalcin }, 415*55a74a43SLisandro Dalcin '__pyx_capi__': "__pyx_capi__: Final[Dict[str, Any]] = ...", 416*55a74a43SLisandro Dalcin '__type_registry__': "__type_registry__: Final[Dict[int, type[Object]]] = ...", 417*55a74a43SLisandro Dalcin} 418*55a74a43SLisandro Dalcin 419*55a74a43SLisandro DalcinTYPING = """ 420*55a74a43SLisandro Dalcin""" 421*55a74a43SLisandro Dalcin 422*55a74a43SLisandro Dalcin 423*55a74a43SLisandro Dalcindef visit_petsc4py_PETSc(done=None): 424*55a74a43SLisandro Dalcin from petsc4py import PETSc as module 425*55a74a43SLisandro Dalcin lines = Lines() 426*55a74a43SLisandro Dalcin lines.add = IMPORTS 427*55a74a43SLisandro Dalcin lines.add = "" 428*55a74a43SLisandro Dalcin lines.add = visit_module(module) 429*55a74a43SLisandro Dalcin lines.add = TYPING 430*55a74a43SLisandro Dalcin return lines 431*55a74a43SLisandro Dalcin 432*55a74a43SLisandro Dalcin 433*55a74a43SLisandro Dalcindef generate(filename): 434*55a74a43SLisandro Dalcin dirname = os.path.dirname(filename) 435*55a74a43SLisandro Dalcin os.makedirs(dirname, exist_ok=True) 436*55a74a43SLisandro Dalcin with open(filename, 'w') as f: 437*55a74a43SLisandro Dalcin for line in visit_petsc4py_PETSc(): 438*55a74a43SLisandro Dalcin print(line, file=f) 439*55a74a43SLisandro Dalcin 440*55a74a43SLisandro Dalcin 441*55a74a43SLisandro DalcinOUTDIR = os.path.join('src', 'petsc4py') 442*55a74a43SLisandro Dalcin 443*55a74a43SLisandro Dalcinif __name__ == '__main__': 444*55a74a43SLisandro Dalcin generate(os.path.join(OUTDIR, 'PETSc.pyi')) 445