diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 07f10b61..40d83bbc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -83,15 +83,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Setup Alpine Linux v3.15 for aarch64 + - name: Setup Alpine Linux for aarch64 uses: jirutka/setup-alpine@v1 with: arch: x86 packages: gcc g++ make cmake libc-dev linux-headers python3 - branch: v3.15 - name: Build and Test run: | - ln -s /usr/bin/python3 /usr/bin/python uname -m python cmake_build.py python scripts/run_tests.py diff --git a/include/pocketpy/cffi.h b/include/pocketpy/cffi.h index 8cdd0598..d607ae4c 100644 --- a/include/pocketpy/cffi.h +++ b/include/pocketpy/cffi.h @@ -8,17 +8,9 @@ namespace pkpy { #define PY_CLASS(T, mod, name) \ static Type _type(VM* vm) { return vm->_cxx_typeid_map[&typeid(T)]; } \ - static void _check_type(VM* vm, PyObject* val){ \ - if(!vm->isinstance(val, T::_type(vm))){ \ - vm->TypeError("expected '" #mod "." #name "', got " + _type_name(vm, vm->_tp(val)).escape()); \ - } \ - } \ static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \ std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \ - if(mod_name != #mod) { \ - Str msg = _S("register_class() failed: ", mod_name, " != ", #mod); \ - throw std::runtime_error(msg.str()); \ - } \ + if(mod_name != #mod) throw std::runtime_error(_S("register_class() failed: ", mod_name, " != ", #mod).str()); \ PyObject* type = vm->new_type_object(mod, #name, base); \ mod->attr().set(#name, type); \ vm->_cxx_typeid_map[&typeid(T)] = PK_OBJ_GET(Type, type); \ diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 0b6b89c4..bc8ce73b 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -354,6 +354,11 @@ public: TypeError("expected " + _type_name(vm, type).escape() + ", got " + _type_name(vm, _tp(obj)).escape()); } + void check_compatible_type(PyObject* obj, Type type){ + if(isinstance(obj, type)) return; + TypeError(_S(_type_name(vm, _tp(obj)).escape(), " is not compatible with ", _type_name(vm, type).escape())); + } + PyObject* _t(Type t){ return _all_types[t.index].obj; } @@ -371,7 +376,10 @@ public: struct ImportContext{ std::vector pending; pod_vector pending_is_init; // a.k.a __init__.py + struct Temp{ + PK_ALWAYS_PASS_BY_POINTER(Temp) + ImportContext* ctx; Temp(ImportContext* ctx, Str name, bool is_init) : ctx(ctx){ ctx->pending.push_back(name); @@ -436,7 +444,7 @@ public: #elif _MSC_VER throw std::runtime_error(__FUNCSIG__ + std::string(" failed: T not found")); #else - throw std::runtime_error("py_var() failed: T not found"); + throw std::runtime_error("_find_type_in_cxx_typeid_map() failed: T not found"); #endif } return it->second; @@ -556,7 +564,7 @@ __T _py_cast__internal(VM* vm, PyObject* obj) { } } Type type = vm->_find_type_in_cxx_typeid_map(); - if constexpr(with_check) vm->check_non_tagged_type(obj, type); + if constexpr(with_check) vm->check_compatible_type(obj, type); return PK_OBJ_GET(T, obj); }