From 9b57b1c56271b06108d92cc78f623c1c9b16a12a Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 30 Oct 2010 19:04:39 +0200 Subject: [PATCH] support for 'final' cdef types using a directive decorator --- Cython/Compiler/Options.py | 2 ++ Cython/Compiler/TypeSlots.py | 4 +++- tests/run/final_cdef_class.pyx | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/run/final_cdef_class.pyx diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py index ccc5c0f9..fd7666ac 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@ -81,6 +81,7 @@ directive_defaults = { # Override types possibilities above, if needed directive_types = { + 'final' : bool, # final cdef classes and methods 'infer_types' : bool, # values can be True/None/False } @@ -90,6 +91,7 @@ for key, val in directive_defaults.items(): 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',), diff --git a/Cython/Compiler/TypeSlots.py b/Cython/Compiler/TypeSlots.py index b4dbdda9..6e1b1131 100644 --- a/Cython/Compiler/TypeSlots.py +++ b/Cython/Compiler/TypeSlots.py @@ -323,7 +323,9 @@ class TypeFlagsSlot(SlotDescriptor): # 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 diff --git a/tests/run/final_cdef_class.pyx b/tests/run/final_cdef_class.pyx new file mode 100644 index 00000000..6845c71e --- /dev/null +++ b/tests/run/final_cdef_class.pyx @@ -0,0 +1,43 @@ + +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" -- 2.26.2