def select_constant(context, expr) -> Object: from machaon.core.importer import attribute_loader loader = attribute_loader(expr) if not loader: raise BadExpressionError("bad import expression") attr = loader() if (callable(attr)): value = attr() else: value = attr return value_to_obj(context, value)
def pyvalue(self, symbol, _app): """ @task 外部モジュールの変数あるいは引数無し関数呼び出しとして評価する。 Returns: Any: """ from machaon.core.importer import attribute_loader loader = attribute_loader(symbol) imported = loader(fallback=False) if not callable(imported): return imported # 変数 else: return imported() # 関数実行
def constructor(self, context, value): """ @meta Params: Str: 型名 / クラスの完全な名前(qualname) """ if isinstance(value, str): if "." in value: from machaon.core.importer import attribute_loader d = TypeDefinition(attribute_loader(value)) if not d.load_declaration_docstring(): raise BadTypeDeclaration() return d.define(context.type_module) # 即座にロードする else: return context.select_type(value) else: raise TypeError("value")
def pyinvoke(self, selfarg, context, symbol, *args): """ @method reciever-param context 外部モジュールの関数を評価する。 Params: selfarg(Object): 引数1 symbol(str): シンボル *args(Any): 引数 Returns: Any: """ from machaon.core.importer import attribute_loader loader = attribute_loader(symbol) imported = loader(fallback=False) if not callable(imported): raise ValueError("'{}'は呼び出し可能な関数ではありません".format(symbol)) return imported(selfarg.value, *args) # 関数実行
def load(self, this_type): """ 実装をロードする。 """ if self.flags & METHOD_LOADED: return if self.target is None: self.target = normalize_method_target(self.name) # 実装コードを読み込む from machaon.core.importer import attribute_loader action = None source = None while True: callobj = None if self.target.startswith("."): # 外部モジュールから定義をロードする loader = attribute_loader(self.target) callobj = loader() # モジュールやメンバが見つからなければ例外が投げられる source = self.target else: # クラスに定義されたメソッドが実装となる typefn = this_type.delegate_method(self.target) if typefn is not None: callobj = typefn source = "{}:{}".format(this_type.get_scoped_typename(), self.name) if this_type.is_methods_type_bound(): self.flags |= METHOD_TYPE_BOUND # 第1引数は型オブジェクト、第2引数はインスタンスを渡す # アクションオブジェクトの初期化処理 if hasattr(callobj, "describe_method"): # アクションに定義されたメソッド定義処理があれば実行 callobj.describe_method(self) elif hasattr(callobj, "__doc__") and callobj.__doc__ is not None: # callobjのdocstringsを解析する self.parse_syntax_from_docstring(callobj.__doc__, callobj) else: raise BadMethodDeclaration( "メソッド定義がありません。メソッド 'describe_method' かドキュメント文字列で記述してください") if isinstance(callobj, type): callobj = callobj() if callobj is not None and callable(callobj): action = callobj break raise ValueError("無効なアクションです:{}".format(self.target)) # 返り値が無い場合はレシーバ自身を返す if not self.result: self.add_result_self(this_type) if self.flags & METHOD_UNSPECIFIED_MASK: self._action = None else: self._action = action self.target = source self.flags |= METHOD_LOADED