[Script] Fixed export function to work with Optional (requires python 3.8+)

This commit is contained in:
Ferdinand Thiessen 2020-11-11 23:56:07 +01:00
parent 824ffc8675
commit 7074c29d63
2 changed files with 29 additions and 9 deletions

View File

View File

@ -1,43 +1,63 @@
#!/usr/bin/python3 #!/usr/bin/python3
import inspect import inspect
import argparse import argparse
import sys
import pkg_resources import pkg_resources
class InterfaceGenerator: class InterfaceGenerator:
known = [] known = []
classes = {} classes = {}
mapper = {"str": "string", "int": "number", "float": "number", "datetime": "Date"} mapper = {"str": "string", "int": "number", "float": "number", "datetime": "Date", "NoneType": "null"}
def __init__(self, namespace, filename): def __init__(self, namespace, filename):
self.basename = "" self.basename = ""
self.namespace = namespace self.namespace = namespace
self.filename = filename self.filename = filename
self.this_type = None
def pytype(self, cls): def pytype(self, cls):
if isinstance(cls, list): if isinstance(cls, list):
return "", "Array<{}>".format(self.pytype(cls[0])[1]) return "", "Array<{}>".format(self.pytype(cls[0])[1])
# if typing.get_origin(cls) is typing.Optional: if sys.version_info >= (3, 8):
# return "?", pytype(typing.get_args(cls)[1]) import typing
if isinstance(cls, typing.ForwardRef):
return "", "this" if cls.__forward_arg__ == self.this_type else cls.__forward_arg__
if typing.get_origin(cls) == typing.Union:
types = typing.get_args(cls)
if len(types) == 2 and types[-1] is type(None):
return "?", self.pytype(types[0])[1]
else:
return "", "|".join([self.pytype(pt)[1] for pt in types])
if hasattr(cls, "__name__"): if hasattr(cls, "__name__"):
if cls.__name__ in self.mapper: if cls.__name__ in self.mapper:
return "", self.mapper[cls.__name__] return "", self.mapper[cls.__name__]
else: else:
return "", cls.__name__ return "", cls.__name__
print(
"WARNING: This python version might not detect all types (try >= 3.8). Could not identify >{}<".format(cls)
)
return "?", "any" return "?", "any"
def walker(self, module): def walker(self, module):
if inspect.ismodule(module[1]) and module[1].__name__.startswith(self.basename) and module[1].__name__ not in self.known: if (
inspect.ismodule(module[1])
and module[1].__name__.startswith(self.basename)
and module[1].__name__ not in self.known
):
self.known.append(module[1].__name__) self.known.append(module[1].__name__)
for cls in inspect.getmembers(module[1], lambda x: inspect.isclass(x) or inspect.ismodule(x)): for cls in inspect.getmembers(module[1], lambda x: inspect.isclass(x) or inspect.ismodule(x)):
self.walker(cls) self.walker(cls)
elif ( elif (
inspect.isclass(module[1]) inspect.isclass(module[1])
and module[1].__module__.startswith(self.basename) and module[1].__module__.startswith(self.basename)
and module[0] not in self.classes and module[0] not in self.classes
and not module[0].startswith("_") and not module[0].startswith("_")
and hasattr(module[1], "__annotations__") and hasattr(module[1], "__annotations__")
): ):
self.this_type = module[0]
d = { d = {
param: self.pytype(ptype) param: self.pytype(ptype)
for param, ptype in module[1].__annotations__.items() for param, ptype in module[1].__annotations__.items()