diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000000000000000000000000000000000..7676f3941e6122f4f35162fa355e668553cf52cd
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "external/pybind11"]
+	path = external/pybind11
+	url = https://github.com/pybind/pybind11.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ae071c551d9d22384dd94f7d5712cb4a0e2791a9
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.8)
+
+project(pybind11-std-unique-ptr)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED YES)
+
+add_subdirectory("${CMAKE_SOURCE_DIR}/external/pybind11")
+
+pybind11_add_module(mymodule mymodule.cc)
+
+#include_directories(${pybind11_INCLUDE_DIRS})
\ No newline at end of file
diff --git a/external/pybind11 b/external/pybind11
new file mode 160000
index 0000000000000000000000000000000000000000..75007dda72ad4508064c1f080394eae50d3a61ee
--- /dev/null
+++ b/external/pybind11
@@ -0,0 +1 @@
+Subproject commit 75007dda72ad4508064c1f080394eae50d3a61ee
diff --git a/mymodule.cc b/mymodule.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8a1e18578f99efbaa0ae5b81d9da91cb769be424
--- /dev/null
+++ b/mymodule.cc
@@ -0,0 +1,82 @@
+#include <iostream>
+#include <string>
+
+#include <pybind11/pybind11.h>
+
+namespace py = pybind11;
+
+// template<typename T> std::unique_ptr<T> py_unique_ptr(T &object) {
+//     py::object py_object(pybind11::cast(&object));
+//     return std::unique_ptr<T>(&object, [](T* p){});
+// }
+
+class Pet {
+  public:
+
+    Pet(const std::string &name) :
+    name_(name)
+    {
+      std::cout << "A pet named " << name_ << " came to life." << std::endl;
+    }
+
+    // Option 1 - no move constructor - moving will make a copy
+    // 
+    // Pet(Pet &&other)=delete;
+
+    // Option 2 - default move constructor - members will be moved into new object
+    // Pet(Pet &&other)=default;
+
+    // Option 3 - Custom move constructor
+    Pet(Pet &&other) :
+      name_((std::move(other.name_)))
+    {
+      std::cout << "Moving " << name_ << " to new pet." << std::endl;
+    }
+
+    virtual ~Pet()
+    {
+      std::cout << "A pet named '" << name_ << "' died." << std::endl;
+    }
+
+    std::string GetName() {return name_;}
+
+  private:
+    std::string name_;
+};
+
+class PetHolder {
+  public:
+    PetHolder(std::unique_ptr<Pet> pet) :
+      pet_(std::move(pet))
+    {}
+
+    std::string GetPetName() const {
+        return pet_->GetName();
+    }
+
+    void SetPet(std::unique_ptr<Pet> pet) {
+        pet_ = std::move(pet);
+    }
+  private:
+    std::unique_ptr<Pet> pet_;
+
+};
+
+class PyPetHolder : public PetHolder {
+  public:
+    PyPetHolder(Pet &pet) : PetHolder(std::make_unique<Pet>(std::move(pet)))
+    {}
+};
+
+PYBIND11_MODULE(mymodule, m) {
+  m.doc() = R"pbdoc(
+   module to demonstrate handling of std::unique_ptr arguments in pybind11.
+  )pbdoc";
+
+  py::class_<Pet>(m, "Pet")
+    .def(py::init<const std::string &>());
+    
+  py::class_<PyPetHolder>(m, "PetHolder")
+    .def(py::init<Pet&>());
+
+}
diff --git a/testmymodule.py b/testmymodule.py
new file mode 100755
index 0000000000000000000000000000000000000000..918aa1142480634058787316bab8cc097843ec2c
--- /dev/null
+++ b/testmymodule.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+# Output:
+
+# A pet named Tweety came to life.
+# Moving Tweety to new pet.
+# A pet named '' died.
+# A pet named 'Tweety' died.
+
+import mymodule
+
+t = mymodule.Pet("Tweety")
+
+h = mymodule.PetHolder(t)
+
+del t
+del h
+