Commit 55ae33d7 authored by Stefan Behnel's avatar Stefan Behnel

support 'internal' cdef classes that do not show up in the module dict

parent 46e443be
...@@ -2075,12 +2075,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2075,12 +2075,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
type.vtabptr_cname, type.vtabptr_cname,
code.error_goto(entry.pos))) code.error_goto(entry.pos)))
env.use_utility_code(Nodes.set_vtable_utility_code) env.use_utility_code(Nodes.set_vtable_utility_code)
code.putln( if not type.scope.is_internal and not type.scope.directives['internal']:
'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % ( # scope.is_internal is set for types defined by
Naming.module_cname, # Cython (such as closures), the 'internal'
scope.class_name, # directive is set by users
typeobj_cname, code.putln(
code.error_goto(entry.pos))) 'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
Naming.module_cname,
scope.class_name,
typeobj_cname,
code.error_goto(entry.pos)))
weakref_entry = scope.lookup_here("__weakref__") weakref_entry = scope.lookup_here("__weakref__")
if weakref_entry: if weakref_entry:
if weakref_entry.type is py_object_type: if weakref_entry.type is py_object_type:
......
...@@ -3107,7 +3107,7 @@ class CClassDefNode(ClassDefNode): ...@@ -3107,7 +3107,7 @@ class CClassDefNode(ClassDefNode):
error(self.pos, "Base class '%s' of type '%s' is incomplete" % ( error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
self.base_class_name, self.class_name)) self.base_class_name, self.class_name))
elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \ elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
base_class_entry.type.scope.directives.get('final', False): base_class_entry.type.scope.directives['final']:
error(self.pos, "Base class '%s' of type '%s' is final" % ( error(self.pos, "Base class '%s' of type '%s' is final" % (
self.base_class_name, self.class_name)) self.base_class_name, self.class_name))
else: else:
......
...@@ -62,6 +62,8 @@ directive_defaults = { ...@@ -62,6 +62,8 @@ directive_defaults = {
'wraparound' : True, 'wraparound' : True,
'ccomplex' : False, # use C99/C++ for complex types and arith 'ccomplex' : False, # use C99/C++ for complex types and arith
'callspec' : "", 'callspec' : "",
'final' : False,
'internal' : False,
'profile': False, 'profile': False,
'infer_types': None, 'infer_types': None,
'infer_types.verbose': False, 'infer_types.verbose': False,
...@@ -82,6 +84,7 @@ directive_defaults = { ...@@ -82,6 +84,7 @@ directive_defaults = {
# Override types possibilities above, if needed # Override types possibilities above, if needed
directive_types = { directive_types = {
'final' : bool, # final cdef classes and methods 'final' : bool, # final cdef classes and methods
'internal' : bool, # cdef class visibility in the module dict
'infer_types' : bool, # values can be True/None/False 'infer_types' : bool, # values can be True/None/False
} }
...@@ -92,6 +95,7 @@ for key, val in directive_defaults.items(): ...@@ -92,6 +95,7 @@ for key, val in directive_defaults.items():
directive_scopes = { # defaults to available everywhere directive_scopes = { # defaults to available everywhere
# 'module', 'function', 'class', 'with statement' # 'module', 'function', 'class', 'with statement'
'final' : ('cclass',), # add 'method' in the future 'final' : ('cclass',), # add 'method' in the future
'internal' : ('cclass',),
'autotestdict' : ('module',), 'autotestdict' : ('module',),
'test_assert_path_exists' : ('function',), 'test_assert_path_exists' : ('function',),
'test_fail_if_path_exists' : ('function',), 'test_fail_if_path_exists' : ('function',),
......
...@@ -324,7 +324,7 @@ class TypeFlagsSlot(SlotDescriptor): ...@@ -324,7 +324,7 @@ class TypeFlagsSlot(SlotDescriptor):
def slot_code(self, scope): def slot_code(self, scope):
value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER" value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER"
if not scope.directives.get('final', False): if not scope.directives['final']:
value += "|Py_TPFLAGS_BASETYPE" value += "|Py_TPFLAGS_BASETYPE"
if scope.needs_gc(): if scope.needs_gc():
value += "|Py_TPFLAGS_HAVE_GC" value += "|Py_TPFLAGS_HAVE_GC"
......
cimport cython
@cython.internal
cdef class InternalType:
"""
NOTE: this doesn't fail because it is never tested !
>>> i = InternalType
"""
cdef class PublicType:
"""
>>> p = PublicType
"""
def test():
"""
>>> p,i = test()
>>> p = PublicType
>>> i = InternalType
Traceback (most recent call last):
NameError: name 'InternalType' is not defined
"""
p = PublicType
i = InternalType
return p,i
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment