Options.py 15 KB

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