Merge (++, see details)
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Mon, 22 Sep 2008 20:26:49 +0000 (22:26 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Mon, 22 Sep 2008 20:26:49 +0000 (22:26 +0200)
Also fixed a bug that the merge revealed.
Also added CythonTransform.current_directives.

1  2 
Cython/Compiler/AutoDocTransforms.py
Cython/Compiler/Code.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/Main.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/Optimize.py
Cython/Compiler/Options.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/Symtab.py
Cython/Compiler/Visitor.py

index 0000000000000000000000000000000000000000,0ffb73ea6bb4ad98571744efaa47d6e9e1f8af01..0e65ce2e3ed4d3cfc6a5deb664d9bd340a18065b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,173 +1,172 @@@
 -            self.visitchildren(node)
 -            return node
+ 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:
 -        if not node.options['embedsignature']:
++            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 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
index bb70a8bd846b88688cf5c9bf83883c9cc658ec27,e0897b4d450ef4541ede4eb1fd474a4cea6b1c2d..6fe06d88d82f61586dd755195d4140c3a6a3a3dd
@@@ -161,13 -161,7 +161,13 @@@ class GlobalState(object)
      # interned_nums
      # cached_builtins
  
-     def __init__(self, rootwriter):
 +    # directives       set             Temporary variable used to track
 +    #                                  the current set of directives in the code generation
 +    #                                  process.
 +
 +    directives = {}
 +
+     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
Simple merge
index 91e21cba48915c5e6d57b4e92f67d2c8ad0a2f5a,506c63a1da60a66a4f2e1350406c2ff95018a725..138f5e3de9f534f1df46312006e1f69f37773a8a
@@@ -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),
index 32f06168545636bbd9b9663e64d9cdbd41b22e5e,3863974ef0f7e390597009d9b7fa90088af2fb14..035efbde9047acd7e417294eb82389ed3cab363d
@@@ -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:
Simple merge
Simple merge
index 910afc5a865ebd07bc5b2d7e730232564bea586f,28f98ebcd288bd36367243021051e78c9320b2e8..dd26a14a60ecac9cbd3cc8ad4af9c3873aebaef3
@@@ -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):
index 7529114f3bcb2bb14c0bceac3eb08eb070f58dae,895c836bc8046b274f6bee3bbca03169eead66aa..a8691788e79f8b43263091f8215a3b3f8cdea85c
@@@ -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):
Simple merge
index fd26660286cbfeedfb1ca6238e85c0dc2b97282c,80cd3b3585ce9e4b89b94517f4ff2676721d8db2..2b855086cba2e93e878301f0ae665413167961db
@@@ -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):