def inline(f, *args, **kwds): if isinstance(f, basestring): from Cython.Build.Inline import cython_inline return cython_inline(f, *args, **kwds) else: assert len(args) == len(kwds) == 0 return f
def cythonize_func_inline_method(self, func, function_lines, def_line_index, hash_only=False, *args, **kwargs): """ Compiles the function if it hasn't been compile before, and stores the function for reuse """ if hash_only: cython_def_lines = self.format_function_code_to_cython( func, function_lines, def_line_index, hash_only=True, *args, **kwargs ) function_hash_name = self.hash_func(cython_def_lines) return function_hash_name else: cython_function_code, cython_def_lines = self.format_function_code_to_cython( func, function_lines, def_line_index, *args, **kwargs ) cythonized_func = cython_inline(cython_function_code, cython_compiler_directives={ "infer_types": self.infer_types, }) cythonized_func = cythonized_func.get(func.__name__, None) if cythonized_func is None: python_func = "".join(function_lines) cythonized_func = cython.inline(python_func).get(func.__name__, None) if cythonized_func is None: cythonized_func = func function_hash_name = self.hash_func(cython_def_lines) return function_hash_name, cythonized_func
def exec(code, globals_=None, locals_=None): if locals_ and globals_ and (locals_ is not globals_): # a hacky attempt to treat as a class definition code = "class Cls:\n" + "\n".join(" " + line for line in code.split("\n")) code += "\nreturn globals(), locals()" # so we can inspect it for changes, overriding the default cython_inline behaviour try: with StdErrHider() as stderr_handler: try: g, l = cython_inline(code, globals=globals_, locals=locals_) finally: err_messages = stderr_handler.stderr_contents if globals_ is not None: # because Cython inline bundles everything into a function some values that # we'd expect to be in globals end up in locals. This isn't quite right but is # as close as it's possible to get to retrieving the values globals_.update(l) globals_.update(g) except CompileError as exc: raised_message = str(exc) if raised_message.endswith(".pyx"): # unhelpfully Cython sometimes raises a compile error and sometimes just raises the filename raised_message = [] for line in err_messages.split("\n"): line = line.split(":", 3) # a usable error message with be filename:line:char: message if len(line) == 4 and line[0].endswith(".pyx"): raised_message.append(line[-1]) # output all the errors - we aren't worried about reproducing the exact order CPython # emits errors in raised_message = "; ".join(raised_message) raise SyntaxError(raised_message) from None