...
 
Commits (386)
This diff is collapsed.
......@@ -2039,7 +2039,7 @@ class CCodeWriter(object):
entry.cname, dll_linkage=dll_linkage))
if entry.init is not None:
self.put_safe(" = %s" % entry.type.literal_code(entry.init))
elif entry.type.is_pyobject:
elif entry.type.is_pyobject or entry.type.is_cyp_class:
self.put(" = NULL")
self.putln(";")
......@@ -2050,6 +2050,8 @@ class CCodeWriter(object):
self.putln("%s = NULL;" % decl)
elif type.is_memoryviewslice:
self.putln("%s = %s;" % (decl, type.literal_code(type.default_value)))
elif type.is_cyp_class:
self.putln("%s = NULL;" % decl)
else:
self.putln("%s%s;" % (static and "static " or "", decl))
......@@ -2082,7 +2084,8 @@ class CCodeWriter(object):
return ''
return '%s ' % ' '.join([mapper(m,m) for m in modifiers])
# Python objects and reference counting
# Reference counting
def entry_as_pyobject(self, entry):
type = entry.type
......
This diff is collapsed.
This diff is collapsed.
......@@ -373,7 +373,9 @@ class NameDeletion(NameAssignment):
def infer_type(self):
inferred_type = self.rhs.infer_type(self.entry.scope)
if (not inferred_type.is_pyobject
and inferred_type.can_coerce_to_pyobject(self.entry.scope)):
and inferred_type.can_coerce_to_pyobject(self.entry.scope)
and not inferred_type.is_cyp_class):
# do not coerce cypclass to pyobject just for a del statement
return PyrexTypes.py_object_type
self.inferred_type = inferred_type
return inferred_type
......
This diff is collapsed.
......@@ -167,6 +167,9 @@ exc_vars = (exc_type_name, exc_value_name, exc_tb_name)
api_name = pyrex_prefix + "capi__"
# cname for the type that defines the essential memory layout of a cypclass wrapper.
cypclass_wrapper_layout_type = "CyPyObject"
# the h and api guards get changed to:
# __PYX_HAVE__FILENAME (for ascii filenames)
# __PYX_HAVE_U_PUNYCODEFILENAME (for non-ascii filenames)
......
This diff is collapsed.
......@@ -2066,6 +2066,20 @@ def p_with_items(s, is_async=False):
else:
body = p_suite(s)
return Nodes.GILStatNode(pos, state=state, body=body, condition=condition)
elif not s.in_python_file and s.sy == 'IDENT' and s.systring in ('unlocked', 'rlocked', 'wlocked'):
state = s.systring
s.next()
if s.sy != 'IDENT':
s.error("The with %s statement must be followed by the cypclass object to operate on" % state, pos)
obj = p_starred_expr(s)
if s.sy == ',':
s.next()
body = p_with_items(s, is_async=is_async)
else:
body = p_suite(s)
return Nodes.LockCypclassNode(pos, state=state, obj=obj, body=body)
else:
manager = p_test(s)
target = None
......@@ -2249,10 +2263,12 @@ def p_statement(s, ctx, first_statement = 0):
return p_pass_statement(s, with_newline=1)
overridable = 0
nogil_flag = ctx.nogil
if s.sy == 'cdef':
cdef_flag = 1
s.next()
elif s.sy == 'cpdef':
s.level = ctx.level
cdef_flag = 1
overridable = 1
s.next()
......@@ -2260,7 +2276,7 @@ def p_statement(s, ctx, first_statement = 0):
if ctx.level not in ('module', 'module_pxd', 'function', 'c_class', 'c_class_pxd'):
s.error('cdef statement not allowed here')
s.level = ctx.level
node = p_cdef_statement(s, ctx(overridable=overridable))
node = p_cdef_statement(s, ctx(overridable=overridable, nogil=nogil_flag))
if decorators is not None:
tup = (Nodes.CFuncDefNode, Nodes.CVarDefNode, Nodes.CClassDefNode)
if ctx.allow_struct_enum_decorator:
......@@ -3066,6 +3082,8 @@ def p_cdef_statement(s, ctx):
if ctx.overridable:
error(pos, "cdef blocks cannot be declared cpdef")
return p_cdef_block(s, ctx)
elif ctx.overridable and ctx.nogil:
error(pos, "nogil blocks cannot be declared cpdef")
elif s.sy == ':':
if ctx.overridable:
error(pos, "cdef blocks cannot be declared cpdef")
......@@ -3076,7 +3094,7 @@ def p_cdef_statement(s, ctx):
if ctx.overridable:
error(pos, "Extension types cannot be declared cpdef")
return p_c_class_definition(s, pos, ctx)
elif s.sy == 'IDENT' and s.systring == 'cppclass':
elif s.sy == 'IDENT' and s.systring in ('cppclass', 'cypclass'):
return p_cpp_class_definition(s, pos, ctx)
elif s.sy == 'IDENT' and s.systring in struct_enum_union:
if ctx.level not in ('module', 'module_pxd'):
......@@ -3742,7 +3760,8 @@ def p_template_definition(s):
return name, required
def p_cpp_class_definition(s, pos, ctx):
# s.sy == 'cppclass'
# s.sy in ('cppclass', 'cypclass')
cypclass = s.systring == 'cypclass'
s.next()
module_path = []
class_name = p_ident(s)
......@@ -3773,7 +3792,12 @@ def p_cpp_class_definition(s, pos, ctx):
base_classes = []
if s.sy == '[':
error(s.position(), "Name options not allowed for C++ class")
nogil = p_nogil(s)
nogil = p_nogil(s) or cypclass
lock_mode = None
activable = False
if cypclass:
lock_mode = p_cypclass_lock_mode(s)
activable = p_cypclass_activable(s)
if s.sy == ':':
s.next()
s.expect('NEWLINE')
......@@ -3802,13 +3826,13 @@ def p_cpp_class_definition(s, pos, ctx):
visibility = ctx.visibility,
in_pxd = ctx.level == 'module_pxd',
attributes = attributes,
templates = templates)
templates = templates, cypclass=cypclass, lock_mode=lock_mode, activable=activable)
def p_cpp_class_attribute(s, ctx):
decorators = None
if s.sy == '@':
decorators = p_decorators(s)
if s.systring == 'cppclass':
if s.systring in ('cppclass', 'cypclass'):
return p_cpp_class_definition(s, s.position(), ctx)
elif s.systring == 'ctypedef':
return p_ctypedef_statement(s, ctx)
......@@ -3828,6 +3852,20 @@ def p_cpp_class_attribute(s, ctx):
node.decorators = decorators
return node
def p_cypclass_lock_mode(s):
if s.sy == 'IDENT' and s.systring in ('nolock', 'checklock', 'autolock'):
mode = s.systring
s.next()
return mode
else:
return None
def p_cypclass_activable(s):
if s.sy == 'IDENT' and s.systring == 'activable':
s.next()
return True
else:
return False
#----------------------------------------------
#
......
......@@ -141,6 +141,7 @@ def inject_utility_code_stage_factory(context):
def create_pipeline(context, mode, exclude_classes=()):
assert mode in ('pyx', 'py', 'pxd')
from .Visitor import PrintTree
from .CypclassTransforms import CypclassWrapperInjection, CypclassLockTransform
from .ParseTreeTransforms import WithTransform, NormalizeTree, PostParse, PxdPostParse
from .ParseTreeTransforms import ForwardDeclareTypes, InjectGilHandling, AnalyseDeclarationsTransform
from .ParseTreeTransforms import AnalyseExpressionsTransform, FindInvalidUseOfFusedTypes
......@@ -197,6 +198,7 @@ def create_pipeline(context, mode, exclude_classes=()):
ForwardDeclareTypes(context),
InjectGilHandling(),
AnalyseDeclarationsTransform(context),
CypclassWrapperInjection(context),
AutoTestDictTransform(context),
EmbedSignature(context),
EarlyReplaceBuiltinCalls(context), ## Necessary?
......@@ -210,6 +212,7 @@ def create_pipeline(context, mode, exclude_classes=()):
_check_c_declarations,
InlineDefNodeCalls(context),
AnalyseExpressionsTransform(context),
CypclassLockTransform(context),
FindInvalidUseOfFusedTypes(context),
ExpandInplaceOperators(context),
IterationTransform(context),
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -16,6 +16,7 @@ class TestMethodDispatcherTransform(TransformTest):
def fake_module(node):
scope = ModuleScope('test', None, None)
scope.cpp = False
return ModuleNode(node.pos, doc=None, body=node,
scope=scope, full_module_name='test',
directive_comments={})
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.