options: Add a permitted_kwargs function

I've typo'd "value" for the last time, options needs a kwargs validator.
This validator is slightly different than the one used by the main
parser, since it operates on a much simpler representation than the
other one does, and they are not interchangeable.

This also changes the optinterpreter to use pop on 'type' and
'description' so that they're not passed to the validator as kwargs.
pull/2426/head
Dylan Baker 7 years ago
parent 4e18483ff3
commit 7dfad54f06
  1. 27
      mesonbuild/optinterpreter.py
  2. 3
      test cases/failing/62 bad option argument/meson.build
  3. 1
      test cases/failing/62 bad option argument/meson_options.txt

@ -12,10 +12,13 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os, re
import functools
from . import mparser from . import mparser
from . import coredata from . import coredata
from . import mesonlib from . import mesonlib
import os, re
forbidden_option_names = coredata.get_builtin_options() forbidden_option_names = coredata.get_builtin_options()
forbidden_prefixes = {'c_', forbidden_prefixes = {'c_',
@ -43,15 +46,33 @@ def is_invalid_name(name):
class OptionException(mesonlib.MesonException): class OptionException(mesonlib.MesonException):
pass pass
def permitted_kwargs(permitted):
"""Function that validates kwargs for options."""
def _wraps(func):
@functools.wraps(func)
def _inner(name, description, kwargs):
bad = [a for a in kwargs.keys() if a not in permitted]
if bad:
raise OptionException('Invalid kwargs for option "{}": "{}"'.format(
name, ' '.join(bad)))
return func(name, description, kwargs)
return _inner
return _wraps
optname_regex = re.compile('[^a-zA-Z0-9_-]') optname_regex = re.compile('[^a-zA-Z0-9_-]')
@permitted_kwargs({'value'})
def StringParser(name, description, kwargs): def StringParser(name, description, kwargs):
return coredata.UserStringOption(name, description, return coredata.UserStringOption(name, description,
kwargs.get('value', ''), kwargs.get('choices', [])) kwargs.get('value', ''), kwargs.get('choices', []))
@permitted_kwargs({'value'})
def BooleanParser(name, description, kwargs): def BooleanParser(name, description, kwargs):
return coredata.UserBooleanOption(name, description, kwargs.get('value', True)) return coredata.UserBooleanOption(name, description, kwargs.get('value', True))
@permitted_kwargs({'value', 'choices'})
def ComboParser(name, description, kwargs): def ComboParser(name, description, kwargs):
if 'choices' not in kwargs: if 'choices' not in kwargs:
raise OptionException('Combo option missing "choices" keyword.') raise OptionException('Combo option missing "choices" keyword.')
@ -141,7 +162,7 @@ class OptionInterpreter:
(posargs, kwargs) = self.reduce_arguments(node.args) (posargs, kwargs) = self.reduce_arguments(node.args)
if 'type' not in kwargs: if 'type' not in kwargs:
raise OptionException('Option call missing mandatory "type" keyword argument') raise OptionException('Option call missing mandatory "type" keyword argument')
opt_type = kwargs['type'] opt_type = kwargs.pop('type')
if opt_type not in option_types: if opt_type not in option_types:
raise OptionException('Unknown type %s.' % opt_type) raise OptionException('Unknown type %s.' % opt_type)
if len(posargs) != 1: if len(posargs) != 1:
@ -155,7 +176,7 @@ class OptionInterpreter:
raise OptionException('Option name %s is reserved.' % opt_name) raise OptionException('Option name %s is reserved.' % opt_name)
if self.subproject != '': if self.subproject != '':
opt_name = self.subproject + ':' + opt_name opt_name = self.subproject + ':' + opt_name
opt = option_types[opt_type](opt_name, kwargs.get('description', ''), kwargs) opt = option_types[opt_type](opt_name, kwargs.pop('description', ''), kwargs)
if opt.description == '': if opt.description == '':
opt.description = opt_name opt.description = opt_name
if opt_name in self.cmd_line_options: if opt_name in self.cmd_line_options:

@ -0,0 +1,3 @@
project('bad option')
get_option('name')

@ -0,0 +1 @@
option('name', type : 'string', vaule : 'foo')
Loading…
Cancel
Save