From: Dag Sverre Seljebotn Date: Mon, 22 Sep 2008 20:26:49 +0000 (+0200) Subject: Merge (++, see details) X-Git-Tag: 0.9.9.2.beta~95 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a22365263b0e9ce64104f48a026796e29840b184;p=cython.git Merge (++, see details) Also fixed a bug that the merge revealed. Also added CythonTransform.current_directives. --- a22365263b0e9ce64104f48a026796e29840b184 diff --cc Cython/Compiler/AutoDocTransforms.py index 00000000,0ffb73ea..0e65ce2e mode 000000,100644..100644 --- a/Cython/Compiler/AutoDocTransforms.py +++ b/Cython/Compiler/AutoDocTransforms.py @@@ -1,0 -1,173 +1,172 @@@ + import re + + from Cython.Compiler.Visitor import CythonTransform + from Cython.Compiler.Nodes import DefNode, CFuncDefNode + from Cython.Compiler.Errors import CompileError + from Cython.Compiler.StringEncoding import EncodedString + from Cython.Compiler import Options + + + class EmbedSignature(CythonTransform): + + SPECIAL_METHOD_RE = re.compile(r'__\w+__') + + def __init__(self, context): + super(EmbedSignature, self).__init__(context) + self.denv = None # XXX + self.is_in_class = False + self.class_name = None + + def _fmt_basic_c_type_modifiers(self, ctype): + longness = ctype.longness + modifiers = '' + if longness < 0: + modifiers = 'short ' + elif longness > 0: + modifiers = 'long ' * longness + signed = ctype.signed + if signed == 0: + modifiers = 'unsigned ' + modifiers + elif signed == 2: + modifiers = 'signed ' + modifiers + return modifiers[:-1] # strip final space + + def _fmt_arg_type(self, arg): + try: + base_type = arg.base_type + arg_type = base_type.name + except AttributeError: + return '' + if base_type.is_basic_c_type: + modifiers = self._fmt_basic_c_type_modifiers(base_type) + if modifiers: + arg_type = '%s %s' % (modifiers, arg_type) + return arg_type + + def _fmt_arg_name(self, arg): + try: + return arg.declarator.name + except AttributeError: + return arg.declarator.base.name + + def _fmt_arg_defv(self, arg): + if not arg.default: + return None + try: + denv = self.denv # XXX + ctval = arg.default.compile_time_value(self.denv) + return '%s' % ctval + except Exception: + try: + return arg.default.name # XXX + except AttributeError: + return '' + + def _fmt_arg(self, arg): + arg_type = self._fmt_arg_type(arg) + arg_name = self._fmt_arg_name(arg) + arg_defv = self._fmt_arg_defv(arg) + doc = arg_name + if arg_type: + doc = ('%s ' % arg_type) + doc + if arg_defv: + doc = doc + ('=%s' % arg_defv) + return doc + + def _fmt_arglist(self, args, + npargs=0, pargs=None, + nkargs=0, kargs=None): + arglist = [] + for arg in args: + arg_doc = self._fmt_arg(arg) + arglist.append(arg_doc) + if pargs: + arglist.insert(npargs, '*%s' % pargs.name) + elif nkargs: + arglist.insert(npargs, '*') + if kargs: + arglist.append('**%s' % kargs.name) + return arglist + + def _fmt_ret_type(self, ret): + ret_type = ret.name + if ret_type is None: + return '' + modifiers = self._fmt_basic_c_type_modifiers(ret) + if modifiers: + ret_type = '%s %s' % (modifiers, ret_type) + return ret_type + + def _fmt_signature(self, cls_name, func_name, args, + npargs=0, pargs=None, + nkargs=0, kargs=None, + return_type=None): + arglist = self._fmt_arglist(args, + npargs, pargs, + nkargs, kargs) + arglist_doc = ', '.join(arglist) + func_doc = '%s(%s)' % (func_name, arglist_doc) + if cls_name: + func_doc = '%s.%s' % (cls_name, func_doc) + if return_type: + ret_doc = self._fmt_ret_type(return_type) + if ret_doc: + func_doc = '%s -> %s' % (func_doc, ret_doc) + return func_doc + + def _embed_signature(self, signature, node_doc): + if node_doc: + return signature + '\n' + node_doc + else: + return signature + + + def __call__(self, node): + if not Options.docstrings: + return node + else: - self.visitchildren(node) - return node ++ return super(EmbedSignature, self).__call__(node) + + def visit_ClassDefNode(self, node): + oldincls = self.is_in_class + oldname = self.class_name + self.is_in_class = True + try: + # PyClassDefNode + self.class_name = node.name + except AttributeError: + # CClassDefNode + self.class_name = node.class_name + self.visitchildren(node) + self.is_in_class = oldincls + self.class_name = oldname + return node + + def visit_FuncDefNode(self, node): - if not node.options['embedsignature']: ++ if not self.current_directives['embedsignature']: + return node + + signature = None + if type(node) is DefNode: # def FOO(...): + special_method = (self.is_in_class and \ + self.SPECIAL_METHOD_RE.match(node.name)) + if not special_method: + nkargs = getattr(node, 'num_kwonly_args', 0) + npargs = len(node.args) - nkargs + signature = self._fmt_signature( + self.class_name, node.name, node.args, + npargs, node.star_arg, + nkargs, node.starstar_arg, + return_type=None) + elif type(node) is CFuncDefNode: + if node.overridable: # cpdef FOO(...): + signature = self._fmt_signature( + self.class_name, node.declarator.base.name, + node.declarator.args, + return_type=node.base_type) + else: # should not fall here ... + assert False + if signature: + new_doc = self._embed_signature(signature, node.doc) + node.doc = EncodedString(new_doc) # XXX + return node diff --cc Cython/Compiler/Code.py index bb70a8bd,e0897b4d..6fe06d88 --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@@ -161,13 -161,7 +161,13 @@@ class GlobalState(object) # interned_nums # cached_builtins + # directives set Temporary variable used to track + # the current set of directives in the code generation + # process. + + directives = {} + - def __init__(self, rootwriter): + def __init__(self, rootwriter, emit_linenums=False): self.filename_table = {} self.filename_list = [] self.input_file_contents = {} @@@ -421,8 -418,9 +424,9 @@@ class CCodeWriter(object) # generation (labels and temps state etc.) # globalstate GlobalState contains state global for a C file (input file info, # utility code, declared constants etc.) + # emit_linenums boolean whether or not to write #line pragmas - + - def __init__(self, create_from=None, buffer=None, copy_formatting=False): + def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None): if buffer is None: buffer = StringIOTree() self.buffer = buffer self.marker = None diff --cc Cython/Compiler/Main.py index 91e21cba,506c63a1..138f5e3d --- a/Cython/Compiler/Main.py +++ b/Cython/Compiler/Main.py @@@ -79,7 -79,8 +79,8 @@@ class Context from ParseTreeTransforms import WithTransform, NormalizeTree, PostParse, PxdPostParse from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform - from ParseTreeTransforms import ResolveOptions + from ParseTreeTransforms import InterpretCompilerDirectives + from AutoDocTransforms import EmbedSignature from Optimize import FlattenInListTransform, SwitchTransform, OptimizeRefcounting from Buffer import IntroduceBufferAuxiliaryVars from ModuleNode import check_c_classes @@@ -95,7 -96,8 +96,8 @@@ NormalizeTree(self), PostParse(self), _specific_post_parse, - ResolveOptions(self, self.pragma_overrides), + InterpretCompilerDirectives(self, self.pragma_overrides), + EmbedSignature(self), FlattenInListTransform(), WithTransform(self), DecoratorTransform(self), diff --cc Cython/Compiler/ModuleNode.py index 32f06168,3863974e..035efbde --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@@ -41,9 -40,8 +40,10 @@@ class ModuleNode(Nodes.Node, Nodes.Bloc # # scope The module scope. # compilation_source A CompilationSource (see Main) + # directives Top-level compiler directives child_attrs = ["body"] ++ directives = None def analyse_declarations(self, env): if Options.embed_pos_in_docstring: diff --cc Cython/Compiler/Options.py index 910afc5a,28f98ebc..dd26a14a --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@@ -57,12 -57,12 +57,14 @@@ c_line_in_traceback = # Declare pragmas option_types = { 'boundscheck' : bool, - 'nonecheck' : bool - 'embedsignature' : bool, ++ 'nonecheck' : bool, ++ 'embedsignature' : bool } option_defaults = { 'boundscheck' : True, - 'nonecheck' : False ++ 'nonecheck' : False, + 'embedsignature' : False, } def parse_option_value(name, value): diff --cc Cython/Compiler/ParseTreeTransforms.py index 7529114f,895c836b..a8691788 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@@ -343,12 -336,9 +345,12 @@@ class InterpretCompilerDirectives(Cytho newoptions = copy.copy(oldoptions) newoptions.update(options) self.options = newoptions - node = self.visit_Node(node) + assert isinstance(body, StatListNode), body + retbody = self.visit_Node(body) + directive = CompilerDirectivesNode(pos=retbody.pos, body=retbody, - directives=options) ++ directives=newoptions) self.options = oldoptions - return node + return directive # Handle decorators def visit_DefNode(self, node): diff --cc Cython/Compiler/Visitor.py index fd266602,80cd3b35..2b855086 --- a/Cython/Compiler/Visitor.py +++ b/Cython/Compiler/Visitor.py @@@ -164,11 -163,11 +164,26 @@@ class CythonTransform(VisitorTransform) super(CythonTransform, self).__init__() self.context = context ++ def __call__(self, node): ++ import ModuleNode ++ if isinstance(node, ModuleNode.ModuleNode): ++ self.current_directives = node.directives ++ return super(CythonTransform, self).__call__(node) ++ ++ def visit_CompilerDirectivesNode(self, node): ++ old = self.current_directives ++ self.current_directives = node.directives ++ self.visitchildren(node) ++ self.current_directives = old ++ return node ++ def visit_Node(self, node): self.visitchildren(node) return node ++ ++ # Utils def ensure_statlist(node): if not isinstance(node, Nodes.StatListNode):