diff --git a/backend/JavaScriptCore/JscUtils.cc b/backend/JavaScriptCore/JscUtils.cc
index bfa30a8c..f2fc0e78 100644
--- a/backend/JavaScriptCore/JscUtils.cc
+++ b/backend/JavaScriptCore/JscUtils.cc
@@ -73,7 +73,7 @@ std::string_view StringHolder::stringView() const {
 std::string StringHolder::string() const {
   jsc_backend::initString(internalHolder_);
   internalHolder_.inited = false;
-  return std::move(internalHolder_.stringContent);
+  return internalHolder_.stringContent;
 }
 
 #if defined(__cpp_char8_t)
diff --git a/backend/Python/CMakeLists.txt b/backend/Python/CMakeLists.txt
index 6d96b276..161c361c 100644
--- a/backend/Python/CMakeLists.txt
+++ b/backend/Python/CMakeLists.txt
@@ -1 +1,16 @@
-message(FATAL_ERROR "${SCRIPTX_BACKEND} is to be implemented.")
+target_sources(ScriptX PRIVATE
+        ${CMAKE_CURRENT_LIST_DIR}/PyEngine.cc
+        ${CMAKE_CURRENT_LIST_DIR}/PyEngine.h
+        ${CMAKE_CURRENT_LIST_DIR}/PyException.cc
+        ${CMAKE_CURRENT_LIST_DIR}/PyHelper.h
+        ${CMAKE_CURRENT_LIST_DIR}/PyHelper.hpp
+        ${CMAKE_CURRENT_LIST_DIR}/PyHelper.cc
+        ${CMAKE_CURRENT_LIST_DIR}/PyLocalReference.cc
+        ${CMAKE_CURRENT_LIST_DIR}/PyNative.cc
+        ${CMAKE_CURRENT_LIST_DIR}/PyNative.hpp
+        ${CMAKE_CURRENT_LIST_DIR}/PyReference.hpp
+        ${CMAKE_CURRENT_LIST_DIR}/PyScope.h
+        ${CMAKE_CURRENT_LIST_DIR}/PyScope.cc
+        ${CMAKE_CURRENT_LIST_DIR}/PyUtils.cc
+        ${CMAKE_CURRENT_LIST_DIR}/PyValue.cc
+        )
\ No newline at end of file
diff --git a/backend/Python/PyEngine.cc b/backend/Python/PyEngine.cc
new file mode 100644
index 00000000..2d3c2dea
--- /dev/null
+++ b/backend/Python/PyEngine.cc
@@ -0,0 +1,60 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PyEngine.h"
+#include "../../src/Utils.h"
+
+namespace script::py_backend {
+
+PyEngine::PyEngine(std::shared_ptr<utils::MessageQueue> queue)
+    : queue_(queue ? std::move(queue) : std::make_shared<utils::MessageQueue>()) {
+  Py_Initialize();
+}
+
+PyEngine::PyEngine() : PyEngine(nullptr) {}
+
+PyEngine::~PyEngine() = default;
+
+void PyEngine::destroy() noexcept { ScriptEngine::destroyUserData(); }
+
+Local<Value> PyEngine::get(const Local<String>& key) { return Local<Value>(); }
+
+void PyEngine::set(const Local<String>& key, const Local<Value>& value) {}
+
+Local<Value> PyEngine::eval(const Local<String>& script) { return eval(script, Local<Value>()); }
+
+Local<Value> PyEngine::eval(const Local<String>& script, const Local<String>& sourceFile) {
+  return eval(script, sourceFile.asValue());
+}
+
+Local<Value> PyEngine::eval(const Local<String>& script, const Local<Value>& sourceFile) {
+  return Local<Value>();
+}
+
+std::shared_ptr<utils::MessageQueue> PyEngine::messageQueue() { return queue_; }
+
+void PyEngine::gc() {}
+
+void PyEngine::adjustAssociatedMemory(int64_t count) {}
+
+ScriptLanguage PyEngine::getLanguageType() { return ScriptLanguage::kPython; }
+
+std::string PyEngine::getEngineVersion() { return Py_GetVersion(); }
+
+bool PyEngine::isDestroying() const { return false; }
+
+}  // namespace script::py_backend
diff --git a/backend/Python/PyEngine.h b/backend/Python/PyEngine.h
new file mode 100644
index 00000000..e1c57249
--- /dev/null
+++ b/backend/Python/PyEngine.h
@@ -0,0 +1,118 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../../src/Engine.h"
+#include "../../src/Exception.h"
+#include "../../src/utils/MessageQueue.h"
+#include "PyHelper.h"
+
+namespace script::py_backend {
+
+class PyEngine : public ScriptEngine {
+ private:
+  std::shared_ptr<::script::utils::MessageQueue> queue_;
+
+ public:
+  PyEngine(std::shared_ptr<::script::utils::MessageQueue> queue);
+
+  PyEngine();
+
+  SCRIPTX_DISALLOW_COPY_AND_MOVE(PyEngine);
+
+  void destroy() noexcept override;
+
+  bool isDestroying() const override;
+
+  Local<Value> get(const Local<String>& key) override;
+
+  void set(const Local<String>& key, const Local<Value>& value) override;
+  using ScriptEngine::set;
+
+  Local<Value> eval(const Local<String>& script, const Local<Value>& sourceFile);
+  Local<Value> eval(const Local<String>& script, const Local<String>& sourceFile) override;
+  Local<Value> eval(const Local<String>& script) override;
+  using ScriptEngine::eval;
+
+  std::shared_ptr<utils::MessageQueue> messageQueue() override;
+
+  void gc() override;
+
+  void adjustAssociatedMemory(int64_t count) override;
+
+  ScriptLanguage getLanguageType() override;
+
+  std::string getEngineVersion() override;
+
+ protected:
+  ~PyEngine() override;
+
+ private:
+  template <typename T>
+  bool registerNativeClassImpl(const ClassDefine<T>* classDefine) {
+    return false;
+  }
+
+  Local<Object> getNamespaceForRegister(const std::string_view& nameSpace) {
+    TEMPLATE_NOT_IMPLEMENTED();
+  }
+
+  template <typename T>
+  Local<Object> newNativeClassImpl(const ClassDefine<T>* classDefine, size_t size,
+                                   const Local<Value>* args) {
+    TEMPLATE_NOT_IMPLEMENTED();
+  }
+
+  template <typename T>
+  bool isInstanceOfImpl(const Local<Value>& value, const ClassDefine<T>* classDefine) {
+    return false;
+  }
+
+  template <typename T>
+  T* getNativeInstanceImpl(const Local<Value>& value, const ClassDefine<T>* classDefine) {
+    return nullptr;
+  }
+
+ private:
+  template <typename T>
+  friend class ::script::Local;
+
+  template <typename T>
+  friend class ::script::Global;
+
+  template <typename T>
+  friend class ::script::Weak;
+
+  friend class ::script::Object;
+
+  friend class ::script::Array;
+
+  friend class ::script::Function;
+
+  friend class ::script::ByteBuffer;
+
+  friend class ::script::ScriptEngine;
+
+  friend class ::script::Exception;
+
+  friend class ::script::Arguments;
+
+  friend class ::script::ScriptClass;
+};
+
+}  // namespace script::py_backend
\ No newline at end of file
diff --git a/backend/Python/PyException.cc b/backend/Python/PyException.cc
new file mode 100644
index 00000000..871a0f3c
--- /dev/null
+++ b/backend/Python/PyException.cc
@@ -0,0 +1,40 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ScriptX/ScriptX.h>
+
+namespace script {
+
+Exception::Exception(std::string msg) : std::exception(), exception_({}) {
+  exception_.message_ = std::move(msg);
+}
+
+Exception::Exception(const script::Local<script::String>& message)
+    : std::exception(), exception_() {}
+
+Exception::Exception(const script::Local<script::Value>& exception)
+    : std::exception(), exception_({}) {}
+
+Local<Value> Exception::exception() const { return {}; }
+
+std::string Exception::message() const noexcept { return exception_.message_; }
+
+std::string Exception::stacktrace() const noexcept { return "[no stacktrace]"; }
+
+const char* Exception::what() const noexcept { return exception_.message_.c_str(); }
+
+}  // namespace script
diff --git a/backend/Python/PyHelper.cc b/backend/Python/PyHelper.cc
new file mode 100644
index 00000000..ced86204
--- /dev/null
+++ b/backend/Python/PyHelper.cc
@@ -0,0 +1,40 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PyHelper.hpp"
+
+namespace script::py_backend {
+
+PyObject* checkException(PyObject* obj) {
+  if (!obj) {
+    checkException();
+  }
+  return obj;
+}
+
+void checkException() {
+  auto err = PyErr_Occurred();
+  if (err) {
+    // TODO
+  }
+}
+
+void rethrowException(const Exception& exception) {
+  // TODO
+}
+
+}  // namespace script::py_backend
\ No newline at end of file
diff --git a/backend/Python/PyHelper.h b/backend/Python/PyHelper.h
new file mode 100644
index 00000000..fb9b5d81
--- /dev/null
+++ b/backend/Python/PyHelper.h
@@ -0,0 +1,43 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../../src/foundation.h"
+
+// docs:
+// https://docs.python.org/3/c-api/index.html
+// https://docs.python.org/3/extending/embedding.html
+// https://docs.python.org/3.8/c-api/init.html#thread-state-and-the-global-interpreter-lock
+
+SCRIPTX_BEGIN_INCLUDE_LIBRARY
+#ifndef PY_SSIZE_T_CLEAN
+#define PY_SSIZE_T_CLEAN
+#endif
+#include <Python.h>
+#include <pylifecycle.h>
+SCRIPTX_END_INCLUDE_LIBRARY
+
+namespace script::py_backend {
+
+class PyEngine;
+
+PyObject* checkException(PyObject* obj);
+void checkException();
+void rethrowException(const Exception& exception);
+
+}  // namespace script::py_backend
diff --git a/backend/Python/PyHelper.hpp b/backend/Python/PyHelper.hpp
new file mode 100644
index 00000000..c3ef7e21
--- /dev/null
+++ b/backend/Python/PyHelper.hpp
@@ -0,0 +1,53 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include "../../src/Native.hpp"
+#include "../../src/Reference.h"
+#include "PyEngine.h"
+#include "PyHelper.h"
+
+namespace script {
+
+struct py_interop {
+  template <typename T>
+  static Local<T> makeLocal(PyObject* ref) {
+    return Local<T>(ref);
+  }
+
+  /**
+   * @return stolen ref.
+   */
+  template <typename T>
+  static PyObject* toPy(const Local<T>& ref) {
+    return Py_XNewRef(ref.val_);
+  }
+
+  /**
+   * @return borrowed ref.
+   */
+  template <typename T>
+  static PyObject* asPy(const Local<T>& ref) {
+    return ref.val_;
+  }
+
+  static Arguments makeArguments(py_backend::PyEngine* engine, PyObject* self, PyObject* args) {
+    return Arguments(py_backend::ArgumentsData{engine, self, args});
+  }
+};
+
+}  // namespace script
\ No newline at end of file
diff --git a/backend/Python/PyLocalReference.cc b/backend/Python/PyLocalReference.cc
new file mode 100644
index 00000000..4bac19aa
--- /dev/null
+++ b/backend/Python/PyLocalReference.cc
@@ -0,0 +1,267 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../../src/Native.hpp"
+#include "../../src/Reference.h"
+#include "../../src/Utils.h"
+#include "../../src/Value.h"
+#include "PyHelper.hpp"
+#include "PyReference.hpp"
+
+namespace script {
+
+namespace py_backend {
+void valueConstructorCheck(PyObject* value) {
+  SCRIPTX_UNUSED(value);
+#ifndef NDEBUG
+  if (!value) throw Exception("null reference");
+#endif
+}
+}  // namespace py_backend
+
+#define REF_IMPL_BASIC_FUNC(ValueType)                                                           \
+  Local<ValueType>::Local(const Local<ValueType>& copy) : val_(py_backend::incRef(copy.val_)) {} \
+  Local<ValueType>::Local(Local<ValueType>&& move) noexcept : val_(move.val_) {                  \
+    move.val_ = nullptr;                                                                         \
+  }                                                                                              \
+  Local<ValueType>::~Local() { py_backend::decRef(val_); }                                       \
+  Local<ValueType>& Local<ValueType>::operator=(const Local& from) {                             \
+    Local(from).swap(*this);                                                                     \
+    return *this;                                                                                \
+  }                                                                                              \
+  Local<ValueType>& Local<ValueType>::operator=(Local&& move) noexcept {                         \
+    Local(std::move(move)).swap(*this);                                                          \
+    return *this;                                                                                \
+  }                                                                                              \
+  void Local<ValueType>::swap(Local& rhs) noexcept { std::swap(val_, rhs.val_); }
+
+#define REF_IMPL_BASIC_EQUALS(ValueType)                                               \
+  bool Local<ValueType>::operator==(const script::Local<script::Value>& other) const { \
+    return asValue() == other;                                                         \
+  }
+
+#define REF_IMPL_BASIC_NOT_VALUE(ValueType)                                         \
+  Local<ValueType>::Local(InternalLocalRef val) : val_(val) {                       \
+    py_backend::valueConstructorCheck(val);                                         \
+  }                                                                                 \
+  Local<String> Local<ValueType>::describe() const { return asValue().describe(); } \
+  std::string Local<ValueType>::describeUtf8() const { return asValue().describeUtf8(); }
+
+#define REF_IMPL_TO_VALUE(ValueType) \
+  Local<Value> Local<ValueType>::asValue() const { return Local<Value>(py_backend::incRef(val_)); }
+
+REF_IMPL_BASIC_FUNC(Value)
+
+REF_IMPL_BASIC_FUNC(Object)
+REF_IMPL_BASIC_NOT_VALUE(Object)
+REF_IMPL_BASIC_EQUALS(Object)
+REF_IMPL_TO_VALUE(Object)
+
+REF_IMPL_BASIC_FUNC(String)
+REF_IMPL_BASIC_NOT_VALUE(String)
+REF_IMPL_BASIC_EQUALS(String)
+REF_IMPL_TO_VALUE(String)
+
+REF_IMPL_BASIC_FUNC(Number)
+REF_IMPL_BASIC_NOT_VALUE(Number)
+REF_IMPL_BASIC_EQUALS(Number)
+REF_IMPL_TO_VALUE(Number)
+
+REF_IMPL_BASIC_FUNC(Boolean)
+REF_IMPL_BASIC_NOT_VALUE(Boolean)
+REF_IMPL_BASIC_EQUALS(Boolean)
+REF_IMPL_TO_VALUE(Boolean)
+
+REF_IMPL_BASIC_FUNC(Function)
+REF_IMPL_BASIC_NOT_VALUE(Function)
+REF_IMPL_BASIC_EQUALS(Function)
+REF_IMPL_TO_VALUE(Function)
+
+REF_IMPL_BASIC_FUNC(Array)
+REF_IMPL_BASIC_NOT_VALUE(Array)
+REF_IMPL_BASIC_EQUALS(Array)
+REF_IMPL_TO_VALUE(Array)
+
+REF_IMPL_BASIC_FUNC(ByteBuffer)
+REF_IMPL_BASIC_NOT_VALUE(ByteBuffer)
+REF_IMPL_BASIC_EQUALS(ByteBuffer)
+REF_IMPL_TO_VALUE(ByteBuffer)
+
+REF_IMPL_BASIC_FUNC(Unsupported)
+REF_IMPL_BASIC_NOT_VALUE(Unsupported)
+REF_IMPL_BASIC_EQUALS(Unsupported)
+REF_IMPL_TO_VALUE(Unsupported)
+
+// ==== value ====
+
+Local<Value>::Local() noexcept : val_() {}
+
+Local<Value>::Local(InternalLocalRef ref) : val_(ref) {}
+
+bool Local<Value>::isNull() const { return val_ == nullptr; }
+
+void Local<Value>::reset() {
+  py_backend::decRef(val_);
+  val_ = nullptr;
+}
+
+ValueKind Local<Value>::getKind() const {
+  if (isNull()) {
+    return ValueKind::kNull;
+  } else if (isString()) {
+    return ValueKind::kString;
+  } else if (isNumber()) {
+    return ValueKind::kNumber;
+  } else if (isBoolean()) {
+    return ValueKind::kBoolean;
+  } else if (isFunction()) {
+    return ValueKind::kFunction;
+  } else if (isArray()) {
+    return ValueKind::kArray;
+  } else if (isByteBuffer()) {
+    return ValueKind::kByteBuffer;
+  } else if (isObject()) {
+    return ValueKind::kObject;
+  } else {
+    return ValueKind::kUnsupported;
+  }
+}
+
+bool Local<Value>::isString() const { return false; }
+
+bool Local<Value>::isNumber() const { return PyNumber_Check(val_); }
+
+bool Local<Value>::isBoolean() const { return PyBool_Check(val_); }
+
+bool Local<Value>::isFunction() const { return PyCallable_Check(val_); }
+
+bool Local<Value>::isArray() const { return false; }
+
+bool Local<Value>::isByteBuffer() const { return false; }
+
+bool Local<Value>::isObject() const { return false; }
+
+bool Local<Value>::isUnsupported() const { return false; }
+
+Local<String> Local<Value>::asString() const { throw Exception("can't cast value as String"); }
+
+Local<Number> Local<Value>::asNumber() const { throw Exception("can't cast value as Number"); }
+
+Local<Boolean> Local<Value>::asBoolean() const { throw Exception("can't cast value as Boolean"); }
+
+Local<Function> Local<Value>::asFunction() const {
+  throw Exception("can't cast value as Function");
+}
+
+Local<Array> Local<Value>::asArray() const { throw Exception("can't cast value as Array"); }
+
+Local<ByteBuffer> Local<Value>::asByteBuffer() const {
+  throw Exception("can't cast value as ByteBuffer");
+}
+
+Local<Object> Local<Value>::asObject() const { throw Exception("can't cast value as Object"); }
+
+Local<Unsupported> Local<Value>::asUnsupported() const {
+  throw Exception("can't cast value as Unsupported");
+}
+
+bool Local<Value>::operator==(const script::Local<script::Value>& other) const {
+  // TODO: nullptr vs None
+  auto lhs = val_;
+  auto rhs = other.val_;
+
+  // nullptr == nullptr
+  if (lhs == nullptr || rhs == nullptr) {
+    return lhs == rhs;
+  }
+
+  return PyObject_RichCompareBool(lhs, rhs, Py_EQ);
+}
+
+Local<String> Local<Value>::describe() const { TEMPLATE_NOT_IMPLEMENTED(); }
+
+Local<Value> Local<Object>::get(const script::Local<script::String>& key) const { return {}; }
+
+void Local<Object>::set(const script::Local<script::String>& key,
+                        const script::Local<script::Value>& value) const {}
+
+void Local<Object>::remove(const Local<class script::String>& key) const {}
+bool Local<Object>::has(const Local<class script::String>& key) const { return true; }
+
+bool Local<Object>::instanceOf(const Local<class script::Value>& type) const { return false; }
+
+std::vector<Local<String>> Local<Object>::getKeys() const { return {}; }
+
+float Local<Number>::toFloat() const { return static_cast<float>(toDouble()); }
+
+double Local<Number>::toDouble() const { return 0; }
+
+int32_t Local<Number>::toInt32() const { return static_cast<int32_t>(toDouble()); }
+
+int64_t Local<Number>::toInt64() const { return static_cast<int64_t>(toDouble()); }
+
+bool Local<Boolean>::value() const { return false; }
+
+Local<Value> Local<Function>::callImpl(const Local<Value>& thiz, size_t size,
+                                       const Local<Value>* args) const {
+  // PyObject* self = thiz.isObject() ? py_interop::toPy(thiz) : nullptr;
+  // TODO: self
+  PyObject* ret = nullptr;
+  // args to tuple
+  if (size == 0) {
+    ret = PyObject_CallNoArgs(py_interop::asPy(*this));
+  } else if (size == 1) {
+    ret = PyObject_CallOneArg(py_interop::asPy(*this), py_interop::asPy(args[0]));
+  } else {
+    auto tuple = PyTuple_New(static_cast<Py_ssize_t>(size));
+    py_backend::checkException();
+    for (size_t i = 0; i < size; ++i) {
+      PyTuple_SetItem(tuple, static_cast<Py_ssize_t>(i), py_interop::toPy(args[i]));
+      py_backend::checkException();
+    }
+    ret = PyObject_Call(py_interop::asPy(*this), tuple, nullptr);
+  }
+
+  py_backend::checkException();
+  return Local<Value>(ret);
+}
+
+size_t Local<Array>::size() const { return 0; }
+
+Local<Value> Local<Array>::get(size_t index) const { return {}; }
+
+void Local<Array>::set(size_t index, const script::Local<script::Value>& value) const {}
+
+void Local<Array>::add(const script::Local<script::Value>& value) const { set(size(), value); }
+
+void Local<Array>::clear() const {}
+
+ByteBuffer::Type Local<ByteBuffer>::getType() const { return ByteBuffer::Type::KFloat32; }
+
+bool Local<ByteBuffer>::isShared() const { return true; }
+
+void Local<ByteBuffer>::commit() const {}
+
+void Local<ByteBuffer>::sync() const {}
+
+size_t Local<ByteBuffer>::byteLength() const { return 0; }
+
+void* Local<ByteBuffer>::getRawBytes() const { return nullptr; }
+
+std::shared_ptr<void> Local<ByteBuffer>::getRawBytesShared() const { return {}; }
+
+}  // namespace script
diff --git a/backend/Python/PyNative.cc b/backend/Python/PyNative.cc
new file mode 100644
index 00000000..703a43c0
--- /dev/null
+++ b/backend/Python/PyNative.cc
@@ -0,0 +1,61 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../../src/Native.hpp"
+#include "PyEngine.h"
+#include "PyHelper.hpp"
+
+namespace script {
+
+Arguments::Arguments(InternalCallbackInfoType callbackInfo) : callbackInfo_(callbackInfo) {}
+
+Arguments::~Arguments() = default;
+
+Local<Object> Arguments::thiz() const {
+  return py_interop::makeLocal<Value>(callbackInfo_.self).asObject();
+}
+
+bool Arguments::hasThiz() const { return callbackInfo_.self != nullptr; }
+
+size_t Arguments::size() const {
+  if (!callbackInfo_.args) {
+    return 0;
+  }
+  return PyTuple_Size(callbackInfo_.args);
+}
+
+Local<Value> Arguments::operator[](size_t i) const {
+  if (i < size()) {
+    return py_interop::makeLocal<Value>(PyTuple_GetItem(callbackInfo_.args, i));
+  }
+  return {};
+}
+
+ScriptEngine* Arguments::engine() const { return callbackInfo_.engine; }
+
+ScriptClass::ScriptClass(const script::Local<script::Object>& scriptObject) : internalState_() {
+  TEMPLATE_NOT_IMPLEMENTED();
+}
+
+Local<Object> ScriptClass::getScriptObject() const { TEMPLATE_NOT_IMPLEMENTED(); }
+
+Local<Array> ScriptClass::getInternalStore() const { TEMPLATE_NOT_IMPLEMENTED(); }
+
+ScriptEngine* ScriptClass::getScriptEngine() const { TEMPLATE_NOT_IMPLEMENTED(); }
+
+ScriptClass::~ScriptClass() = default;
+}  // namespace script
\ No newline at end of file
diff --git a/backend/Python/PyNative.hpp b/backend/Python/PyNative.hpp
new file mode 100644
index 00000000..ec9c2626
--- /dev/null
+++ b/backend/Python/PyNative.hpp
@@ -0,0 +1,33 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../../src/Native.h"
+#include "PyEngine.h"
+
+namespace script {
+
+template <typename T>
+ScriptClass::ScriptClass(const ScriptClass::ConstructFromCpp<T>) : internalState_() {}
+
+template <typename T>
+T* Arguments::engineAs() const {
+  return nullptr;
+}
+
+}  // namespace script
\ No newline at end of file
diff --git a/backend/Python/PyReference.hpp b/backend/Python/PyReference.hpp
new file mode 100644
index 00000000..393788a4
--- /dev/null
+++ b/backend/Python/PyReference.hpp
@@ -0,0 +1,150 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include <utility>
+
+namespace script {
+
+namespace py_backend {
+
+inline PyObject* incRef(PyObject* ref) { return Py_XNewRef(ref); }
+
+inline void decRef(PyObject* ref) { Py_XDECREF(ref); }
+
+}  // namespace py_backend
+
+template <typename T>
+Global<T>::Global() noexcept : val_() {}
+
+template <typename T>
+Global<T>::Global(const script::Local<T>& localReference) {}
+
+template <typename T>
+Global<T>::Global(const script::Weak<T>& weak) {}
+
+template <typename T>
+Global<T>::Global(const script::Global<T>& copy) : val_(copy.val_) {}
+
+template <typename T>
+Global<T>::Global(script::Global<T>&& move) noexcept : val_(move.val_) {}
+
+template <typename T>
+Global<T>::~Global() {}
+
+template <typename T>
+Global<T>& Global<T>::operator=(const script::Global<T>& assign) {
+  Global(assign).swap(*this);
+  return *this;
+}
+
+template <typename T>
+Global<T>& Global<T>::operator=(script::Global<T>&& move) noexcept {
+  Global(std::move(move)).swap(*this);
+  return *this;
+}
+
+template <typename T>
+void Global<T>::swap(Global& rhs) noexcept {}
+
+template <typename T>
+Global<T>& Global<T>::operator=(const script::Local<T>& assign) {
+  *this = Global<T>(assign);
+  return *this;
+}
+
+template <typename T>
+Local<T> Global<T>::get() const {
+  TEMPLATE_NOT_IMPLEMENTED();
+}
+
+template <typename T>
+Local<Value> Global<T>::getValue() const {
+  TEMPLATE_NOT_IMPLEMENTED();
+}
+
+template <typename T>
+bool Global<T>::isEmpty() const {
+  return false;
+}
+
+template <typename T>
+void Global<T>::reset() {}
+
+// == Weak ==
+
+template <typename T>
+Weak<T>::Weak() noexcept : val_() {}
+
+template <typename T>
+Weak<T>::~Weak() {}
+
+template <typename T>
+Weak<T>::Weak(const script::Local<T>& localReference) {}
+
+template <typename T>
+Weak<T>::Weak(const script::Global<T>& globalReference) {}
+
+template <typename T>
+Weak<T>::Weak(const script::Weak<T>& copy) : val_(copy.val_) {}
+
+template <typename T>
+Weak<T>::Weak(script::Weak<T>&& move) noexcept : val_(std::move(move.val_)) {}
+
+template <typename T>
+Weak<T>& Weak<T>::operator=(const script::Weak<T>& assign) {
+  val_ = assign.val_;
+  return *this;
+}
+
+template <typename T>
+Weak<T>& Weak<T>::operator=(script::Weak<T>&& move) noexcept {
+  val_ = std::move(move.val_);
+  return *this;
+}
+
+template <typename T>
+void Weak<T>::swap(Weak& rhs) noexcept {
+  std::swap(val_, rhs.val_);
+}
+
+template <typename T>
+Weak<T>& Weak<T>::operator=(const script::Local<T>& assign) {
+  *this = Weak<T>(assign);
+  return *this;
+}
+
+template <typename T>
+Local<T> Weak<T>::get() const {
+  if (isEmpty()) throw Exception("get on empty Weak");
+  TEMPLATE_NOT_IMPLEMENTED();
+}
+
+template <typename T>
+Local<Value> Weak<T>::getValue() const {
+  TEMPLATE_NOT_IMPLEMENTED();
+}
+
+template <typename T>
+bool Weak<T>::isEmpty() const {
+  return false;
+}
+
+template <typename T>
+void Weak<T>::reset() noexcept {}
+
+}  // namespace script
diff --git a/backend/Python/PyScope.cc b/backend/Python/PyScope.cc
new file mode 100644
index 00000000..fd45effb
--- /dev/null
+++ b/backend/Python/PyScope.cc
@@ -0,0 +1,31 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PyScope.h"
+
+// reference
+// https://docs.python.org/3.8/c-api/init.html#thread-state-and-the-global-interpreter-lock
+
+namespace script::py_backend {
+
+EngineScopeImpl::EngineScopeImpl(PyEngine &, PyEngine *) : gilState_(PyGILState_Ensure()) {}
+EngineScopeImpl::~EngineScopeImpl() { PyGILState_Release(gilState_); }
+
+ExitEngineScopeImpl::ExitEngineScopeImpl(PyEngine &) : threadState(PyEval_SaveThread()) {}
+ExitEngineScopeImpl::~ExitEngineScopeImpl() { PyEval_RestoreThread(threadState); }
+
+}  // namespace script::py_backend
\ No newline at end of file
diff --git a/backend/Python/PyScope.h b/backend/Python/PyScope.h
new file mode 100644
index 00000000..0d6f98ae
--- /dev/null
+++ b/backend/Python/PyScope.h
@@ -0,0 +1,53 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include "../../src/Reference.h"
+#include "PyHelper.h"
+
+namespace script::py_backend {
+
+class PyEngine;
+
+class EngineScopeImpl {
+  PyGILState_STATE gilState_;
+
+ public:
+  explicit EngineScopeImpl(PyEngine &, PyEngine *);
+
+  ~EngineScopeImpl();
+};
+
+class ExitEngineScopeImpl {
+  PyThreadState *threadState;
+
+ public:
+  explicit ExitEngineScopeImpl(PyEngine &);
+
+  ~ExitEngineScopeImpl();
+};
+
+class StackFrameScopeImpl {
+ public:
+  explicit StackFrameScopeImpl(PyEngine &) {}
+
+  template <typename T>
+  Local<T> returnValue(const Local<T> &localRef) {
+    return localRef;
+  }
+};
+}  // namespace script::py_backend
diff --git a/backend/Python/PyUtils.cc b/backend/Python/PyUtils.cc
new file mode 100644
index 00000000..cd4bf063
--- /dev/null
+++ b/backend/Python/PyUtils.cc
@@ -0,0 +1,46 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ScriptX/ScriptX.h>
+
+namespace script {
+
+StringHolder::StringHolder(const script::Local<script::String> &string) {}
+
+StringHolder::~StringHolder() = default;
+
+size_t StringHolder::length() const { return 0; }
+
+const char *StringHolder::c_str() const { return ""; }
+
+std::string_view StringHolder::stringView() const { return {}; }
+
+std::string StringHolder::string() const { return {}; }
+
+#if defined(__cpp_char8_t)
+// NOLINTNEXTLINE(clang-analyzer-cplusplus.InnerPointer)
+std::u8string StringHolder::u8string() const { return std::u8string(c_u8str(), length()); }
+
+std::u8string_view StringHolder::u8stringView() const {
+  // NOLINTNEXTLINE(clang-analyzer-cplusplus.InnerPointer)
+  return std::u8string_view(c_u8str(), length());
+}
+
+const char8_t *StringHolder::c_u8str() const { return reinterpret_cast<const char8_t *>(c_str()); }
+#endif
+
+}  // namespace script
diff --git a/backend/Python/PyValue.cc b/backend/Python/PyValue.cc
new file mode 100644
index 00000000..3c8fda2e
--- /dev/null
+++ b/backend/Python/PyValue.cc
@@ -0,0 +1,156 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../../src/Exception.h"
+#include "../../src/Reference.h"
+#include "../../src/Scope.h"
+#include "../../src/Value.h"
+#include "PyHelper.hpp"
+
+using script::py_interop;
+using script::py_backend::checkException;
+
+namespace script {
+
+template <typename T>
+Local<T> checkAndMakeLocal(PyObject* ref) {
+  return py_interop::makeLocal<T>(checkException(ref));
+}
+
+// for python this creates an empty dict
+Local<Object> Object::newObject() { return checkAndMakeLocal<Object>(PyDict_New()); }
+
+Local<Object> Object::newObjectImpl(const Local<Value>& type, size_t size,
+                                    const Local<Value>* args) {
+  TEMPLATE_NOT_IMPLEMENTED();
+}
+
+Local<String> String::newString(const char* utf8) {
+  return checkAndMakeLocal<String>(PyBytes_FromString(utf8));
+}
+
+Local<String> String::newString(std::string_view utf8) {
+  return checkAndMakeLocal<String>(
+      PyBytes_FromStringAndSize(utf8.data(), static_cast<Py_ssize_t>(utf8.length())));
+}
+
+Local<String> String::newString(const std::string& utf8) {
+  return checkAndMakeLocal<String>(
+      PyBytes_FromStringAndSize(utf8.c_str(), static_cast<Py_ssize_t>(utf8.length())));
+}
+
+#if defined(__cpp_char8_t)
+
+Local<String> String::newString(const char8_t* utf8) {
+  return newString(reinterpret_cast<const char*>(utf8));
+}
+
+Local<String> String::newString(std::u8string_view utf8) {
+  return newString(std::string_view(reinterpret_cast<const char*>(utf8.data()), utf8.length()));
+}
+
+Local<String> String::newString(const std::u8string& utf8) { return newString(utf8.c_str()); }
+
+#endif
+
+Local<Number> Number::newNumber(float value) { return newNumber(static_cast<double>(value)); }
+
+Local<Number> Number::newNumber(double value) {
+  return checkAndMakeLocal<Number>(PyLong_FromDouble(value));
+}
+
+Local<Number> Number::newNumber(int32_t value) {
+  return checkAndMakeLocal<Number>(PyLong_FromLong(static_cast<long>(value)));
+}
+
+Local<Number> Number::newNumber(int64_t value) {
+  return checkAndMakeLocal<Number>(PyLong_FromLongLong(static_cast<long long>(value)));
+}
+
+Local<Boolean> Boolean::newBoolean(bool value) {
+  return checkAndMakeLocal<Boolean>(PyBool_FromLong(value));
+}
+
+namespace {
+
+static constexpr const char* kFunctionDataName = "_ScriptX_function_data";
+
+struct FunctionData {
+  FunctionCallback function;
+  py_backend::PyEngine* engine = nullptr;
+};
+
+}  // namespace
+
+Local<Function> Function::newFunction(script::FunctionCallback callback) {
+  auto callbackIns = std::make_unique<FunctionData>();
+  callbackIns->engine = EngineScope::currentEngineAs<py_backend::PyEngine>();
+  callbackIns->function = std::move(callback);
+
+  PyMethodDef method{};
+  method.ml_name = "ScriptX_native_method";
+  method.ml_flags = METH_O;
+  method.ml_doc = "ScriptX Function::newFunction";
+  method.ml_meth = [](PyObject* self, PyObject* args) -> PyObject* {
+    auto ptr = PyCapsule_GetPointer(self, kFunctionDataName);
+    if (ptr == nullptr) {
+      ::PyErr_SetString(PyExc_TypeError, "invalid 'self' for native method");
+    } else {
+      auto data = static_cast<FunctionData*>(ptr);
+      try {
+        auto ret = data->function(py_interop::makeArguments(nullptr, self, args));
+        return py_interop::toPy(ret);
+      } catch (Exception& e) {
+        py_backend::rethrowException(e);
+      }
+    }
+    return nullptr;
+  };
+
+  auto ctx = PyCapsule_New(callbackIns.get(), kFunctionDataName, [](PyObject* cap) {
+    auto ptr = PyCapsule_GetPointer(cap, kFunctionDataName);
+    delete static_cast<FunctionData*>(ptr);
+  });
+  py_backend::checkException(ctx);
+  callbackIns.release();
+
+  PyObject* closure = PyCFunction_New(&method, ctx);
+  Py_XDECREF(ctx);
+  py_backend::checkException(closure);
+
+  return Local<Function>(closure);
+}
+
+Local<Array> Array::newArray(size_t size) {
+  return checkAndMakeLocal<Array>(PyList_New(static_cast<Py_ssize_t>(size)));
+}
+
+Local<Array> Array::newArrayImpl(size_t size, const Local<Value>* args) {
+  TEMPLATE_NOT_IMPLEMENTED();
+}
+
+Local<ByteBuffer> ByteBuffer::newByteBuffer(size_t size) { TEMPLATE_NOT_IMPLEMENTED(); }
+
+Local<script::ByteBuffer> ByteBuffer::newByteBuffer(void* nativeBuffer, size_t size) {
+  TEMPLATE_NOT_IMPLEMENTED();
+}
+
+Local<ByteBuffer> ByteBuffer::newByteBuffer(std::shared_ptr<void> nativeBuffer, size_t size) {
+  TEMPLATE_NOT_IMPLEMENTED();
+}
+
+}  // namespace script
\ No newline at end of file
diff --git a/backend/Python/trait/TraitEngine.h b/backend/Python/trait/TraitEngine.h
new file mode 100644
index 00000000..8d6592be
--- /dev/null
+++ b/backend/Python/trait/TraitEngine.h
@@ -0,0 +1,36 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include "../../src/types.h"
+
+#define TEMPLATE_NOT_IMPLEMENTED() throw Exception(std::string(__func__) + " not implemented");
+
+namespace script {
+
+namespace py_backend {
+class PyEngine;
+}
+
+template <>
+struct internal::ImplType<ScriptEngine> {
+  using type = py_backend::PyEngine;
+};
+
+}  // namespace script
\ No newline at end of file
diff --git a/backend/Python/trait/TraitException.h b/backend/Python/trait/TraitException.h
new file mode 100644
index 00000000..80b13f49
--- /dev/null
+++ b/backend/Python/trait/TraitException.h
@@ -0,0 +1,38 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include <string>
+#include "../../src/types.h"
+
+namespace script {
+
+namespace py_backend {
+
+class ExceptionFields {
+ public:
+  mutable std::string message_{};
+};
+
+}  // namespace py_backend
+
+template <>
+struct internal::ImplType<Exception> {
+  using type = py_backend::ExceptionFields;
+};
+
+}  // namespace script
diff --git a/backend/Python/trait/TraitIncludes.h b/backend/Python/trait/TraitIncludes.h
new file mode 100644
index 00000000..6f22d372
--- /dev/null
+++ b/backend/Python/trait/TraitIncludes.h
@@ -0,0 +1,26 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../PyEngine.h"
+#include "../PyNative.hpp"
+#include "../PyReference.hpp"
+
+// global marco
+#define SCRIPTX_BACKEND_PYTHON
+#define SCRIPTX_LANG_PYTHON
\ No newline at end of file
diff --git a/backend/Python/trait/TraitNative.h b/backend/Python/trait/TraitNative.h
new file mode 100644
index 00000000..3022f038
--- /dev/null
+++ b/backend/Python/trait/TraitNative.h
@@ -0,0 +1,49 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include "../../src/types.h"
+#include "../PyHelper.h"
+
+namespace script {
+
+namespace py_backend {
+
+struct ArgumentsData {
+  mutable PyEngine* engine;
+  PyObject* self;
+  PyObject* args;
+};
+
+struct ScriptClassState {
+  ScriptEngine* scriptEngine_ = nullptr;
+  Weak<Object> weakRef_;
+};
+
+}  // namespace py_backend
+
+template <>
+struct internal::ImplType<::script::Arguments> {
+  using type = py_backend::ArgumentsData;
+};
+
+template <>
+struct internal::ImplType<::script::ScriptClass> {
+  using type = py_backend::ScriptClassState;
+};
+
+}  // namespace script
\ No newline at end of file
diff --git a/backend/Python/trait/TraitReference.h b/backend/Python/trait/TraitReference.h
new file mode 100644
index 00000000..d45c7ed5
--- /dev/null
+++ b/backend/Python/trait/TraitReference.h
@@ -0,0 +1,42 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <string>
+#include "../../src/types.h"
+#include "../PyHelper.h"
+
+namespace script::internal {
+
+template <typename T>
+struct ImplType<Local<T>> {
+  using type = PyObject*;
+};
+
+template <typename T>
+struct ImplType<Global<T>> {
+  using type = PyObject*;
+};
+
+template <typename T>
+struct ImplType<Weak<T>> {
+  using type = PyObject*;
+};
+
+}  // namespace script::internal
\ No newline at end of file
diff --git a/backend/Python/trait/TraitScope.h b/backend/Python/trait/TraitScope.h
new file mode 100644
index 00000000..d3cd8996
--- /dev/null
+++ b/backend/Python/trait/TraitScope.h
@@ -0,0 +1,40 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "../PyScope.h"
+#include "TraitEngine.h"
+
+namespace script {
+
+template <>
+struct internal::ImplType<EngineScope> {
+  using type = py_backend::EngineScopeImpl;
+};
+
+template <>
+struct internal::ImplType<ExitEngineScope> {
+  using type = py_backend::ExitEngineScopeImpl;
+};
+
+template <>
+struct internal::ImplType<StackFrameScope> {
+  using type = py_backend::StackFrameScopeImpl;
+};
+
+}  // namespace script
\ No newline at end of file
diff --git a/backend/Python/trait/TraitUtils.h b/backend/Python/trait/TraitUtils.h
new file mode 100644
index 00000000..215f6802
--- /dev/null
+++ b/backend/Python/trait/TraitUtils.h
@@ -0,0 +1,35 @@
+/*
+ * Tencent is pleased to support the open source community by making ScriptX available.
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+#include "../../src/types.h"
+
+namespace script {
+
+struct py_interop;
+
+template <>
+struct internal::ImplType<StringHolder> {
+  using type = int;
+};
+
+template <>
+struct internal::ImplType<internal::interop> {
+  using type = py_interop;
+};
+
+}  // namespace script
\ No newline at end of file
diff --git a/backend/Template/trait/TraitNative.h b/backend/Template/trait/TraitNative.h
index 568325b6..3077e648 100644
--- a/backend/Template/trait/TraitNative.h
+++ b/backend/Template/trait/TraitNative.h
@@ -26,7 +26,7 @@ struct ArgumentsData {
   size_t size;
 };
 
-struct JscScriptClassState {
+struct ScriptClassState {
   ScriptEngine* scriptEngine_ = nullptr;
   Weak<Object> weakRef_;
 };
@@ -40,7 +40,7 @@ struct internal::ImplType<::script::Arguments> {
 
 template <>
 struct internal::ImplType<::script::ScriptClass> {
-  using type = template_backend::JscScriptClassState;
+  using type = template_backend::ScriptClassState;
 };
 
 }  // namespace script
\ No newline at end of file
diff --git a/test/cmake/TestEnv.cmake b/test/cmake/TestEnv.cmake
index 1d582f2a..f04e0735 100644
--- a/test/cmake/TestEnv.cmake
+++ b/test/cmake/TestEnv.cmake
@@ -159,5 +159,10 @@ elseif (${SCRIPTX_BACKEND} STREQUAL WebAssembly)
 elseif (${SCRIPTX_BACKEND} STREQUAL QuickJs)
     include("${SCRIPTX_TEST_LIBS}/quickjs/CMakeLists.txt")
     set(DEVOPS_LIBS_LIBPATH QuickJs CACHE STRING "" FORCE)
+elseif (${SCRIPTX_BACKEND} STREQUAL Python)
+    set(DEVOPS_LIBS_INCLUDE
+            "/usr/local/Cellar/python@3.10/3.10.0_2/Frameworks/Python.framework/Headers/"
+                CACHE STRING "" FORCE)
+    set(DEVOPS_LIBS_LIBPATH "/usr/local/Cellar/python@3.10/3.10.0_2/Frameworks/Python.framework/Versions/Current/lib/libpython3.10.dylib" CACHE STRING "" FORCE)
 endif ()
 
diff --git a/test/src/gtest_main.cc b/test/src/gtest_main.cc
index e9a0258b..ab9c6c5d 100644
--- a/test/src/gtest_main.cc
+++ b/test/src/gtest_main.cc
@@ -65,13 +65,16 @@ void ScriptXTestFixture::SetUp() {
     using script::String;
 
     EngineScope engineScope(engine);
+#if defined(SCRIPTX_LANG_JAVASCRIPT) && !defined(SCRIPTX_BACKEND_WEBASSEMBLY)
     auto log = Function::newFunction(consoleLog);
-#ifndef SCRIPTX_BACKEND_WEBASSEMBLY
     auto console = Object::newObject();
     console.set(String::newString(u8"log"), log);
     engine->set(String::newString(u8"console"), console);
 #endif
+#ifdef SCRIPTX_BACKEND_LUA
+    auto log = Function::newFunction(consoleLog);
     engine->set(String::newString(u8"print"), log);
+#endif
   }
 }
 
