We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Default value of UserFeatureOption is `enabled` instead of `auto`
According to `meson --help`:

```
  --auto-features {enabled,disabled,auto}
                        Override value of all 'auto' features (default: auto).
```

However, in reality the default value is `enabled`. We should fix it to be `auto`.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mesonbuild/optinterpreter.py`
Content:
```
1 # Copyright 2013-2014 The Meson development team
2 
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 import os, re
16 import functools
17 
18 from . import mparser
19 from . import coredata
20 from . import mesonlib
21 from . import compilers
22 
23 forbidden_option_names = coredata.get_builtin_options()
24 forbidden_prefixes = [lang + '_' for lang in compilers.all_languages] + ['b_', 'backend_']
25 
26 def is_invalid_name(name):
27     if name in forbidden_option_names:
28         return True
29     pref = name.split('_')[0] + '_'
30     if pref in forbidden_prefixes:
31         return True
32     return False
33 
34 class OptionException(mesonlib.MesonException):
35     pass
36 
37 
38 def permitted_kwargs(permitted):
39     """Function that validates kwargs for options."""
40     def _wraps(func):
41         @functools.wraps(func)
42         def _inner(name, description, kwargs):
43             bad = [a for a in kwargs.keys() if a not in permitted]
44             if bad:
45                 raise OptionException('Invalid kwargs for option "{}": "{}"'.format(
46                     name, ' '.join(bad)))
47             return func(name, description, kwargs)
48         return _inner
49     return _wraps
50 
51 
52 optname_regex = re.compile('[^a-zA-Z0-9_-]')
53 
54 @permitted_kwargs({'value', 'yield'})
55 def StringParser(name, description, kwargs):
56     return coredata.UserStringOption(name,
57                                      description,
58                                      kwargs.get('value', ''),
59                                      kwargs.get('choices', []),
60                                      kwargs.get('yield', coredata.default_yielding))
61 
62 @permitted_kwargs({'value', 'yield'})
63 def BooleanParser(name, description, kwargs):
64     return coredata.UserBooleanOption(name, description,
65                                       kwargs.get('value', True),
66                                       kwargs.get('yield', coredata.default_yielding))
67 
68 @permitted_kwargs({'value', 'yield', 'choices'})
69 def ComboParser(name, description, kwargs):
70     if 'choices' not in kwargs:
71         raise OptionException('Combo option missing "choices" keyword.')
72     choices = kwargs['choices']
73     if not isinstance(choices, list):
74         raise OptionException('Combo choices must be an array.')
75     for i in choices:
76         if not isinstance(i, str):
77             raise OptionException('Combo choice elements must be strings.')
78     return coredata.UserComboOption(name,
79                                     description,
80                                     choices,
81                                     kwargs.get('value', choices[0]),
82                                     kwargs.get('yield', coredata.default_yielding),)
83 
84 
85 @permitted_kwargs({'value', 'min', 'max', 'yield'})
86 def IntegerParser(name, description, kwargs):
87     if 'value' not in kwargs:
88         raise OptionException('Integer option must contain value argument.')
89     return coredata.UserIntegerOption(name,
90                                       description,
91                                       kwargs.get('min', None),
92                                       kwargs.get('max', None),
93                                       kwargs['value'],
94                                       kwargs.get('yield', coredata.default_yielding))
95 
96 # FIXME: Cannot use FeatureNew while parsing options because we parse it before
97 # reading options in project(). See func_project() in interpreter.py
98 #@FeatureNew('array type option()', '0.44.0')
99 @permitted_kwargs({'value', 'yield', 'choices'})
100 def string_array_parser(name, description, kwargs):
101     if 'choices' in kwargs:
102         choices = kwargs['choices']
103         if not isinstance(choices, list):
104             raise OptionException('Array choices must be an array.')
105         for i in choices:
106             if not isinstance(i, str):
107                 raise OptionException('Array choice elements must be strings.')
108             value = kwargs.get('value', choices)
109     else:
110         choices = None
111         value = kwargs.get('value', [])
112     if not isinstance(value, list):
113         raise OptionException('Array choices must be passed as an array.')
114     return coredata.UserArrayOption(name,
115                                     description,
116                                     value,
117                                     choices=choices,
118                                     yielding=kwargs.get('yield', coredata.default_yielding))
119 
120 @permitted_kwargs({'value', 'yield'})
121 def FeatureParser(name, description, kwargs):
122     return coredata.UserFeatureOption(name,
123                                       description,
124                                       kwargs.get('value', 'enabled'),
125                                       yielding=kwargs.get('yield', coredata.default_yielding))
126 
127 option_types = {'string': StringParser,
128                 'boolean': BooleanParser,
129                 'combo': ComboParser,
130                 'integer': IntegerParser,
131                 'array': string_array_parser,
132                 'feature': FeatureParser,
133                 }
134 
135 class OptionInterpreter:
136     def __init__(self, subproject):
137         self.options = {}
138         self.subproject = subproject
139 
140     def process(self, option_file):
141         try:
142             with open(option_file, 'r', encoding='utf8') as f:
143                 ast = mparser.Parser(f.read(), '').parse()
144         except mesonlib.MesonException as me:
145             me.file = option_file
146             raise me
147         if not isinstance(ast, mparser.CodeBlockNode):
148             e = OptionException('Option file is malformed.')
149             e.lineno = ast.lineno()
150             raise e
151         for cur in ast.lines:
152             try:
153                 self.evaluate_statement(cur)
154             except Exception as e:
155                 e.lineno = cur.lineno
156                 e.colno = cur.colno
157                 e.file = os.path.join('meson_options.txt')
158                 raise e
159 
160     def reduce_single(self, arg):
161         if isinstance(arg, str):
162             return arg
163         elif isinstance(arg, (mparser.StringNode, mparser.BooleanNode,
164                               mparser.NumberNode)):
165             return arg.value
166         elif isinstance(arg, mparser.ArrayNode):
167             return [self.reduce_single(curarg) for curarg in arg.args.arguments]
168         else:
169             raise OptionException('Arguments may only be string, int, bool, or array of those.')
170 
171     def reduce_arguments(self, args):
172         assert(isinstance(args, mparser.ArgumentNode))
173         if args.incorrect_order():
174             raise OptionException('All keyword arguments must be after positional arguments.')
175         reduced_pos = [self.reduce_single(arg) for arg in args.arguments]
176         reduced_kw = {}
177         for key in args.kwargs.keys():
178             if not isinstance(key, str):
179                 raise OptionException('Keyword argument name is not a string.')
180             a = args.kwargs[key]
181             reduced_kw[key] = self.reduce_single(a)
182         return reduced_pos, reduced_kw
183 
184     def evaluate_statement(self, node):
185         if not isinstance(node, mparser.FunctionNode):
186             raise OptionException('Option file may only contain option definitions')
187         func_name = node.func_name
188         if func_name != 'option':
189             raise OptionException('Only calls to option() are allowed in option files.')
190         (posargs, kwargs) = self.reduce_arguments(node.args)
191 
192         # FIXME: Cannot use FeatureNew while parsing options because we parse
193         # it before reading options in project(). See func_project() in
194         # interpreter.py
195         #if 'yield' in kwargs:
196         #    FeatureNew('option yield', '0.45.0').use(self.subproject)
197 
198         if 'type' not in kwargs:
199             raise OptionException('Option call missing mandatory "type" keyword argument')
200         opt_type = kwargs.pop('type')
201         if opt_type not in option_types:
202             raise OptionException('Unknown type %s.' % opt_type)
203         if len(posargs) != 1:
204             raise OptionException('Option() must have one (and only one) positional argument')
205         opt_name = posargs[0]
206         if not isinstance(opt_name, str):
207             raise OptionException('Positional argument must be a string.')
208         if optname_regex.search(opt_name) is not None:
209             raise OptionException('Option names can only contain letters, numbers or dashes.')
210         if is_invalid_name(opt_name):
211             raise OptionException('Option name %s is reserved.' % opt_name)
212         if self.subproject != '':
213             opt_name = self.subproject + ':' + opt_name
214         opt = option_types[opt_type](opt_name, kwargs.pop('description', ''), kwargs)
215         if opt.description == '':
216             opt.description = opt_name
217         self.options[opt_name] = opt
218
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -121,7 +121,7 @@
 def FeatureParser(name, description, kwargs):
     return coredata.UserFeatureOption(name,
                                       description,
-                                      kwargs.get('value', 'enabled'),
+                                      kwargs.get('value', 'auto'),
                                       yielding=kwargs.get('yield', coredata.default_yielding))
 
 option_types = {'string': StringParser,

{"golden_diff": "diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py\n--- a/mesonbuild/optinterpreter.py\n+++ b/mesonbuild/optinterpreter.py\n@@ -121,7 +121,7 @@\n def FeatureParser(name, description, kwargs):\n     return coredata.UserFeatureOption(name,\n                                       description,\n-                                      kwargs.get('value', 'enabled'),\n+                                      kwargs.get('value', 'auto'),\n                                       yielding=kwargs.get('yield', coredata.default_yielding))\n \n option_types = {'string': StringParser,\n", "issue": "Default value of UserFeatureOption is `enabled` instead of `auto`\nAccording to `meson --help`:\r\n\r\n```\r\n  --auto-features {enabled,disabled,auto}\r\n                        Override value of all 'auto' features (default: auto).\r\n```\r\n\r\nHowever, in reality the default value is `enabled`. We should fix it to be `auto`.\n", "before_files": [{"content": "# Copyright 2013-2014 The Meson development team\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport os, re\nimport functools\n\nfrom . import mparser\nfrom . import coredata\nfrom . import mesonlib\nfrom . import compilers\n\nforbidden_option_names = coredata.get_builtin_options()\nforbidden_prefixes = [lang + '_' for lang in compilers.all_languages] + ['b_', 'backend_']\n\ndef is_invalid_name(name):\n    if name in forbidden_option_names:\n        return True\n    pref = name.split('_')[0] + '_'\n    if pref in forbidden_prefixes:\n        return True\n    return False\n\nclass OptionException(mesonlib.MesonException):\n    pass\n\n\ndef permitted_kwargs(permitted):\n    \"\"\"Function that validates kwargs for options.\"\"\"\n    def _wraps(func):\n        @functools.wraps(func)\n        def _inner(name, description, kwargs):\n            bad = [a for a in kwargs.keys() if a not in permitted]\n            if bad:\n                raise OptionException('Invalid kwargs for option \"{}\": \"{}\"'.format(\n                    name, ' '.join(bad)))\n            return func(name, description, kwargs)\n        return _inner\n    return _wraps\n\n\noptname_regex = re.compile('[^a-zA-Z0-9_-]')\n\n@permitted_kwargs({'value', 'yield'})\ndef StringParser(name, description, kwargs):\n    return coredata.UserStringOption(name,\n                                     description,\n                                     kwargs.get('value', ''),\n                                     kwargs.get('choices', []),\n                                     kwargs.get('yield', coredata.default_yielding))\n\n@permitted_kwargs({'value', 'yield'})\ndef BooleanParser(name, description, kwargs):\n    return coredata.UserBooleanOption(name, description,\n                                      kwargs.get('value', True),\n                                      kwargs.get('yield', coredata.default_yielding))\n\n@permitted_kwargs({'value', 'yield', 'choices'})\ndef ComboParser(name, description, kwargs):\n    if 'choices' not in kwargs:\n        raise OptionException('Combo option missing \"choices\" keyword.')\n    choices = kwargs['choices']\n    if not isinstance(choices, list):\n        raise OptionException('Combo choices must be an array.')\n    for i in choices:\n        if not isinstance(i, str):\n            raise OptionException('Combo choice elements must be strings.')\n    return coredata.UserComboOption(name,\n                                    description,\n                                    choices,\n                                    kwargs.get('value', choices[0]),\n                                    kwargs.get('yield', coredata.default_yielding),)\n\n\n@permitted_kwargs({'value', 'min', 'max', 'yield'})\ndef IntegerParser(name, description, kwargs):\n    if 'value' not in kwargs:\n        raise OptionException('Integer option must contain value argument.')\n    return coredata.UserIntegerOption(name,\n                                      description,\n                                      kwargs.get('min', None),\n                                      kwargs.get('max', None),\n                                      kwargs['value'],\n                                      kwargs.get('yield', coredata.default_yielding))\n\n# FIXME: Cannot use FeatureNew while parsing options because we parse it before\n# reading options in project(). See func_project() in interpreter.py\n#@FeatureNew('array type option()', '0.44.0')\n@permitted_kwargs({'value', 'yield', 'choices'})\ndef string_array_parser(name, description, kwargs):\n    if 'choices' in kwargs:\n        choices = kwargs['choices']\n        if not isinstance(choices, list):\n            raise OptionException('Array choices must be an array.')\n        for i in choices:\n            if not isinstance(i, str):\n                raise OptionException('Array choice elements must be strings.')\n            value = kwargs.get('value', choices)\n    else:\n        choices = None\n        value = kwargs.get('value', [])\n    if not isinstance(value, list):\n        raise OptionException('Array choices must be passed as an array.')\n    return coredata.UserArrayOption(name,\n                                    description,\n                                    value,\n                                    choices=choices,\n                                    yielding=kwargs.get('yield', coredata.default_yielding))\n\n@permitted_kwargs({'value', 'yield'})\ndef FeatureParser(name, description, kwargs):\n    return coredata.UserFeatureOption(name,\n                                      description,\n                                      kwargs.get('value', 'enabled'),\n                                      yielding=kwargs.get('yield', coredata.default_yielding))\n\noption_types = {'string': StringParser,\n                'boolean': BooleanParser,\n                'combo': ComboParser,\n                'integer': IntegerParser,\n                'array': string_array_parser,\n                'feature': FeatureParser,\n                }\n\nclass OptionInterpreter:\n    def __init__(self, subproject):\n        self.options = {}\n        self.subproject = subproject\n\n    def process(self, option_file):\n        try:\n            with open(option_file, 'r', encoding='utf8') as f:\n                ast = mparser.Parser(f.read(), '').parse()\n        except mesonlib.MesonException as me:\n            me.file = option_file\n            raise me\n        if not isinstance(ast, mparser.CodeBlockNode):\n            e = OptionException('Option file is malformed.')\n            e.lineno = ast.lineno()\n            raise e\n        for cur in ast.lines:\n            try:\n                self.evaluate_statement(cur)\n            except Exception as e:\n                e.lineno = cur.lineno\n                e.colno = cur.colno\n                e.file = os.path.join('meson_options.txt')\n                raise e\n\n    def reduce_single(self, arg):\n        if isinstance(arg, str):\n            return arg\n        elif isinstance(arg, (mparser.StringNode, mparser.BooleanNode,\n                              mparser.NumberNode)):\n            return arg.value\n        elif isinstance(arg, mparser.ArrayNode):\n            return [self.reduce_single(curarg) for curarg in arg.args.arguments]\n        else:\n            raise OptionException('Arguments may only be string, int, bool, or array of those.')\n\n    def reduce_arguments(self, args):\n        assert(isinstance(args, mparser.ArgumentNode))\n        if args.incorrect_order():\n            raise OptionException('All keyword arguments must be after positional arguments.')\n        reduced_pos = [self.reduce_single(arg) for arg in args.arguments]\n        reduced_kw = {}\n        for key in args.kwargs.keys():\n            if not isinstance(key, str):\n                raise OptionException('Keyword argument name is not a string.')\n            a = args.kwargs[key]\n            reduced_kw[key] = self.reduce_single(a)\n        return reduced_pos, reduced_kw\n\n    def evaluate_statement(self, node):\n        if not isinstance(node, mparser.FunctionNode):\n            raise OptionException('Option file may only contain option definitions')\n        func_name = node.func_name\n        if func_name != 'option':\n            raise OptionException('Only calls to option() are allowed in option files.')\n        (posargs, kwargs) = self.reduce_arguments(node.args)\n\n        # FIXME: Cannot use FeatureNew while parsing options because we parse\n        # it before reading options in project(). See func_project() in\n        # interpreter.py\n        #if 'yield' in kwargs:\n        #    FeatureNew('option yield', '0.45.0').use(self.subproject)\n\n        if 'type' not in kwargs:\n            raise OptionException('Option call missing mandatory \"type\" keyword argument')\n        opt_type = kwargs.pop('type')\n        if opt_type not in option_types:\n            raise OptionException('Unknown type %s.' % opt_type)\n        if len(posargs) != 1:\n            raise OptionException('Option() must have one (and only one) positional argument')\n        opt_name = posargs[0]\n        if not isinstance(opt_name, str):\n            raise OptionException('Positional argument must be a string.')\n        if optname_regex.search(opt_name) is not None:\n            raise OptionException('Option names can only contain letters, numbers or dashes.')\n        if is_invalid_name(opt_name):\n            raise OptionException('Option name %s is reserved.' % opt_name)\n        if self.subproject != '':\n            opt_name = self.subproject + ':' + opt_name\n        opt = option_types[opt_type](opt_name, kwargs.pop('description', ''), kwargs)\n        if opt.description == '':\n            opt.description = opt_name\n        self.options[opt_name] = opt\n", "path": "mesonbuild/optinterpreter.py"}], "after_files": [{"content": "# Copyright 2013-2014 The Meson development team\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport os, re\nimport functools\n\nfrom . import mparser\nfrom . import coredata\nfrom . import mesonlib\nfrom . import compilers\n\nforbidden_option_names = coredata.get_builtin_options()\nforbidden_prefixes = [lang + '_' for lang in compilers.all_languages] + ['b_', 'backend_']\n\ndef is_invalid_name(name):\n    if name in forbidden_option_names:\n        return True\n    pref = name.split('_')[0] + '_'\n    if pref in forbidden_prefixes:\n        return True\n    return False\n\nclass OptionException(mesonlib.MesonException):\n    pass\n\n\ndef permitted_kwargs(permitted):\n    \"\"\"Function that validates kwargs for options.\"\"\"\n    def _wraps(func):\n        @functools.wraps(func)\n        def _inner(name, description, kwargs):\n            bad = [a for a in kwargs.keys() if a not in permitted]\n            if bad:\n                raise OptionException('Invalid kwargs for option \"{}\": \"{}\"'.format(\n                    name, ' '.join(bad)))\n            return func(name, description, kwargs)\n        return _inner\n    return _wraps\n\n\noptname_regex = re.compile('[^a-zA-Z0-9_-]')\n\n@permitted_kwargs({'value', 'yield'})\ndef StringParser(name, description, kwargs):\n    return coredata.UserStringOption(name,\n                                     description,\n                                     kwargs.get('value', ''),\n                                     kwargs.get('choices', []),\n                                     kwargs.get('yield', coredata.default_yielding))\n\n@permitted_kwargs({'value', 'yield'})\ndef BooleanParser(name, description, kwargs):\n    return coredata.UserBooleanOption(name, description,\n                                      kwargs.get('value', True),\n                                      kwargs.get('yield', coredata.default_yielding))\n\n@permitted_kwargs({'value', 'yield', 'choices'})\ndef ComboParser(name, description, kwargs):\n    if 'choices' not in kwargs:\n        raise OptionException('Combo option missing \"choices\" keyword.')\n    choices = kwargs['choices']\n    if not isinstance(choices, list):\n        raise OptionException('Combo choices must be an array.')\n    for i in choices:\n        if not isinstance(i, str):\n            raise OptionException('Combo choice elements must be strings.')\n    return coredata.UserComboOption(name,\n                                    description,\n                                    choices,\n                                    kwargs.get('value', choices[0]),\n                                    kwargs.get('yield', coredata.default_yielding),)\n\n\n@permitted_kwargs({'value', 'min', 'max', 'yield'})\ndef IntegerParser(name, description, kwargs):\n    if 'value' not in kwargs:\n        raise OptionException('Integer option must contain value argument.')\n    return coredata.UserIntegerOption(name,\n                                      description,\n                                      kwargs.get('min', None),\n                                      kwargs.get('max', None),\n                                      kwargs['value'],\n                                      kwargs.get('yield', coredata.default_yielding))\n\n# FIXME: Cannot use FeatureNew while parsing options because we parse it before\n# reading options in project(). See func_project() in interpreter.py\n#@FeatureNew('array type option()', '0.44.0')\n@permitted_kwargs({'value', 'yield', 'choices'})\ndef string_array_parser(name, description, kwargs):\n    if 'choices' in kwargs:\n        choices = kwargs['choices']\n        if not isinstance(choices, list):\n            raise OptionException('Array choices must be an array.')\n        for i in choices:\n            if not isinstance(i, str):\n                raise OptionException('Array choice elements must be strings.')\n            value = kwargs.get('value', choices)\n    else:\n        choices = None\n        value = kwargs.get('value', [])\n    if not isinstance(value, list):\n        raise OptionException('Array choices must be passed as an array.')\n    return coredata.UserArrayOption(name,\n                                    description,\n                                    value,\n                                    choices=choices,\n                                    yielding=kwargs.get('yield', coredata.default_yielding))\n\n@permitted_kwargs({'value', 'yield'})\ndef FeatureParser(name, description, kwargs):\n    return coredata.UserFeatureOption(name,\n                                      description,\n                                      kwargs.get('value', 'auto'),\n                                      yielding=kwargs.get('yield', coredata.default_yielding))\n\noption_types = {'string': StringParser,\n                'boolean': BooleanParser,\n                'combo': ComboParser,\n                'integer': IntegerParser,\n                'array': string_array_parser,\n                'feature': FeatureParser,\n                }\n\nclass OptionInterpreter:\n    def __init__(self, subproject):\n        self.options = {}\n        self.subproject = subproject\n\n    def process(self, option_file):\n        try:\n            with open(option_file, 'r', encoding='utf8') as f:\n                ast = mparser.Parser(f.read(), '').parse()\n        except mesonlib.MesonException as me:\n            me.file = option_file\n            raise me\n        if not isinstance(ast, mparser.CodeBlockNode):\n            e = OptionException('Option file is malformed.')\n            e.lineno = ast.lineno()\n            raise e\n        for cur in ast.lines:\n            try:\n                self.evaluate_statement(cur)\n            except Exception as e:\n                e.lineno = cur.lineno\n                e.colno = cur.colno\n                e.file = os.path.join('meson_options.txt')\n                raise e\n\n    def reduce_single(self, arg):\n        if isinstance(arg, str):\n            return arg\n        elif isinstance(arg, (mparser.StringNode, mparser.BooleanNode,\n                              mparser.NumberNode)):\n            return arg.value\n        elif isinstance(arg, mparser.ArrayNode):\n            return [self.reduce_single(curarg) for curarg in arg.args.arguments]\n        else:\n            raise OptionException('Arguments may only be string, int, bool, or array of those.')\n\n    def reduce_arguments(self, args):\n        assert(isinstance(args, mparser.ArgumentNode))\n        if args.incorrect_order():\n            raise OptionException('All keyword arguments must be after positional arguments.')\n        reduced_pos = [self.reduce_single(arg) for arg in args.arguments]\n        reduced_kw = {}\n        for key in args.kwargs.keys():\n            if not isinstance(key, str):\n                raise OptionException('Keyword argument name is not a string.')\n            a = args.kwargs[key]\n            reduced_kw[key] = self.reduce_single(a)\n        return reduced_pos, reduced_kw\n\n    def evaluate_statement(self, node):\n        if not isinstance(node, mparser.FunctionNode):\n            raise OptionException('Option file may only contain option definitions')\n        func_name = node.func_name\n        if func_name != 'option':\n            raise OptionException('Only calls to option() are allowed in option files.')\n        (posargs, kwargs) = self.reduce_arguments(node.args)\n\n        # FIXME: Cannot use FeatureNew while parsing options because we parse\n        # it before reading options in project(). See func_project() in\n        # interpreter.py\n        #if 'yield' in kwargs:\n        #    FeatureNew('option yield', '0.45.0').use(self.subproject)\n\n        if 'type' not in kwargs:\n            raise OptionException('Option call missing mandatory \"type\" keyword argument')\n        opt_type = kwargs.pop('type')\n        if opt_type not in option_types:\n            raise OptionException('Unknown type %s.' % opt_type)\n        if len(posargs) != 1:\n            raise OptionException('Option() must have one (and only one) positional argument')\n        opt_name = posargs[0]\n        if not isinstance(opt_name, str):\n            raise OptionException('Positional argument must be a string.')\n        if optname_regex.search(opt_name) is not None:\n            raise OptionException('Option names can only contain letters, numbers or dashes.')\n        if is_invalid_name(opt_name):\n            raise OptionException('Option name %s is reserved.' % opt_name)\n        if self.subproject != '':\n            opt_name = self.subproject + ':' + opt_name\n        opt = option_types[opt_type](opt_name, kwargs.pop('description', ''), kwargs)\n        if opt.description == '':\n            opt.description = opt_name\n        self.options[opt_name] = opt\n", "path": "mesonbuild/optinterpreter.py"}]}