From 2db8ba020a93a45d2b73e334262f5639e2e5e777 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sun, 6 Dec 2009 11:55:19 +0100 Subject: [PATCH] support non-bool options and multiple options as compiler comment directives --- Cython/Compiler/CmdLine.py | 2 +- Cython/Compiler/Options.py | 35 +++++++++++++++-------------------- Cython/Compiler/Parsing.py | 8 +++----- 3 files changed, 19 insertions(+), 26 deletions(-) diff --git a/Cython/Compiler/CmdLine.py b/Cython/Compiler/CmdLine.py index 4818789e..92e66e8c 100644 --- a/Cython/Compiler/CmdLine.py +++ b/Cython/Compiler/CmdLine.py @@ -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) diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py index 0e031c19..d5a540d7 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@ -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 diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 95769e84..73345a98 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -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() -- 2.26.2