# Override types possibilities above, if needed
directive_types = {
+ 'final' : bool, # final cdef classes and methods
'infer_types' : bool, # values can be True/None/False
}
directive_scopes = { # defaults to available everywhere
# 'module', 'function', 'class', 'with statement'
+ 'final' : ('cclass',), # add 'method' in the future
'autotestdict' : ('module',),
'test_assert_path_exists' : ('function',),
'test_fail_if_path_exists' : ('function',),
# Descriptor for the type flags slot.
def slot_code(self, scope):
- value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_NEWBUFFER"
+ value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER"
+ if not scope.directives.get('final', False):
+ value += "|Py_TPFLAGS_BASETYPE"
if scope.needs_gc():
value += "|Py_TPFLAGS_HAVE_GC"
return value
--- /dev/null
+
+cimport cython
+
+@cython.final
+cdef class FinalClass:
+ """
+ >>> f = FinalClass()
+ >>> test_final_class(f)
+ Type tested
+
+ >>> try:
+ ... class SubType(FinalClass): pass
+ ... except TypeError:
+ ... print 'PASSED!'
+ PASSED!
+ """
+
+cdef class NonFinalClass:
+ """
+ >>> class SubType(NonFinalClass): pass
+ >>> s = SubType()
+ """
+
+@cython.final
+cdef class FinalSubClass(NonFinalClass):
+ """
+ >>> f = FinalSubClass()
+ >>> test_non_final_class(f)
+ Type tested
+
+ >>> try:
+ ... class SubType(FinalSubClass): pass
+ ... except TypeError:
+ ... print 'PASSED!'
+ PASSED!
+ """
+
+
+def test_final_class(FinalClass c):
+ print u"Type tested"
+
+def test_non_final_class(NonFinalClass c):
+ print u"Type tested"