OLD | NEW |
(Empty) | |
| 1 # |
| 2 # Cython - Compilation-wide options and pragma declarations |
| 3 # |
| 4 |
| 5 # Perform lookups on builtin names only once, at module initialisation |
| 6 # time. This will prevent the module from getting imported if a |
| 7 # builtin name that it uses cannot be found during initialisation. |
| 8 cache_builtins = True |
| 9 |
| 10 embed_pos_in_docstring = False |
| 11 gcc_branch_hints = True |
| 12 |
| 13 pre_import = None |
| 14 docstrings = True |
| 15 |
| 16 # Decref global variables in this module on exit for garbage collection. |
| 17 # 0: None, 1+: interned objects, 2+: cdef globals, 3+: types objects |
| 18 # Mostly for reducing noise for Valgrind, only executes at process exit |
| 19 # (when all memory will be reclaimed anyways). |
| 20 generate_cleanup_code = False |
| 21 |
| 22 annotate = False |
| 23 |
| 24 # This will abort the compilation on the first error occured rather than trying |
| 25 # to keep going and printing further error messages. |
| 26 fast_fail = False |
| 27 |
| 28 # Make all warnings into errors. |
| 29 warning_errors = False |
| 30 |
| 31 # Make unknown names an error. Python raises a NameError when |
| 32 # encountering unknown names at runtime, whereas this option makes |
| 33 # them a compile time error. If you want full Python compatibility, |
| 34 # you should disable this option and also 'cache_builtins'. |
| 35 error_on_unknown_names = True |
| 36 |
| 37 # Make uninitialized local variable reference a compile time error. |
| 38 # Python raises UnboundLocalError at runtime, whereas this option makes |
| 39 # them a compile time error. Note that this option affects only variables |
| 40 # of "python object" type. |
| 41 error_on_uninitialized = True |
| 42 |
| 43 # This will convert statements of the form "for i in range(...)" |
| 44 # to "for i from ..." when i is a cdef'd integer type, and the direction |
| 45 # (i.e. sign of step) can be determined. |
| 46 # WARNING: This may change the semantics if the range causes assignment to |
| 47 # i to overflow. Specifically, if this option is set, an error will be |
| 48 # raised before the loop is entered, wheras without this option the loop |
| 49 # will execute until an overflowing value is encountered. |
| 50 convert_range = True |
| 51 |
| 52 # Enable this to allow one to write your_module.foo = ... to overwrite the |
| 53 # definition if the cpdef function foo, at the cost of an extra dictionary |
| 54 # lookup on every call. |
| 55 # If this is 0 it simply creates a wrapper. |
| 56 lookup_module_cpdef = False |
| 57 |
| 58 # Whether or not to embed the Python interpreter, for use in making a |
| 59 # standalone executable or calling from external libraries. |
| 60 # This will provide a method which initalizes the interpreter and |
| 61 # executes the body of this module. |
| 62 embed = None |
| 63 |
| 64 # In previous iterations of Cython, globals() gave the first non-Cython module |
| 65 # globals in the call stack. Sage relies on this behavior for variable injectio
n. |
| 66 old_style_globals = False |
| 67 |
| 68 # Allows cimporting from a pyx file without a pxd file. |
| 69 cimport_from_pyx = False |
| 70 |
| 71 # max # of dims for buffers -- set lower than number of dimensions in numpy, as |
| 72 # slices are passed by value and involve a lot of copying |
| 73 buffer_max_dims = 8 |
| 74 |
| 75 # Number of function closure instances to keep in a freelist (0: no freelists) |
| 76 closure_freelist_size = 8 |
| 77 |
| 78 # Should tp_clear() set object fields to None instead of clearing them to NULL? |
| 79 clear_to_none = True |
| 80 |
| 81 |
| 82 # Declare compiler directives |
| 83 directive_defaults = { |
| 84 'boundscheck' : True, |
| 85 'nonecheck' : False, |
| 86 'initializedcheck' : True, |
| 87 'embedsignature' : False, |
| 88 'locals' : {}, |
| 89 'auto_cpdef': False, |
| 90 'cdivision': False, # was True before 0.12 |
| 91 'cdivision_warnings': False, |
| 92 'overflowcheck': False, |
| 93 'overflowcheck.fold': True, |
| 94 'always_allow_keywords': False, |
| 95 'allow_none_for_extension_args': True, |
| 96 'wraparound' : True, |
| 97 'ccomplex' : False, # use C99/C++ for complex types and arith |
| 98 'callspec' : "", |
| 99 'final' : False, |
| 100 'internal' : False, |
| 101 'profile': False, |
| 102 'no_gc_clear': False, |
| 103 'linetrace': False, |
| 104 'infer_types': None, |
| 105 'infer_types.verbose': False, |
| 106 'autotestdict': True, |
| 107 'autotestdict.cdef': False, |
| 108 'autotestdict.all': False, |
| 109 'language_level': 2, |
| 110 'fast_getattr': False, # Undocumented until we come up with a better way to
handle this everywhere. |
| 111 'py2_import': False, # For backward compatibility of Cython's source code in
Py3 source mode |
| 112 'c_string_type': 'bytes', |
| 113 'c_string_encoding': '', |
| 114 'type_version_tag': True, # enables Py_TPFLAGS_HAVE_VERSION_TAG on extensi
on types |
| 115 'unraisable_tracebacks': False, |
| 116 |
| 117 # set __file__ and/or __path__ to known source/target path at import time (i
nstead of not having them available) |
| 118 'set_initial_path' : None, # SOURCEFILE or "/full/path/to/module" |
| 119 |
| 120 'warn': None, |
| 121 'warn.undeclared': False, |
| 122 'warn.unreachable': True, |
| 123 'warn.maybe_uninitialized': False, |
| 124 'warn.unused': False, |
| 125 'warn.unused_arg': False, |
| 126 'warn.unused_result': False, |
| 127 'warn.multiple_declarators': True, |
| 128 |
| 129 # optimizations |
| 130 'optimize.inline_defnode_calls': True, |
| 131 |
| 132 # remove unreachable code |
| 133 'remove_unreachable': True, |
| 134 |
| 135 # control flow debug directives |
| 136 'control_flow.dot_output': "", # Graphviz output filename |
| 137 'control_flow.dot_annotate_defs': False, # Annotate definitions |
| 138 |
| 139 # test support |
| 140 'test_assert_path_exists' : [], |
| 141 'test_fail_if_path_exists' : [], |
| 142 |
| 143 # experimental, subject to change |
| 144 'binding': None, |
| 145 'freelist': 0, |
| 146 } |
| 147 |
| 148 # Extra warning directives |
| 149 extra_warnings = { |
| 150 'warn.maybe_uninitialized': True, |
| 151 'warn.unreachable': True, |
| 152 'warn.unused': True, |
| 153 } |
| 154 |
| 155 def one_of(*args): |
| 156 def validate(name, value): |
| 157 if value not in args: |
| 158 raise ValueError("%s directive must be one of %s, got '%s'" % ( |
| 159 name, args, value)) |
| 160 else: |
| 161 return value |
| 162 return validate |
| 163 |
| 164 |
| 165 def normalise_encoding_name(option_name, encoding): |
| 166 """ |
| 167 >>> normalise_encoding_name('c_string_encoding', 'ascii') |
| 168 'ascii' |
| 169 >>> normalise_encoding_name('c_string_encoding', 'AsCIi') |
| 170 'ascii' |
| 171 >>> normalise_encoding_name('c_string_encoding', 'us-ascii') |
| 172 'ascii' |
| 173 >>> normalise_encoding_name('c_string_encoding', 'utF8') |
| 174 'utf8' |
| 175 >>> normalise_encoding_name('c_string_encoding', 'utF-8') |
| 176 'utf8' |
| 177 >>> normalise_encoding_name('c_string_encoding', 'deFAuLT') |
| 178 'default' |
| 179 >>> normalise_encoding_name('c_string_encoding', 'default') |
| 180 'default' |
| 181 >>> normalise_encoding_name('c_string_encoding', 'SeriousLyNoSuch--Encoding'
) |
| 182 'SeriousLyNoSuch--Encoding' |
| 183 """ |
| 184 if not encoding: |
| 185 return '' |
| 186 if encoding.lower() in ('default', 'ascii', 'utf8'): |
| 187 return encoding.lower() |
| 188 import codecs |
| 189 try: |
| 190 decoder = codecs.getdecoder(encoding) |
| 191 except LookupError: |
| 192 return encoding # may exists at runtime ... |
| 193 for name in ('ascii', 'utf8'): |
| 194 if codecs.getdecoder(name) == decoder: |
| 195 return name |
| 196 return encoding |
| 197 |
| 198 |
| 199 # Override types possibilities above, if needed |
| 200 directive_types = { |
| 201 'final' : bool, # final cdef classes and methods |
| 202 'internal' : bool, # cdef class visibility in the module dict |
| 203 'infer_types' : bool, # values can be True/None/False |
| 204 'binding' : bool, |
| 205 'cfunc' : None, # decorators do not take directive value |
| 206 'ccall' : None, |
| 207 'cclass' : None, |
| 208 'returns' : type, |
| 209 'set_initial_path': str, |
| 210 'freelist': int, |
| 211 'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'), |
| 212 'c_string_encoding': normalise_encoding_name, |
| 213 } |
| 214 |
| 215 for key, val in directive_defaults.items(): |
| 216 if key not in directive_types: |
| 217 directive_types[key] = type(val) |
| 218 |
| 219 directive_scopes = { # defaults to available everywhere |
| 220 # 'module', 'function', 'class', 'with statement' |
| 221 'final' : ('cclass', 'function'), |
| 222 'no_gc_clear' : ('cclass',), |
| 223 'internal' : ('cclass',), |
| 224 'autotestdict' : ('module',), |
| 225 'autotestdict.all' : ('module',), |
| 226 'autotestdict.cdef' : ('module',), |
| 227 'set_initial_path' : ('module',), |
| 228 'test_assert_path_exists' : ('function', 'class', 'cclass'), |
| 229 'test_fail_if_path_exists' : ('function', 'class', 'cclass'), |
| 230 'freelist': ('cclass',), |
| 231 # Avoid scope-specific to/from_py_functions for c_string. |
| 232 'c_string_type': ('module',), |
| 233 'c_string_encoding': ('module',), |
| 234 'type_version_tag': ('module', 'cclass'), |
| 235 } |
| 236 |
| 237 def parse_directive_value(name, value, relaxed_bool=False): |
| 238 """ |
| 239 Parses value as an option value for the given name and returns |
| 240 the interpreted value. None is returned if the option does not exist. |
| 241 |
| 242 >>> print parse_directive_value('nonexisting', 'asdf asdfd') |
| 243 None |
| 244 >>> parse_directive_value('boundscheck', 'True') |
| 245 True |
| 246 >>> parse_directive_value('boundscheck', 'true') |
| 247 Traceback (most recent call last): |
| 248 ... |
| 249 ValueError: boundscheck directive must be set to True or False, got 'true' |
| 250 |
| 251 >>> parse_directive_value('c_string_encoding', 'us-ascii') |
| 252 'ascii' |
| 253 >>> parse_directive_value('c_string_type', 'str') |
| 254 'str' |
| 255 >>> parse_directive_value('c_string_type', 'bytes') |
| 256 'bytes' |
| 257 >>> parse_directive_value('c_string_type', 'bytearray') |
| 258 'bytearray' |
| 259 >>> parse_directive_value('c_string_type', 'unicode') |
| 260 'unicode' |
| 261 >>> parse_directive_value('c_string_type', 'unnicode') |
| 262 Traceback (most recent call last): |
| 263 ValueError: c_string_type directive must be one of ('bytes', 'bytearray', 's
tr', 'unicode'), got 'unnicode' |
| 264 """ |
| 265 type = directive_types.get(name) |
| 266 if not type: return None |
| 267 orig_value = value |
| 268 if type is bool: |
| 269 value = str(value) |
| 270 if value == 'True': return True |
| 271 if value == 'False': return False |
| 272 if relaxed_bool: |
| 273 value = value.lower() |
| 274 if value in ("true", "yes"): return True |
| 275 elif value in ("false", "no"): return False |
| 276 raise ValueError("%s directive must be set to True or False, got '%s'" %
( |
| 277 name, orig_value)) |
| 278 elif type is int: |
| 279 try: |
| 280 return int(value) |
| 281 except ValueError: |
| 282 raise ValueError("%s directive must be set to an integer, got '%s'"
% ( |
| 283 name, orig_value)) |
| 284 elif type is str: |
| 285 return str(value) |
| 286 elif callable(type): |
| 287 return type(name, value) |
| 288 else: |
| 289 assert False |
| 290 |
| 291 def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False, |
| 292 current_settings=None): |
| 293 """ |
| 294 Parses a comma-separated list of pragma options. Whitespace |
| 295 is not considered. |
| 296 |
| 297 >>> parse_directive_list(' ') |
| 298 {} |
| 299 >>> (parse_directive_list('boundscheck=True') == |
| 300 ... {'boundscheck': True}) |
| 301 True |
| 302 >>> parse_directive_list(' asdf') |
| 303 Traceback (most recent call last): |
| 304 ... |
| 305 ValueError: Expected "=" in option "asdf" |
| 306 >>> parse_directive_list('boundscheck=hey') |
| 307 Traceback (most recent call last): |
| 308 ... |
| 309 ValueError: boundscheck directive must be set to True or False, got 'hey' |
| 310 >>> parse_directive_list('unknown=True') |
| 311 Traceback (most recent call last): |
| 312 ... |
| 313 ValueError: Unknown option: "unknown" |
| 314 >>> warnings = parse_directive_list('warn.all=True') |
| 315 >>> len(warnings) > 1 |
| 316 True |
| 317 >>> sum(warnings.values()) == len(warnings) # all true. |
| 318 True |
| 319 """ |
| 320 if current_settings is None: |
| 321 result = {} |
| 322 else: |
| 323 result = current_settings |
| 324 for item in s.split(','): |
| 325 item = item.strip() |
| 326 if not item: continue |
| 327 if not '=' in item: raise ValueError('Expected "=" in option "%s"' % ite
m) |
| 328 name, value = [ s.strip() for s in item.strip().split('=', 1) ] |
| 329 if name not in directive_defaults: |
| 330 found = False |
| 331 if name.endswith('.all'): |
| 332 prefix = name[:-3] |
| 333 for directive in directive_defaults: |
| 334 if directive.startswith(prefix): |
| 335 found = True |
| 336 parsed_value = parse_directive_value(directive, value, r
elaxed_bool=relaxed_bool) |
| 337 result[directive] = parsed_value |
| 338 if not found and not ignore_unknown: |
| 339 raise ValueError('Unknown option: "%s"' % name) |
| 340 else: |
| 341 parsed_value = parse_directive_value(name, value, relaxed_bool=relax
ed_bool) |
| 342 result[name] = parsed_value |
| 343 return result |
OLD | NEW |