Commit 2a581a2b authored by Robert Bradshaw's avatar Robert Bradshaw

Add infrastructure for migrating options to compiler directives.

parent ac4cbf02
......@@ -33,7 +33,7 @@ class _FakePool(object):
def parse_directives(option, name, value, parser):
dest = option.dest
old_directives = dict(getattr(parser.values, dest,
Options.directive_defaults))
Options.get_directive_defaults()))
directives = Options.parse_directive_list(
value, relaxed_bool=True, current_settings=old_directives)
setattr(parser.values, dest, directives)
......
......@@ -4,6 +4,30 @@
from __future__ import absolute_import
class ShouldBeFromDirective(object):
known_directives = []
def __init__(self, options_name, directive_name=None, dissallow=False):
self.options_name = options_name
self.directive_name = directive_name or options_name
self.dissallow = dissallow
self.known_directives.append(self)
def __nonzero__(self):
self._bad_access()
def __int__(self):
self._bad_access()
def _bad_access(self):
raise RuntimeError(repr(self))
def __repr__(self):
return (
"Illegal access of '%s' from Options module rather than directive '%s'"
% (self.options_name, self.directive_name))
# Include docstrings.
docstrings = True
......@@ -95,8 +119,25 @@ buffer_max_dims = 8
closure_freelist_size = 8
def get_directive_defaults():
# To add an item to this list, all accesses should be changed to use the new
# directive, and the global option itself should be set to an instance of
# ShouldBeFromDirective.
for old_option in ShouldBeFromDirective.known_directives:
value = globals().get(old_option.options_name)
assert old_option.directive_name in _directive_defaults
if not isinstance(value, ShouldBeFromDirective):
if old_option.disallow:
raise RuntimeError(
"Option '%s' must be set from directive '%s'" % (
old_option.option_name, old_option.directive_name))
else:
# Warn?
_directive_defaults[old_option.directive_name] = value
return _directive_defaults
# Declare compiler directives
directive_defaults = {
_directive_defaults = {
'boundscheck' : True,
'nonecheck' : False,
'initializedcheck' : True,
......@@ -237,7 +278,7 @@ directive_types = {
'c_string_encoding': normalise_encoding_name,
}
for key, val in directive_defaults.items():
for key, val in _directive_defaults.items():
if key not in directive_types:
directive_types[key] = type(val)
......@@ -366,7 +407,7 @@ def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False,
if not '=' in item:
raise ValueError('Expected "=" in option "%s"' % item)
name, value = [s.strip() for s in item.strip().split('=', 1)]
if name not in directive_defaults:
if name not in _directive_defaults:
found = False
if name.endswith('.all'):
prefix = name[:-3]
......
......@@ -661,7 +661,7 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
self.cython_module_names = set()
self.directive_names = {'staticmethod': 'staticmethod'}
self.parallel_directives = {}
directives = copy.deepcopy(Options.directive_defaults)
directives = copy.deepcopy(Options.get_directive_defaults())
for key, value in compilation_directive_defaults.items():
directives[_unicode(key)] = copy.deepcopy(value)
self.directives = directives
......@@ -673,8 +673,7 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
'is not allowed in %s scope' % (directive, scope)))
return False
else:
if (directive not in Options.directive_defaults
and directive not in Options.directive_types):
if directive not in Options.directive_types:
error(pos, "Invalid directive: '%s'." % (directive,))
return True
......@@ -869,7 +868,7 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
def try_to_parse_directive(self, optname, args, kwds, pos):
directivetype = Options.directive_types.get(optname)
if len(args) == 1 and isinstance(args[0], ExprNodes.NoneNode):
return optname, Options.directive_defaults[optname]
return optname, Options.get_directive_defaults()[optname]
elif directivetype is bool:
if kwds is not None or len(args) != 1 or not isinstance(args[0], ExprNodes.BoolNode):
raise PostParseError(pos,
......
......@@ -645,7 +645,7 @@ class CythonCompileTestCase(unittest.TestCase):
(name, getattr(Options, name))
for name in ('warning_errors', 'clear_to_none', 'error_on_unknown_names', 'error_on_uninitialized')
]
self._saved_default_directives = list(Options.directive_defaults.items())
self._saved_default_directives = list(Options.get_directive_defaults().items())
Options.warning_errors = self.warning_errors
if sys.version_info >= (3, 4):
Options.directive_defaults['autotestdict'] = False
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment