Add is_final to disallow inheritance from Python

- Not currently supported on PyPy
diff --git a/docs/advanced/classes.rst b/docs/advanced/classes.rst
index ae5907d..20760b7 100644
--- a/docs/advanced/classes.rst
+++ b/docs/advanced/classes.rst
@@ -1042,6 +1042,32 @@
     ``.def("foo", static_cast<int (A::*)() const>(&Publicist::foo));``
     where ``int (A::*)() const`` is the type of ``A::foo``.
 
+Binding final classes
+=====================
+
+Some classes may not be appropriate to inherit from. In C++11, classes can
+use the ``final`` specifier to ensure that a class cannot be inherited from.
+The ``py::is_final`` attribute can be used to ensure that Python classes 
+cannot inherit from a specified type. The underlying C++ type does not need
+to be declared final.
+
+.. code-block:: cpp
+
+    class IsFinal final {};
+
+    py::class_<IsFinal>(m, "IsFinal", py::is_final());
+
+When you try to inherit from such a class in Python, you will now get this
+error:
+
+.. code-block:: pycon
+
+    >>> class PyFinalChild(IsFinal):
+    ...     pass
+    TypeError: type 'IsFinal' is not an acceptable base type
+
+.. note:: This attribute is currently ignored on PyPy
+
 Custom automatic downcasters
 ============================
 
diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h
index 6962d6f..744284a 100644
--- a/include/pybind11/attr.h
+++ b/include/pybind11/attr.h
@@ -23,6 +23,9 @@
 /// Annotation for operators
 struct is_operator { };
 
+/// Annotation for classes that cannot be subclassed
+struct is_final { };
+
 /// Annotation for parent scope
 struct scope { handle value; scope(const handle &s) : value(s) { } };
 
@@ -201,7 +204,7 @@
 struct type_record {
     PYBIND11_NOINLINE type_record()
         : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false),
-          default_holder(true), module_local(false) { }
+          default_holder(true), module_local(false), is_final(false) { }
 
     /// Handle to the parent scope
     handle scope;
@@ -254,6 +257,9 @@
     /// Is the class definition local to the module shared object?
     bool module_local : 1;
 
+    /// Is the class inheritable from python classes?
+    bool is_final : 1;
+
     PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) {
         auto base_info = detail::get_type_info(base, false);
         if (!base_info) {
@@ -417,6 +423,11 @@
 };
 
 template <>
+struct process_attribute<is_final> : process_attribute_default<is_final> {
+    static void init(const is_final &, type_record *r) { r->is_final = true; }
+};
+
+template <>
 struct process_attribute<buffer_protocol> : process_attribute_default<buffer_protocol> {
     static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; }
 };
diff --git a/include/pybind11/detail/class.h b/include/pybind11/detail/class.h
index edfa7de..a05edeb 100644
--- a/include/pybind11/detail/class.h
+++ b/include/pybind11/detail/class.h
@@ -604,10 +604,12 @@
 #endif
 
     /* Flags */
-    type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
+    type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
 #if PY_MAJOR_VERSION < 3
     type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
 #endif
+    if (!rec.is_final)
+        type->tp_flags |= Py_TPFLAGS_BASETYPE;
 
     if (rec.dynamic_attr)
         enable_dynamic_attributes(heap_type);
diff --git a/tests/test_class.cpp b/tests/test_class.cpp
index 499d0cc..128bc39 100644
--- a/tests/test_class.cpp
+++ b/tests/test_class.cpp
@@ -367,6 +367,14 @@
             .def(py::init<>())
             .def("ptr", &Aligned::ptr);
     #endif
+
+    // test_final
+    struct IsFinal final {};
+    py::class_<IsFinal>(m, "IsFinal", py::is_final());
+
+    // test_non_final_final
+    struct IsNonFinalFinal {};
+    py::class_<IsNonFinalFinal>(m, "IsNonFinalFinal", py::is_final());
 }
 
 template <int N> class BreaksBase { public: virtual ~BreaksBase() = default; };
diff --git a/tests/test_class.py b/tests/test_class.py
index ed63ca8..e58fef6 100644
--- a/tests/test_class.py
+++ b/tests/test_class.py
@@ -279,3 +279,21 @@
     if hasattr(m, "Aligned"):
         p = m.Aligned().ptr()
         assert p % 1024 == 0
+
+
+# https://bitbucket.org/pypy/pypy/issues/2742
+@pytest.unsupported_on_pypy
+def test_final():
+    with pytest.raises(TypeError) as exc_info:
+        class PyFinalChild(m.IsFinal):
+            pass
+    assert str(exc_info.value).endswith("is not an acceptable base type")
+
+
+# https://bitbucket.org/pypy/pypy/issues/2742
+@pytest.unsupported_on_pypy
+def test_non_final_final():
+    with pytest.raises(TypeError) as exc_info:
+        class PyNonFinalFinalChild(m.IsNonFinalFinal):
+            pass
+    assert str(exc_info.value).endswith("is not an acceptable base type")