mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
Move all reflection logic inside helper module
This commit is contained in:
@@ -1,14 +1,40 @@
|
||||
import typing
|
||||
import inspect
|
||||
import collections
|
||||
import importlib
|
||||
from types import ModuleType
|
||||
|
||||
def extract_docs(
|
||||
module: ModuleType,
|
||||
submodule_name: str,
|
||||
cls_name: str,
|
||||
method_name: str,
|
||||
boilerplate_args : typing.Iterable[str]=None):
|
||||
"""Extract class docstrings and method arguments
|
||||
|
||||
:param module: Parent module from which to extract the submodule class
|
||||
:param submodule_name: Submodule from which to extract the class
|
||||
:param cls_name: Class from which to extract the docstring and method arguments
|
||||
:param method_name: Class Method name from which to extract arguments
|
||||
:param boilerplate_args: String iterable containing arguments that shall not be parsed
|
||||
"""
|
||||
spec = importlib.util.spec_from_file_location(submodule_name, f"{module.__path__[0]}/recipes/{submodule_name}.py")
|
||||
submodule = importlib.util.module_from_spec(spec)
|
||||
try:
|
||||
spec.loader.exec_module(submodule)
|
||||
try:
|
||||
return _extract_docs(getattr(submodule, cls_name), method_name, boilerplate_args)
|
||||
except AttributeError as e:
|
||||
print(e)
|
||||
except ModuleNotFoundError as e:
|
||||
print("Error : " + str(e) + "in " + str(submodule))
|
||||
|
||||
def extract_docs(patcher, boilerplate_args=None):
|
||||
def _extract_docs(cls, method_name, boilerplate_args):
|
||||
inputs = collections.OrderedDict()
|
||||
function_init = patcher.__init__
|
||||
node_data = {"patcher": patcher}
|
||||
method = getattr(cls, method_name)
|
||||
node_data = {"class": cls}
|
||||
|
||||
signature = inspect.signature(function_init)
|
||||
signature = inspect.signature(method)
|
||||
for name, parameter in signature.parameters.items():
|
||||
if name == "self":
|
||||
continue
|
||||
@@ -16,7 +42,7 @@ def extract_docs(patcher, boilerplate_args=None):
|
||||
if isinstance(parameter.default, (str, float, int, bool)):
|
||||
inputs[name]["default"] = parameter.default
|
||||
|
||||
type_hints = typing.get_type_hints(function_init)
|
||||
type_hints = typing.get_type_hints(method)
|
||||
for name, socket_data in inputs.items():
|
||||
type_hint = type_hints.get(name, None)
|
||||
if type_hint is None: # The argument is not type-hinted. (Or hinted to None ??)
|
||||
@@ -27,7 +53,7 @@ def extract_docs(patcher, boilerplate_args=None):
|
||||
inputs[name]["type"] = type_hint.__name__
|
||||
|
||||
description = ""
|
||||
doc = function_init.__doc__
|
||||
doc = method.__doc__
|
||||
if doc is not None:
|
||||
for i, line in enumerate(doc.split("\n")):
|
||||
line = line.strip()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import bpy
|
||||
import json
|
||||
import ifcpatch
|
||||
from .helper import extract_docs
|
||||
|
||||
|
||||
@@ -47,7 +48,7 @@ class ExecuteIfcPatch(bpy.types.Operator):
|
||||
return os.path.isfile(input_file) and "ifc" in os.path.splitext(input_file)[1]
|
||||
|
||||
def execute(self, context):
|
||||
import ifcpatch
|
||||
|
||||
|
||||
ifcpatch.execute(
|
||||
{
|
||||
@@ -73,37 +74,22 @@ class PopulatePatchArguments(bpy.types.Operator):
|
||||
recipe: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
import importlib
|
||||
import ifcpatch
|
||||
|
||||
patch_args = context.scene.BIMPatchProperties.ifc_patch_args_attr
|
||||
patch_args.clear()
|
||||
recipe = self.recipe
|
||||
spec = importlib.util.spec_from_file_location(recipe, f"{ifcpatch.__path__[0]}/recipes/{recipe}.py")
|
||||
patcher = importlib.util.module_from_spec(spec)
|
||||
try:
|
||||
spec.loader.exec_module(patcher)
|
||||
try:
|
||||
docs = extract_docs(patcher.Patcher, boilerplate_args=("src", "file", "logger", "args"))
|
||||
if "inputs" in docs:
|
||||
for arg_name in docs["inputs"]:
|
||||
arg_info = docs["inputs"][arg_name]
|
||||
new_attr = patch_args.add()
|
||||
new_attr.data_type = self.TYPE_BINDINGS[arg_info["type"]]
|
||||
new_attr.name = arg_name
|
||||
if new_attr.data_type == "string":
|
||||
new_attr.string_value = arg_info.get("default", "")
|
||||
elif new_attr.data_type == "float":
|
||||
new_attr.float_value = arg_info.get("default", 0)
|
||||
elif new_attr.data_type == "integer":
|
||||
new_attr.int_value = arg_info.get("default", 0)
|
||||
elif new_attr.data_type == "boolean":
|
||||
new_attr.bool_value = arg_info.get("default", False)
|
||||
|
||||
new_attr.description =arg_info.get("description", "")
|
||||
|
||||
except AttributeError as e:
|
||||
print(e)
|
||||
except ModuleNotFoundError as e:
|
||||
print("Error : " + str(e) + "in " + str(patcher))
|
||||
docs = extract_docs(ifcpatch, self.recipe, "Patcher", "__init__", ("src", "file", "logger", "args"))
|
||||
if "inputs" in docs:
|
||||
for arg_name in docs["inputs"]:
|
||||
arg_info = docs["inputs"][arg_name]
|
||||
new_attr = patch_args.add()
|
||||
new_attr.data_type = self.TYPE_BINDINGS[arg_info["type"]]
|
||||
new_attr.name = arg_name
|
||||
if new_attr.data_type == "string":
|
||||
new_attr.string_value = arg_info.get("default", "")
|
||||
elif new_attr.data_type == "float":
|
||||
new_attr.float_value = arg_info.get("default", 0)
|
||||
elif new_attr.data_type == "integer":
|
||||
new_attr.int_value = arg_info.get("default", 0)
|
||||
elif new_attr.data_type == "boolean":
|
||||
new_attr.bool_value = arg_info.get("default", False)
|
||||
new_attr.description = arg_info.get("description", "")
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -26,15 +26,7 @@ class BIM_PT_patch(bpy.types.Panel):
|
||||
|
||||
recipe = props.ifc_patch_recipes
|
||||
|
||||
spec = importlib.util.spec_from_file_location(recipe, f"{ifcpatch.__path__[0]}/recipes/{recipe}.py")
|
||||
patcher = importlib.util.module_from_spec(spec)
|
||||
try:
|
||||
spec.loader.exec_module(patcher)
|
||||
try:
|
||||
docs = extract_docs(patcher.Patcher, boilerplate_args=("src", "file", "logger", "args"))
|
||||
if "name" in docs:
|
||||
layout.label(text=docs["name"])
|
||||
if "description" in docs:
|
||||
docs = extract_docs(ifcpatch, recipe, "Patcher", "__init__", ("src", "file", "logger", "args"))
|
||||
for line in docs["description"].split("\n"):
|
||||
layout.label(text=line)
|
||||
except AttributeError as e:
|
||||
|
||||
Reference in New Issue
Block a user