aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/cython/Cython/Compiler/Options.py
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:44:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:49 +0300
commit718c552901d703c502ccbefdfc3c9028d608b947 (patch)
tree46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/tools/cython/Cython/Compiler/Options.py
parente9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff)
downloadydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/cython/Cython/Compiler/Options.py')
-rw-r--r--contrib/tools/cython/Cython/Compiler/Options.py512
1 files changed, 256 insertions, 256 deletions
diff --git a/contrib/tools/cython/Cython/Compiler/Options.py b/contrib/tools/cython/Cython/Compiler/Options.py
index b3ffbcd927..a90813e954 100644
--- a/contrib/tools/cython/Cython/Compiler/Options.py
+++ b/contrib/tools/cython/Cython/Compiler/Options.py
@@ -4,182 +4,182 @@
from __future__ import absolute_import
+
+class ShouldBeFromDirective(object):
-class ShouldBeFromDirective(object):
-
- known_directives = []
+ known_directives = []
def __init__(self, options_name, directive_name=None, disallow=False):
- self.options_name = options_name
- self.directive_name = directive_name or options_name
+ self.options_name = options_name
+ self.directive_name = directive_name or options_name
self.disallow = disallow
- 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))
-
-
-"""
-The members of this module are documented using autodata in
-Cython/docs/src/reference/compilation.rst.
-See http://www.sphinx-doc.org/en/master/ext/autodoc.html#directive-autoattribute
-for how autodata works.
-Descriptions of those members should start with a #:
-Donc forget to keep the docs in sync by removing and adding
-the members in both this file and the .rst file.
-"""
-
-#: Whether or not to include docstring in the Python extension. If False, the binary size
-#: will be smaller, but the ``__doc__`` attribute of any class or function will be an
-#: empty string.
+ 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))
+
+
+"""
+The members of this module are documented using autodata in
+Cython/docs/src/reference/compilation.rst.
+See http://www.sphinx-doc.org/en/master/ext/autodoc.html#directive-autoattribute
+for how autodata works.
+Descriptions of those members should start with a #:
+Donc forget to keep the docs in sync by removing and adding
+the members in both this file and the .rst file.
+"""
+
+#: Whether or not to include docstring in the Python extension. If False, the binary size
+#: will be smaller, but the ``__doc__`` attribute of any class or function will be an
+#: empty string.
docstrings = True
-#: Embed the source code position in the docstrings of functions and classes.
-embed_pos_in_docstring = False
-
-#: Copy the original source code line by line into C code comments
-#: in the generated code file to help with understanding the output.
-#: This is also required for coverage analysis.
-emit_code_comments = True
-
-# undocumented
-pre_import = None
-
-#: Decref global variables in each module on exit for garbage collection.
-#: 0: None, 1+: interned objects, 2+: cdef globals, 3+: types objects
-#: Mostly for reducing noise in Valgrind as it typically executes at process exit
-#: (when all memory will be reclaimed anyways).
-#: Note that directly or indirectly executed cleanup code that makes use of global
-#: variables or types may no longer be safe when enabling the respective level since
-#: there is no guaranteed order in which the (reference counted) objects will
-#: be cleaned up. The order can change due to live references and reference cycles.
+#: Embed the source code position in the docstrings of functions and classes.
+embed_pos_in_docstring = False
+
+#: Copy the original source code line by line into C code comments
+#: in the generated code file to help with understanding the output.
+#: This is also required for coverage analysis.
+emit_code_comments = True
+
+# undocumented
+pre_import = None
+
+#: Decref global variables in each module on exit for garbage collection.
+#: 0: None, 1+: interned objects, 2+: cdef globals, 3+: types objects
+#: Mostly for reducing noise in Valgrind as it typically executes at process exit
+#: (when all memory will be reclaimed anyways).
+#: Note that directly or indirectly executed cleanup code that makes use of global
+#: variables or types may no longer be safe when enabling the respective level since
+#: there is no guaranteed order in which the (reference counted) objects will
+#: be cleaned up. The order can change due to live references and reference cycles.
generate_cleanup_code = False
-#: Should tp_clear() set object fields to None instead of clearing them to NULL?
-clear_to_none = True
-
-#: Generate an annotated HTML version of the input source files for debugging and optimisation purposes.
-#: This has the same effect as the ``annotate`` argument in :func:`cythonize`.
+#: Should tp_clear() set object fields to None instead of clearing them to NULL?
+clear_to_none = True
+
+#: Generate an annotated HTML version of the input source files for debugging and optimisation purposes.
+#: This has the same effect as the ``annotate`` argument in :func:`cythonize`.
annotate = False
-# When annotating source files in HTML, include coverage information from
-# this file.
-annotate_coverage_xml = None
-
-#: This will abort the compilation on the first error occurred rather than trying
-#: to keep going and printing further error messages.
+# When annotating source files in HTML, include coverage information from
+# this file.
+annotate_coverage_xml = None
+
+#: This will abort the compilation on the first error occurred rather than trying
+#: to keep going and printing further error messages.
fast_fail = False
-#: Turn all warnings into errors.
+#: Turn all warnings into errors.
warning_errors = False
-#: Make unknown names an error. Python raises a NameError when
-#: encountering unknown names at runtime, whereas this option makes
-#: them a compile time error. If you want full Python compatibility,
-#: you should disable this option and also 'cache_builtins'.
+#: Make unknown names an error. Python raises a NameError when
+#: encountering unknown names at runtime, whereas this option makes
+#: them a compile time error. If you want full Python compatibility,
+#: you should disable this option and also 'cache_builtins'.
error_on_unknown_names = True
-#: Make uninitialized local variable reference a compile time error.
-#: Python raises UnboundLocalError at runtime, whereas this option makes
-#: them a compile time error. Note that this option affects only variables
-#: of "python object" type.
+#: Make uninitialized local variable reference a compile time error.
+#: Python raises UnboundLocalError at runtime, whereas this option makes
+#: them a compile time error. Note that this option affects only variables
+#: of "python object" type.
error_on_uninitialized = True
-#: This will convert statements of the form ``for i in range(...)``
-#: to ``for i from ...`` when ``i`` is a C integer type, and the direction
-#: (i.e. sign of step) can be determined.
-#: WARNING: This may change the semantics if the range causes assignment to
-#: i to overflow. Specifically, if this option is set, an error will be
-#: raised before the loop is entered, whereas without this option the loop
-#: will execute until an overflowing value is encountered.
+#: This will convert statements of the form ``for i in range(...)``
+#: to ``for i from ...`` when ``i`` is a C integer type, and the direction
+#: (i.e. sign of step) can be determined.
+#: WARNING: This may change the semantics if the range causes assignment to
+#: i to overflow. Specifically, if this option is set, an error will be
+#: raised before the loop is entered, whereas without this option the loop
+#: will execute until an overflowing value is encountered.
convert_range = True
-#: Perform lookups on builtin names only once, at module initialisation
-#: time. This will prevent the module from getting imported if a
-#: builtin name that it uses cannot be found during initialisation.
-#: Default is True.
-#: Note that some legacy builtins are automatically remapped
-#: from their Python 2 names to their Python 3 names by Cython
-#: when building in Python 3.x,
-#: so that they do not get in the way even if this option is enabled.
-cache_builtins = True
-
-#: Generate branch prediction hints to speed up error handling etc.
-gcc_branch_hints = True
-
-#: Enable this to allow one to write ``your_module.foo = ...`` to overwrite the
-#: definition if the cpdef function foo, at the cost of an extra dictionary
-#: lookup on every call.
-#: If this is false it generates only the Python wrapper and no override check.
+#: Perform lookups on builtin names only once, at module initialisation
+#: time. This will prevent the module from getting imported if a
+#: builtin name that it uses cannot be found during initialisation.
+#: Default is True.
+#: Note that some legacy builtins are automatically remapped
+#: from their Python 2 names to their Python 3 names by Cython
+#: when building in Python 3.x,
+#: so that they do not get in the way even if this option is enabled.
+cache_builtins = True
+
+#: Generate branch prediction hints to speed up error handling etc.
+gcc_branch_hints = True
+
+#: Enable this to allow one to write ``your_module.foo = ...`` to overwrite the
+#: definition if the cpdef function foo, at the cost of an extra dictionary
+#: lookup on every call.
+#: If this is false it generates only the Python wrapper and no override check.
lookup_module_cpdef = False
-#: Whether or not to embed the Python interpreter, for use in making a
-#: standalone executable or calling from external libraries.
-#: This will provide a C function which initialises the interpreter and
-#: executes the body of this module.
-#: See `this demo <https://github.com/cython/cython/tree/master/Demos/embed>`_
-#: for a concrete example.
-#: If true, the initialisation function is the C main() function, but
-#: this option can also be set to a non-empty string to provide a function name explicitly.
-#: Default is False.
+#: Whether or not to embed the Python interpreter, for use in making a
+#: standalone executable or calling from external libraries.
+#: This will provide a C function which initialises the interpreter and
+#: executes the body of this module.
+#: See `this demo <https://github.com/cython/cython/tree/master/Demos/embed>`_
+#: for a concrete example.
+#: If true, the initialisation function is the C main() function, but
+#: this option can also be set to a non-empty string to provide a function name explicitly.
+#: Default is False.
embed = None
# In previous iterations of Cython, globals() gave the first non-Cython module
# globals in the call stack. Sage relies on this behavior for variable injection.
-old_style_globals = ShouldBeFromDirective('old_style_globals')
+old_style_globals = ShouldBeFromDirective('old_style_globals')
-#: Allows cimporting from a pyx file without a pxd file.
+#: Allows cimporting from a pyx file without a pxd file.
cimport_from_pyx = False
-#: Maximum number of dimensions for buffers -- set lower than number of
-#: dimensions in numpy, as
-#: slices are passed by value and involve a lot of copying.
+#: Maximum number of dimensions for buffers -- set lower than number of
+#: dimensions in numpy, as
+#: slices are passed by value and involve a lot of copying.
buffer_max_dims = 8
-#: Number of function closure instances to keep in a freelist (0: no freelists)
+#: Number of function closure instances to keep in a freelist (0: no freelists)
closure_freelist_size = 8
# Arcadia specific
source_root = None
-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
+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,
'embedsignature' : False,
'auto_cpdef': False,
'auto_pickle': None,
- 'cdivision': False, # was True before 0.12
+ 'cdivision': False, # was True before 0.12
'cdivision_warnings': False,
'c_api_binop_methods': True,
'overflowcheck': False,
@@ -187,28 +187,28 @@ _directive_defaults = {
'always_allow_keywords': False,
'allow_none_for_extension_args': True,
'wraparound' : True,
- 'ccomplex' : False, # use C99/C++ for complex types and arith
+ 'ccomplex' : False, # use C99/C++ for complex types and arith
'callspec' : "",
- 'nogil' : False,
+ 'nogil' : False,
'profile': False,
'linetrace': False,
- 'emit_code_comments': True, # copy original source code into C code comments
- 'annotation_typing': True, # read type declarations from Python function annotations
+ 'emit_code_comments': True, # copy original source code into C code comments
+ 'annotation_typing': True, # read type declarations from Python function annotations
'infer_types': None,
'infer_types.verbose': False,
'autotestdict': True,
'autotestdict.cdef': False,
'autotestdict.all': False,
- 'language_level': None,
- 'fast_getattr': False, # Undocumented until we come up with a better way to handle this everywhere.
- 'py2_import': False, # For backward compatibility of Cython's source code in Py3 source mode
+ 'language_level': None,
+ 'fast_getattr': False, # Undocumented until we come up with a better way to handle this everywhere.
+ 'py2_import': False, # For backward compatibility of Cython's source code in Py3 source mode
'preliminary_late_includes_cy28': False, # Temporary directive in 0.28, to be removed in a later version (see GH#2079).
'iterable_coroutine': False, # Make async coroutines backwards compatible with the old asyncio yield-from syntax.
'c_string_type': 'bytes',
'c_string_encoding': '',
- 'type_version_tag': True, # enables Py_TPFLAGS_HAVE_VERSION_TAG on extension types
+ 'type_version_tag': True, # enables Py_TPFLAGS_HAVE_VERSION_TAG on extension types
'unraisable_tracebacks': True,
- 'old_style_globals': False,
+ 'old_style_globals': False,
'np_pythran': False,
'fast_gil': False,
@@ -226,16 +226,16 @@ _directive_defaults = {
# optimizations
'optimize.inline_defnode_calls': True,
- 'optimize.unpack_method_calls': True, # increases code size when True
- 'optimize.unpack_method_calls_in_pyinit': False, # uselessly increases code size when True
+ 'optimize.unpack_method_calls': True, # increases code size when True
+ 'optimize.unpack_method_calls_in_pyinit': False, # uselessly increases code size when True
'optimize.use_switch': True,
# remove unreachable code
'remove_unreachable': True,
# control flow debug directives
- 'control_flow.dot_output': "", # Graphviz output filename
- 'control_flow.dot_annotate_defs': False, # Annotate definitions
+ 'control_flow.dot_output': "", # Graphviz output filename
+ 'control_flow.dot_annotate_defs': False, # Annotate definitions
# test support
'test_assert_path_exists' : [],
@@ -243,8 +243,8 @@ _directive_defaults = {
# experimental, subject to change
'binding': None,
-
- 'formal_grammar': False,
+
+ 'formal_grammar': False,
}
# Extra warning directives
@@ -300,49 +300,49 @@ def normalise_encoding_name(option_name, encoding):
# Override types possibilities above, if needed
directive_types = {
- 'language_level': str, # values can be None/2/3/'3str', where None == 2+warning
+ 'language_level': str, # values can be None/2/3/'3str', where None == 2+warning
'auto_pickle': bool,
- 'locals': dict,
+ 'locals': dict,
'final' : bool, # final cdef classes and methods
- 'nogil' : bool,
+ 'nogil' : bool,
'internal' : bool, # cdef class visibility in the module dict
- 'infer_types' : bool, # values can be True/None/False
+ 'infer_types' : bool, # values can be True/None/False
'binding' : bool,
- 'cfunc' : None, # decorators do not take directive value
+ 'cfunc' : None, # decorators do not take directive value
'ccall' : None,
'inline' : None,
'staticmethod' : None,
'cclass' : None,
- 'no_gc_clear' : bool,
- 'no_gc' : bool,
+ 'no_gc_clear' : bool,
+ 'no_gc' : bool,
'returns' : type,
- 'exceptval': type, # actually (type, check=True/False), but has its own parser
+ 'exceptval': type, # actually (type, check=True/False), but has its own parser
'set_initial_path': str,
'freelist': int,
'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'),
'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)
-directive_scopes = { # defaults to available everywhere
+directive_scopes = { # defaults to available everywhere
# 'module', 'function', 'class', 'with statement'
'auto_pickle': ('module', 'cclass'),
'final' : ('cclass', 'function'),
- 'nogil' : ('function', 'with statement'),
+ 'nogil' : ('function', 'with statement'),
'inline' : ('function',),
- 'cfunc' : ('function', 'with statement'),
- 'ccall' : ('function', 'with statement'),
+ 'cfunc' : ('function', 'with statement'),
+ 'ccall' : ('function', 'with statement'),
'returns' : ('function',),
'exceptval' : ('function',),
'locals' : ('function',),
'staticmethod' : ('function',), # FIXME: analysis currently lacks more specific function scope
'no_gc_clear' : ('cclass',),
- 'no_gc' : ('cclass',),
+ 'no_gc' : ('cclass',),
'internal' : ('cclass',),
- 'cclass' : ('class', 'cclass', 'with statement'),
+ 'cclass' : ('class', 'cclass', 'with statement'),
'autotestdict' : ('module',),
'autotestdict.all' : ('module',),
'autotestdict.cdef' : ('module',),
@@ -350,28 +350,28 @@ directive_scopes = { # defaults to available everywhere
'test_assert_path_exists' : ('function', 'class', 'cclass'),
'test_fail_if_path_exists' : ('function', 'class', 'cclass'),
'freelist': ('cclass',),
- 'emit_code_comments': ('module',),
+ 'emit_code_comments': ('module',),
'annotation_typing': ('module',), # FIXME: analysis currently lacks more specific function scope
# Avoid scope-specific to/from_py_functions for c_string.
'c_string_type': ('module',),
'c_string_encoding': ('module',),
'type_version_tag': ('module', 'cclass'),
- 'language_level': ('module',),
- # globals() could conceivably be controlled at a finer granularity,
- # but that would complicate the implementation
- 'old_style_globals': ('module',),
+ 'language_level': ('module',),
+ # globals() could conceivably be controlled at a finer granularity,
+ # but that would complicate the implementation
+ 'old_style_globals': ('module',),
'np_pythran': ('module',),
'fast_gil': ('module',),
'iterable_coroutine': ('module', 'function'),
}
-
+
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.
- >>> print(parse_directive_value('nonexisting', 'asdf asdfd'))
+ >>> print(parse_directive_value('nonexisting', 'asdf asdfd'))
None
>>> parse_directive_value('boundscheck', 'True')
True
@@ -395,21 +395,21 @@ def parse_directive_value(name, value, relaxed_bool=False):
ValueError: c_string_type directive must be one of ('bytes', 'bytearray', 'str', 'unicode'), got 'unnicode'
"""
type = directive_types.get(name)
- if not type:
- return None
+ if not type:
+ return None
orig_value = value
if type is bool:
value = str(value)
- if value == 'True':
- return True
- if value == 'False':
- return False
+ 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
+ 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, got '%s'" % (
name, orig_value))
elif type is int:
@@ -425,7 +425,7 @@ def parse_directive_value(name, value, relaxed_bool=False):
else:
assert False
-
+
def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False,
current_settings=None):
"""
@@ -461,16 +461,16 @@ def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False,
result = current_settings
for item in s.split(','):
item = item.strip()
- if not item:
- continue
- 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 not item:
+ continue
+ 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:
found = False
if name.endswith('.all'):
prefix = name[:-3]
- for directive in _directive_defaults:
+ for directive in _directive_defaults:
if directive.startswith(prefix):
found = True
parsed_value = parse_directive_value(directive, value, relaxed_bool=relaxed_bool)
@@ -481,73 +481,73 @@ def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False,
parsed_value = parse_directive_value(name, value, relaxed_bool=relaxed_bool)
result[name] = parsed_value
return result
-
-
-def parse_variable_value(value):
- """
- Parses value as an option value for the given name and returns
- the interpreted value.
-
- >>> parse_variable_value('True')
- True
- >>> parse_variable_value('true')
- 'true'
- >>> parse_variable_value('us-ascii')
- 'us-ascii'
- >>> parse_variable_value('str')
- 'str'
- >>> parse_variable_value('123')
- 123
- >>> parse_variable_value('1.23')
- 1.23
-
- """
- if value == "True":
- return True
- elif value == "False":
- return False
- elif value == "None":
- return None
- elif value.isdigit():
- return int(value)
- else:
- try:
- value = float(value)
- except Exception:
- # Not a float
- pass
- return value
-
-
-def parse_compile_time_env(s, current_settings=None):
- """
- Parses a comma-separated list of pragma options. Whitespace
- is not considered.
-
- >>> parse_compile_time_env(' ')
- {}
- >>> (parse_compile_time_env('HAVE_OPENMP=True') ==
- ... {'HAVE_OPENMP': True})
- True
- >>> parse_compile_time_env(' asdf')
- Traceback (most recent call last):
- ...
- ValueError: Expected "=" in option "asdf"
- >>> parse_compile_time_env('NUM_THREADS=4') == {'NUM_THREADS': 4}
- True
- >>> parse_compile_time_env('unknown=anything') == {'unknown': 'anything'}
- True
- """
- if current_settings is None:
- result = {}
- else:
- result = current_settings
- for item in s.split(','):
- item = item.strip()
- if not item:
- continue
- if '=' not in item:
- raise ValueError('Expected "=" in option "%s"' % item)
- name, value = [s.strip() for s in item.split('=', 1)]
- result[name] = parse_variable_value(value)
- return result
+
+
+def parse_variable_value(value):
+ """
+ Parses value as an option value for the given name and returns
+ the interpreted value.
+
+ >>> parse_variable_value('True')
+ True
+ >>> parse_variable_value('true')
+ 'true'
+ >>> parse_variable_value('us-ascii')
+ 'us-ascii'
+ >>> parse_variable_value('str')
+ 'str'
+ >>> parse_variable_value('123')
+ 123
+ >>> parse_variable_value('1.23')
+ 1.23
+
+ """
+ if value == "True":
+ return True
+ elif value == "False":
+ return False
+ elif value == "None":
+ return None
+ elif value.isdigit():
+ return int(value)
+ else:
+ try:
+ value = float(value)
+ except Exception:
+ # Not a float
+ pass
+ return value
+
+
+def parse_compile_time_env(s, current_settings=None):
+ """
+ Parses a comma-separated list of pragma options. Whitespace
+ is not considered.
+
+ >>> parse_compile_time_env(' ')
+ {}
+ >>> (parse_compile_time_env('HAVE_OPENMP=True') ==
+ ... {'HAVE_OPENMP': True})
+ True
+ >>> parse_compile_time_env(' asdf')
+ Traceback (most recent call last):
+ ...
+ ValueError: Expected "=" in option "asdf"
+ >>> parse_compile_time_env('NUM_THREADS=4') == {'NUM_THREADS': 4}
+ True
+ >>> parse_compile_time_env('unknown=anything') == {'unknown': 'anything'}
+ True
+ """
+ if current_settings is None:
+ result = {}
+ else:
+ result = current_settings
+ for item in s.split(','):
+ item = item.strip()
+ if not item:
+ continue
+ if '=' not in item:
+ raise ValueError('Expected "=" in option "%s"' % item)
+ name, value = [s.strip() for s in item.split('=', 1)]
+ result[name] = parse_variable_value(value)
+ return result