Merge -dagss and -devel
authorRobert Bradshaw <robertwb@math.washington.edu>
Sat, 7 Jun 2008 00:46:37 +0000 (17:46 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sat, 7 Jun 2008 00:46:37 +0000 (17:46 -0700)
1  2 
Cython/Compiler/CmdLine.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/Main.py
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/Parsing.py
Cython/Compiler/Scanning.py
tests/run/big_indices.pyx

Simple merge
Simple merge
index 5d45408741604ae2d7fe3720cbcd7cbd10f77454,c2348fce4f2f4f5a0b23bc3857bb4f76024e6365..d308457571b86e32501c744faaf6d9805d491652
@@@ -14,31 -14,15 +14,30 @@@ except NameError
      from sets import Set as set
  
  from time import time
+ import Code
+ import Errors
+ import Parsing
  import Version
- import Errors
 +from Scanning import PyrexScanner, FileSourceDescriptor
  from Errors import PyrexError, CompileError, error
- import Parsing
 -from Scanning import PyrexScanner
  from Symtab import BuiltinScope, ModuleScope
- import Code
- from Cython.Utils import replace_suffix
  from Cython import Utils
 -import Transform
 +
 +# Note: PHASES and TransformSet should be removed soon; but that's for
 +# another day and another commit.
 +PHASES = [
 +    'before_analyse_function', # run in FuncDefNode.generate_function_definitions
 +    'after_analyse_function'   # run in FuncDefNode.generate_function_definitions
 +]
 +
 +class TransformSet(dict):
 +    def __init__(self):
 +        for name in PHASES:
 +            self[name] = []
 +    def run(self, name, node, **options):
 +        assert name in self, "Transform phase %s not defined" % name
 +        for transform in self[name]:
 +            transform(node, phase=name, **options)
  
  verbose = 0
  
@@@ -140,17 -126,90 +142,93 @@@ class Context
          # None if not found, but does not report an error.
          dirs = self.include_directories
          if pos:
 -            here_dir = os.path.dirname(pos[0])
 +            file_desc = pos[0]
 +            if not isinstance(file_desc, FileSourceDescriptor):
 +                raise RuntimeError("Only file sources for code supported")
 +            here_dir = os.path.dirname(file_desc.filename)
              dirs = [here_dir] + dirs
+         dotted_filename = qualified_name + suffix
+         if split_package:
+             names = qualified_name.split('.')
+             package_names = names[:-1]
+             module_name = names[-1]
+             module_filename = module_name + suffix
+             package_filename = "__init__" + suffix
          for dir in dirs:
-             path = os.path.join(dir, filename)
+             path = os.path.join(dir, dotted_filename)
              if os.path.exists(path):
                  return path
+             if split_package:
+                 package_dir = self.check_package_dir(dir, package_names)
+                 if package_dir is not None:
+                     path = os.path.join(package_dir, module_filename)
+                     if os.path.exists(path):
+                         return path
+                     path = os.path.join(dir, package_dir, module_name,
+                                         package_filename)
+                     if os.path.exists(path):
+                         return path
          return None
  
+     def check_package_dir(self, dir, package_names):
+         package_dir = os.path.join(dir, *package_names)
+         if not os.path.exists(package_dir):
+             return None
+         for dirname in package_names:
+             dir = os.path.join(dir, dirname)
+             package_init = os.path.join(dir, "__init__.py")
+             if not os.path.exists(package_init) and \
+                     not os.path.exists(package_init + "x"): # same with .pyx ?
+                 return None
+         return package_dir
+     def c_file_out_of_date(self, source_path):
+         c_path = Utils.replace_suffix(source_path, ".c")
+         if not os.path.exists(c_path):
+             return 1
+         c_time = Utils.modification_time(c_path)
+         if Utils.file_newer_than(source_path, c_time):
+             return 1
+         pos = [source_path]
+         pxd_path = Utils.replace_suffix(source_path, ".pxd")
+         if os.path.exists(pxd_path) and Utils.file_newer_than(pxd_path, c_time):
+             return 1
+         for kind, name in self.read_dependency_file(source_path):
+             if kind == "cimport":
+                 dep_path = self.find_pxd_file(name, pos)
+             elif kind == "include":
+                 dep_path = self.search_include_directories(name, pos)
+             else:
+                 continue
+             if dep_path and Utils.file_newer_than(dep_path, c_time):
+                 return 1
+         return 0
+     
+     def find_cimported_module_names(self, source_path):
+         return [ name for kind, name in self.read_dependency_file(source_path)
+                  if kind == "cimport" ]
+     def is_package_dir(self, dir_path):
+         #  Return true if the given directory is a package directory.
+         for filename in ("__init__.py", "__init__.pyx"):
+             path = os.path.join(dir_path, filename)
+             if os.path.exists(path):
+                 return 1
+     def read_dependency_file(self, source_path):
+         dep_path = replace_suffix(source_path, ".dep")
+         if os.path.exists(dep_path):
+             f = open(dep_path, "rU")
+             chunks = [ line.strip().split(" ", 1)
+                        for line in f.readlines()
+                        if " " in line.strip() ]
+             f.close()
+             return chunks
+         else:
+             return ()
      def lookup_submodule(self, name):
          # Look up a top-level module. Returns None if not found.
          return self.modules.get(name, None)
                  c_suffix = ".cpp"
              else:
                  c_suffix = ".c"
-             result.c_file = replace_suffix(source, c_suffix)
 -            result.c_file = Utils.replace_suffix(source, c_suffix)
++            result.c_file = Utils .replace_suffix(source, c_suffix)
 +        c_stat = None
 +        if result.c_file:
 +            try:
 +                c_stat = os.stat(result.c_file)
 +            except EnvironmentError:
 +                pass
-         module_name = full_module_name # self.extract_module_name(source, options)
+         module_name = full_module_name or self.extract_module_name(source, options)
 +        source = FileSourceDescriptor(source)
          initial_pos = (source, 1, 0)
          scope = self.find_module(module_name, pos = initial_pos, need_pxd = 0)
          errors_occurred = False
          try:
-             tree = self.parse(source, scope.type_names, pxd = 0, full_module_name = full_module_name)
 -            tree = self.parse(source, scope, pxd = 0,
++            tree = self.parse(source, scope.type_names, pxd = 0,
+                               full_module_name = full_module_name)
              tree.process_implementation(scope, options, result)
          except CompileError:
              errors_occurred = True
@@@ -387,9 -516,13 +546,12 @@@ default_options = dict
      output_file = None,
      annotate = False,
      generate_pxi = 0,
-     working_path = "")
-     
 +    transforms = TransformSet(),
 -    quiet = 0,
 -    transforms = Transform.TransformSet(),
 -    working_path = "")
 -    
++    working_path = "",
+     recursive = 0,
+     timestamps = None,
+     verbose = 0,
++    quiet = 0)
  if sys.platform == "mac":
      from Cython.Mac.MacSystem import c_compile, c_link, CCompilerError
      default_options['use_listing_file'] = 1
Simple merge
index c280caa533e3a0b80dee644c99341af184a48b26,1e5479fd62343b2b5d60b6b9a28ec93172d9b35d..829c4ffb841d3d7cd35b4ee14e00d7bdc369ebc6
@@@ -82,19 -106,58 +82,28 @@@ class Node(object)
      def __init__(self, pos, **kw):
          self.pos = pos
          self.__dict__.update(kw)
 -
 +    
+     gil_message = "Operation"
+     def gil_check(self, env):
+         if env.nogil:
+             self.gil_error()
+     def gil_error(self):
+         error(self.pos, "%s not allowed without gil" % self.gil_message)
 -    def get_child_accessors(self):
 -        """Returns an iterator over the children of the Node. Each member in the
 -        iterated list is an object with get(), set(value), and name() methods,
 -        which can be used to fetch and replace the child and query the name
 -        the relation this node has with the child. For instance, for an
 -        assignment node, this code:
 -        
 -        for child in assignment_node.get_child_accessors():
 -            print(child.name())
 -            child.set(i_node)
 -        
 -        will print "lhs", "rhs", and change the assignment statement to "i = i"
 -        (assuming that i_node is a node able to represent the variable i in the
 -        tree).
 -        
 -        Any kind of objects can in principle be returned, but the typical
 -        candidates are either Node instances or lists of node instances.
 -        
 -        The object returned in each iteration stage can only be used until the
 -        iterator is advanced to the next child attribute. (However, the objects
 -        returned by the get() function can be kept).
 -        
 -        Typically, a Node instance will have other interesting and potentially
 -        hierarchical attributes as well. These must be explicitly accessed -- this
 -        method only provides access to attributes that are deemed to naturally
 -        belong in the parse tree.
 -        
 -        Descandant classes can either specify child_attrs, override get_child_attrs,
 -        or override this method directly in order to provide access to their
 -        children. All descendants of Node *must* declare their children -- leaf nodes
 -        should simply declare "child_attrs = []".
 -        """
 -        attrnames = self.get_child_attrs()
 -        if attrnames is None:
 -            raise InternalError("Children access not implemented for %s" % \
 -                self.__class__.__name__)
 -        return _AttributeIterator(self, attrnames)
 -    
 -    def get_child_attrs(self):
 -        """Utility method for more easily implementing get_child_accessors.
 -        If you override get_child_accessors then this method is not used."""
 -        return self.child_attrs
 +    def clone_node(self):
 +        """Clone the node. This is defined as a shallow copy, except for member lists
 +           amongst the child attributes (from get_child_accessors) which are also
 +           copied. Lists containing child nodes are thus seen as a way for the node
 +           to hold multiple children directly; the list is not treated as a seperate
 +           level in the tree."""
 +        result = copy.copy(self)
 +        for attrname in result.child_attrs:
 +            value = getattr(result, attrname)
 +            if isinstance(value, list):
 +                setattr(result, attrname, value)
 +        return result
      
      
      #
index 7bdfa4d2d690371f258a36558184bbddc289de1a,74c670e8c8e0a1ca6a822f80cdd4df36d2809258..32ecde7d67eae88b441a4d8c3936a0b7b4be658b
@@@ -3,9 -3,8 +3,8 @@@
  #
  
  import os, re
- from string import join, replace
  from types import ListType, TupleType
 -from Scanning import PyrexScanner
 +from Scanning import PyrexScanner, FileSourceDescriptor
  import Nodes
  import ExprNodes
  from ModuleNode import ModuleNode
@@@ -1204,11 -1220,12 +1220,12 @@@ def p_include_statement(s, ctx)
      if s.compile_time_eval:
          include_file_path = s.context.find_include_file(include_file_name, pos)
          if include_file_path:
+             s.included_files.append(include_file_name)
              f = Utils.open_source_file(include_file_path, mode="rU")
 -            s2 = PyrexScanner(f, include_file_path, parent_scanner = s,
 -                              source_encoding=f.encoding)
 +            source_desc = FileSourceDescriptor(include_file_path)
 +            s2 = PyrexScanner(f, source_desc, s, source_encoding=f.encoding)
              try:
-                 tree = p_statement_list(s2, level)
+                 tree = p_statement_list(s2, ctx)
              finally:
                  f.close()
              return tree
index 4ba1718c7d4ca87903acf273021ff9a73d8f711d,39b89433fc701953982109a10dfed90886a2d043..2e20d18add461ca9780a99d780f4fc99fa6e854f
@@@ -287,8 -213,7 +287,7 @@@ class PyrexScanner(Scanner)
      resword_dict = build_resword_dict()
  
      def __init__(self, file, filename, parent_scanner = None, 
-             type_names = None, context = None, source_encoding=None):
 -                 scope = None, context = None, source_encoding=None):
++                 type_names = None, context = None, source_encoding=None):
          Scanner.__init__(self, get_lexicon(), file, filename)
          if parent_scanner:
              self.context = parent_scanner.context
index d8f3a765b6cef03f1da849255d2b9c327d2260a3,0bf13916d4e8fba240ef8e2e9b08909a9385234c..7a787912f987e97273d5ff39d5aab2aa4b934b1a
@@@ -1,7 -1,7 +1,7 @@@
  __doc__ = u"""
      >>> test()
--    neg -1
--    pos 4294967294
++    neg False
++    pos True
      neg
      pos
      neg
@@@ -12,10 -12,10 +12,10 @@@ def test()
      cdef long neg = -1
      cdef unsigned long pos = -2 # will be a large positive number
  
-     print "neg", neg
-     print "pos", pos
 -    print u"neg", neg
 -    print u"pos", pos
++    print "neg", neg > 0
++    print "pos", pos > -
  
 -    D = { neg: u'neg', pos: u'pos' }
 +    D = { neg: 'neg', pos: 'pos' }
  
      print D[<object>neg]
      print D[<object>pos]