# Buggy code
def generate_execution_code(self, code):
    """
    Generate code in the following steps

        1)  copy any closure variables determined thread-private
            into temporaries

        2)  allocate temps for start, stop and step

        3)  generate a loop that calculates the total number of steps,
            which then computes the target iteration variable for every step:

                for i in prange(start, stop, step):
                    ...

            becomes

                nsteps = (stop - start) / step;
                i = start;

                #pragma omp parallel for lastprivate(i)
                for (temp = 0; temp < nsteps; temp++) {
                    i = start + step * temp;
                    ...
                }

            Note that accumulation of 'i' would have a data dependency
            between iterations.

            Also, you can't do this

                for (i = start; i < stop; i += step)
                    ...

            as the '<' operator should become '>' for descending loops.
            'for i from x < i < y:' does not suffer from this problem
            as the relational operator is known at compile time!

        4) release our temps and write back any private closure variables
    """
    self.declare_closure_privates(code)

    # This can only be a NameNode
    target_index_cname = self.target.entry.cname

    # This will be used as the dict to format our code strings, holding
    # the start, stop , step, temps and target cnames
    fmt_dict = {
        "target": target_index_cname,
        "target_type": self.target.type.empty_declaration_code(),
    }

    # Setup start, stop and step, allocating temps if needed
    start_stop_step = self.start, self.stop, self.step
    defaults = "0", "0", "1"
    for node, name, default in zip(start_stop_step, self.names, defaults):
        if node is None:
            result = default
        elif node.is_literal:
            result = node.get_constant_c_result_code()
        else:
            node.generate_evaluation_code(code)
            result = node.result()

        fmt_dict[name] = result

    fmt_dict["i"] = code.funcstate.allocate_temp(self.index_type, False)
    fmt_dict["nsteps"] = code.funcstate.allocate_temp(self.index_type, False)

    # TODO: check if the step is 0 and if so, raise an exception in a
    # 'with gil' block. For now, just abort
    code.putln("if (%(step)s == 0) abort();" % fmt_dict)

    self.setup_parallel_control_flow_block(code)  # parallel control flow block

    self.control_flow_var_code_point = code.insertion_point()

    # Note: nsteps is private in an outer scope if present
    code.putln(
        "%(nsteps)s = (%(stop)s - %(start)s + %(step)s - %(step)s/abs(%(step)s)) / %(step)s;"
        % fmt_dict
    )

    # The target iteration variable might not be initialized, do it only if
    # we are executing at least 1 iteration, otherwise we should leave the
    # target unaffected. The target iteration variable is firstprivate to
    # shut up compiler warnings caused by lastprivate, as the compiler
    # erroneously believes that nsteps may be <= 0, leaving the private
    # target index uninitialized
    code.putln("if (%(nsteps)s > 0)" % fmt_dict)
    code.begin_block()  # if block
    self.generate_loop(code, fmt_dict)
    code.end_block()  # end if block

    self.restore_labels(code)

    if self.else_clause:
        if self.breaking_label_used:
            code.put("if (%s < 2)" % Naming.parallel_why)

        code.begin_block()  # else block
        code.putln("/* else */")
        self.else_clause.generate_execution_code(code)
        code.end_block()  # end else block

    # ------ cleanup ------
    self.end_parallel_control_flow_block(code)  # end parallel control flow block

    # And finally, release our privates and write back any closure
    # variables
    for temp in start_stop_step + (self.chunksize, self.num_threads):
        if temp is not None:
            temp.generate_disposal_code(code)
            temp.free_temps(code)

    code.funcstate.release_temp(fmt_dict["i"])
    code.funcstate.release_temp(fmt_dict["nsteps"])

    self.release_closure_privates(code)


# Traceback (TypeError)
%%cython
from contextlib import contextmanager

@contextmanager
def tag(name):
print("<%s>" % name)
yield
print("</%s>" % name)

from cython.parallel cimport prange
from libc.stdio cimport printf

def func():
cdef int i

with tag('aaa'):
for i in prange(5, nogil=True):   # using "xrange" or "with nogil" works well
printf("%d", i)

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Main.py:367: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /Users/tema/.ipython/cython/_cython_magic_52369e6689303208367674016d90c298.pyx
tree = Parsing.p_module(s, pxd, full_module_name)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-72854e963c38> in <module>()
----> 1 get_ipython().run_cell_magic(u'cython', u'', u'from contextlib import contextmanager\n\n@contextmanager\ndef tag(name):\n    print("<%s>" % name)\n    yield\n    print("</%s>" % name)\n\n\nfrom cython.parallel cimport prange\nfrom libc.stdio cimport printf\n\n\ndef func():\n    cdef int i\n\n    with tag(\'aaa\'):\n        for i in prange(5, nogil=True):\n            printf("%d", i)')

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/IPython/core/interactiveshell.pyc in run_cell_magic(self, magic_name, line, cell)
2115             magic_arg_s = self.var_expand(line, stack_depth)
2116             with self.builtin_trap:
-> 2117                 result = fn(magic_arg_s, cell)
2118             return result
2119

<decorator-gen-118> in cython(self, line, cell)

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/IPython/core/magic.pyc in <lambda>(f, *a, **k)
186     # but it's overkill for just that one bit of state.
187     def magic_deco(arg):
--> 188         call = lambda f, *a, **k: f(*a, **k)
189
190         if callable(arg):

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Build/IpythonMagic.pyc in cython(self, line, cell)
322         extension = None
323         if need_cythonize:
--> 324             extensions = self._cythonize(module_name, code, lib_dir, args, quiet=args.quiet)
325             assert len(extensions) == 1
326             extension = extensions[0]

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Build/IpythonMagic.pyc in _cythonize(self, module_name, code, lib_dir, args, quiet)
430             elif sys.version_info[0] >= 3:
431                 opts['language_level'] = 3
--> 432             return cythonize([extension], **opts)
433         except CompileError:
434             return None

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Build/Dependencies.pyc in cythonize(module_list, exclude, nthreads, aliases, quiet, force, language, exclude_failures, **options)
1084     if not nthreads:
1085         for args in to_compile:
-> 1086             cythonize_one(*args)
1087
1088     if exclude_failures:

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Build/Dependencies.pyc in cythonize_one(pyx_file, c_file, fingerprint, quiet, options, raise_on_failure, embedded_metadata, full_module_name, progress)
1190     any_failures = 0
1191     try:
-> 1192         result = compile_single(pyx_file, options, full_module_name=full_module_name)
1193         if result.num_errors > 0:
1194             any_failures = 1

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Main.pyc in compile_single(source, options, full_module_name)
723     recursion.
724     """
--> 725     return run_pipeline(source, options, full_module_name)
726
727

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Main.pyc in run_pipeline(source, options, full_module_name, context)
511
512     context.setup_errors(options, result)
--> 513     err, enddata = Pipeline.run_pipeline(pipeline, source)
514     context.teardown_errors(err, options, result)
515     return result

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Pipeline.pyc in run_pipeline(pipeline, source, printtree)
353                             exec("def %s(phase, data): return phase(data)" % phase_name, exec_ns)
354                             run = _pipeline_entry_points[phase_name] = exec_ns[phase_name]
--> 355                     data = run(phase, data)
356                     if DebugFlags.debug_verbose_pipeline:
357                         print("    %.3f seconds" % (time() - t))

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Pipeline.pyc in run(phase, data)
333
334     def run(phase, data):
--> 335         return phase(data)
336
337     error = None

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Pipeline.pyc in generate_pyx_code_stage(module_node)
50 def generate_pyx_code_stage_factory(options, result):
51     def generate_pyx_code_stage(module_node):
---> 52         module_node.process_implementation(options, result)
53         result.compilation_source = module_node.compilation_source
54         return result

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/ModuleNode.pyc in process_implementation(self, options, result)
141         self.find_referenced_modules(env, self.referenced_modules, {})
142         self.sort_cdef_classes(env)
--> 143         self.generate_c_code(env, options, result)
144         self.generate_h_code(env, options, result)
145         self.generate_api_code(env, options, result)

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/ModuleNode.pyc in generate_c_code(self, env, options, result)
377         self.generate_variable_definitions(env, code)
378
--> 379         self.body.generate_function_definitions(env, code)
380
381         code.mark_pos(None)

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Nodes.pyc in generate_function_definitions(self, env, code)
440         #print "StatListNode.generate_function_definitions" ###
441         for stat in self.stats:
--> 442             stat.generate_function_definitions(env, code)
443
444     def generate_execution_code(self, code):

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Nodes.pyc in generate_function_definitions(self, env, code)
3171             self.py_wrapper.func_cname = self.entry.func_cname
3172             self.py_wrapper.generate_function_definitions(env, code)
-> 3173         FuncDefNode.generate_function_definitions(self, env, code)
3174
3175     def generate_function_header(self, code, with_pymethdef, proto_only=0):

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Nodes.pyc in generate_function_definitions(self, env, code)
1981         # ----- Function body -----
1982         # -------------------------
-> 1983         self.generate_function_body(env, code)
1984
1985         code.mark_pos(self.pos, trace=False)

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Nodes.pyc in generate_function_body(self, env, code)
1743
1744     def generate_function_body(self, env, code):
-> 1745         self.body.generate_execution_code(code)
1746
1747     def generate_function_definitions(self, env, code):

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Nodes.pyc in generate_execution_code(self, code)
446         for stat in self.stats:
447             code.mark_pos(stat.pos)
--> 448             stat.generate_execution_code(code)
449
450     def annotate(self, code):

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Nodes.pyc in generate_execution_code(self, code)
7090
7091         code.error_label = old_error_label
-> 7092         self.body.generate_execution_code(code)
7093
7094         if code.label_used(intermediate_error_label):

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Nodes.pyc in generate_execution_code(self, code)
7559         if not self.body.is_terminator:
7560             code.putln('/*normal exit:*/{')
-> 7561             fresh_finally_clause().generate_execution_code(code)
7562             if not self.finally_clause.is_terminator:
7563                 code.put_goto(catch_label)

/Users/tema/Projects/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Nodes.pyc in fresh_finally_clause(_next)
7547             # generate the original subtree once and always keep a fresh copy
7548             node = _next[0]
-> 7549             node_copy = copy.deepcopy(node)
7550             if node is self.finally_clause:
7551                 _next[0] = node_copy

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_list(x, memo)
228     memo[id(x)] = y
229     for a in x:
--> 230         y.append(deepcopy(a, memo))
231     return y
232 d[list] = _deepcopy_list

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_list(x, memo)
228     memo[id(x)] = y
229     for a in x:
--> 230         y.append(deepcopy(a, memo))
231     return y
232 d[list] = _deepcopy_list

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
188                             raise Error(
189                                 "un(deep)copyable object of type %s" % cls)
--> 190                 y = _reconstruct(x, rv, 1, memo)
191
192     memo[d] = y

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _reconstruct(x, info, deep, memo)
332     if state is not None:
333         if deep:
--> 334             state = deepcopy(state, memo)
335         if hasattr(y, '__setstate__'):
336             y.__setstate__(state)

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
161     copier = _deepcopy_dispatch.get(cls)
162     if copier:
--> 163         y = copier(x, memo)
164     else:
165         try:

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in _deepcopy_dict(x, memo)
255     memo[id(x)] = y
256     for key, value in x.iteritems():
--> 257         y[deepcopy(key, memo)] = deepcopy(value, memo)
258     return y
259 d[dict] = _deepcopy_dict

/Users/tema/Projects/miniconda2/lib/python2.7/copy.pyc in deepcopy(x, memo, _nil)
180                     reductor = getattr(x, "__reduce_ex__", None)
181                     if reductor:
--> 182                         rv = reductor(2)
183                     else:
184                         reductor = getattr(x, "__reduce__", None)

TypeError: can't pickle cStringIO.StringO objects

# Fixed code
def generate_execution_code(self, code):
    """
    Generate code in the following steps

        1)  copy any closure variables determined thread-private
            into temporaries

        2)  allocate temps for start, stop and step

        3)  generate a loop that calculates the total number of steps,
            which then computes the target iteration variable for every step:

                for i in prange(start, stop, step):
                    ...

            becomes

                nsteps = (stop - start) / step;
                i = start;

                #pragma omp parallel for lastprivate(i)
                for (temp = 0; temp < nsteps; temp++) {
                    i = start + step * temp;
                    ...
                }

            Note that accumulation of 'i' would have a data dependency
            between iterations.

            Also, you can't do this

                for (i = start; i < stop; i += step)
                    ...

            as the '<' operator should become '>' for descending loops.
            'for i from x < i < y:' does not suffer from this problem
            as the relational operator is known at compile time!

        4) release our temps and write back any private closure variables
    """
    self.declare_closure_privates(code)

    # This can only be a NameNode
    target_index_cname = self.target.entry.cname

    # This will be used as the dict to format our code strings, holding
    # the start, stop , step, temps and target cnames
    fmt_dict = {
        "target": target_index_cname,
        "target_type": self.target.type.empty_declaration_code(),
    }

    # Setup start, stop and step, allocating temps if needed
    start_stop_step = self.start, self.stop, self.step
    defaults = "0", "0", "1"
    for node, name, default in zip(start_stop_step, self.names, defaults):
        if node is None:
            result = default
        elif node.is_literal:
            result = node.get_constant_c_result_code()
        else:
            node.generate_evaluation_code(code)
            result = node.result()

        fmt_dict[name] = result

    fmt_dict["i"] = code.funcstate.allocate_temp(self.index_type, False)
    fmt_dict["nsteps"] = code.funcstate.allocate_temp(self.index_type, False)

    # TODO: check if the step is 0 and if so, raise an exception in a
    # 'with gil' block. For now, just abort
    code.putln("if (%(step)s == 0) abort();" % fmt_dict)

    self.setup_parallel_control_flow_block(code)  # parallel control flow block

    # Note: nsteps is private in an outer scope if present
    code.putln(
        "%(nsteps)s = (%(stop)s - %(start)s + %(step)s - %(step)s/abs(%(step)s)) / %(step)s;"
        % fmt_dict
    )

    # The target iteration variable might not be initialized, do it only if
    # we are executing at least 1 iteration, otherwise we should leave the
    # target unaffected. The target iteration variable is firstprivate to
    # shut up compiler warnings caused by lastprivate, as the compiler
    # erroneously believes that nsteps may be <= 0, leaving the private
    # target index uninitialized
    code.putln("if (%(nsteps)s > 0)" % fmt_dict)
    code.begin_block()  # if block
    self.generate_loop(code, fmt_dict)
    code.end_block()  # end if block

    self.restore_labels(code)

    if self.else_clause:
        if self.breaking_label_used:
            code.put("if (%s < 2)" % Naming.parallel_why)

        code.begin_block()  # else block
        code.putln("/* else */")
        self.else_clause.generate_execution_code(code)
        code.end_block()  # end else block

    # ------ cleanup ------
    self.end_parallel_control_flow_block(code)  # end parallel control flow block

    # And finally, release our privates and write back any closure
    # variables
    for temp in start_stop_step + (self.chunksize, self.num_threads):
        if temp is not None:
            temp.generate_disposal_code(code)
            temp.free_temps(code)

    code.funcstate.release_temp(fmt_dict["i"])
    code.funcstate.release_temp(fmt_dict["nsteps"])

    self.release_closure_privates(code)