support non-bool options and multiple options as compiler comment directives
authorStefan Behnel <scoder@users.berlios.de>
Sun, 6 Dec 2009 10:55:19 +0000 (11:55 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Sun, 6 Dec 2009 10:55:19 +0000 (11:55 +0100)
Cython/Compiler/CmdLine.py
Cython/Compiler/Options.py
Cython/Compiler/Parsing.py

index 4818789eaef901b820dc9a1965f36a2154ba62b1..92e66e8c2056d2c232554f540efe04528e432a0f 100644 (file)
@@ -121,7 +121,7 @@ def parse_command_line(args):
                 options.emit_linenums = True
             elif option in ("-X", "--directive"):
                 try:
-                    options.compiler_directives = Options.parse_directive_list(pop_arg())
+                    options.compiler_directives = Options.parse_directive_list(pop_arg(), relaxed_bool=True)
                 except ValueError, e:
                     sys.stderr.write("Error in compiler directive: %s\n" % e.message)
                     sys.exit(1)
index 0e031c19925b1764ffce96e8f0750ce1b3aa380b..d5a540d70fa4d79b750c8878fa2c442bccdeb8d8 100644 (file)
@@ -84,7 +84,7 @@ directive_scopes = { # defaults to available everywhere
     'test_fail_if_path_exists' : ('function',),
 }
 
-def parse_directive_value(name, value):
+def parse_directive_value(name, value, relaxed_bool=False):
     """
     Parses value as an option value for the given name and returns
     the interpreted value. None is returned if the option does not exist.
@@ -102,9 +102,14 @@ def parse_directive_value(name, value):
     type = directive_types.get(name)
     if not type: return None
     if type is bool:
-        if value == "True": return True
-        elif value == "False": return False
-        else: raise ValueError("%s directive must be set to True or False" % name)
+        value = str(value)
+        if value == 'True': return True
+        if value == 'False': return False
+        if relaxed_bool:
+            value = value.lower()
+            if value in ("true", "yes"): return True
+            elif value in ("false", "no"): return False
+        raise ValueError("%s directive must be set to True or False" % name)
     elif type is int:
         try:
             return int(value)
@@ -115,7 +120,7 @@ def parse_directive_value(name, value):
     else:
         assert False
 
-def parse_directive_list(s):
+def parse_directive_list(s, relaxed_bool=False):
     """
     Parses a comma-seperated list of pragma options. Whitespace
     is not considered.
@@ -132,7 +137,7 @@ def parse_directive_list(s):
     >>> parse_directive_list('boundscheck=hey')
     Traceback (most recent call last):
        ...
-    ValueError: Must pass a boolean value for option "boundscheck"
+    ValueError: boundscheck directive must be set to True or False
     >>> parse_directive_list('unknown=True')
     Traceback (most recent call last):
        ...
@@ -143,19 +148,9 @@ def parse_directive_list(s):
         item = item.strip()
         if not item: continue
         if not '=' in item: raise ValueError('Expected "=" in option "%s"' % item)
-        name, value = item.strip().split('=')
-        try:
-            type = directive_types[name]
-        except KeyError:
+        name, value = [ s.strip() for s in item.strip().split('=', 1) ]
+        parsed_value = parse_directive_value(name, value, relaxed_bool=relaxed_bool)
+        if parsed_value is None:
             raise ValueError('Unknown option: "%s"' % name)
-        if type is bool:
-            value = value.lower()
-            if value in ('true', 'yes'):
-                value = True
-            elif value in ('false', 'no'):
-                value = False
-            else: raise ValueError('Must pass a boolean value for option "%s"' % name)
-            result[name] = value
-        else:
-            assert False
+        result[name] = parsed_value
     return result
index 95769e849ef4e9dd96fa55d5328ab000843bbd1d..73345a9879d532bab9f22fc487fe870121fd9901 100644 (file)
@@ -2579,18 +2579,16 @@ def p_code(s, level=None):
             repr(s.sy), repr(s.systring)))
     return body
 
-COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*(\w+)\s*=(.*)$")
+COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*(\w+\s*=.*)$")
 
 def p_compiler_directive_comments(s):
     result = {}
     while s.sy == 'commentline':
         m = COMPILER_DIRECTIVE_COMMENT_RE.match(s.systring)
         if m:
-            name = m.group(1)
+            directives = m.group(1).strip()
             try:
-                value = Options.parse_directive_value(str(name), str(m.group(2).strip()))
-                if value is not None: # can be False!
-                    result[name] = value
+                result.update( Options.parse_directive_list(directives) )
             except ValueError, e:
                 s.error(e.args[0], fatal=False)
         s.next()