You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IronPython3宿主继承.NET类时抛出TypeErrorException元类冲突问题

问题:IronPython继承C#类型时触发元类冲突错误

定义的C#类型

[PythonType]
public class ScriptBase
{
    public virtual int TestMe()
    {
        return 11;
    }
}

IronPython继承代码

from Base import ScriptBase

class TestClass (ScriptBase):
    pass

抛出的错误

TypeErrorException: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

C#引擎初始化与类型注册代码

// 测试执行代码
ScriptEngine _engine = Python.CreateEngine();

// 创建基础模块
ScriptScope _gameScope = _engine.CreateModule("Base");

// 在模块中暴露ScriptBase类
_gameScope.SetVariable(nameof(ScriptBase), typeof(ScriptBase));

// 通过包装器从文件流加载源码并编译
ScriptSource source = engine.CreateScriptSource(new CodeProvider(inStream), package, Encoding.ASCII, SourceCodeKind.Statements);
CompiledCode compiled = source.Compile();

// 为继承类创建新模块
_scope = engine.CreateModule(package);

// 执行代码——此行抛出异常
compiled.Execute(_scope);

补充信息

  • 已尝试导入CLR、定义__init__和__new__,均无效
  • 使用.CreateModule可正常实例化和管理现有类型,仅继承操作出错
  • 运行环境:Mono,目标框架.Net 4.x

完整调用栈

TypeErrorException: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
IronPython.Runtime.Types.PythonType.FindMetaClass (IronPython.Runtime.Types.PythonType cls, IronPython.Runtime.PythonTuple bases) (at <57a5bd653356491bba8a61ecf9211193>:0)
IronPython.Runtime.Operations.PythonOps.MakeClass (IronPython.Runtime.FunctionCode funcCode, System.Func`2[T,TResult] body, IronPython.Runtime.CodeContext parentContext, System.String name, IronPython.Runtime.PythonTuple bases, IronPython.Runtime.PythonDictionary keywords, System.String selfNames) (at <57a5bd653356491bba8a61ecf9211193>:0)
Microsoft.Scripting.Interpreter.FuncCallInstruction`8[T0,T1,T2,T3,T4,T5,T6,TRet].Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) (at <9784853821ea47dbb6bb1f3e03091049>:0)
Microsoft.Scripting.Interpreter.Interpreter.Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) (at <9784853821ea47dbb6bb1f3e03091049>:0)
Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet] (T0 arg0, T1 arg1) (at <9784853821ea47dbb6bb1f3e03091049>:0)
IronPython.Compiler.PythonScriptCode.RunWorker (IronPython.Runtime.CodeContext ctx) (at <57a5bd653356491bba8a61ecf9211193>:0)
IronPython.Compiler.PythonScriptCode.Run (Microsoft.Scripting.Runtime.Scope scope) (at <57a5bd653356491bba8a61ecf9211193>:0)
IronPython.Compiler.RuntimeScriptCode.InvokeTarget (Microsoft.Scripting.Runtime.Scope scope) (at <57a5bd653356491bba8a61ecf9211193>:0)
IronPython.Compiler.RuntimeScriptCode.Run (Microsoft.Scripting.Runtime.Scope scope) (at <57a5bd653356491bba8a61ecf9211193>:0)
Microsoft.Scripting.Hosting.CompiledCode.Execute (Microsoft.Scripting.Hosting.ScriptScope scope) (at <0d164baeace648b2930cfd25249cf9f3>:0)
(wrapper remoting-invoke-with-check) Microsoft.Scripting.Hosting.CompiledCode.Execute(Microsoft.Scripting.Hosting.ScriptScope)

解决方案

错误核心原因:直接将C#的Type对象暴露给IronPython,未经过IronPython的类型包装,导致原生CLR类型的元类与IronPython类的元类不兼容,无法满足继承的元类规则。

修复方式一:包装C#类型后再注册

修改C#中注册类型的代码,用IronPython的ClrModule.GetPythonType方法将原生C#类型包装为IronPython可识别的继承类型:

// 替换原来的SetVariable行
var wrappedType = IronPython.Runtime.ClrModule.GetPythonType(_engine, typeof(ScriptBase));
_gameScope.SetVariable(nameof(ScriptBase), wrappedType);

修复方式二:在Python脚本中直接导入CLR类型

如果允许,可通过IronPython的clr模块直接导入C#程序集,无需手动注册类型,IronPython会自动处理包装:

import clr
clr.AddReference("你的C#程序集名称")
from 你的命名空间 import ScriptBase

class TestClass(ScriptBase):
    pass

原理说明

直接传递typeof(ScriptBase)时,IronPython仅将其视为外部CLR类型,而非可继承的Python类型。经过GetPythonType包装后的类型会携带IronPython类的元类,才能让Python子类正确继承。


内容的提问来源于stack exchange,提问作者noisy cat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 18:28:17