From 5326aee8e8bc4f7ac2472d95bbfb125a19393cef Mon Sep 17 00:00:00 2001 From: Xavier Thompson <xavier.thompson@nexedi.com> Date: Thu, 10 Sep 2020 15:58:50 +0200 Subject: [PATCH] Introduce 'mutable' specifier from C++ --- Cython/Compiler/ModuleNode.py | 2 ++ Cython/Compiler/Nodes.py | 8 ++++++++ Cython/Compiler/Parsing.py | 2 +- Cython/Compiler/Symtab.py | 2 ++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index cc0d08e99..f9be333b2 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -1628,6 +1628,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.putln("%s;" % dunder_activate_entry.type.declaration_code(dunder_activate_entry.cname)) for attr in scope.var_entries: cname = attr.cname + if attr.is_mutable: + code.put("mutable ") if attr.type.is_cfunction and attr.type.is_static_method: code.put("static ") elif attr.name == "<init>": diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 17c4f0013..41d3cfcee 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1423,6 +1423,8 @@ class CVarDefNode(StatNode): cfunc_declarator.args = [] cfunc_declarator.skipped_self = None + if 'mutable' in self.modifiers: + error(self.pos, "Functions cannot be 'mutable'") self.entry = dest_scope.declare_cfunction( name, type, declarator.pos, cname=cname, visibility=self.visibility, in_pxd=self.in_pxd, @@ -1447,6 +1449,10 @@ class CVarDefNode(StatNode): api=self.api, is_cdef=1) if Options.docstrings: self.entry.doc = embed_position(self.pos, self.doc) + if 'mutable' in self.modifiers: + if not dest_scope.is_cpp_class_scope: + error(self.pos, "Specifier 'mutable' can only apply to cppclass variable members") + self.entry.is_mutable = 1 class CStructOrUnionDefNode(StatNode): @@ -2689,6 +2695,8 @@ class CFuncDefNode(FuncDefNode): typ.is_static_method = self.is_static_method typ.is_cyp_class_method = self.is_cyp_class_method + if 'mutable' in self.modifiers: + error(self.pos, "Functions cannot be 'mutable'") self.entry = env.declare_cfunction( name, typ, self.pos, cname=cname, visibility=self.visibility, api=self.api, diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 90be754ea..4f239c5c4 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -3332,7 +3332,7 @@ def p_visibility(s, prev_visibility): return visibility def p_c_modifiers(s): - if s.sy == 'IDENT' and s.systring in ('inline',): + if s.sy == 'IDENT' and s.systring in ('inline', 'mutable'): modifier = s.systring s.next() return [modifier] + p_c_modifiers(s) diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 21bfde3f9..d514d6af7 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -105,6 +105,7 @@ class Entry(object): # is_cclass boolean Is an extension class # is_cpp_class boolean Is a C++ class # is_const boolean Is a constant + # is_mutable boolean Is a mutable attribute # is_property boolean Is a property of an extension type: # doc_cname string or None C const holding the docstring # getter_cname string C func for getting property @@ -201,6 +202,7 @@ class Entry(object): is_cclass = 0 is_cpp_class = 0 is_const = 0 + is_mutable = 0 is_property = 0 is_cproperty = 0 doc_cname = None -- 2.30.9