| | |
| | |
| | |
| |
|
| | from __future__ import absolute_import |
| |
|
| |
|
| | class ShouldBeFromDirective(object): |
| |
|
| | 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.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. |
| | """ |
| |
|
| | |
| | |
| | |
| | docstrings = True |
| |
|
| | |
| | embed_pos_in_docstring = False |
| |
|
| | |
| | |
| | |
| | emit_code_comments = True |
| |
|
| | |
| | pre_import = None |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | generate_cleanup_code = False |
| |
|
| | |
| | clear_to_none = True |
| |
|
| | |
| | |
| | annotate = False |
| |
|
| | |
| | |
| | annotate_coverage_xml = None |
| |
|
| | |
| | |
| | fast_fail = False |
| |
|
| | |
| | warning_errors = False |
| |
|
| | |
| | |
| | |
| | |
| | error_on_unknown_names = True |
| |
|
| | |
| | |
| | |
| | |
| | error_on_uninitialized = True |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | convert_range = True |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | cache_builtins = True |
| |
|
| | |
| | gcc_branch_hints = True |
| |
|
| | |
| | |
| | |
| | |
| | lookup_module_cpdef = False |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | embed = None |
| |
|
| | |
| | |
| | old_style_globals = ShouldBeFromDirective('old_style_globals') |
| |
|
| | |
| | cimport_from_pyx = False |
| |
|
| | |
| | |
| | |
| | buffer_max_dims = 8 |
| |
|
| | |
| | closure_freelist_size = 8 |
| |
|
| |
|
| | def get_directive_defaults(): |
| | |
| | |
| | |
| | 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: |
| | |
| | _directive_defaults[old_option.directive_name] = value |
| | return _directive_defaults |
| |
|
| | |
| | _directive_defaults = { |
| | 'boundscheck' : True, |
| | 'nonecheck' : False, |
| | 'initializedcheck' : True, |
| | 'embedsignature' : False, |
| | 'auto_cpdef': False, |
| | 'auto_pickle': None, |
| | 'cdivision': False, |
| | 'cdivision_warnings': False, |
| | 'c_api_binop_methods': True, |
| | 'cpow': True, |
| | 'overflowcheck': False, |
| | 'overflowcheck.fold': True, |
| | 'always_allow_keywords': False, |
| | 'allow_none_for_extension_args': True, |
| | 'wraparound' : True, |
| | 'ccomplex' : False, |
| | 'callspec' : "", |
| | 'nogil' : False, |
| | 'profile': False, |
| | 'linetrace': False, |
| | 'emit_code_comments': True, |
| | 'annotation_typing': True, |
| | 'infer_types': None, |
| | 'infer_types.verbose': False, |
| | 'autotestdict': True, |
| | 'autotestdict.cdef': False, |
| | 'autotestdict.all': False, |
| | 'language_level': None, |
| | 'fast_getattr': False, |
| | 'py2_import': False, |
| | 'preliminary_late_includes_cy28': False, |
| | 'iterable_coroutine': False, |
| | 'c_string_type': 'bytes', |
| | 'c_string_encoding': '', |
| | 'type_version_tag': True, |
| | 'unraisable_tracebacks': True, |
| | 'old_style_globals': False, |
| | 'np_pythran': False, |
| | 'fast_gil': False, |
| |
|
| | |
| | 'set_initial_path' : None, |
| |
|
| | 'warn': None, |
| | 'warn.undeclared': False, |
| | 'warn.unreachable': True, |
| | 'warn.maybe_uninitialized': False, |
| | 'warn.unused': False, |
| | 'warn.unused_arg': False, |
| | 'warn.unused_result': False, |
| | 'warn.multiple_declarators': True, |
| |
|
| | |
| | 'optimize.inline_defnode_calls': True, |
| | 'optimize.unpack_method_calls': True, |
| | 'optimize.unpack_method_calls_in_pyinit': False, |
| | 'optimize.use_switch': True, |
| |
|
| | |
| | 'remove_unreachable': True, |
| |
|
| | |
| | 'control_flow.dot_output': "", |
| | 'control_flow.dot_annotate_defs': False, |
| |
|
| | |
| | 'test_assert_path_exists' : [], |
| | 'test_fail_if_path_exists' : [], |
| |
|
| | |
| | 'binding': None, |
| |
|
| | 'formal_grammar': False, |
| | } |
| |
|
| | |
| | extra_warnings = { |
| | 'warn.maybe_uninitialized': True, |
| | 'warn.unreachable': True, |
| | 'warn.unused': True, |
| | } |
| |
|
| | def one_of(*args): |
| | def validate(name, value): |
| | if value not in args: |
| | raise ValueError("%s directive must be one of %s, got '%s'" % ( |
| | name, args, value)) |
| | else: |
| | return value |
| | return validate |
| |
|
| |
|
| | def normalise_encoding_name(option_name, encoding): |
| | """ |
| | >>> normalise_encoding_name('c_string_encoding', 'ascii') |
| | 'ascii' |
| | >>> normalise_encoding_name('c_string_encoding', 'AsCIi') |
| | 'ascii' |
| | >>> normalise_encoding_name('c_string_encoding', 'us-ascii') |
| | 'ascii' |
| | >>> normalise_encoding_name('c_string_encoding', 'utF8') |
| | 'utf8' |
| | >>> normalise_encoding_name('c_string_encoding', 'utF-8') |
| | 'utf8' |
| | >>> normalise_encoding_name('c_string_encoding', 'deFAuLT') |
| | 'default' |
| | >>> normalise_encoding_name('c_string_encoding', 'default') |
| | 'default' |
| | >>> normalise_encoding_name('c_string_encoding', 'SeriousLyNoSuch--Encoding') |
| | 'SeriousLyNoSuch--Encoding' |
| | """ |
| | if not encoding: |
| | return '' |
| | if encoding.lower() in ('default', 'ascii', 'utf8'): |
| | return encoding.lower() |
| | import codecs |
| | try: |
| | decoder = codecs.getdecoder(encoding) |
| | except LookupError: |
| | return encoding |
| | for name in ('ascii', 'utf8'): |
| | if codecs.getdecoder(name) == decoder: |
| | return name |
| | return encoding |
| |
|
| |
|
| | |
| | directive_types = { |
| | 'language_level': str, |
| | 'auto_pickle': bool, |
| | 'locals': dict, |
| | 'final' : bool, |
| | 'nogil' : bool, |
| | 'internal' : bool, |
| | 'infer_types' : bool, |
| | 'binding' : bool, |
| | 'cfunc' : None, |
| | 'ccall' : None, |
| | 'inline' : None, |
| | 'staticmethod' : None, |
| | 'cclass' : None, |
| | 'no_gc_clear' : bool, |
| | 'no_gc' : bool, |
| | 'returns' : type, |
| | 'exceptval': type, |
| | 'set_initial_path': str, |
| | 'freelist': int, |
| | 'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'), |
| | 'c_string_encoding': normalise_encoding_name, |
| | 'cpow': bool |
| | } |
| |
|
| | for key, val in _directive_defaults.items(): |
| | if key not in directive_types: |
| | directive_types[key] = type(val) |
| |
|
| | directive_scopes = { |
| | |
| | 'auto_pickle': ('module', 'cclass'), |
| | 'final' : ('cclass', 'function'), |
| | 'nogil' : ('function', 'with statement'), |
| | 'inline' : ('function',), |
| | 'cfunc' : ('function', 'with statement'), |
| | 'ccall' : ('function', 'with statement'), |
| | 'returns' : ('function',), |
| | 'exceptval' : ('function',), |
| | 'locals' : ('function',), |
| | 'staticmethod' : ('function',), |
| | 'no_gc_clear' : ('cclass',), |
| | 'no_gc' : ('cclass',), |
| | 'internal' : ('cclass',), |
| | 'cclass' : ('class', 'cclass', 'with statement'), |
| | 'autotestdict' : ('module',), |
| | 'autotestdict.all' : ('module',), |
| | 'autotestdict.cdef' : ('module',), |
| | 'set_initial_path' : ('module',), |
| | 'test_assert_path_exists' : ('function', 'class', 'cclass'), |
| | 'test_fail_if_path_exists' : ('function', 'class', 'cclass'), |
| | 'freelist': ('cclass',), |
| | 'emit_code_comments': ('module',), |
| | 'annotation_typing': ('module',), |
| | |
| | 'c_string_type': ('module',), |
| | 'c_string_encoding': ('module',), |
| | 'type_version_tag': ('module', 'cclass'), |
| | 'language_level': ('module',), |
| | |
| | |
| | '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')) |
| | None |
| | >>> parse_directive_value('boundscheck', 'True') |
| | True |
| | >>> parse_directive_value('boundscheck', 'true') |
| | Traceback (most recent call last): |
| | ... |
| | ValueError: boundscheck directive must be set to True or False, got 'true' |
| | |
| | >>> parse_directive_value('c_string_encoding', 'us-ascii') |
| | 'ascii' |
| | >>> parse_directive_value('c_string_type', 'str') |
| | 'str' |
| | >>> parse_directive_value('c_string_type', 'bytes') |
| | 'bytes' |
| | >>> parse_directive_value('c_string_type', 'bytearray') |
| | 'bytearray' |
| | >>> parse_directive_value('c_string_type', 'unicode') |
| | 'unicode' |
| | >>> parse_directive_value('c_string_type', 'unnicode') |
| | Traceback (most recent call last): |
| | 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 |
| | orig_value = value |
| | if type is bool: |
| | value = str(value) |
| | 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 |
| | raise ValueError("%s directive must be set to True or False, got '%s'" % ( |
| | name, orig_value)) |
| | elif type is int: |
| | try: |
| | return int(value) |
| | except ValueError: |
| | raise ValueError("%s directive must be set to an integer, got '%s'" % ( |
| | name, orig_value)) |
| | elif type is str: |
| | return str(value) |
| | elif callable(type): |
| | return type(name, value) |
| | else: |
| | assert False |
| |
|
| |
|
| | def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False, |
| | current_settings=None): |
| | """ |
| | Parses a comma-separated list of pragma options. Whitespace |
| | is not considered. |
| | |
| | >>> parse_directive_list(' ') |
| | {} |
| | >>> (parse_directive_list('boundscheck=True') == |
| | ... {'boundscheck': True}) |
| | True |
| | >>> parse_directive_list(' asdf') |
| | Traceback (most recent call last): |
| | ... |
| | ValueError: Expected "=" in option "asdf" |
| | >>> parse_directive_list('boundscheck=hey') |
| | Traceback (most recent call last): |
| | ... |
| | ValueError: boundscheck directive must be set to True or False, got 'hey' |
| | >>> parse_directive_list('unknown=True') |
| | Traceback (most recent call last): |
| | ... |
| | ValueError: Unknown option: "unknown" |
| | >>> warnings = parse_directive_list('warn.all=True') |
| | >>> len(warnings) > 1 |
| | True |
| | >>> sum(warnings.values()) == len(warnings) # all true. |
| | 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.strip().split('=', 1)] |
| | if name not in _directive_defaults: |
| | found = False |
| | if name.endswith('.all'): |
| | prefix = name[:-3] |
| | for directive in _directive_defaults: |
| | if directive.startswith(prefix): |
| | found = True |
| | parsed_value = parse_directive_value(directive, value, relaxed_bool=relaxed_bool) |
| | result[directive] = parsed_value |
| | if not found and not ignore_unknown: |
| | raise ValueError('Unknown option: "%s"' % name) |
| | else: |
| | 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: |
| | |
| | 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 |
| |
|