optinterpreter: Fix builtin option names not being reserved anymore

pull/9402/head
Xavier Claessens 3 years ago committed by Xavier Claessens
parent 5e96730d7d
commit 8a0d12ec29
  1. 20
      mesonbuild/optinterpreter.py
  2. 34
      unittests/platformagnostictests.py

@ -15,7 +15,6 @@
import re
import typing as T
from . import compilers
from . import coredata
from . import mesonlib
from . import mparser
@ -43,21 +42,6 @@ if T.TYPE_CHECKING:
})
forbidden_option_names = set(coredata.BUILTIN_OPTIONS.keys())
forbidden_prefixes = [lang + '_' for lang in compilers.all_languages] + ['b_', 'backend_']
reserved_prefixes = ['cross_']
def is_invalid_name(name: str, *, log: bool = True) -> bool:
if name in forbidden_option_names:
return True
pref = name.split('_')[0] + '_'
if pref in forbidden_prefixes:
return True
if pref in reserved_prefixes:
if log:
mlog.deprecation('Option uses prefix "%s", which is reserved for Meson. This will become an error in the future.' % pref)
return False
class OptionException(mesonlib.MesonException):
pass
@ -176,7 +160,8 @@ class OptionInterpreter:
opt_name = args[0]
if optname_regex.search(opt_name) is not None:
raise OptionException('Option names can only contain letters, numbers or dashes.')
if is_invalid_name(opt_name):
key = mesonlib.OptionKey.from_string(opt_name).evolve(subproject=self.subproject)
if not key.is_project():
raise OptionException('Option name %s is reserved.' % opt_name)
opt_type = kwargs['type']
@ -192,7 +177,6 @@ class OptionInterpreter:
opt = parser(description, T.cast('ParserArgs', parser_kwargs))
opt.deprecated = kwargs['deprecated']
key = mesonlib.OptionKey(opt_name, self.subproject)
if key in self.options:
mlog.deprecation(f'Option {opt_name} already exists.')
self.options[key] = opt

@ -13,11 +13,13 @@
# limitations under the License.
import os
import tempfile
from unittest import skipIf
from .baseplatformtests import BasePlatformTests
from .helpers import is_ci
from mesonbuild.mesonlib import is_linux
from mesonbuild.optinterpreter import OptionInterpreter, OptionException
@skipIf(is_ci() and not is_linux(), "Run only on fast platforms")
class PlatformAgnosticTests(BasePlatformTests):
@ -32,3 +34,35 @@ class PlatformAgnosticTests(BasePlatformTests):
'''
testdir = os.path.join(self.unit_test_dir, '99 relative find program')
self.init(testdir, workdir=testdir)
def test_invalid_option_names(self):
interp = OptionInterpreter('')
def write_file(code: str):
with tempfile.NamedTemporaryFile('w', dir=self.builddir, encoding='utf-8', delete=False) as f:
f.write(code)
return f.name
fname = write_file("option('default_library', type: 'string')")
self.assertRaisesRegex(OptionException, 'Option name default_library is reserved.',
interp.process, fname)
fname = write_file("option('c_anything', type: 'string')")
self.assertRaisesRegex(OptionException, 'Option name c_anything is reserved.',
interp.process, fname)
fname = write_file("option('b_anything', type: 'string')")
self.assertRaisesRegex(OptionException, 'Option name b_anything is reserved.',
interp.process, fname)
fname = write_file("option('backend_anything', type: 'string')")
self.assertRaisesRegex(OptionException, 'Option name backend_anything is reserved.',
interp.process, fname)
fname = write_file("option('foo.bar', type: 'string')")
self.assertRaisesRegex(OptionException, 'Option names can only contain letters, numbers or dashes.',
interp.process, fname)
# platlib is allowed, only python.platlib is reserved.
fname = write_file("option('platlib', type: 'string')")
interp.process(fname)

Loading…
Cancel
Save